+end_of_eth:
+ tap_queue_packet(eth_tap, pinfo, ehdr);
+ return;
+}
+
+/*
+ * Add an Ethernet trailer - which, for some captures, might be the FCS
+ * rather than a pad-to-60-bytes trailer.
+ *
+ * If fcs_len is 0, we assume the frame has no FCS; if it's 4, we assume
+ * it has an FCS; if it's anything else (such as -1, which means "maybe
+ * it does, maybe it doesn't"), we try to infer whether it has an FCS.
+ */
+void
+add_ethernet_trailer(proto_tree *fh_tree, int trailer_id, tvbuff_t *tvb,
+ tvbuff_t *trailer_tvb, int fcs_len)
+{
+ /* If there're some bytes left over, show those bytes as a trailer.
+
+ However, if the Ethernet frame was claimed to have had 64 or more
+ bytes - i.e., it was at least an FCS worth of data longer than
+ the minimum payload size - assume the last 4 bytes of the trailer
+ are an FCS. */
+ if (trailer_tvb && fh_tree) {
+ guint trailer_length, trailer_reported_length;
+ gboolean has_fcs = FALSE;
+
+ trailer_length = tvb_length(trailer_tvb);
+ trailer_reported_length = tvb_reported_length(trailer_tvb);
+ if (fcs_len != 0) {
+ /* If fcs_len is 4, we assume we definitely have an FCS.
+ Otherwise, then, if the frame is big enough that, if we
+ have a trailer, it probably inclues an FCS, and we have
+ enough space in the trailer for the FCS, we assume we
+ have an FCS.
+
+ "Big enough" means 64 bytes or more; any frame that big
+ needs no trailer, as there's no need to pad an Ethernet
+ packet past 60 bytes.
+
+ The trailer must be at least 4 bytes long to have enough
+ space for an FCS. */
+
+ if (fcs_len == 4 || (tvb_reported_length(tvb) >= 64 &&
+ trailer_reported_length >= 4)) {
+ /* Either we know we have an FCS, or we believe we have an FCS. */
+ if (trailer_length < trailer_reported_length) {
+ /* The packet is claimed to have enough data for a 4-byte FCS,
+ but we didn't capture all of the packet.
+ Slice off the 4-byte FCS from the reported length, and
+ trim the captured length so it's no more than the reported
+ length; that will slice off what of the FCS, if any, is
+ in the captured packet. */
+ trailer_reported_length -= 4;
+ if (trailer_length > trailer_reported_length)
+ trailer_length = trailer_reported_length;
+ has_fcs = TRUE;
+ } else {
+ /* We captured all of the packet, including what appears to
+ be a 4-byte FCS. Slice it off. */
+ trailer_length -= 4;
+ trailer_reported_length -= 4;
+ has_fcs = TRUE;
+ }
+ }
+ }
+ if (trailer_length != 0) {
+ proto_tree_add_item(fh_tree, trailer_id, trailer_tvb, 0,
+ trailer_length, FALSE);
+ }
+ if (has_fcs) {
+ guint32 sent_fcs = tvb_get_ntohl(trailer_tvb, trailer_length);
+ guint32 fcs = crc32_tvb_802(tvb, tvb_length(tvb) - 4);
+ if (fcs == sent_fcs) {
+ proto_tree_add_text(fh_tree, trailer_tvb, trailer_length, 4,
+ "Frame check sequence: 0x%08x (correct)",
+ sent_fcs);
+ } else {
+ proto_tree_add_text(fh_tree, trailer_tvb, trailer_length, 4,
+ "Frame check sequence: 0x%08x (incorrect, should be 0x%08x)",
+ sent_fcs, fcs);
+ }
+ }