summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-ieee8023.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/packet-ieee8023.c')
-rw-r--r--epan/dissectors/packet-ieee8023.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/epan/dissectors/packet-ieee8023.c b/epan/dissectors/packet-ieee8023.c
new file mode 100644
index 00000000..626df268
--- /dev/null
+++ b/epan/dissectors/packet-ieee8023.c
@@ -0,0 +1,138 @@
+/* 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
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#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 - https://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:
+ */