2 * Routine for dissecting 802.3 (as opposed to D/I/X Ethernet) packets.
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 #include <epan/packet.h>
31 #include <epan/expert.h>
32 #include "packet-ieee8023.h"
33 #include "packet-eth.h"
34 #include "packet-frame.h"
36 static dissector_handle_t ipx_handle;
37 static dissector_handle_t llc_handle;
38 static dissector_handle_t ccsds_handle;
41 dissect_802_3(volatile int length, gboolean is_802_2, tvbuff_t *tvb,
42 int offset_after_length, packet_info *pinfo, proto_tree *tree,
43 proto_tree *fh_tree, int length_id, int trailer_id,
46 proto_item *length_it;
47 tvbuff_t *volatile next_tvb = NULL;
48 tvbuff_t *volatile trailer_tvb = NULL;
49 const char *saved_proto;
50 gint captured_length, reported_length;
52 length_it = proto_tree_add_uint(fh_tree, length_id, tvb,
53 offset_after_length - 2, 2, length);
55 /* Get the length of the payload.
56 If the FCS length is positive, remove the FCS.
57 (If it's zero, there's no FCS; if it's negative, we don't know whether
58 there's an FCS, so we'll guess based on the length of the trailer.) */
59 reported_length = tvb_reported_length_remaining(tvb, offset_after_length);
61 if (reported_length >= fcs_len)
62 reported_length -= fcs_len;
65 /* Make sure the length in the 802.3 header doesn't go past the end of
67 if (length > reported_length) {
68 length = reported_length;
69 expert_add_info_format(pinfo, length_it, PI_MALFORMED, PI_ERROR,
70 "Length field value goes past the end of the payload");
73 /* Give the next dissector only 'length' number of bytes. */
74 captured_length = tvb_length_remaining(tvb, offset_after_length);
75 if (captured_length > length)
76 captured_length = length;
77 next_tvb = tvb_new_subset(tvb, offset_after_length, captured_length, length);
79 trailer_tvb = tvb_new_subset_remaining(tvb, offset_after_length + length);
81 CATCH2(BoundsError, ReportedBoundsError) {
82 /* The packet has exactly "length" bytes worth of captured data
83 left in it, so the "tvb_new_subset()" creating "trailer_tvb"
86 This means that all the data in the frame is within the length
87 value (assuming our offset isn't past the end of the tvb), so
88 we give all the data to the next protocol and have no trailer. */
93 /* Dissect the payload either as IPX or as an LLC frame.
94 Catch BoundsError and ReportedBoundsError, so that if the
95 reported length of "next_tvb" was reduced by some dissector
96 before an exception was thrown, we can still put in an item
98 saved_proto = pinfo->current_proto;
101 call_dissector(llc_handle, next_tvb, pinfo, tree);
103 /* Check if first three bits of payload are 0x7.
104 If so, then payload is IPX. If not, then it's CCSDS.
105 Refer to packet-eth.c for setting of is_802_2 variable. */
106 if (tvb_get_bits8(next_tvb, 0, 3) == 7)
107 call_dissector(ipx_handle, next_tvb, pinfo, tree);
109 call_dissector(ccsds_handle, next_tvb, pinfo, tree);
113 /* Somebody threw BoundsError, which means that dissecting the payload
114 found that the packet was cut off by a snapshot length before the
115 end of the payload. The trailer comes after the payload, so *all*
116 of the trailer is cut off - don't bother adding the trailer, just
117 rethrow the exception so it gets reported. */
121 /* Well, somebody threw an exception other than BoundsError.
122 Show the exception, and then drive on to show the trailer,
123 restoring the protocol value that was in effect before we
124 called the subdissector. */
125 show_exception(next_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
126 pinfo->current_proto = saved_proto;
130 add_ethernet_trailer(pinfo, fh_tree, trailer_id, tvb, trailer_tvb, fcs_len);
134 proto_reg_handoff_ieee802_3(void)
137 * Get handles for the subdissectors.
139 ipx_handle = find_dissector("ipx");
140 llc_handle = find_dissector("llc");
141 ccsds_handle = find_dissector("ccsds");