From 4abec47c053491a55ef0fca8750af2d363033421 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Tue, 18 Aug 2015 12:14:07 -0700 Subject: [PATCH] Clean up handling of time stamps. Use common code for all time stamps, so it's handled the same for the Packet Block, Enhanced Packet Block, and Interface Statistics Block. Show the high and low parts of the time stamp as fields; file dissectors should show the raw file details. Mark the calculated time stamp as generated, as it's not the raw file data. Get the 64-bit time stamp by shifting the high part left 32 bits and ORing in the low part; no need to play games with unions and byte order Change-Id: I19b2c3227a3ca1e93ec653f279136aa18687581f Reviewed-on: https://code.wireshark.org/review/10116 Reviewed-by: Guy Harris --- epan/dissectors/file-pcapng.c | 101 +++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 43 deletions(-) diff --git a/epan/dissectors/file-pcapng.c b/epan/dissectors/file-pcapng.c index 824b07222b..70b65711d5 100644 --- a/epan/dissectors/file-pcapng.c +++ b/epan/dissectors/file-pcapng.c @@ -119,6 +119,8 @@ static int hf_pcapng_packet_length = -1; static int hf_pcapng_packet_data = -1; static int hf_pcapng_packet_padding = -1; static int hf_pcapng_interface_id = -1; +static int hf_pcapng_timestamp_high = -1; +static int hf_pcapng_timestamp_low = -1; static int hf_pcapng_timestamp = -1; static int hf_pcapng_timestamp_data = -1; static int hf_pcapng_records = -1; @@ -1007,6 +1009,48 @@ static gint dissect_options(proto_tree *tree, packet_info *pinfo, return offset; } +static void +pcapng_add_timestamp(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, + int offset, guint encoding, guint32 interface_id, struct info *info) +{ + proto_tree_add_item(tree, hf_pcapng_timestamp_high, tvb, offset, 4, encoding); + proto_tree_add_item(tree, hf_pcapng_timestamp_low, tvb, offset + 4, 4, encoding); + + if (interface_id < wmem_array_get_count(info->interfaces)) { + struct interface_description *interface_description; + nstime_t timestamp; + guint64 ts; + guint32 base; + guint32 i_resolution; + guint64 resolution = 1; + proto_item *ti; + + interface_description = (struct interface_description *) wmem_array_index(info->interfaces, interface_id); + ts = ((guint64)(tvb_get_guint32(tvb, offset, encoding))) << 32 | + tvb_get_guint32(tvb, offset + 4, encoding); + + ts += interface_description->timestamp_offset; + if (interface_description->timestamp_resolution == 0) + interface_description->timestamp_resolution = 6; + + if (interface_description->timestamp_resolution & 0x80) { + base = 2; + } else { + base = 10; + } + + for (i_resolution = 0; i_resolution < (guint32)(interface_description->timestamp_resolution & 0x7F); i_resolution += 1) + resolution *= base; + timestamp.secs = (time_t)(ts / resolution); + timestamp.nsecs = (int)(ts - (ts / resolution) * resolution); + + ti = proto_tree_add_time(tree, hf_pcapng_timestamp, tvb, offset, 8, ×tamp); + PROTO_ITEM_SET_GENERATED(ti); + + pinfo->fd->abs_ts = timestamp; + } +} + static gint dissect_block(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, guint encoding, struct info *info) { @@ -1099,7 +1143,7 @@ static gint dissect_block(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, proto_tree_add_item(block_data_tree, hf_pcapng_packet_block_drops_count, tvb, offset, 2, encoding); offset += 2; - proto_tree_add_item(block_data_tree, hf_pcapng_timestamp_data, tvb, offset, 8, encoding); + pcapng_add_timestamp(block_data_tree, pinfo, tvb, offset, encoding, interface_id, info); offset += 8; proto_tree_add_item(block_data_tree, hf_pcapng_captured_length, tvb, offset, 4, encoding); @@ -1266,9 +1310,10 @@ static gint dissect_block(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, break; case BLOCK_INTERFACE_STATISTICS: proto_tree_add_item(block_data_tree, hf_pcapng_interface_id, tvb, offset, 4, encoding); + interface_id = tvb_get_guint32(tvb, offset, encoding); offset += 4; - proto_tree_add_item(block_data_tree, hf_pcapng_timestamp_data, tvb, offset, 8, encoding); + pcapng_add_timestamp(block_data_tree, pinfo, tvb, offset, encoding, interface_id, info); offset += 8; next_tvb = tvb_new_subset_length(tvb, offset, block_data_length - 4 - 8); @@ -1283,47 +1328,7 @@ static gint dissect_block(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, interface_id = tvb_get_guint32(tvb, offset, encoding); offset += 4; - if (interface_id < wmem_array_get_count(info->interfaces)) { - struct interface_description *interface_description; - nstime_t timestamp; - union { - guint32 u32[2]; - guint64 u64; - } ts; - guint32 base; - guint32 i_resolution; - guint64 resolution = 1; - - interface_description = (struct interface_description *) wmem_array_index(info->interfaces, interface_id); -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - ts.u32[1] = tvb_get_guint32(tvb, offset, encoding); - ts.u32[0] = tvb_get_guint32(tvb, offset + 4, encoding); -#else - ts.u32[0] = tvb_get_guint32(tvb, offset, encoding); - ts.u32[1] = tvb_get_guint32(tvb, offset + 4, encoding); -#endif - - ts.u64 += interface_description->timestamp_offset; - if (interface_description->timestamp_resolution == 0) - interface_description->timestamp_resolution = 6; - - if (interface_description->timestamp_resolution & 0x80) { - base = 2; - } else { - base = 10; - } - - for (i_resolution = 0; i_resolution < (guint32)(interface_description->timestamp_resolution & 0x7F); i_resolution += 1) - resolution *= base; - timestamp.secs = (time_t)(ts.u64 / resolution); - timestamp.nsecs = (int)(ts.u64 - (ts.u64 / resolution) * resolution); - - proto_tree_add_time(block_data_tree, hf_pcapng_timestamp, tvb, offset, 8, ×tamp); - - pinfo->fd->abs_ts = timestamp; - } else { - proto_tree_add_item(block_data_tree, hf_pcapng_timestamp_data, tvb, offset, 8, encoding); - } + pcapng_add_timestamp(block_data_tree, pinfo, tvb, offset, encoding, interface_id, info); offset += 8; proto_tree_add_item(block_data_tree, hf_pcapng_captured_length, tvb, offset, 4, encoding); @@ -1829,6 +1834,16 @@ proto_register_pcapng(void) FT_UINT16, BASE_HEX, NULL, 0x00, NULL, HFILL } }, + { &hf_pcapng_timestamp_high, + { "Timestamp (High)", "pcapng.timestamp_high", + FT_UINT32, BASE_DEC, NULL, 0x00, + NULL, HFILL } + }, + { &hf_pcapng_timestamp_low, + { "Timestamp (Low)", "pcapng.timestamp_low", + FT_UINT32, BASE_DEC, NULL, 0x00, + NULL, HFILL } + }, { &hf_pcapng_timestamp, { "Timestamp", "pcapng.timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x00,