Update Laurent Meyer's e-mail address.
[obnox/wireshark/wip.git] / packet-ethertype.c
1 /* ethertype.c
2  * Routines for calling the right protocol for the ethertype.
3  *
4  * $Id: packet-ethertype.c,v 1.36 2003/06/11 09:17:00 guy Exp $
5  *
6  * Gilbert Ramirez <gram@alumni.rice.edu>
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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-ip.h"
34 #include "packet-ipv6.h"
35 #include "packet-ipx.h"
36 #include "packet-vlan.h"
37 #include "packet-vines.h"
38 #include "etypes.h"
39 #include "ppptypes.h"
40
41 static dissector_table_t ethertype_dissector_table;
42
43 static dissector_handle_t data_handle;
44
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"                },
82
83     /*
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.
87      *
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).
93      *
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.
97      */
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" },
102     {0,                         NULL                            } };
103
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);
106
107 void
108 capture_ethertype(guint16 etype, const guchar *pd, int offset, int len,
109                   packet_counts *ld)
110 {
111   switch (etype) {
112     case ETHERTYPE_ARP:
113       ld->arp++;
114       break;
115     case ETHERTYPE_IP:
116       capture_ip(pd, offset, len, ld);
117       break;
118     case ETHERTYPE_IPv6:
119       capture_ipv6(pd, offset, len, ld);
120       break;
121     case ETHERTYPE_IPX:
122       capture_ipx(ld);
123       break;
124     case ETHERTYPE_VLAN:
125       capture_vlan(pd, offset, len, ld);
126       break;
127     case ETHERTYPE_VINES_IP:
128     case ETHERTYPE_VINES_ECHO:
129       capture_vines(ld);
130       break;
131     default:
132       ld->other++;
133       break;
134   }
135 }
136
137 void
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)
141 {
142         char                    *description;
143         tvbuff_t                *next_tvb;
144         guint                   length_before;
145         volatile gboolean       dissector_found;
146
147         /* Add to proto_tree */
148         if (tree) {
149                 proto_tree_add_uint(fh_tree, etype_id, tvb,
150                     offset_after_etype - 2, 2, etype);
151         }
152
153         /* Tvbuff for the payload after the Ethernet type. */
154         next_tvb = tvb_new_subset(tvb, offset_after_etype, -1, -1);
155
156         pinfo->ethertype = etype;
157
158         /* Remember how much data there is in it. */
159         length_before = tvb_reported_length(next_tvb);
160
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
165            for the trailer. */
166         TRY {
167                 dissector_found = dissector_try_port(ethertype_dissector_table,
168                     etype, next_tvb, pinfo, tree);
169         }
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
174                    columns. */
175                 dissector_found = TRUE;
176
177                 /* Add the trailer, if appropriate. */
178                 add_trailer(fh_tree, trailer_id, tvb, next_tvb,
179                     offset_after_etype, length_before);
180
181                 /* Rrethrow the exception, so the "Short Frame" or "Mangled
182                    Frame" indication can be put into the tree. */
183                 RETHROW;
184
185                 /* XXX - RETHROW shouldn't return. */
186                 g_assert_not_reached();
187         }
188         ENDTRY;
189
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);
194
195                 /* Label protocol */
196                 switch (etype) {
197
198                 case ETHERTYPE_LOOP:
199                         if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
200                                 col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "LOOP");
201                         }
202                         break;
203
204                 default:
205                         if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
206                                 col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "0x%04x",
207                                     etype);
208                         }
209                         break;
210                 }
211                 if (check_col(pinfo->cinfo, COL_INFO)) {
212                         description = match_strval(etype, etype_vals);
213                         if (description) {
214                                 col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
215                                     description);
216                         }
217                 }
218         }
219
220         add_trailer(fh_tree, trailer_id, tvb, next_tvb, offset_after_etype,
221             length_before);
222 }
223
224 static void
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)
227 {
228         guint           length;
229         tvbuff_t        *volatile trailer_tvb;
230
231         if (fh_tree == NULL)
232                 return; /* we're not building a protocol tree */
233
234         if (trailer_id == -1)
235                 return; /* our caller doesn't care about trailers */
236
237         /* OK, how much is there in that tvbuff now? */
238         length = tvb_reported_length(next_tvb);
239
240         /* If there's less than there was before, what's left is
241            a trailer. */
242         if (length < length_before) {
243                 /*
244                  * Create a tvbuff for the padding.
245                  */
246                 TRY {
247                         trailer_tvb = tvb_new_subset(tvb,
248                             offset_after_etype + length, -1, -1);
249                 }
250                 CATCH2(BoundsError, ReportedBoundsError) {
251                         /* The packet doesn't have "length" bytes worth of
252                            captured data left in it.  No trailer to display. */
253                         trailer_tvb = NULL;
254                 }
255                 ENDTRY;
256         } else
257                 trailer_tvb = NULL;     /* no trailer */
258
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. */
261         if (trailer_tvb) {
262                 guint   trailer_length;
263
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);
268                 }
269         }
270 }
271
272
273 void
274 proto_register_ethertype(void)
275 {
276         /* subdissector code */
277         ethertype_dissector_table = register_dissector_table("ethertype",
278             "Ethertype", FT_UINT16, BASE_HEX);
279 }
280
281 void
282 proto_reg_handoff_ethertype(void){
283   data_handle = find_dissector("data");
284 }