Give the code that computes protocol statistics a progress dialog box,
[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.12 2001/02/01 07:34:29 guy Exp $
5  *
6  * Gilbert Ramirez <gram@xiexie.org>
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@zing.org>
10  * Copyright 1998 Gerald Combs
11  *
12  * 
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  * 
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  * 
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26  */
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #ifdef HAVE_SYS_TYPES_H
33 # include <sys/types.h>
34 #endif
35
36 #include <glib.h>
37 #include "packet.h"
38 #include "packet-ip.h"
39 #include "packet-ipx.h"
40 #include "packet-vlan.h"
41 #include "packet-vines.h"
42 #include "etypes.h"
43
44 static dissector_table_t ethertype_dissector_table;
45
46 const value_string etype_vals[] = {
47     {ETHERTYPE_IP,              "IP"                            },
48     {ETHERTYPE_IPv6,            "IPv6"                          },
49     {ETHERTYPE_X25L3,           "X.25 Layer 3"                  },
50     {ETHERTYPE_ARP,             "ARP"                           },
51     {ETHERTYPE_REVARP,          "RARP"                          },
52     {ETHERTYPE_DEC_LB,          "DEC LanBridge"                 },
53     {ETHERTYPE_ATALK,           "Appletalk"                     },
54     {ETHERTYPE_AARP,            "AARP"                          },
55     {ETHERTYPE_IPX,             "Netware IPX/SPX"               },
56     {ETHERTYPE_VINES,           "Vines"                         },
57     {ETHERTYPE_TRAIN,           "Netmon Train"                  },
58     {ETHERTYPE_LOOP,            "Loopback"                      }, /* Ethernet Loopback */
59     {ETHERTYPE_PPPOED,          "PPPoE Discovery"               }, 
60     {ETHERTYPE_PPPOES,          "PPPoE Session"                 }, 
61     {ETHERTYPE_VLAN,            "802.1Q Virtual LAN"            },
62     {ETHERTYPE_MPLS,            "MPLS label switched packet"    },
63     {ETHERTYPE_MPLS_MULTI,      "MPLS multicast label switched packet" },
64     {ETHERTYPE_3C_NBP_DGRAM,    "3Com NBP Datagram"             },
65     {ETHERTYPE_DEC,             "DEC proto"                     },
66     {ETHERTYPE_DNA_DL,          "DEC DNA Dump/Load"             },
67     {ETHERTYPE_DNA_RC,          "DEC DNA Remote Console"        },
68     {ETHERTYPE_DNA_RT,          "DEC DNA Routing"               },
69     {ETHERTYPE_LAT,             "DEC LAT"                       },
70     {ETHERTYPE_DEC_DIAG,        "DEC Diagnostics"               },
71     {ETHERTYPE_DEC_CUST,        "DEC Customer use"              },
72     {ETHERTYPE_DEC_SCA,         "DEC LAVC/SCA"                  },
73     {0,                         NULL                            } };
74
75 static void add_trailer(proto_tree *fh_tree, int trailer_id, tvbuff_t *tvb,
76     tvbuff_t *next_tvb, int offset_after_etype, guint length_before);
77
78 void
79 capture_ethertype(guint16 etype, int offset,
80                 const u_char *pd, packet_counts *ld)
81 {
82   switch (etype) {
83     case ETHERTYPE_IP:
84       capture_ip(pd, offset, ld);
85       break;
86     case ETHERTYPE_IPX:
87       capture_ipx(pd, offset, ld);
88       break;
89     case ETHERTYPE_VLAN:
90       capture_vlan(pd, offset, ld);
91       break;
92     case ETHERTYPE_VINES:
93       capture_vines(pd, offset, ld);
94       break;
95     default:
96       ld->other++;
97       break;
98   }
99 }
100
101 void
102 ethertype(guint16 etype, tvbuff_t *tvb, int offset_after_etype,
103                 packet_info *pinfo, proto_tree *tree, proto_tree *fh_tree,
104                 int etype_id, int trailer_id)
105 {
106         char                    *description;
107         tvbuff_t                *next_tvb;
108         guint                   length_before;
109         volatile gboolean       dissector_found;
110         
111         /* Add to proto_tree */
112         if (tree) {
113                 proto_tree_add_uint(fh_tree, etype_id, tvb,
114                     offset_after_etype - 2, 2, etype);
115         }
116
117         /* Tvbuff for the payload after the Ethernet type. */
118         next_tvb = tvb_new_subset(tvb, offset_after_etype, -1, -1);
119
120         pinfo->ethertype = etype;
121
122         /* Remember how much data there is in it. */
123         length_before = tvb_reported_length(next_tvb);
124
125         /* Look for sub-dissector, and call it if found.
126            Catch BoundsError and ReportedBoundsError, so that if the
127            reported length of "next_tvb" was reduced by some dissector
128            before an exception was thrown, we can still put in an item
129            for the trailer. */
130         TRY {
131                 dissector_found = dissector_try_port(ethertype_dissector_table,
132                     etype, next_tvb, pinfo, tree);
133         }
134         CATCH2(BoundsError, ReportedBoundsError) {
135                 /* Well, somebody threw an exception; that means that a
136                    dissector was found, so we don't need to dissect
137                    the payload as data or update the protocol or info
138                    columns. */
139                 dissector_found = TRUE;
140
141                 /* Add the trailer, if appropriate. */
142                 add_trailer(fh_tree, trailer_id, tvb, next_tvb,
143                     offset_after_etype, length_before);
144
145                 /* Rrethrow the exception, so the "Short Frame" or "Mangled
146                    Frame" indication can be put into the tree. */
147                 RETHROW;
148
149                 /* XXX - RETHROW shouldn't return. */
150                 g_assert_not_reached();
151         }
152         ENDTRY;
153
154         if (!dissector_found) {
155                 /* No sub-dissector found.
156                    Label rest of packet as "Data" */
157                 dissect_data(next_tvb, 0, pinfo, tree);
158
159                 /* Label protocol */
160                 switch (etype) {
161
162                 case ETHERTYPE_LOOP:
163                         if (check_col(pinfo->fd, COL_PROTOCOL)) {
164                                 col_add_fstr(pinfo->fd, COL_PROTOCOL, "LOOP");
165                         }
166                         break;
167
168                 default:
169                         if (check_col(pinfo->fd, COL_PROTOCOL)) {
170                                 col_add_fstr(pinfo->fd, COL_PROTOCOL, "0x%04x",
171                                     etype);
172                         }
173                         break;
174                 }
175                 if (check_col(pinfo->fd, COL_INFO)) {
176                         description = match_strval(etype, etype_vals);
177                         if (description) {
178                                 col_add_fstr(pinfo->fd, COL_INFO, "%s",
179                                     description);
180                         }
181                 }
182         }
183
184         add_trailer(fh_tree, trailer_id, tvb, next_tvb, offset_after_etype,
185             length_before);
186 }
187
188 static void
189 add_trailer(proto_tree *fh_tree, int trailer_id, tvbuff_t *tvb,
190     tvbuff_t *next_tvb, int offset_after_etype, guint length_before)
191 {
192         guint           length;
193         tvbuff_t        *volatile trailer_tvb;
194
195         if (fh_tree == NULL)
196                 return; /* we're not building a protocol tree */
197
198         if (trailer_id == -1)
199                 return; /* our caller doesn't care about trailers */
200
201         /* OK, how much is there in that tvbuff now? */
202         length = tvb_reported_length(next_tvb);
203
204         /* If there's less than there was before, what's left is
205            a trailer. */
206         if (length < length_before) {
207                 /*
208                  * Create a tvbuff for the padding.
209                  */
210                 TRY {
211                         trailer_tvb = tvb_new_subset(tvb,
212                             offset_after_etype + length, -1, -1);
213                 }
214                 CATCH2(BoundsError, ReportedBoundsError) {
215                         /* The packet doesn't have "length" bytes worth of
216                            captured data left in it.  No trailer to display. */
217                         trailer_tvb = NULL;
218                 }
219                 ENDTRY;
220         } else
221                 trailer_tvb = NULL;     /* no trailer */
222
223         /* If there's some bytes left over, and we were given an item ID
224            for a trailer, mark those bytes as a trailer. */
225         if (trailer_tvb) {
226                 guint   trailer_length;
227
228                 trailer_length = tvb_length(trailer_tvb);
229                 if (trailer_length != 0) {
230                         proto_tree_add_item(fh_tree, trailer_id, trailer_tvb, 0,
231                             trailer_length, FALSE);
232                 }
233         }
234 }
235
236
237 void
238 proto_register_ethertype(void)
239 {
240         /* subdissector code */
241         ethertype_dissector_table = register_dissector_table("ethertype");
242 }