aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-frame.c85
-rw-r--r--text2pcap.c42
-rw-r--r--ui/text_import.c8
-rw-r--r--wiretap/pcapng.c4
-rw-r--r--wiretap/wtap.h73
5 files changed, 143 insertions, 69 deletions
diff --git a/epan/dissectors/packet-frame.c b/epan/dissectors/packet-frame.c
index 5d46796103..cad0d9e384 100644
--- a/epan/dissectors/packet-frame.c
+++ b/epan/dissectors/packet-frame.c
@@ -113,36 +113,19 @@ static const value_string p2p_dirs[] = {
{ 0, NULL }
};
-#define PACKET_WORD_DIRECTION_MASK 0x00000003
-#define PACKET_WORD_RECEPTION_TYPE_MASK 0x0000001C
-#define PACKET_WORD_FCS_LENGTH_MASK 0x000001E0
-#define PACKET_WORD_RESERVED_MASK 0x0000FE00
-#define PACKET_WORD_CRC_ERR_MASK 0x01000000
-#define PACKET_WORD_PACKET_TOO_LONG_ERR_MASK 0x02000000
-#define PACKET_WORD_PACKET_TOO_SHORT_ERR_MASK 0x04000000
-#define PACKET_WORD_WRONG_INTER_FRAME_GAP_ERR_MASK 0x08000000
-#define PACKET_WORD_UNALIGNED_FRAME_ERR_MASK 0x10000000
-#define PACKET_WORD_START_FRAME_DELIMITER_ERR_MASK 0x20000000
-#define PACKET_WORD_PREAMBLE_ERR_MASK 0x40000000
-#define PACKET_WORD_SYMBOL_ERR_MASK 0x80000000
-
static const value_string packet_word_directions[] = {
- { 0x00, "Not available" },
- { 0x01, "Inbound" },
- { 0x02, "Outbound" },
- { 0x03, "Undefined" },
+ { PACK_FLAGS_DIRECTION_UNKNOWN, "Unknown" },
+ { PACK_FLAGS_DIRECTION_INBOUND, "Inbound" },
+ { PACK_FLAGS_DIRECTION_OUTBOUND, "Outbound" },
{ 0, NULL }
};
static const value_string packet_word_reception_types[] = {
- { 0x00, "Not specified" },
- { 0x01, "Unicast" },
- { 0x02, "Multicast" },
- { 0x03, "Broadcast" },
- { 0x04, "Promiscuous" },
- { 0x05, "Undefined" },
- { 0x06, "Undefined" },
- { 0x07, "Undefined" },
+ { PACK_FLAGS_RECEPTION_TYPE_UNSPECIFIED, "Not specified" },
+ { PACK_FLAGS_RECEPTION_TYPE_UNICAST, "Unicast" },
+ { PACK_FLAGS_RECEPTION_TYPE_MULTICAST, "Multicast" },
+ { PACK_FLAGS_RECEPTION_TYPE_BROADCAST, "Broadcast" },
+ { PACK_FLAGS_RECEPTION_TYPE_PROMISCUOUS, "Promiscuous" },
{ 0, NULL }
};
@@ -236,10 +219,21 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
case REC_TYPE_PACKET:
pinfo->current_proto = "Frame";
if (pinfo->rec->presence_flags & WTAP_HAS_PACK_FLAGS) {
- if (pinfo->rec->rec_header.packet_header.pack_flags & 0x00000001)
+ switch (PACK_FLAGS_DIRECTION(pinfo->rec->rec_header.packet_header.pack_flags)) {
+
+ case PACK_FLAGS_DIRECTION_UNKNOWN:
+ default:
+ pinfo->p2p_dir = P2P_DIR_UNKNOWN;
+ break;
+
+ case PACK_FLAGS_DIRECTION_INBOUND:
pinfo->p2p_dir = P2P_DIR_RECV;
- if (pinfo->rec->rec_header.packet_header.pack_flags & 0x00000002)
+ break;
+
+ case PACK_FLAGS_DIRECTION_OUTBOUND:
pinfo->p2p_dir = P2P_DIR_SENT;
+ break;
+ }
}
/*
@@ -362,10 +356,19 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
pinfo->rec->rec_header.packet_header.interface_id);
}
if (pinfo->rec->presence_flags & WTAP_HAS_PACK_FLAGS) {
- if (pinfo->rec->rec_header.packet_header.pack_flags & 0x00000001)
+ switch (PACK_FLAGS_DIRECTION(pinfo->rec->rec_header.packet_header.pack_flags)) {
+
+ case PACK_FLAGS_DIRECTION_INBOUND:
proto_item_append_text(ti, " (inbound)");
- if (pinfo->rec->rec_header.packet_header.pack_flags & 0x00000002)
+ break;
+
+ case PACK_FLAGS_DIRECTION_OUTBOUND:
proto_item_append_text(ti, " (outbound)");
+ break;
+
+ default:
+ break;
+ }
}
break;
@@ -911,62 +914,62 @@ proto_register_frame(void)
{ &hf_frame_pack_direction,
{ "Direction", "frame.packet_flags_direction",
- FT_UINT32, BASE_HEX, VALS(packet_word_directions), PACKET_WORD_DIRECTION_MASK,
+ FT_UINT32, BASE_HEX, VALS(packet_word_directions), PACK_FLAGS_DIRECTION_MASK,
NULL, HFILL }},
{ &hf_frame_pack_reception_type,
{ "Reception type", "frame.packet_flags_reception_type",
- FT_UINT32, BASE_DEC, VALS(packet_word_reception_types), PACKET_WORD_RECEPTION_TYPE_MASK,
+ FT_UINT32, BASE_DEC, VALS(packet_word_reception_types), PACK_FLAGS_RECEPTION_TYPE_MASK,
NULL, HFILL }},
{ &hf_frame_pack_fcs_length,
{ "FCS length", "frame.packet_flags_fcs_length",
- FT_UINT32, BASE_DEC, NULL, PACKET_WORD_FCS_LENGTH_MASK,
+ FT_UINT32, BASE_DEC, NULL, PACK_FLAGS_FCS_LENGTH_MASK,
NULL, HFILL }},
{ &hf_frame_pack_reserved,
{ "Reserved", "frame.packet_flags_reserved",
- FT_UINT32, BASE_DEC, NULL, PACKET_WORD_RESERVED_MASK,
+ FT_UINT32, BASE_DEC, NULL, PACK_FLAGS_RESERVED_MASK,
NULL, HFILL }},
{ &hf_frame_pack_crc_error,
{ "CRC error", "frame.packet_flags_crc_error",
- FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACKET_WORD_CRC_ERR_MASK,
+ FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACK_FLAGS_CRC_ERROR,
NULL, HFILL }},
{ &hf_frame_pack_wrong_packet_too_long_error,
{ "Packet too long error", "frame.packet_flags_packet_too_error",
- FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACKET_WORD_PACKET_TOO_LONG_ERR_MASK,
+ FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACK_FLAGS_PACKET_TOO_LONG,
NULL, HFILL }},
{ &hf_frame_pack_wrong_packet_too_short_error,
{ "Packet too short error", "frame.packet_flags_packet_too_short_error",
- FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACKET_WORD_PACKET_TOO_SHORT_ERR_MASK,
+ FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACK_FLAGS_PACKET_TOO_SHORT,
NULL, HFILL }},
{ &hf_frame_pack_wrong_inter_frame_gap_error,
{ "Wrong interframe gap error", "frame.packet_flags_wrong_inter_frame_gap_error",
- FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACKET_WORD_WRONG_INTER_FRAME_GAP_ERR_MASK,
+ FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACK_FLAGS_WRONG_INTER_FRAME_GAP,
NULL, HFILL }},
{ &hf_frame_pack_unaligned_frame_error,
{ "Unaligned frame error", "frame.packet_flags_unaligned_frame_error",
- FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACKET_WORD_UNALIGNED_FRAME_ERR_MASK,
+ FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACK_FLAGS_UNALIGNED_FRAME,
NULL, HFILL }},
{ &hf_frame_pack_start_frame_delimiter_error,
{ "Start frame delimiter error", "frame.packet_flags_start_frame_delimiter_error",
- FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACKET_WORD_START_FRAME_DELIMITER_ERR_MASK,
+ FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACK_FLAGS_START_FRAME_DELIMITER_ERROR,
NULL, HFILL }},
{ &hf_frame_pack_preamble_error,
{ "Preamble error", "frame.packet_flags_preamble_error",
- FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACKET_WORD_PREAMBLE_ERR_MASK,
+ FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACK_FLAGS_PREAMBLE_ERROR,
NULL, HFILL }},
{ &hf_frame_pack_symbol_error,
{ "Symbol error", "frame.packet_flags_symbol_error",
- FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACKET_WORD_SYMBOL_ERR_MASK,
+ FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACK_FLAGS_SYMBOL_ERROR,
NULL, HFILL }},
{ &hf_comments_text,
diff --git a/text2pcap.c b/text2pcap.c
index 226d53094f..30cc579f1d 100644
--- a/text2pcap.c
+++ b/text2pcap.c
@@ -194,7 +194,7 @@ static guint32 hdr_data_chunk_ppid = 0;
static gboolean identify_ascii = FALSE;
static gboolean has_direction = FALSE;
-static guint32 direction = 0;
+static guint32 direction = PACK_FLAGS_DIRECTION_UNKNOWN;
/*--- Local data -----------------------------------------------------------------*/
@@ -617,8 +617,8 @@ write_current_packet (gboolean cont)
if (curr_offset > header_length) {
/* Write the packet */
- /* Is direction indication on with an inbound packet? */
- gboolean isInbound = has_direction && (direction == 2);
+ /* Is direction indication on with an outbound packet? */
+ gboolean isOutbound = has_direction && (direction == PACK_FLAGS_DIRECTION_OUTBOUND);
/* Compute packet length */
length = curr_offset;
@@ -632,7 +632,7 @@ write_current_packet (gboolean cont)
/* Write Ethernet header */
if (hdr_ethernet) {
- if (isInbound)
+ if (isOutbound)
{
memcpy(HDR_ETHERNET.dest_addr, hdr_eth_src_addr, 6);
memcpy(HDR_ETHERNET.src_addr, hdr_eth_dest_addr, 6);
@@ -646,7 +646,7 @@ write_current_packet (gboolean cont)
/* Write IP header */
if (hdr_ip) {
- if (isInbound) {
+ if (isOutbound) {
HDR_IP.src_addr = hdr_ip_dest_addr ? hdr_ip_dest_addr : IP_DST;
HDR_IP.dest_addr = hdr_ip_src_addr? hdr_ip_src_addr : IP_SRC;
}
@@ -672,10 +672,10 @@ write_current_packet (gboolean cont)
pseudoh.length = g_htons(length - header_length + sizeof(HDR_UDP));
}
} else if (hdr_ipv6) {
- if (memcmp(isInbound ? &hdr_ipv6_dest_addr : &hdr_ipv6_src_addr, &NO_IPv6_ADDRESS, sizeof(ws_in6_addr)))
- memcpy(&HDR_IPv6.ip6_src, isInbound ? &hdr_ipv6_dest_addr : &hdr_ipv6_src_addr, sizeof(ws_in6_addr));
- if (memcmp(isInbound ? &hdr_ipv6_src_addr : &hdr_ipv6_dest_addr, &NO_IPv6_ADDRESS, sizeof(ws_in6_addr)))
- memcpy(&HDR_IPv6.ip6_dst, isInbound ? &hdr_ipv6_src_addr : &hdr_ipv6_dest_addr, sizeof(ws_in6_addr));
+ if (memcmp(isOutbound ? &hdr_ipv6_dest_addr : &hdr_ipv6_src_addr, &NO_IPv6_ADDRESS, sizeof(ws_in6_addr)))
+ memcpy(&HDR_IPv6.ip6_src, isOutbound ? &hdr_ipv6_dest_addr : &hdr_ipv6_src_addr, sizeof(ws_in6_addr));
+ if (memcmp(isOutbound ? &hdr_ipv6_src_addr : &hdr_ipv6_dest_addr, &NO_IPv6_ADDRESS, sizeof(ws_in6_addr)))
+ memcpy(&HDR_IPv6.ip6_dst, isOutbound ? &hdr_ipv6_src_addr : &hdr_ipv6_dest_addr, sizeof(ws_in6_addr));
HDR_IPv6.ip6_ctlun.ip6_un2_vfc &= 0x0F;
HDR_IPv6.ip6_ctlun.ip6_un2_vfc |= (6<< 4);
@@ -702,8 +702,8 @@ write_current_packet (gboolean cont)
guint32 u;
/* initialize the UDP header */
- HDR_UDP.source_port = isInbound ? g_htons(hdr_dest_port): g_htons(hdr_src_port);
- HDR_UDP.dest_port = isInbound ? g_htons(hdr_src_port) : g_htons(hdr_dest_port);
+ HDR_UDP.source_port = isOutbound ? g_htons(hdr_dest_port): g_htons(hdr_src_port);
+ HDR_UDP.dest_port = isOutbound ? g_htons(hdr_src_port) : g_htons(hdr_dest_port);
HDR_UDP.length = hdr_ipv6 ? pseudoh6.length : pseudoh.length;
HDR_UDP.checksum = 0;
/* Note: g_ntohs()/g_htons() macro arg may be eval'd twice so calc value before invoking macro */
@@ -726,19 +726,19 @@ write_current_packet (gboolean cont)
guint32 u;
/* initialize the TCP header */
- HDR_TCP.source_port = isInbound ? g_htons(hdr_dest_port): g_htons(hdr_src_port);
- HDR_TCP.dest_port = isInbound ? g_htons(hdr_src_port) : g_htons(hdr_dest_port);
+ HDR_TCP.source_port = isOutbound ? g_htons(hdr_dest_port): g_htons(hdr_src_port);
+ HDR_TCP.dest_port = isOutbound ? g_htons(hdr_src_port) : g_htons(hdr_dest_port);
/* set ack number if we have direction */
if (has_direction) {
HDR_TCP.flags = 0x10;
- HDR_TCP.ack_num = g_ntohl(isInbound ? tcp_out_seq_num : tcp_in_seq_num);
+ HDR_TCP.ack_num = g_ntohl(isOutbound ? tcp_out_seq_num : tcp_in_seq_num);
HDR_TCP.ack_num = g_htonl(HDR_TCP.ack_num);
}
else {
HDR_TCP.flags = 0;
HDR_TCP.ack_num = 0;
}
- HDR_TCP.seq_num = isInbound ? tcp_in_seq_num : tcp_out_seq_num;
+ HDR_TCP.seq_num = isOutbound ? tcp_in_seq_num : tcp_out_seq_num;
HDR_TCP.window = g_htons(0x2000);
HDR_TCP.checksum = 0;
/* Note: g_ntohs()/g_htons() macro arg may be eval'd twice so calc value before invoking macro */
@@ -753,7 +753,7 @@ write_current_packet (gboolean cont)
if (HDR_TCP.checksum == 0) /* differentiate between 'none' and 0 */
HDR_TCP.checksum = g_htons(1);
write_bytes((const char *)&HDR_TCP, sizeof(HDR_TCP));
- if (isInbound) {
+ if (isOutbound) {
tcp_in_seq_num = g_ntohl(tcp_in_seq_num) + length - header_length;
tcp_in_seq_num = g_htonl(tcp_in_seq_num);
}
@@ -789,8 +789,8 @@ write_current_packet (gboolean cont)
if (hdr_sctp) {
guint32 zero = 0;
- HDR_SCTP.src_port = isInbound ? g_htons(hdr_sctp_dest): g_htons(hdr_sctp_src);
- HDR_SCTP.dest_port = isInbound ? g_htons(hdr_sctp_src) : g_htons(hdr_sctp_dest);
+ HDR_SCTP.src_port = isOutbound ? g_htons(hdr_sctp_dest): g_htons(hdr_sctp_src);
+ HDR_SCTP.dest_port = isOutbound ? g_htons(hdr_sctp_src) : g_htons(hdr_sctp_dest);
HDR_SCTP.tag = g_htonl(hdr_sctp_tag);
HDR_SCTP.checksum = g_htonl(0);
HDR_SCTP.checksum = crc32c((guint8 *)&HDR_SCTP, sizeof(HDR_SCTP), ~0);
@@ -970,16 +970,16 @@ parse_preamble (void)
switch (packet_preamble[0]) {
case 'i':
case 'I':
- direction = 0x00000001;
+ direction = PACK_FLAGS_DIRECTION_INBOUND;
packet_preamble[0] = ' ';
break;
case 'o':
case 'O':
- direction = 0x00000002;
+ direction = PACK_FLAGS_DIRECTION_OUTBOUND;
packet_preamble[0] = ' ';
break;
default:
- direction = 0x00000000;
+ direction = PACK_FLAGS_DIRECTION_UNKNOWN;
break;
}
i = 0;
diff --git a/ui/text_import.c b/ui/text_import.c
index 191e4547de..6c8c8d2fa6 100644
--- a/ui/text_import.c
+++ b/ui/text_import.c
@@ -157,7 +157,7 @@ static gboolean hdr_export_pdu = FALSE;
static gchar* hdr_export_pdu_payload = NULL;
static gboolean has_direction = FALSE;
-static guint32 direction = 0;
+static guint32 direction = PACK_FLAGS_RECEPTION_TYPE_UNSPECIFIED;
/*--- Local data -----------------------------------------------------------------*/
@@ -627,16 +627,16 @@ parse_preamble (void)
switch (packet_preamble[0]) {
case 'i':
case 'I':
- direction = 0x00000001;
+ direction = PACK_FLAGS_DIRECTION_INBOUND;
packet_preamble[0] = ' ';
break;
case 'o':
case 'O':
- direction = 0x00000002;
+ direction = PACK_FLAGS_DIRECTION_OUTBOUND;
packet_preamble[0] = ' ';
break;
default:
- direction = 0x00000000;
+ direction = PACK_FLAGS_DIRECTION_UNKNOWN;
break;
}
i = 0;
diff --git a/wiretap/pcapng.c b/wiretap/pcapng.c
index bd101b4722..7eaafcdd79 100644
--- a/wiretap/pcapng.c
+++ b/wiretap/pcapng.c
@@ -1400,9 +1400,9 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
wblock->rec->rec_header.packet_header.pack_flags = GUINT32_SWAP_LE_BE(wblock->rec->rec_header.packet_header.pack_flags);
memcpy(option_content, &wblock->rec->rec_header.packet_header.pack_flags, sizeof(guint32));
}
- if (wblock->rec->rec_header.packet_header.pack_flags & 0x000001E0) {
+ if (PACK_FLAGS_FCS_LENGTH(wblock->rec->rec_header.packet_header.pack_flags) != 0) {
/* The FCS length is present */
- fcslen = (wblock->rec->rec_header.packet_header.pack_flags & 0x000001E0) >> 5;
+ fcslen = PACK_FLAGS_FCS_LENGTH(wblock->rec->rec_header.packet_header.pack_flags);
}
pcapng_debug("pcapng_read_packet_block: pack_flags %u (ignored)", wblock->rec->rec_header.packet_header.pack_flags);
break;
diff --git a/wiretap/wtap.h b/wiretap/wtap.h
index 96631b8e99..4e2eb7c4f3 100644
--- a/wiretap/wtap.h
+++ b/wiretap/wtap.h
@@ -1268,11 +1268,82 @@ typedef struct {
/* options */
guint64 drop_count; /* number of packets lost (by the interface and the
operating system) between this packet and the preceding one. */
- guint32 pack_flags; /* XXX - 0 for now (any value for "we don't have it"?) */
+ guint32 pack_flags; /* various flags, as per pcapng EPB */
union wtap_pseudo_header pseudo_header;
} wtap_packet_header;
+/*
+ * The pcapng specification says "The word is encoded as an unsigned
+ * 32-bit integer, using the endianness of the Section Header Block
+ * scope it is in. In the following table, the bits are numbered with
+ * 0 being the most-significant bit and 31 being the least-significant
+ * bit of the 32-bit unsigned integer."
+ *
+ * From that, the direction, in bits 0 and 1, is at the *top* of the word.
+ *
+ * However, several implementations, such as:
+ *
+ * the Wireshark pcapng file reading code;
+ *
+ * macOS libpcap and tcpdump;
+ *
+ * text2pcap;
+ *
+ * and probably the software that generated the capture in bug 11665;
+ *
+ * treat 0 as the *least*-significant bit and bit 31 being the *most*-
+ * significant bit of the flags word, and put the direction at the
+ * *bottom* of the word.
+ *
+ * For now, we go with the known implementations.
+ */
+
+/* Direction field of the packet flags */
+#define PACK_FLAGS_DIRECTION_MASK 0x00000003 /* unshifted */
+#define PACK_FLAGS_DIRECTION_SHIFT 0
+#define PACK_FLAGS_DIRECTION(pack_flags) (((pack_flags) & PACK_FLAGS_DIRECTION_MASK) >> PACK_FLAGS_DIRECTION_SHIFT)
+#define PACK_FLAGS_DIRECTION_UNKNOWN 0
+#define PACK_FLAGS_DIRECTION_INBOUND 1
+#define PACK_FLAGS_DIRECTION_OUTBOUND 2
+
+/* Reception type field of the packet flags */
+#define PACK_FLAGS_RECEPTION_TYPE_MASK 0x0000001C /* unshifted */
+#define PACK_FLAGS_RECEPTION_TYPE_SHIFT 2
+#define PACK_FLAGS_RECEPTION_TYPE(pack_flags) (((pack_flags) & PACK_FLAGS_RECEPTION_TYPE_MASK) >> PACK_FLAGS_RECEPTION_TYPE_SHIFT)
+#define PACK_FLAGS_RECEPTION_TYPE_UNSPECIFIED 0
+#define PACK_FLAGS_RECEPTION_TYPE_UNICAST 1
+#define PACK_FLAGS_RECEPTION_TYPE_MULTICAST 2
+#define PACK_FLAGS_RECEPTION_TYPE_BROADCAST 3
+#define PACK_FLAGS_RECEPTION_TYPE_PROMISCUOUS 4
+
+/* FCS length field of the packet flags */
+#define PACK_FLAGS_FCS_LENGTH_MASK 0x000001E0 /* unshifted */
+#define PACK_FLAGS_FCS_LENGTH_SHIFT 5
+#define PACK_FLAGS_FCS_LENGTH(pack_flags) (((pack_flags) & PACK_FLAGS_FCS_LENGTH_MASK) >> PACK_FLAGS_FCS_LENGTH_SHIFT)
+
+/* Reserved bits of the packet flags */
+#define PACK_FLAGS_RESERVED_MASK 0x0000FE00
+
+/* Link-layer-dependent errors of the packet flags */
+
+/* For Ethernet and possibly some other network types */
+#define PACK_FLAGS_CRC_ERROR 0x01000000
+#define PACK_FLAGS_PACKET_TOO_LONG 0x02000000
+#define PACK_FLAGS_PACKET_TOO_SHORT 0x04000000
+#define PACK_FLAGS_WRONG_INTER_FRAME_GAP 0x08000000
+#define PACK_FLAGS_UNALIGNED_FRAME 0x10000000
+#define PACK_FLAGS_START_FRAME_DELIMITER_ERROR 0x20000000
+#define PACK_FLAGS_PREAMBLE_ERROR 0x40000000
+#define PACK_FLAGS_SYMBOL_ERROR 0x80000000
+
+/* Construct a pack_flags value from its subfield values */
+#define PACK_FLAGS_VALUE(direction, reception_type, fcs_length, ll_dependent_errors) \
+ (((direction) << 30) | \
+ ((reception_type) << 27) | \
+ ((fcs_length) << 23) | \
+ (ll_dependent_errors))
+
typedef struct {
guint record_type; /* the type of record this is - file type-specific value */
guint32 record_len; /* length of the record */