dbcdb8b18fbfbbbf62a28638ee8e73c3b495d4f8
[obnox/wireshark/wip.git] / epan / dissectors / packet-ethertype.c
1 /* packet-ethertype.c
2  * Routines for calling the right protocol for the ethertype.
3  *
4  * $Id$
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  * 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.
16  *
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.
21  *
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
25  */
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <glib.h>
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-ieee8021ah.h"
40 #include "packet-vines.h"
41 #include <epan/etypes.h>
42 #include <epan/ppptypes.h>
43
44 static dissector_table_t ethertype_dissector_table;
45
46 static dissector_handle_t data_handle;
47
48 const value_string etype_vals[] = {
49     {ETHERTYPE_IP,                                              "IP"                            },
50     {ETHERTYPE_IPv6,                                    "IPv6"                          },
51     {ETHERTYPE_WLCCP,                                   "Cisco Wireless Lan Context Control Protocol"           },
52     {ETHERTYPE_CENTRINO_PROMISC,                "IEEE 802.11 (Centrino promiscuous)" },
53     {ETHERTYPE_XNS_IDP,                                 "XNS Internet Datagram Protocol" },
54     {ETHERTYPE_X25L3,                                   "X.25 Layer 3"                  },
55     {ETHERTYPE_ARP,                                             "ARP"                           },
56     {ETHERTYPE_WOL,                                             "Wake on LAN"                   },
57     {ETHERTYPE_WMX_M2M,                                 "WiMax Mac-to-Mac"              },
58     {ETHERTYPE_EPL_V1,                                  "EPL_V1"                                },
59     {ETHERTYPE_REVARP,                                  "RARP"                          },
60     {ETHERTYPE_DEC_LB,                                  "DEC LanBridge"                 },
61     {ETHERTYPE_ATALK,                                   "Appletalk"                     },
62     {ETHERTYPE_SNA,                                             "SNA-over-Ethernet"             },
63     {ETHERTYPE_AARP,                                    "AARP"                          },
64     {ETHERTYPE_IPX,                                             "Netware IPX/SPX"               },
65     {ETHERTYPE_VINES_IP,                                "Vines IP"                      },
66     {ETHERTYPE_VINES_ECHO,                              "Vines Echo"                    },
67     {ETHERTYPE_TRAIN,                                   "Netmon Train"                  },
68     {ETHERTYPE_LOOP,                                    "Loopback"                      }, /* Ethernet Loopback */
69     {ETHERTYPE_FOUNDRY,                                 "Foundry proprietary"           },
70     {ETHERTYPE_WCP,                                             "Wellfleet Compression Protocol" },
71     {ETHERTYPE_STP,                                             "Spanning Tree Protocol"        },
72     {ETHERTYPE_ISMP,                                    "Cabletron Interswitch Message Protocol" },
73     {ETHERTYPE_ISMP_TBFLOOD,                    "Cabletron SFVLAN 1.8 Tag-Based Flood" },
74                                 /* for ISMP, see RFC 2641, RFC 2642, RFC 2643 */
75     {ETHERTYPE_PPPOED,                                  "PPPoE Discovery"               },
76     {ETHERTYPE_PPPOES,                                  "PPPoE Session"                 },
77     {ETHERTYPE_INTEL_ANS,                               "Intel ANS probe"               },
78     {ETHERTYPE_MS_NLB_HEARTBEAT,                "MS NLB heartbeat"      },
79     {ETHERTYPE_HOMEPLUG,                                "Homeplug"                      },
80     {ETHERTYPE_VLAN,                                    "802.1Q Virtual LAN"            },
81     {ETHERTYPE_IEEE_802_1AD,                    "802.1ad Provider Bridge (Q-in-Q)"},
82     {ETHERTYPE_IEEE_802_1AH,                    "802.1ah Provider Backbone Bridge (mac-in-mac)"},
83     {ETHERTYPE_EAPOL,                                   "802.1X Authentication"         },
84     {ETHERTYPE_RSN_PREAUTH,                             "802.11i Pre-Authentication"    },
85     {ETHERTYPE_MPLS,                                    "MPLS label switched packet"    },
86     {ETHERTYPE_MPLS_MULTI,                              "MPLS multicast label switched packet" },
87     {ETHERTYPE_3C_NBP_DGRAM,                    "3Com NBP Datagram"             },
88     {ETHERTYPE_DEC,                                             "DEC proto"                     },
89     {ETHERTYPE_DNA_DL,                                  "DEC DNA Dump/Load"             },
90     {ETHERTYPE_DNA_RC,                                  "DEC DNA Remote Console"        },
91     {ETHERTYPE_DNA_RT,                                  "DEC DNA Routing"               },
92     {ETHERTYPE_LAT,                                             "DEC LAT"                       },
93     {ETHERTYPE_DEC_DIAG,                                "DEC Diagnostics"               },
94     {ETHERTYPE_DEC_CUST,                                "DEC Customer use"              },
95     {ETHERTYPE_DEC_SCA,                                 "DEC LAVC/SCA"                  },
96     {ETHERTYPE_DEC_LAST,                                "DEC LAST"                      },
97     {ETHERTYPE_ETHBRIDGE,                               "Transparent Ethernet bridging" },
98     {ETHERTYPE_CGMP,                                    "Cisco Group Management Protocol" },
99     {ETHERTYPE_MAC_CONTROL,                             "MAC Control"                   },
100     {ETHERTYPE_SLOW_PROTOCOLS,                  "Slow Protocols"                },
101     {ETHERTYPE_RTMAC,                                   "Real-Time Media Access Control" },
102     {ETHERTYPE_RTCFG,                                   "Real-Time Configuration Protocol" },
103     {ETHERTYPE_CDMA2000_A10_UBS,                "CDMA2000 A10 Unstructured byte stream" },
104     {ETHERTYPE_PROFINET,                                "PROFINET"                      },
105     {ETHERTYPE_AOE,                                             "ATA over Ethernet"             },
106     {ETHERTYPE_ECATF,                                   "EtherCAT frame" },
107     {ETHERTYPE_TELKONET,                                "Telkonet powerline"    },
108     {ETHERTYPE_EPL_V2,                                  "ETHERNET Powerlink v2"                 },
109     {ETHERTYPE_CSM_ENCAPS,                              "CSM_ENCAPS Protocol"             },
110     {ETHERTYPE_IEEE802_OUI_EXTENDED,    "IEEE 802a OUI Extended Ethertype" },
111     {ETHERTYPE_IEC61850_GOOSE,                  "IEC 61850/GOOSE" },
112     {ETHERTYPE_IEC61850_GSE,                    "IEC 61850/GSE management services" },
113     {ETHERTYPE_IEC61850_SV,                             "IEC 61850/SV (Sampled Value Transmission" },
114     {ETHERTYPE_TIPC,                                    "Transparent Inter Process Communication" },
115     {ETHERTYPE_LLDP,                                    "802.1 Link Layer Discovery Protocol (LLDP)" },
116     {ETHERTYPE_3GPP2,                                   "CDMA2000 A10 3GPP2 Packet" },
117     {ETHERTYPE_LLTD,                                    "Link Layer Topology Discovery (LLTD)" },
118     {ETHERTYPE_WSMP,                                    "(WAVE) Short Message Protocol (WSM)" },
119     {ETHERTYPE_COBRANET,                                "Cirrus Cobranet Packet" },
120     {ETHERTYPE_NSRP,                                    "Juniper Netscreen Redundant Protocol" },
121     /*
122      * NDISWAN on Windows translates Ethernet frames from higher-level
123      * protocols into PPP frames to hand to the PPP driver, and translates
124      * PPP frames from the PPP driver to hand to the higher-level protocols.
125      *
126      * Apparently the PPP driver, on at least some versions of Windows,
127      * passes frames for internal-to-PPP protocols up through NDISWAN;
128      * the protocol type field appears to be passed through unchanged
129      * (unlike what's done with, for example, the protocol type field
130      * for IP, which is mapped from its PPP value to its Ethernet value).
131      *
132      * This means that we may see, on Ethernet captures, frames for
133      * protocols internal to PPP, so we list as "Ethernet" protocol
134      * types the PPP protocol types we've seen.
135      */
136     {PPP_IPCP,                                  "PPP IP Control Protocol" },
137     {PPP_LCP,                                   "PPP Link Control Protocol" },
138     {PPP_PAP,                                   "PPP Password Authentication Protocol" },
139     {PPP_CCP,                                   "PPP Compression Control Protocol" },
140     {ETHERTYPE_LLT,                             "Veritas Low Latency Transport (not officially registered)"},
141     {ETHERTYPE_CFM,                             "IEEE 802.1ag Connectivity Fault Management (CFM) protocol" },
142     {ETHERTYPE_FCOE,                    "Fibre Channel over Ethernet" },
143     {ETHERTYPE_FIP,                             "FCoE Initialization Protocol" },
144     {ETHERTYPE_PTP,                             "PTPv2 over Ethernet (IEEE1588)"},
145     {ETHERTYPE_PRP,                             "Parallel Redundancy Protocol (IEC62439 Chapter 6)"},
146     {0,                                         NULL } };
147
148 static void add_dix_trailer(packet_info *pinfo, proto_tree *fh_tree,
149     int trailer_id, tvbuff_t *tvb, tvbuff_t *next_tvb, int offset_after_etype,
150     guint length_before, gint fcs_len);
151
152 void
153 capture_ethertype(guint16 etype, const guchar *pd, int offset, int len,
154                   packet_counts *ld)
155 {
156   switch (etype) {
157     case ETHERTYPE_ARP:
158       ld->arp++;
159       break;
160     case ETHERTYPE_IP:
161       capture_ip(pd, offset, len, ld);
162       break;
163     case ETHERTYPE_IPv6:
164       capture_ipv6(pd, offset, len, ld);
165       break;
166     case ETHERTYPE_IPX:
167       capture_ipx(ld);
168       break;
169     case ETHERTYPE_VLAN:
170       capture_vlan(pd, offset, len, ld);
171       break;
172     case ETHERTYPE_IEEE_802_1AD:
173     case ETHERTYPE_IEEE_802_1AH:
174       capture_ieee8021ah(pd, offset, len, ld);
175       break;
176     case ETHERTYPE_VINES_IP:
177     case ETHERTYPE_VINES_ECHO:
178       capture_vines(ld);
179       break;
180     default:
181       ld->other++;
182       break;
183   }
184 }
185
186 void
187 ethertype(guint16 etype, tvbuff_t *tvb, int offset_after_etype,
188                 packet_info *pinfo, proto_tree *tree, proto_tree *fh_tree,
189                 int etype_id, int trailer_id, int fcs_len)
190 {
191         const char              *description;
192         tvbuff_t                *volatile next_tvb;
193         guint                   length_before;
194         gint                    captured_length, reported_length;
195         volatile gboolean       dissector_found = FALSE;
196         const char              *volatile saved_proto;
197
198         /* Add the Ethernet type to the protocol tree */
199         if (tree) {
200                 proto_tree_add_uint(fh_tree, etype_id, tvb,
201                     offset_after_etype - 2, 2, etype);
202         }
203
204         /* Get the captured length and reported length of the data
205            after the Ethernet type. */
206         captured_length = tvb_length_remaining(tvb, offset_after_etype);
207         reported_length = tvb_reported_length_remaining(tvb,
208             offset_after_etype);
209
210         /* Remember how much data there is after the Ethernet type,
211            including any trailer and FCS. */
212         length_before = reported_length;
213
214         /* Construct a tvbuff for the payload after the Ethernet type.
215            If the FCS length is positive, remove the FCS.
216            (If it's zero, there's no FCS; if it's negative,
217            we don't know whether there's an FCS, so we'll
218            guess based on the length of the trailer.) */
219         if (fcs_len > 0) {
220                 if (captured_length >= 0 && reported_length >= 0) {
221                         if (reported_length >= fcs_len)
222                                 reported_length -= fcs_len;
223                         if (captured_length > reported_length)
224                                 captured_length = reported_length;
225                 }
226         }
227         next_tvb = tvb_new_subset(tvb, offset_after_etype, captured_length,
228             reported_length);
229
230         pinfo->ethertype = etype;
231
232         /* Look for sub-dissector, and call it if found.
233            Catch exceptions, so that if the reported length of "next_tvb"
234            was reduced by some dissector before an exception was thrown,
235            we can still put in an item for the trailer. */
236         saved_proto = pinfo->current_proto;
237         TRY {
238                 dissector_found = dissector_try_port(ethertype_dissector_table,
239                     etype, next_tvb, pinfo, tree);
240         }
241         CATCH(BoundsError) {
242                 /* Somebody threw BoundsError, which means that:
243
244                      1) a dissector was found, so we don't need to
245                         dissect the payload as data or update the
246                         protocol or info columns;
247
248                      2) dissecting the payload found that the packet was
249                         cut off by a snapshot length before the end of
250                         the payload.  The trailer comes after the payload,
251                         so *all* of the trailer is cut off, and we'll
252                         just get another BoundsError if we add the trailer.
253
254                    Therefore, we just rethrow the exception so it gets
255                    reported; we don't dissect the trailer or do anything
256                    else. */
257                  RETHROW;
258         }
259         CATCH(OutOfMemoryError) {
260                  RETHROW;
261         }
262         CATCH_ALL {
263                 /* Somebody threw an exception other than BoundsError, which
264                    means that a dissector was found, so we don't need to
265                    dissect the payload as data or update the protocol or info
266                    columns.  We just show the exception and then drive on
267                    to show the trailer, after noting that a dissector was
268                    found and restoring the protocol value that was in effect
269                    before we called the subdissector. */
270                 show_exception(next_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
271                 dissector_found = TRUE;
272                 pinfo->current_proto = saved_proto;
273         }
274         ENDTRY;
275
276         if (!dissector_found) {
277                 /* No sub-dissector found.
278                    Label rest of packet as "Data" */
279                 call_dissector(data_handle,next_tvb, pinfo, tree);
280
281                 /* Label protocol */
282                 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
283                         col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "0x%04x",
284                             etype);
285                 }
286                 if (check_col(pinfo->cinfo, COL_INFO)) {
287                         description = match_strval(etype, etype_vals);
288                         if (description) {
289                                 col_add_str(pinfo->cinfo, COL_INFO, 
290                                     description);
291                         }
292                 }
293         }
294
295         add_dix_trailer(pinfo, fh_tree, trailer_id, tvb, next_tvb, offset_after_etype,
296             length_before, fcs_len);
297 }
298
299 static void
300 add_dix_trailer(packet_info *pinfo, proto_tree *fh_tree, int trailer_id,
301     tvbuff_t *tvb, tvbuff_t *next_tvb, int offset_after_etype,
302     guint length_before, gint fcs_len)
303 {
304         guint           length;
305         tvbuff_t        *trailer_tvb;
306
307         if (fh_tree == NULL)
308                 return; /* we're not building a protocol tree */
309
310         if (trailer_id == -1)
311                 return; /* our caller doesn't care about trailers */
312
313         /* OK, how much is there in that tvbuff now? */
314         length = tvb_reported_length(next_tvb);
315
316         /* If there's less than there was before, what's left is
317            a trailer. */
318         if (length < length_before) {
319                 /*
320                  * Is any of the padding present in the tvbuff?
321                  */
322                 if (tvb_offset_exists(tvb, offset_after_etype + length)) {
323                         /*
324                          * Yes - create a tvbuff for the padding.
325                          */
326                         trailer_tvb = tvb_new_subset(tvb,
327                             offset_after_etype + length, -1, -1);
328                 } else {
329                         /*
330                          * No - don't bother showing the trailer.
331                          * XXX - show a Short Frame indication?
332                          */
333                         trailer_tvb = NULL;
334                 }
335         } else
336                 trailer_tvb = NULL;     /* no trailer */
337
338         add_ethernet_trailer(pinfo, fh_tree, trailer_id, tvb, trailer_tvb, fcs_len);
339 }
340
341 void
342 proto_register_ethertype(void)
343 {
344         /* subdissector code */
345         ethertype_dissector_table = register_dissector_table("ethertype",
346             "Ethertype", FT_UINT16, BASE_HEX);
347 }
348
349 void
350 proto_reg_handoff_ethertype(void)
351 {
352         data_handle = find_dissector("data");
353 }