Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-ethertype.c
blob8f4827944f5368cb2388e7c5a09990e9224b9ec9
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).
6 * Gilbert Ramirez <gram@alumni.rice.edu>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * SPDX-License-Identifier: GPL-2.0-or-later
15 #include "config.h"
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"
27 void proto_register_ethertype(void);
29 static dissector_table_t ethertype_dissector_table;
31 static int proto_ethertype;
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 Heterogeneous 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_FORTINET_FGCP_HB, "Fortinet FGCP (FortiGate Cluster Protocol) HB (HeartBeat)" },
87 { ETHERTYPE_RSN_PREAUTH, "802.11i Pre-Authentication" },
88 { ETHERTYPE_MPLS, "MPLS label switched packet" },
89 { ETHERTYPE_MPLS_MULTI, "MPLS multicast label switched packet" },
90 { ETHERTYPE_3C_NBP_DGRAM, "3Com NBP Datagram" },
91 { ETHERTYPE_DEC, "DEC proto" },
92 { ETHERTYPE_DNA_DL, "DEC DNA Dump/Load" },
93 { ETHERTYPE_DNA_RC, "DEC DNA Remote Console" },
94 { ETHERTYPE_DNA_RT, "DEC DNA Routing" },
95 { ETHERTYPE_LAT, "DEC LAT" },
96 { ETHERTYPE_DEC_DIAG, "DEC Diagnostics" },
97 { ETHERTYPE_DEC_CUST, "DEC Customer use" },
98 { ETHERTYPE_DEC_SCA, "DEC LAVC/SCA" },
99 { ETHERTYPE_DEC_LAST, "DEC LAST" },
100 { ETHERTYPE_ETHBRIDGE, "Transparent Ethernet bridging" },
101 { ETHERTYPE_CGMP, "Cisco Group Management Protocol" },
102 { ETHERTYPE_GIGAMON, "Gigamon Header" },
103 { ETHERTYPE_MSRP, "802.1Qat Multiple Stream Reservation Protocol" },
104 { ETHERTYPE_MMRP, "802.1ak Multiple Mac Registration Protocol" },
105 { ETHERTYPE_NSH, "Network Service Header" },
106 { ETHERTYPE_PA_HBBACKUP, "PA HB Backup" },
107 { ETHERTYPE_AVTP, "IEEE 1722 Audio Video Transport Protocol" },
108 { ETHERTYPE_ROHC, "Robust Header Compression(RoHC)" },
109 { ETHERTYPE_TRILL, "Transparent Interconnection of Lots of Links" },
110 { ETHERTYPE_L2ISIS, "Intermediate System to Intermediate System" },
111 { ETHERTYPE_MAC_CONTROL, "MAC Control" },
112 { ETHERTYPE_SLOW_PROTOCOLS, "Slow Protocols" },
113 { ETHERTYPE_RTMAC, "Real-Time Media Access Control" },
114 { ETHERTYPE_RTCFG, "Real-Time Configuration Protocol" },
115 { ETHERTYPE_CDMA2000_A10_UBS, "CDMA2000 A10 Unstructured byte stream" },
116 { ETHERTYPE_ATMOE, "ATM over Ethernet" },
117 { ETHERTYPE_PROFINET, "PROFINET" },
118 { ETHERTYPE_REALTEK, "Realtek Layer 2 Protocols" },
119 { ETHERTYPE_AOE, "ATA over Ethernet" },
120 { ETHERTYPE_ECATF, "EtherCAT frame" },
121 { ETHERTYPE_TELKONET, "Telkonet powerline" },
122 { ETHERTYPE_EPL_V2, "ETHERNET Powerlink v2" },
123 { ETHERTYPE_XIMETA, "XiMeta Technology" },
124 { ETHERTYPE_CSM_ENCAPS, "CSM_ENCAPS Protocol" },
125 { ETHERTYPE_EXPERIMENTAL_ETH1, "Local Experimental Ethertype 1" },
126 { ETHERTYPE_EXPERIMENTAL_ETH2, "Local Experimental Ethertype 2" },
127 { ETHERTYPE_IEEE802_OUI_EXTENDED, "IEEE 802a OUI Extended Ethertype" },
128 { ETHERTYPE_IEC61850_GOOSE, "IEC 61850/GOOSE" },
129 { ETHERTYPE_IEC61850_GSE, "IEC 61850/GSE management services" },
130 { ETHERTYPE_IEC61850_SV, "IEC 61850/SV (Sampled Value Transmission" },
131 { ETHERTYPE_TIPC, "Transparent Inter Process Communication" },
132 { ETHERTYPE_LLDP, "802.1 Link Layer Discovery Protocol (LLDP)" },
133 { ETHERTYPE_3GPP2, "CDMA2000 A10 3GPP2 Packet" },
134 { ETHERTYPE_TTE_PCF, "TTEthernet Protocol Control Frame" },
135 { ETHERTYPE_CESOETH, "Circuit Emulation Services over Ethernet (MEF8)" },
136 { ETHERTYPE_LLTD, "Link Layer Topology Discovery (LLTD)" },
137 { ETHERTYPE_WSMP, "(WAVE) Short Message Protocol (WSM)" },
138 { ETHERTYPE_VMLAB, "VMware Lab Manager" },
139 { ETHERTYPE_COBRANET, "Cirrus Cobranet Packet" },
140 { ETHERTYPE_NSRP, "Juniper Netscreen Redundant Protocol" },
141 { ETHERTYPE_EERO, "EERO Broadcast Packet" },
143 * NDISWAN on Windows translates Ethernet frames from higher-level
144 * protocols into PPP frames to hand to the PPP driver, and translates
145 * PPP frames from the PPP driver to hand to the higher-level protocols.
147 * Apparently the PPP driver, on at least some versions of Windows,
148 * passes frames for internal-to-PPP protocols up through NDISWAN;
149 * the protocol type field appears to be passed through unchanged
150 * (unlike what's done with, for example, the protocol type field
151 * for IP, which is mapped from its PPP value to its Ethernet value).
153 * This means that we may see, on Ethernet captures, frames for
154 * protocols internal to PPP, so we list as "Ethernet" protocol
155 * types the PPP protocol types we've seen.
157 { PPP_IPCP, "PPP IP Control Protocol" },
158 { PPP_LCP, "PPP Link Control Protocol" },
159 { PPP_PAP, "PPP Password Authentication Protocol" },
160 { PPP_CCP, "PPP Compression Control Protocol" },
161 { ETHERTYPE_LLT, "Veritas Low Latency Transport (not officially registered)" },
162 { ETHERTYPE_CFM, "IEEE 802.1Q Connectivity Fault Management (CFM) protocol" },
163 { ETHERTYPE_DCE, "Data Center Ethernet (DCE) protocol(Cisco)" },
164 { ETHERTYPE_FCOE, "Fibre Channel over Ethernet" },
165 { ETHERTYPE_IEEE80211_DATA_ENCAP, "IEEE 802.11 data encapsulation" },
166 { ETHERTYPE_LINX, "LINX IPC Protocol" },
167 { ETHERTYPE_FIP, "FCoE Initialization Protocol" },
168 { ETHERTYPE_MIH, "Media Independent Handover Protocol" },
169 { ETHERTYPE_ELMI, "Ethernet Local Management Interface (MEF16)" },
170 { ETHERTYPE_PTP, "PTPv2 over Ethernet (IEEE1588)" },
171 { ETHERTYPE_NCSI, "Network Controller Sideband Interface" },
172 { ETHERTYPE_PRP, "Parallel Redundancy Protocol (PRP) and HSR Supervision (IEC62439 Part 3)" },
173 { ETHERTYPE_FLIP, "Flow Layer Internal Protocol" },
174 { ETHERTYPE_ROCE, "RDMA over Converged Ethernet" },
175 { ETHERTYPE_TDMOE, "Digium TDM over Ethernet Protocol" },
176 { ETHERTYPE_WAI, "WAI Authentication Protocol" },
177 { ETHERTYPE_VNTAG, "VN-Tag" },
178 { ETHERTYPE_SEL_L2, "Schweitzer Engineering Labs Layer 2 Protocol" },
179 { ETHERTYPE_HSR, "High-availability Seamless Redundancy (IEC62439 Part 3)" },
180 { ETHERTYPE_BPQ, "AX.25" },
181 { ETHERTYPE_CMD, "CiscoMetaData" },
182 { ETHERTYPE_GEONETWORKING, "GeoNetworking" },
183 { ETHERTYPE_XIP, "eXpressive Internet Protocol" },
184 { ETHERTYPE_NWP, "Neighborhood Watch Protocol" },
185 { ETHERTYPE_BLUECOM, "bluecom Protocol" },
186 { ETHERTYPE_QINQ_OLD, "QinQ: old non-standard 802.1ad" },
187 { ETHERTYPE_TECMP, "Technically Enhanced Capture Module Protocol (TECMP) or ASAM Capture Module Protocol (CMP)" },
188 { ETHERTYPE_6LOWPAN, "6LoWPAN" },
189 { ETHERTYPE_AVSP, "Arista Vendor Specific Protocol" },
190 { ETHERTYPE_ECPRI, "eCPRI" },
191 { ETHERTYPE_CABLELABS, "CableLabs Layer-3 Protocol" },
192 { ETHERTYPE_EXEH, "EXos internal Extra Header" },
193 { ETHERTYPE_ATRL, "Allied Telesis Resiliency Link" },
194 { ETHERTYPE_ACIGLEAN, "Cisco ACI ARP gleaning" },
195 { ETHERTYPE_IEEE_802_1CB, "802.1CB Frame Replication and Elimination for Reliability" },
196 { 0, NULL }
199 static void eth_prompt(packet_info *pinfo, char* result)
201 snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "Ethertype 0x%04x as",
202 GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto_ethertype, pinfo->curr_layer_num)));
205 static void *eth_value(packet_info *pinfo)
207 return p_get_proto_data(pinfo->pool, pinfo, proto_ethertype, pinfo->curr_layer_num);
210 static void add_dix_trailer(packet_info *pinfo, proto_tree *tree, proto_tree *fh_tree,
211 int trailer_id, tvbuff_t *tvb, tvbuff_t *next_tvb, int offset_after_etype,
212 unsigned length_before, int fcs_len);
215 void
216 ethertype(uint16_t etype, tvbuff_t *tvb, int offset_after_etype,
217 packet_info *pinfo, proto_tree *tree, proto_tree *fh_tree,
218 int etype_id, int trailer_id, int fcs_len)
220 static int
221 dissect_ethertype(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
223 const char *description;
224 tvbuff_t *volatile next_tvb;
225 unsigned length_before;
226 int captured_length, reported_length;
227 volatile int dissector_found = 0;
228 const char *volatile saved_proto;
229 ethertype_data_t *ethertype_data;
231 /* Reject the packet if data is NULL */
232 if (data == NULL)
233 return 0;
234 ethertype_data = (ethertype_data_t*)data;
236 /* Get the captured length and reported length of the data
237 after the Ethernet type. */
238 captured_length = tvb_captured_length_remaining(tvb, ethertype_data->payload_offset);
239 reported_length = tvb_reported_length_remaining(tvb,
240 ethertype_data->payload_offset);
242 /* With Cisco ACI gleaning, the rest of the packet is dissected for informational purposes only */
243 if (ethertype_data->etype == ETHERTYPE_ACIGLEAN) {
245 unsigned gleantype, payload_etype;
247 col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "0x%04x", ethertype_data->etype);
248 col_set_writable(pinfo->cinfo, COL_PROTOCOL, false);
250 description = try_val_to_str(ethertype_data->etype, etype_vals);
251 col_add_str(pinfo->cinfo, COL_INFO, description);
252 col_set_writable(pinfo->cinfo, COL_INFO, false);
253 if (reported_length >= 1) {
254 gleantype = (tvb_get_uint8(tvb, ethertype_data->payload_offset) & 0xF0) >> 4;
255 switch (gleantype) {
256 case 4: /* IPv4 */
257 payload_etype = 0x0800;
258 break;
259 case 6: /* IPv6 */
260 payload_etype = 0x86BB;
261 break;
262 default: /* ARP */
263 payload_etype = 0x0806;
265 ethertype_data->etype = payload_etype;
266 // FIXME: Add glean to protocol-stack in frame-header
270 /* Remember how much data there is after the Ethernet type,
271 including any trailer and FCS. */
272 length_before = reported_length;
274 /* Construct a tvbuff for the payload after the Ethernet type.
275 If the FCS length is positive, remove the FCS.
276 (If it's zero, there's no FCS; if it's negative,
277 we don't know whether there's an FCS, so we'll
278 guess based on the length of the trailer.) */
279 if (ethertype_data->fcs_len > 0) {
280 if (captured_length >= 0 && reported_length >= 0) {
281 if (reported_length >= ethertype_data->fcs_len)
282 reported_length -= ethertype_data->fcs_len;
283 if (captured_length > reported_length)
284 captured_length = reported_length;
287 next_tvb = tvb_new_subset_length_caplen(tvb, ethertype_data->payload_offset, captured_length,
288 reported_length);
290 p_add_proto_data(pinfo->pool, pinfo, proto_ethertype, pinfo->curr_layer_num, GUINT_TO_POINTER((unsigned)ethertype_data->etype));
292 /* Look for sub-dissector, and call it if found.
293 Catch exceptions, so that if the reported length of "next_tvb"
294 was reduced by some dissector before an exception was thrown,
295 we can still put in an item for the trailer. */
296 saved_proto = pinfo->current_proto;
297 TRY {
298 dissector_found = dissector_try_uint(ethertype_dissector_table,
299 ethertype_data->etype, next_tvb, pinfo, tree);
301 CATCH_NONFATAL_ERRORS {
302 /* Somebody threw an exception that means that there
303 was a problem dissecting the payload; that means
304 that a dissector was found, so we don't need to
305 dissect the payload as data or update the protocol
306 or info columns.
308 Just show the exception and then drive on to show
309 the trailer, after noting that a dissector was found
310 and restoring the protocol value that was in effect
311 before we called the subdissector. */
312 show_exception(next_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
314 dissector_found = 1;
315 pinfo->current_proto = saved_proto;
317 ENDTRY;
319 if (!dissector_found) {
320 /* No sub-dissector found.
321 Label rest of packet as "Data" */
322 call_data_dissector(next_tvb, pinfo, tree);
324 /* Label protocol */
325 col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "0x%04x", ethertype_data->etype);
327 description = try_val_to_str(ethertype_data->etype, etype_vals);
328 if (description) {
329 col_add_str(pinfo->cinfo, COL_INFO, description);
333 add_dix_trailer(pinfo, tree, ethertype_data->fh_tree, ethertype_data->trailer_id, tvb, next_tvb, ethertype_data->payload_offset,
334 length_before, ethertype_data->fcs_len);
336 return tvb_captured_length(tvb);
339 static void
340 add_dix_trailer(packet_info *pinfo, proto_tree *tree, proto_tree *fh_tree, int trailer_id,
341 tvbuff_t *tvb, tvbuff_t *next_tvb, int offset_after_etype,
342 unsigned length_before, int fcs_len)
344 unsigned length;
345 tvbuff_t *trailer_tvb;
347 /* OK, how much is there in that tvbuff now? */
348 length = tvb_reported_length(next_tvb);
350 /* If there's less than there was before, what's left is
351 a trailer. */
352 if (length < length_before) {
354 * Is any of the padding present in the tvbuff?
356 if (tvb_offset_exists(tvb, offset_after_etype + length)) {
358 * Yes - create a tvbuff for the padding.
360 trailer_tvb = tvb_new_subset_remaining(tvb,
361 offset_after_etype + length);
362 } else {
364 * No - don't bother showing the trailer.
365 * XXX - show a Short Frame indication?
367 trailer_tvb = NULL;
369 } else
370 trailer_tvb = NULL; /* no trailer */
372 /* XXX: If the length of next_tvb is less than it was before, but this
373 * is not the first time the ethertype dissector has been called, we
374 * would rather not add the trailer here, but instead also reduce the
375 * length of tvb and have the previous ethertype dissector add the
376 * trailer instead. That's the only way we can properly detect and
377 * check the FCS in "maybefcs" mode (we need the full frame.)
378 * It also would be less confusing because we would always just
379 * use eth.trailer instead of sometimes e.g. vlan.trailer (#18252).
381 * It does require that the second time the ethertype dissector was
382 * called that ethertype_data.payload_offset was set and the original
383 * tvb used instead of creating a new subset tvb - in the latter case
384 * tvb here is not the same as the next_tvb from the previous ethertype
385 * dissector. That's not the case for ethertypes like 802.1AE MACSec
386 * that add a trailer as well, where we likely took a subset to shave
387 * off the trailer.
389 * We can't just "set the reported length of the backing tvbuff",
390 * because the ultimately backing tvbuff might be something that
391 * encapsulates the Ethernet frame, e.g. ISL or GSE Bridged Frames)
393 * To see if the ethertype dissector was called earlier from the entire
394 * Ethernet frame, we can't just check if offset_after_etype != 14, as
395 * it could be something that calls ethertype directly without having the
396 * entire Ethernet frame somewhere (e.g. a Linux "cooked mode" capture
397 * (packet-sll), or something set in the USER ENCAP UAT, etc.)
398 * We also can't check pinfo->curr_proto_layer_num or proto_layers if
399 * there are multiple entire Ethernet frames encapsulated in this
400 * frame, e.g. a DVB BaseBand Frame with multiple GSE frames with
401 * Bridge Frame encapsulation.
403 * We might need to add a new field to ethertype_data, or set
404 * something in pinfo->pool scoped packet data.
406 add_ethernet_trailer(pinfo, tree, fh_tree, trailer_id, tvb, trailer_tvb, fcs_len, offset_after_etype);
409 void
410 proto_register_ethertype(void)
412 /* Decode As handling */
413 static build_valid_func eth_da_build_value[1] = {eth_value};
414 static decode_as_value_t eth_da_values = {eth_prompt, 1, eth_da_build_value};
415 static decode_as_t ethertype_da = {"ethertype", "ethertype", 1, 0, &eth_da_values, NULL, NULL,
416 decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL};
419 proto_ethertype = proto_register_protocol("Ethertype", "Ethertype", "ethertype");
420 /* This isn't a real protocol, so you can't disable its dissection. */
421 proto_set_cant_toggle(proto_ethertype);
423 register_dissector("ethertype", dissect_ethertype, proto_ethertype);
425 /* subdissector code */
426 ethertype_dissector_table = register_dissector_table("ethertype",
427 "Ethertype", proto_ethertype, FT_UINT16, BASE_HEX);
428 register_capture_dissector_table("ethertype", "Ethertype");
430 register_decode_as(&ethertype_da);
434 * Editor modelines - https://www.wireshark.org/tools/modelines.html
436 * Local variables:
437 * c-basic-offset: 8
438 * tab-width: 8
439 * indent-tabs-mode: t
440 * End:
442 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
443 * :indentSize=8:tabSize=8:noTabs=false: