wireshark/epan/dissectors/packet-ieee8023.c
Guy Harris 7cd6906056 Rename tvb_new_subset() to tvb_new_subset_length_caplen().
This emphasizes that there is no such thing as *the* routine to
construct a subset tvbuff; you need to choose one of
tvb_new_subset_remaining() (if you want a new tvbuff that contains
everything past a certain point in an existing tvbuff),
tvb_new_subset_length() (if you want a subset that contains everything
past a certain point, for some number of bytes, in an existing tvbuff),
and tvb_new_subset_length_caplen() (for all other cases).

Many of the calls to tvb_new_subset_length_caplen() should really be
calling one of the other routines; that's the next step.  (This also
makes it easier to find the calls that need fixing.)

Change-Id: Ieb3d676d8cda535451c119487d7cd3b559221f2b
Reviewed-on: https://code.wireshark.org/review/19597
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2017-01-10 06:19:37 +00:00

151 lines
5.4 KiB
C

/* packet-ieee8023.c
* Routine for dissecting Ethernet packets with a length field (as opposed
* to a type field).
*
* The name "ieee8023" is historical, dating back to when IEEE Std 802.3
* had only a length field and expected all packets to have an 802.2
* header following the MAC header. Since IEEE 802.3y-1997, 802.3
* supports either a type field or a length field, so it's no longer
* correct to refer to "802.3" vs. "D/I/X" or vs. "Ethernet II" frames.
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <epan/packet.h>
#include <epan/exceptions.h>
#include <epan/expert.h>
#include <epan/show_exception.h>
#include "packet-ieee8023.h"
#include "packet-eth.h"
void proto_reg_handoff_ieee802_3(void);
static dissector_handle_t ipx_handle;
static dissector_handle_t llc_handle;
static dissector_handle_t ccsds_handle;
void
dissect_802_3(volatile int length, gboolean is_802_2, tvbuff_t *tvb,
int offset_after_length, packet_info *pinfo, proto_tree *tree,
proto_tree *fh_tree, int length_id, int trailer_id, expert_field* ei_len,
int fcs_len)
{
proto_item *length_it;
tvbuff_t *volatile next_tvb = NULL;
tvbuff_t *trailer_tvb = NULL;
const char *saved_proto;
gint captured_length, reported_length;
length_it = proto_tree_add_uint(fh_tree, length_id, tvb,
offset_after_length - 2, 2, length);
/* Get the length of the payload.
If the FCS length is positive, remove the FCS.
(If it's zero, there's no FCS; if it's negative, we don't know whether
there's an FCS, so we'll guess based on the length of the trailer.) */
reported_length = tvb_reported_length_remaining(tvb, offset_after_length);
if (fcs_len > 0) {
if (reported_length >= fcs_len)
reported_length -= fcs_len;
}
/* Make sure the length in the 802.3 header doesn't go past the end of
the payload. */
if (length > reported_length) {
length = reported_length;
expert_add_info(pinfo, length_it, ei_len);
}
/* Give the next dissector only 'length' number of bytes. */
captured_length = tvb_captured_length_remaining(tvb, offset_after_length);
if (captured_length > length)
captured_length = length;
next_tvb = tvb_new_subset_length_caplen(tvb, offset_after_length, captured_length, length);
/* Dissect the payload either as IPX or as an LLC frame.
Catch non-fatal exceptions, so that if the reported length
of "next_tvb" was reduced by some dissector before an
exception was thrown, we can still put in an item for
the trailer. */
saved_proto = pinfo->current_proto;
TRY {
if (is_802_2)
call_dissector(llc_handle, next_tvb, pinfo, tree);
else {
/* Check if first three bits of payload are 0x7.
If so, then payload is IPX. If not, then it's CCSDS.
Refer to packet-eth.c for setting of is_802_2 variable. */
if (tvb_get_bits8(next_tvb, 0, 3) == 7)
call_dissector(ipx_handle, next_tvb, pinfo, tree);
else
call_dissector(ccsds_handle, next_tvb, pinfo, tree);
}
}
CATCH_NONFATAL_ERRORS {
/* Somebody threw an exception that means that there was a problem
dissecting the payload; that means that a dissector was found,
so we don't need to dissect the payload as data or update the
protocol or info columns.
Just show the exception and then drive on to show the trailer,
after noting that a dissector was found and restoring the
protocol value that was in effect before we called the subdissector. */
show_exception(next_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
}
ENDTRY;
/* Restore the protocol value, so that any exception thrown by
tvb_new_subset_remaining() refers to the protocol for which
this is a trailer. */
pinfo->current_proto = saved_proto;
/* Construct a tvbuff for the trailer; if the trailer is past the
end of the captured data, this will throw a BoundsError, which
is what we want, as it'll report that the packet was cut short. */
trailer_tvb = tvb_new_subset_remaining(tvb, offset_after_length + length);
add_ethernet_trailer(pinfo, tree, fh_tree, trailer_id, tvb, trailer_tvb, fcs_len);
}
void
proto_reg_handoff_ieee802_3(void)
{
/*
* Get handles for the subdissectors.
*/
ipx_handle = find_dissector("ipx");
llc_handle = find_dissector("llc");
ccsds_handle = find_dissector("ccsds");
}
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local Variables:
* c-basic-offset: 2
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* ex: set shiftwidth=2 tabstop=8 expandtab:
* :indentSize=2:tabSize=8:noTabs=true:
*/