diff options
-rw-r--r-- | epan/dissectors/packet-frame.c | 85 | ||||
-rw-r--r-- | text2pcap.c | 42 | ||||
-rw-r--r-- | ui/text_import.c | 8 | ||||
-rw-r--r-- | wiretap/pcapng.c | 4 | ||||
-rw-r--r-- | wiretap/wtap.h | 73 |
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 */ |