forked from osmocom/wireshark
pcapng (dissector): don't assume the endianness doesn't change.
Keep the endianness (as an ENC_ value) in the info structure we use while dissecting. When dissecting an SPB, peek ahead at the byte-order magic before dissecting the block length, to determine the byte order of all fields in that block *and* all other blocks in that section. Report an error and stop dissecting if the byte-order magic isn't valid. Change-Id: I6d94d4fad10d60f327f4a486e180cdcee2f6be2d Reviewed-on: https://code.wireshark.org/review/37138 Petri-Dish: Guy Harris <gharris@sonic.net> Tested-by: Petri Dish Buildbot Reviewed-by: Guy Harris <gharris@sonic.net>
This commit is contained in:
parent
432cb20707
commit
b99a0c95d8
|
@ -135,6 +135,7 @@ static int hf_pcapng_option_data_packet_darwin_dpeb_id = -1;
|
|||
static int hf_pcapng_option_data_packet_darwin_svc_class = -1;
|
||||
static int hf_pcapng_option_data_packet_darwin_edpeb_id = -1;
|
||||
|
||||
static expert_field ei_invalid_byte_order_magic = EI_INIT;
|
||||
static expert_field ei_block_length_too_short = EI_INIT;
|
||||
static expert_field ei_block_length_not_multiple_of_4 = EI_INIT;
|
||||
static expert_field ei_invalid_option_length = EI_INIT;
|
||||
|
@ -188,6 +189,7 @@ struct info {
|
|||
guint32 interface_number;
|
||||
guint32 darwin_process_event_number;
|
||||
guint32 frame_number;
|
||||
guint encoding;
|
||||
wmem_array_t *interfaces;
|
||||
wmem_array_t *darwin_process_events;
|
||||
};
|
||||
|
@ -551,6 +553,15 @@ static const value_string dsb_secrets_types_vals[] = {
|
|||
void proto_register_pcapng(void);
|
||||
void proto_reg_handoff_pcapng(void);
|
||||
|
||||
#define BYTE_ORDER_MAGIC_SIZE 4
|
||||
|
||||
static const guint8 pcapng_big_endian_magic[BYTE_ORDER_MAGIC_SIZE] = {
|
||||
0x1A, 0x2B, 0x3C, 0x4D
|
||||
};
|
||||
static const guint8 pcapng_little_endian_magic[BYTE_ORDER_MAGIC_SIZE] = {
|
||||
0x4D, 0x3C, 0x2B, 0x1A
|
||||
};
|
||||
|
||||
static gint dissect_options(proto_tree *tree, packet_info *pinfo,
|
||||
guint32 block_type, tvbuff_t *tvb, guint encoding, void *user_data)
|
||||
{
|
||||
|
@ -1266,14 +1277,52 @@ get_interface_description(struct info *info, guint interface_id,
|
|||
return (struct interface_description *) wmem_array_index(info->interfaces, interface_id);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is tricky - for most blocks, we can dissect this first, but, for
|
||||
* a Section Header Block, we must dissect it *after* determining the
|
||||
* byte order.
|
||||
*
|
||||
* So we extract it into a routine and call it at the appropriate time.
|
||||
*/
|
||||
static proto_tree *
|
||||
dissect_block_length(proto_tree *block_tree, packet_info *pinfo,
|
||||
tvbuff_t *tvb, int offset, guint32 *block_data_length_p,
|
||||
guint encoding)
|
||||
{
|
||||
proto_item *block_length_item;
|
||||
proto_item *block_data_item;
|
||||
|
||||
block_length_item = proto_tree_add_item_ret_uint(block_tree, hf_pcapng_block_length, tvb, offset, 4, encoding, block_data_length_p);
|
||||
if (*block_data_length_p < 3*4)
|
||||
expert_add_info(pinfo, block_length_item, &ei_block_length_too_short);
|
||||
/*
|
||||
* To quote the current pcapng spec, "Block Total Length (32 bits) ...
|
||||
* This value MUST be a multiple of 4."
|
||||
*/
|
||||
if ((*block_data_length_p % 4) != 0)
|
||||
expert_add_info(pinfo, block_length_item, &ei_block_length_not_multiple_of_4);
|
||||
|
||||
/*
|
||||
* Subtract the per-block overhead (block type, block length, trailing
|
||||
* block length).
|
||||
*/
|
||||
*block_data_length_p -= 3*4;
|
||||
|
||||
/*
|
||||
* Now that we know the block data length, create an item for its
|
||||
* tree.
|
||||
*/
|
||||
offset += 4;
|
||||
block_data_item = proto_tree_add_item(block_tree, hf_pcapng_block_data, tvb, offset, *block_data_length_p, ENC_NA);
|
||||
return proto_item_add_subtree(block_data_item, ett_pcapng_block_data);
|
||||
}
|
||||
|
||||
static gint dissect_block(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
|
||||
guint encoding, struct info *info)
|
||||
struct info *info)
|
||||
{
|
||||
proto_tree *block_tree;
|
||||
proto_item *block_item;
|
||||
proto_item *block_length_item;
|
||||
proto_tree *block_data_tree;
|
||||
proto_item *block_data_item;
|
||||
proto_item *byte_order_magic_item;
|
||||
proto_item *packet_data_item;
|
||||
gint offset = 0;
|
||||
|
@ -1285,38 +1334,20 @@ static gint dissect_block(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
|
|||
guint32 interface_id;
|
||||
tvbuff_t *next_tvb;
|
||||
|
||||
block_type = tvb_get_guint32(tvb, offset + 0, encoding);
|
||||
length = tvb_get_guint32(tvb, offset + 4, encoding);
|
||||
block_type = tvb_get_guint32(tvb, offset + 0, info->encoding);
|
||||
length = tvb_get_guint32(tvb, offset + 4, info->encoding);
|
||||
|
||||
block_item = proto_tree_add_item(tree, hf_pcapng_block, tvb, offset, length, ENC_NA);
|
||||
block_tree = proto_item_add_subtree(block_item, ett_pcapng_section_header_block);
|
||||
proto_item_append_text(block_item, ": %s", val_to_str_const(block_type, block_type_vals, "Unknown"));
|
||||
|
||||
proto_tree_add_bitmask_with_flags(block_tree, tvb, offset, hf_pcapng_block_type, ett_pcapng_option, hfx_pcapng_block_type, encoding, BMT_NO_APPEND);
|
||||
proto_tree_add_bitmask_with_flags(block_tree, tvb, offset, hf_pcapng_block_type, ett_pcapng_option, hfx_pcapng_block_type, info->encoding, BMT_NO_APPEND);
|
||||
offset += 4;
|
||||
|
||||
block_length_item = proto_tree_add_item_ret_uint(block_tree, hf_pcapng_block_length, tvb, offset, 4, encoding, &block_data_length);
|
||||
if (block_data_length < 3*4)
|
||||
expert_add_info(pinfo, block_length_item, &ei_block_length_too_short);
|
||||
/*
|
||||
* To quote the current pcapng spec, "Block Total Length (32 bits) ...
|
||||
* This value MUST be a multiple of 4."
|
||||
*/
|
||||
if ((block_data_length % 4) != 0)
|
||||
expert_add_info(pinfo, block_length_item, &ei_block_length_not_multiple_of_4);
|
||||
if (block_type == BLOCK_SECTION_HEADER) {
|
||||
/* Section Header Block - this needs special byte-order handling */
|
||||
gboolean byte_order_magic_bad = FALSE;
|
||||
|
||||
/*
|
||||
* Subtract the per-block overhead (block type, block length, trailing
|
||||
* block length).
|
||||
*/
|
||||
block_data_length -= 3*4;
|
||||
offset += 4;
|
||||
|
||||
block_data_item = proto_tree_add_item(block_tree, hf_pcapng_block_data, tvb, offset, block_data_length, ENC_NA);
|
||||
block_data_tree = proto_item_add_subtree(block_data_item, ett_pcapng_block_data);
|
||||
|
||||
switch (block_type) {
|
||||
case BLOCK_SECTION_HEADER: /* Section Header Block */
|
||||
proto_item_append_text(block_item, " %u", info->section_number);
|
||||
info->section_number += 1;
|
||||
info->interface_number = 0;
|
||||
|
@ -1327,385 +1358,406 @@ static gint dissect_block(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
|
|||
}
|
||||
info->interfaces = wmem_array_new(wmem_packet_scope(), sizeof(struct interface_description));
|
||||
|
||||
if (tvb_memeql(tvb, 8, pcapng_big_endian_magic, BYTE_ORDER_MAGIC_SIZE) == 0) {
|
||||
info->encoding = ENC_BIG_ENDIAN;
|
||||
} else if (tvb_memeql(tvb, 8, pcapng_little_endian_magic, BYTE_ORDER_MAGIC_SIZE) == 0) {
|
||||
info->encoding = ENC_LITTLE_ENDIAN;
|
||||
} else {
|
||||
byte_order_magic_bad = TRUE;
|
||||
}
|
||||
|
||||
block_data_tree = dissect_block_length(block_tree, pinfo, tvb, offset, &block_data_length, info->encoding);
|
||||
offset += 4;
|
||||
|
||||
byte_order_magic_item = proto_tree_add_item(block_data_tree, hf_pcapng_section_header_byte_order_magic, tvb, offset, 4, ENC_NA);
|
||||
if (encoding == ENC_BIG_ENDIAN)
|
||||
if (byte_order_magic_bad) {
|
||||
expert_add_info(pinfo, byte_order_magic_item, &ei_invalid_byte_order_magic);
|
||||
return -1;
|
||||
}
|
||||
if (info->encoding == ENC_BIG_ENDIAN)
|
||||
proto_item_append_text(byte_order_magic_item, " (Big-endian)");
|
||||
else
|
||||
proto_item_append_text(byte_order_magic_item, " (Little-endian)");
|
||||
offset += 4;
|
||||
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_section_header_major_version, tvb, offset, 2, encoding);
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_section_header_major_version, tvb, offset, 2, info->encoding);
|
||||
offset += 2;
|
||||
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_section_header_minor_version, tvb, offset, 2, encoding);
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_section_header_minor_version, tvb, offset, 2, info->encoding);
|
||||
offset += 2;
|
||||
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_section_header_section_length, tvb, offset, 8, encoding);
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_section_header_section_length, tvb, offset, 8, info->encoding);
|
||||
offset += 8;
|
||||
|
||||
next_tvb = tvb_new_subset_length(tvb, offset, block_data_length - 4 - 2 - 2 - 8);
|
||||
offset += dissect_options(block_data_tree, pinfo, block_type, next_tvb, encoding, NULL);
|
||||
|
||||
break;
|
||||
case BLOCK_INTERFACE_DESCRIPTION: {
|
||||
struct interface_description interface_description;
|
||||
|
||||
memset(&interface_description, 0, sizeof(struct interface_description));
|
||||
interface_description.timestamp_resolution = 1000000; /* 1 microsecond resolution is the default */
|
||||
|
||||
proto_item_append_text(block_item, " %u", info->interface_number);
|
||||
info->interface_number += 1;
|
||||
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_interface_description_link_type, tvb, offset, 2, encoding);
|
||||
interface_description.link_type = tvb_get_guint16(tvb, offset, encoding);
|
||||
offset += 2;
|
||||
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_interface_description_reserved, tvb, offset, 2, encoding);
|
||||
offset += 2;
|
||||
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_interface_description_snap_length, tvb, offset, 4, encoding);
|
||||
interface_description.snap_len = tvb_get_guint32(tvb, offset, encoding);
|
||||
offset += dissect_options(block_data_tree, pinfo, block_type, next_tvb, info->encoding, NULL);
|
||||
} else {
|
||||
/*
|
||||
* Not an SHB, so we know the byte order.
|
||||
*/
|
||||
block_data_tree = dissect_block_length(block_tree, pinfo, tvb, offset, &block_data_length, info->encoding);
|
||||
offset += 4;
|
||||
|
||||
next_tvb = tvb_new_subset_length(tvb, offset, block_data_length - 2 - 2 - 4);
|
||||
offset += dissect_options(block_data_tree, pinfo, block_type, next_tvb, encoding, &interface_description);
|
||||
switch (block_type) {
|
||||
case BLOCK_INTERFACE_DESCRIPTION: {
|
||||
struct interface_description interface_description;
|
||||
|
||||
wmem_array_append_one(info->interfaces, interface_description);
|
||||
}
|
||||
break;
|
||||
case BLOCK_PACKET: {
|
||||
struct interface_description *interface_description;
|
||||
memset(&interface_description, 0, sizeof(struct interface_description));
|
||||
interface_description.timestamp_resolution = 1000000; /* 1 microsecond resolution is the default */
|
||||
|
||||
proto_item_append_text(block_item, " %u", info->frame_number);
|
||||
proto_item_append_text(block_item, " %u", info->interface_number);
|
||||
info->interface_number += 1;
|
||||
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_packet_block_interface_id, tvb, offset, 2, encoding);
|
||||
interface_id = tvb_get_guint16(tvb, offset, encoding);
|
||||
offset += 2;
|
||||
interface_description = get_interface_description(info, interface_id,
|
||||
pinfo, block_tree);
|
||||
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_packet_block_drops_count, tvb, offset, 2, encoding);
|
||||
offset += 2;
|
||||
|
||||
pcapng_add_timestamp(block_data_tree, pinfo, tvb, offset, encoding, interface_description);
|
||||
offset += 8;
|
||||
|
||||
proto_tree_add_item_ret_uint(block_data_tree, hf_pcapng_captured_length, tvb, offset, 4, encoding, &captured_length);
|
||||
offset += 4;
|
||||
|
||||
proto_tree_add_item_ret_uint(block_data_tree, hf_pcapng_packet_length, tvb, offset, 4, encoding, &reported_length);
|
||||
offset += 4;
|
||||
|
||||
packet_data_item = proto_tree_add_item(block_data_tree, hf_pcapng_packet_data, tvb, offset, captured_length, encoding);
|
||||
|
||||
if (pref_dissect_next_layer && interface_description != NULL) {
|
||||
proto_tree *packet_data_tree = proto_item_add_subtree(packet_data_item, ett_pcapng_packet_data);
|
||||
|
||||
pinfo->num = info->frame_number;
|
||||
|
||||
TRY {
|
||||
call_dissector_with_data(pcap_pktdata_handle, tvb_new_subset_length_caplen(tvb, offset, captured_length, reported_length),
|
||||
pinfo, packet_data_tree, &interface_description->link_type);
|
||||
}
|
||||
CATCH_BOUNDS_ERRORS {
|
||||
show_exception(tvb, pinfo, packet_data_tree, EXCEPT_CODE, GET_MESSAGE);
|
||||
}
|
||||
ENDTRY;
|
||||
}
|
||||
info->frame_number += 1;
|
||||
offset += captured_length;
|
||||
|
||||
if (captured_length % 4) {
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_packet_padding, tvb, offset, ((captured_length % 4) ? (4 - (captured_length % 4)) : 0), ENC_NA);
|
||||
offset += ((captured_length % 4) ?(4 - (captured_length % 4)):0);
|
||||
}
|
||||
|
||||
next_tvb = tvb_new_subset_length(tvb, offset, block_data_length - 2 - 2 - 8 - 4 - 4 - captured_length - ((captured_length % 4)?(4 - (captured_length % 4)):0));
|
||||
offset += dissect_options(block_data_tree, pinfo, block_type, next_tvb, encoding, NULL);
|
||||
|
||||
}
|
||||
break;
|
||||
case BLOCK_SIMPLE_PACKET: {
|
||||
struct interface_description *interface_description;
|
||||
proto_item *ti;
|
||||
|
||||
interface_description = get_interface_description(info, 0,
|
||||
pinfo, block_tree);
|
||||
|
||||
proto_item_append_text(block_item, " %u", info->frame_number);
|
||||
|
||||
proto_tree_add_item_ret_uint(block_data_tree, hf_pcapng_packet_length, tvb, offset, 4, encoding, &reported_length);
|
||||
offset += 4;
|
||||
|
||||
captured_length = reported_length;
|
||||
if (interface_description && interface_description->snap_len != 0) {
|
||||
captured_length = MIN(reported_length, interface_description->snap_len);
|
||||
}
|
||||
ti = proto_tree_add_uint(block_data_tree, hf_pcapng_captured_length, tvb, 0, 0, captured_length);
|
||||
proto_item_set_generated(ti);
|
||||
|
||||
packet_data_item = proto_tree_add_item(block_data_tree, hf_pcapng_packet_data, tvb, offset, captured_length, encoding);
|
||||
|
||||
if (pref_dissect_next_layer && interface_description != NULL) {
|
||||
proto_tree *packet_data_tree = proto_item_add_subtree(packet_data_item, ett_pcapng_packet_data);
|
||||
|
||||
pinfo->num = info->frame_number;
|
||||
|
||||
TRY {
|
||||
call_dissector_with_data(pcap_pktdata_handle, tvb_new_subset_length(tvb, offset, captured_length),
|
||||
pinfo, packet_data_tree, &interface_description->link_type);
|
||||
}
|
||||
CATCH_BOUNDS_ERRORS {
|
||||
show_exception(tvb, pinfo, packet_data_tree, EXCEPT_CODE, GET_MESSAGE);
|
||||
}
|
||||
ENDTRY;
|
||||
}
|
||||
info->frame_number += 1;
|
||||
offset += captured_length;
|
||||
|
||||
if (captured_length % 4) {
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_packet_padding, tvb, offset, ((captured_length % 4)?(4 - (captured_length % 4)):0), ENC_NA);
|
||||
offset += ((captured_length % 4) ? (4 - (captured_length % 4)):0);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case BLOCK_NAME_RESOLUTION:
|
||||
{
|
||||
proto_tree *records_tree;
|
||||
proto_item *records_item;
|
||||
proto_tree *record_tree;
|
||||
proto_item *record_item;
|
||||
proto_item *record_length_item;
|
||||
gint offset_record_start;
|
||||
gint offset_string_start;
|
||||
guint32 record_code;
|
||||
guint32 record_length;
|
||||
gint string_length;
|
||||
gchar *str = NULL;
|
||||
address addr;
|
||||
|
||||
records_item = proto_tree_add_item(block_data_tree, hf_pcapng_records, tvb, offset, block_data_length, ENC_NA);
|
||||
records_tree = proto_item_add_subtree(records_item, ett_pcapng_records);
|
||||
|
||||
offset_record_start = offset;
|
||||
while (block_data_length - (offset_record_start - offset) > 0) {
|
||||
record_item = proto_tree_add_item(records_tree, hf_pcapng_record, tvb, offset, -1, ENC_NA);
|
||||
record_tree = proto_item_add_subtree(record_item, ett_pcapng_record);
|
||||
|
||||
proto_tree_add_item_ret_uint(record_tree, hf_pcapng_record_code, tvb, offset, 2, encoding, &record_code);
|
||||
proto_item_append_text(record_item, ": %s", val_to_str_const(record_code, record_code_vals, "Unknown"));
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_interface_description_link_type, tvb, offset, 2, info->encoding);
|
||||
interface_description.link_type = tvb_get_guint16(tvb, offset, info->encoding);
|
||||
offset += 2;
|
||||
|
||||
record_length_item = proto_tree_add_item_ret_uint(record_tree, hf_pcapng_record_length, tvb, offset, 2, encoding, &record_length);
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_interface_description_reserved, tvb, offset, 2, info->encoding);
|
||||
offset += 2;
|
||||
|
||||
if (record_code == 0) {
|
||||
if (record_length != 0)
|
||||
expert_add_info(pinfo, record_length_item, &ei_invalid_record_length);
|
||||
proto_item_set_len(record_item, record_length + 2 * 2);
|
||||
break;
|
||||
} else switch (record_code) {
|
||||
case 0x0001: /* IPv4 Record */
|
||||
if (record_length < 5) {
|
||||
expert_add_info(pinfo, record_length_item, &ei_invalid_record_length);
|
||||
offset += record_length;
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_interface_description_snap_length, tvb, offset, 4, info->encoding);
|
||||
interface_description.snap_len = tvb_get_guint32(tvb, offset, info->encoding);
|
||||
offset += 4;
|
||||
|
||||
next_tvb = tvb_new_subset_length(tvb, offset, block_data_length - 2 - 2 - 4);
|
||||
offset += dissect_options(block_data_tree, pinfo, block_type, next_tvb, info->encoding, &interface_description);
|
||||
|
||||
wmem_array_append_one(info->interfaces, interface_description);
|
||||
}
|
||||
break;
|
||||
case BLOCK_PACKET: {
|
||||
struct interface_description *interface_description;
|
||||
|
||||
proto_item_append_text(block_item, " %u", info->frame_number);
|
||||
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_packet_block_interface_id, tvb, offset, 2, info->encoding);
|
||||
interface_id = tvb_get_guint16(tvb, offset, info->encoding);
|
||||
offset += 2;
|
||||
interface_description = get_interface_description(info, interface_id,
|
||||
pinfo, block_tree);
|
||||
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_packet_block_drops_count, tvb, offset, 2, info->encoding);
|
||||
offset += 2;
|
||||
|
||||
pcapng_add_timestamp(block_data_tree, pinfo, tvb, offset, info->encoding, interface_description);
|
||||
offset += 8;
|
||||
|
||||
proto_tree_add_item_ret_uint(block_data_tree, hf_pcapng_captured_length, tvb, offset, 4, info->encoding, &captured_length);
|
||||
offset += 4;
|
||||
|
||||
proto_tree_add_item_ret_uint(block_data_tree, hf_pcapng_packet_length, tvb, offset, 4, info->encoding, &reported_length);
|
||||
offset += 4;
|
||||
|
||||
packet_data_item = proto_tree_add_item(block_data_tree, hf_pcapng_packet_data, tvb, offset, captured_length, info->encoding);
|
||||
|
||||
if (pref_dissect_next_layer && interface_description != NULL) {
|
||||
proto_tree *packet_data_tree = proto_item_add_subtree(packet_data_item, ett_pcapng_packet_data);
|
||||
|
||||
pinfo->num = info->frame_number;
|
||||
|
||||
TRY {
|
||||
call_dissector_with_data(pcap_pktdata_handle, tvb_new_subset_length_caplen(tvb, offset, captured_length, reported_length),
|
||||
pinfo, packet_data_tree, &interface_description->link_type);
|
||||
}
|
||||
CATCH_BOUNDS_ERRORS {
|
||||
show_exception(tvb, pinfo, packet_data_tree, EXCEPT_CODE, GET_MESSAGE);
|
||||
}
|
||||
ENDTRY;
|
||||
}
|
||||
info->frame_number += 1;
|
||||
offset += captured_length;
|
||||
|
||||
if (captured_length % 4) {
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_packet_padding, tvb, offset, ((captured_length % 4) ? (4 - (captured_length % 4)) : 0), ENC_NA);
|
||||
offset += ((captured_length % 4) ?(4 - (captured_length % 4)):0);
|
||||
}
|
||||
|
||||
next_tvb = tvb_new_subset_length(tvb, offset, block_data_length - 2 - 2 - 8 - 4 - 4 - captured_length - ((captured_length % 4)?(4 - (captured_length % 4)):0));
|
||||
offset += dissect_options(block_data_tree, pinfo, block_type, next_tvb, info->encoding, NULL);
|
||||
|
||||
}
|
||||
break;
|
||||
case BLOCK_SIMPLE_PACKET: {
|
||||
struct interface_description *interface_description;
|
||||
proto_item *ti;
|
||||
|
||||
interface_description = get_interface_description(info, 0,
|
||||
pinfo, block_tree);
|
||||
|
||||
proto_item_append_text(block_item, " %u", info->frame_number);
|
||||
|
||||
proto_tree_add_item_ret_uint(block_data_tree, hf_pcapng_packet_length, tvb, offset, 4, info->encoding, &reported_length);
|
||||
offset += 4;
|
||||
|
||||
captured_length = reported_length;
|
||||
if (interface_description && interface_description->snap_len != 0) {
|
||||
captured_length = MIN(reported_length, interface_description->snap_len);
|
||||
}
|
||||
ti = proto_tree_add_uint(block_data_tree, hf_pcapng_captured_length, tvb, 0, 0, captured_length);
|
||||
proto_item_set_generated(ti);
|
||||
|
||||
packet_data_item = proto_tree_add_item(block_data_tree, hf_pcapng_packet_data, tvb, offset, captured_length, info->encoding);
|
||||
|
||||
if (pref_dissect_next_layer && interface_description != NULL) {
|
||||
proto_tree *packet_data_tree = proto_item_add_subtree(packet_data_item, ett_pcapng_packet_data);
|
||||
|
||||
pinfo->num = info->frame_number;
|
||||
|
||||
TRY {
|
||||
call_dissector_with_data(pcap_pktdata_handle, tvb_new_subset_length(tvb, offset, captured_length),
|
||||
pinfo, packet_data_tree, &interface_description->link_type);
|
||||
}
|
||||
CATCH_BOUNDS_ERRORS {
|
||||
show_exception(tvb, pinfo, packet_data_tree, EXCEPT_CODE, GET_MESSAGE);
|
||||
}
|
||||
ENDTRY;
|
||||
}
|
||||
info->frame_number += 1;
|
||||
offset += captured_length;
|
||||
|
||||
if (captured_length % 4) {
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_packet_padding, tvb, offset, ((captured_length % 4)?(4 - (captured_length % 4)):0), ENC_NA);
|
||||
offset += ((captured_length % 4) ? (4 - (captured_length % 4)):0);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case BLOCK_NAME_RESOLUTION:
|
||||
{
|
||||
proto_tree *records_tree;
|
||||
proto_item *records_item;
|
||||
proto_tree *record_tree;
|
||||
proto_item *record_item;
|
||||
proto_item *record_length_item;
|
||||
gint offset_record_start;
|
||||
gint offset_string_start;
|
||||
guint32 record_code;
|
||||
guint32 record_length;
|
||||
gint string_length;
|
||||
gchar *str = NULL;
|
||||
address addr;
|
||||
|
||||
records_item = proto_tree_add_item(block_data_tree, hf_pcapng_records, tvb, offset, block_data_length, ENC_NA);
|
||||
records_tree = proto_item_add_subtree(records_item, ett_pcapng_records);
|
||||
|
||||
offset_record_start = offset;
|
||||
while (block_data_length - (offset_record_start - offset) > 0) {
|
||||
record_item = proto_tree_add_item(records_tree, hf_pcapng_record, tvb, offset, -1, ENC_NA);
|
||||
record_tree = proto_item_add_subtree(record_item, ett_pcapng_record);
|
||||
|
||||
proto_tree_add_item_ret_uint(record_tree, hf_pcapng_record_code, tvb, offset, 2, info->encoding, &record_code);
|
||||
proto_item_append_text(record_item, ": %s", val_to_str_const(record_code, record_code_vals, "Unknown"));
|
||||
offset += 2;
|
||||
|
||||
record_length_item = proto_tree_add_item_ret_uint(record_tree, hf_pcapng_record_length, tvb, offset, 2, info->encoding, &record_length);
|
||||
offset += 2;
|
||||
|
||||
if (record_code == 0) {
|
||||
if (record_length != 0)
|
||||
expert_add_info(pinfo, record_length_item, &ei_invalid_record_length);
|
||||
proto_item_set_len(record_item, record_length + 2 * 2);
|
||||
break;
|
||||
}
|
||||
|
||||
proto_tree_add_item(record_tree, hf_pcapng_record_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||
set_address_tvb(&addr, AT_IPv4, 4, tvb, offset);
|
||||
offset += 4;
|
||||
|
||||
offset_string_start = offset;
|
||||
while ((guint)(offset - offset_string_start) < record_length - 4) {
|
||||
string_length = tvb_strnlen(tvb, offset, (offset - offset_string_start) + record_length - 4);
|
||||
if (string_length >= 0) {
|
||||
proto_tree_add_item(record_tree, hf_pcapng_record_name, tvb, offset, string_length + 1, encoding);
|
||||
offset += string_length + 1;
|
||||
} else {
|
||||
/*
|
||||
* XXX - flag with an error, as this means we didn't
|
||||
* see a terminating NUL, but the spec says "zero
|
||||
* or more zero-terminated UTF-8 strings containing
|
||||
* the DNS entries for that address".
|
||||
*/
|
||||
proto_tree_add_item(record_tree, hf_pcapng_record_data, tvb, offset, (record_length - 4) - (offset - offset_string_start), encoding);
|
||||
offset += (record_length - 4) - (offset - offset_string_start);
|
||||
} else switch (record_code) {
|
||||
case 0x0001: /* IPv4 Record */
|
||||
if (record_length < 5) {
|
||||
expert_add_info(pinfo, record_length_item, &ei_invalid_record_length);
|
||||
offset += record_length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
str = address_to_display(wmem_packet_scope(), &addr);
|
||||
break;
|
||||
case 0x0002: /* IPv6 Record */
|
||||
if (record_length < 17) {
|
||||
expert_add_info(pinfo, record_length_item, &ei_invalid_record_length);
|
||||
offset += record_length;
|
||||
proto_tree_add_item(record_tree, hf_pcapng_record_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||
set_address_tvb(&addr, AT_IPv4, 4, tvb, offset);
|
||||
offset += 4;
|
||||
|
||||
offset_string_start = offset;
|
||||
while ((guint)(offset - offset_string_start) < record_length - 4) {
|
||||
string_length = tvb_strnlen(tvb, offset, (offset - offset_string_start) + record_length - 4);
|
||||
if (string_length >= 0) {
|
||||
proto_tree_add_item(record_tree, hf_pcapng_record_name, tvb, offset, string_length + 1, info->encoding);
|
||||
offset += string_length + 1;
|
||||
} else {
|
||||
/*
|
||||
* XXX - flag with an error, as this means we didn't
|
||||
* see a terminating NUL, but the spec says "zero
|
||||
* or more zero-terminated UTF-8 strings containing
|
||||
* the DNS entries for that address".
|
||||
*/
|
||||
proto_tree_add_item(record_tree, hf_pcapng_record_data, tvb, offset, (record_length - 4) - (offset - offset_string_start), info->encoding);
|
||||
offset += (record_length - 4) - (offset - offset_string_start);
|
||||
}
|
||||
}
|
||||
|
||||
str = address_to_display(wmem_packet_scope(), &addr);
|
||||
break;
|
||||
}
|
||||
|
||||
proto_tree_add_item(record_tree, hf_pcapng_record_ipv6, tvb, offset, 16, ENC_NA);
|
||||
set_address_tvb(&addr, AT_IPv6, 16, tvb, offset);
|
||||
offset += 16;
|
||||
|
||||
offset_string_start = offset;
|
||||
while ((guint)(offset - offset_string_start) < record_length - 16) {
|
||||
string_length = tvb_strnlen(tvb, offset, (offset - offset_string_start) + record_length - 16);
|
||||
if (string_length >= 0) {
|
||||
proto_tree_add_item(record_tree, hf_pcapng_record_name, tvb, offset, string_length + 1, encoding);
|
||||
offset += string_length + 1;
|
||||
} else {
|
||||
/*
|
||||
* XXX - flag with an error, as this means we didn't
|
||||
* see a terminating NUL, but the spec says "zero
|
||||
* or more zero-terminated UTF-8 strings containing
|
||||
* the DNS entries for that address".
|
||||
*/
|
||||
proto_tree_add_item(record_tree, hf_pcapng_record_data, tvb, offset, (record_length - 16) - (offset - offset_string_start), encoding);
|
||||
offset += (record_length - 16) - (offset - offset_string_start);
|
||||
case 0x0002: /* IPv6 Record */
|
||||
if (record_length < 17) {
|
||||
expert_add_info(pinfo, record_length_item, &ei_invalid_record_length);
|
||||
offset += record_length;
|
||||
break;
|
||||
}
|
||||
|
||||
proto_tree_add_item(record_tree, hf_pcapng_record_ipv6, tvb, offset, 16, ENC_NA);
|
||||
set_address_tvb(&addr, AT_IPv6, 16, tvb, offset);
|
||||
offset += 16;
|
||||
|
||||
offset_string_start = offset;
|
||||
while ((guint)(offset - offset_string_start) < record_length - 16) {
|
||||
string_length = tvb_strnlen(tvb, offset, (offset - offset_string_start) + record_length - 16);
|
||||
if (string_length >= 0) {
|
||||
proto_tree_add_item(record_tree, hf_pcapng_record_name, tvb, offset, string_length + 1, info->encoding);
|
||||
offset += string_length + 1;
|
||||
} else {
|
||||
/*
|
||||
* XXX - flag with an error, as this means we didn't
|
||||
* see a terminating NUL, but the spec says "zero
|
||||
* or more zero-terminated UTF-8 strings containing
|
||||
* the DNS entries for that address".
|
||||
*/
|
||||
proto_tree_add_item(record_tree, hf_pcapng_record_data, tvb, offset, (record_length - 16) - (offset - offset_string_start), info->encoding);
|
||||
offset += (record_length - 16) - (offset - offset_string_start);
|
||||
}
|
||||
}
|
||||
|
||||
str = address_to_display(wmem_packet_scope(), &addr);
|
||||
|
||||
break;
|
||||
default:
|
||||
proto_tree_add_item(record_tree, hf_pcapng_record_data, tvb, offset, record_length, ENC_NA);
|
||||
offset += record_length;
|
||||
}
|
||||
|
||||
str = address_to_display(wmem_packet_scope(), &addr);
|
||||
if (record_code != 0 && record_length % 4) {
|
||||
proto_item_set_len(record_item, record_length + 2 * 2 + (4 - record_length % 4));
|
||||
record_length = 4 - record_length % 4;
|
||||
proto_tree_add_item(record_tree, hf_pcapng_record_padding, tvb, offset, record_length, ENC_NA);
|
||||
offset += record_length;
|
||||
} else
|
||||
proto_item_set_len(record_item, record_length + 2 * 2);
|
||||
|
||||
break;
|
||||
default:
|
||||
proto_tree_add_item(record_tree, hf_pcapng_record_data, tvb, offset, record_length, ENC_NA);
|
||||
offset += record_length;
|
||||
if (str)
|
||||
proto_item_append_text(record_item, " = %s", str);
|
||||
}
|
||||
|
||||
if (record_code != 0 && record_length % 4) {
|
||||
proto_item_set_len(record_item, record_length + 2 * 2 + (4 - record_length % 4));
|
||||
record_length = 4 - record_length % 4;
|
||||
proto_tree_add_item(record_tree, hf_pcapng_record_padding, tvb, offset, record_length, ENC_NA);
|
||||
offset += record_length;
|
||||
} else
|
||||
proto_item_set_len(record_item, record_length + 2 * 2);
|
||||
|
||||
if (str)
|
||||
proto_item_append_text(record_item, " = %s", str);
|
||||
}
|
||||
|
||||
next_tvb = tvb_new_subset_length(tvb, offset, block_data_length - (offset - offset_record_start));
|
||||
offset += dissect_options(block_data_tree, pinfo, block_type, next_tvb, encoding, NULL);
|
||||
}
|
||||
|
||||
break;
|
||||
case BLOCK_INTERFACE_STATISTICS: {
|
||||
struct interface_description *interface_description;
|
||||
|
||||
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;
|
||||
interface_description = get_interface_description(info, interface_id,
|
||||
pinfo, block_tree);
|
||||
|
||||
pcapng_add_timestamp(block_data_tree, pinfo, tvb, offset, encoding, interface_description);
|
||||
offset += 8;
|
||||
|
||||
next_tvb = tvb_new_subset_length(tvb, offset, block_data_length - 4 - 8);
|
||||
offset += dissect_options(block_data_tree, pinfo, block_type, next_tvb, encoding, NULL);
|
||||
|
||||
}
|
||||
break;
|
||||
case BLOCK_ENHANCED_PACKET: {
|
||||
struct interface_description *interface_description;
|
||||
|
||||
proto_item_append_text(block_item, " %u", info->frame_number);
|
||||
|
||||
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;
|
||||
interface_description = get_interface_description(info, interface_id,
|
||||
pinfo, block_tree);
|
||||
|
||||
pcapng_add_timestamp(block_data_tree, pinfo, tvb, offset, encoding, interface_description);
|
||||
offset += 8;
|
||||
|
||||
proto_tree_add_item_ret_uint(block_data_tree, hf_pcapng_captured_length, tvb, offset, 4, encoding, &captured_length);
|
||||
offset += 4;
|
||||
|
||||
proto_tree_add_item_ret_uint(block_data_tree, hf_pcapng_packet_length, tvb, offset, 4, encoding, &reported_length);
|
||||
offset += 4;
|
||||
|
||||
packet_data_item = proto_tree_add_item(block_data_tree, hf_pcapng_packet_data, tvb, offset, captured_length, encoding);
|
||||
|
||||
if (pref_dissect_next_layer && interface_description != NULL) {
|
||||
proto_tree *packet_data_tree = proto_item_add_subtree(packet_data_item, ett_pcapng_packet_data);
|
||||
|
||||
pinfo->num = info->frame_number;
|
||||
|
||||
TRY {
|
||||
call_dissector_with_data(pcap_pktdata_handle, tvb_new_subset_length_caplen(tvb, offset, captured_length, reported_length),
|
||||
pinfo, packet_data_tree, &interface_description->link_type);
|
||||
next_tvb = tvb_new_subset_length(tvb, offset, block_data_length - (offset - offset_record_start));
|
||||
offset += dissect_options(block_data_tree, pinfo, block_type, next_tvb, info->encoding, NULL);
|
||||
}
|
||||
CATCH_BOUNDS_ERRORS {
|
||||
show_exception(tvb, pinfo, packet_data_tree, EXCEPT_CODE, GET_MESSAGE);
|
||||
|
||||
break;
|
||||
case BLOCK_INTERFACE_STATISTICS: {
|
||||
struct interface_description *interface_description;
|
||||
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_interface_id, tvb, offset, 4, info->encoding);
|
||||
interface_id = tvb_get_guint32(tvb, offset, info->encoding);
|
||||
offset += 4;
|
||||
interface_description = get_interface_description(info, interface_id,
|
||||
pinfo, block_tree);
|
||||
|
||||
pcapng_add_timestamp(block_data_tree, pinfo, tvb, offset, info->encoding, interface_description);
|
||||
offset += 8;
|
||||
|
||||
next_tvb = tvb_new_subset_length(tvb, offset, block_data_length - 4 - 8);
|
||||
offset += dissect_options(block_data_tree, pinfo, block_type, next_tvb, info->encoding, NULL);
|
||||
|
||||
}
|
||||
ENDTRY;
|
||||
break;
|
||||
case BLOCK_ENHANCED_PACKET: {
|
||||
struct interface_description *interface_description;
|
||||
|
||||
proto_item_append_text(block_item, " %u", info->frame_number);
|
||||
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_interface_id, tvb, offset, 4, info->encoding);
|
||||
interface_id = tvb_get_guint32(tvb, offset, info->encoding);
|
||||
offset += 4;
|
||||
interface_description = get_interface_description(info, interface_id,
|
||||
pinfo, block_tree);
|
||||
|
||||
pcapng_add_timestamp(block_data_tree, pinfo, tvb, offset, info->encoding, interface_description);
|
||||
offset += 8;
|
||||
|
||||
proto_tree_add_item_ret_uint(block_data_tree, hf_pcapng_captured_length, tvb, offset, 4, info->encoding, &captured_length);
|
||||
offset += 4;
|
||||
|
||||
proto_tree_add_item_ret_uint(block_data_tree, hf_pcapng_packet_length, tvb, offset, 4, info->encoding, &reported_length);
|
||||
offset += 4;
|
||||
|
||||
packet_data_item = proto_tree_add_item(block_data_tree, hf_pcapng_packet_data, tvb, offset, captured_length, info->encoding);
|
||||
|
||||
if (pref_dissect_next_layer && interface_description != NULL) {
|
||||
proto_tree *packet_data_tree = proto_item_add_subtree(packet_data_item, ett_pcapng_packet_data);
|
||||
|
||||
pinfo->num = info->frame_number;
|
||||
|
||||
TRY {
|
||||
call_dissector_with_data(pcap_pktdata_handle, tvb_new_subset_length_caplen(tvb, offset, captured_length, reported_length),
|
||||
pinfo, packet_data_tree, &interface_description->link_type);
|
||||
}
|
||||
CATCH_BOUNDS_ERRORS {
|
||||
show_exception(tvb, pinfo, packet_data_tree, EXCEPT_CODE, GET_MESSAGE);
|
||||
}
|
||||
ENDTRY;
|
||||
}
|
||||
info->frame_number += 1;
|
||||
offset += captured_length;
|
||||
|
||||
if (captured_length % 4) {
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_packet_padding, tvb, offset, ((captured_length % 4)? (4 - (captured_length % 4)):0), ENC_NA);
|
||||
offset += ((captured_length % 4) ?(4 - (captured_length % 4)):0);
|
||||
}
|
||||
|
||||
next_tvb = tvb_new_subset_length(tvb, offset, block_data_length - 4 - 8 - 4 - 4 - captured_length - ((captured_length % 4)?(4 - (captured_length % 4)):0));
|
||||
offset += dissect_options(block_data_tree, pinfo, block_type, next_tvb, info->encoding, NULL);
|
||||
|
||||
}
|
||||
break;
|
||||
case BLOCK_DSB:
|
||||
{
|
||||
guint32 secrets_length;
|
||||
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_dsb_secrets_type, tvb, offset, 4, info->encoding);
|
||||
offset += 4;
|
||||
proto_tree_add_item_ret_uint(block_data_tree, hf_pcapng_dsb_secrets_length, tvb, offset, 4, info->encoding, &secrets_length);
|
||||
offset += 4;
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_dsb_secrets_data, tvb, offset, secrets_length, info->encoding);
|
||||
offset += secrets_length;
|
||||
|
||||
guint32 padlen = (4 - (secrets_length & 3)) & 3;
|
||||
if (padlen) {
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_record_padding, tvb, offset, padlen, ENC_NA);
|
||||
offset += padlen;
|
||||
}
|
||||
|
||||
if (block_data_length > 4 + 4 + secrets_length + padlen) {
|
||||
next_tvb = tvb_new_subset_length(tvb, offset, block_data_length - 4 - 4 - secrets_length - padlen);
|
||||
offset += dissect_options(block_data_tree, pinfo, block_type, next_tvb, info->encoding, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case BLOCK_DARWIN_PROCESS:
|
||||
proto_item_append_text(block_item, " %u", info->darwin_process_event_number);
|
||||
info->darwin_process_event_number += 1;
|
||||
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_darwin_process_id, tvb, offset, 4, info->encoding);
|
||||
offset += 4;
|
||||
|
||||
next_tvb = tvb_new_subset_length(tvb, offset, block_data_length - 4);
|
||||
offset += dissect_options(block_data_tree, pinfo, block_type, next_tvb, info->encoding, NULL);
|
||||
|
||||
break;
|
||||
case BLOCK_IRIG_TIMESTAMP:
|
||||
case BLOCK_ARINC_429:
|
||||
default:
|
||||
offset += block_data_length;
|
||||
}
|
||||
info->frame_number += 1;
|
||||
offset += captured_length;
|
||||
|
||||
if (captured_length % 4) {
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_packet_padding, tvb, offset, ((captured_length % 4)? (4 - (captured_length % 4)):0), ENC_NA);
|
||||
offset += ((captured_length % 4) ?(4 - (captured_length % 4)):0);
|
||||
}
|
||||
|
||||
next_tvb = tvb_new_subset_length(tvb, offset, block_data_length - 4 - 8 - 4 - 4 - captured_length - ((captured_length % 4)?(4 - (captured_length % 4)):0));
|
||||
offset += dissect_options(block_data_tree, pinfo, block_type, next_tvb, encoding, NULL);
|
||||
|
||||
}
|
||||
break;
|
||||
case BLOCK_DSB:
|
||||
{
|
||||
guint32 secrets_length;
|
||||
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_dsb_secrets_type, tvb, offset, 4, encoding);
|
||||
offset += 4;
|
||||
proto_tree_add_item_ret_uint(block_data_tree, hf_pcapng_dsb_secrets_length, tvb, offset, 4, encoding, &secrets_length);
|
||||
offset += 4;
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_dsb_secrets_data, tvb, offset, secrets_length, encoding);
|
||||
offset += secrets_length;
|
||||
|
||||
guint32 padlen = (4 - (secrets_length & 3)) & 3;
|
||||
if (padlen) {
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_record_padding, tvb, offset, padlen, ENC_NA);
|
||||
offset += padlen;
|
||||
}
|
||||
|
||||
if (block_data_length > 4 + 4 + secrets_length + padlen) {
|
||||
next_tvb = tvb_new_subset_length(tvb, offset, block_data_length - 4 - 4 - secrets_length - padlen);
|
||||
offset += dissect_options(block_data_tree, pinfo, block_type, next_tvb, encoding, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case BLOCK_DARWIN_PROCESS:
|
||||
proto_item_append_text(block_item, " %u", info->darwin_process_event_number);
|
||||
info->darwin_process_event_number += 1;
|
||||
|
||||
proto_tree_add_item(block_data_tree, hf_pcapng_darwin_process_id, tvb, offset, 4, encoding);
|
||||
offset += 4;
|
||||
|
||||
next_tvb = tvb_new_subset_length(tvb, offset, block_data_length - 4);
|
||||
offset += dissect_options(block_data_tree, pinfo, block_type, next_tvb, encoding, NULL);
|
||||
|
||||
break;
|
||||
case BLOCK_IRIG_TIMESTAMP:
|
||||
case BLOCK_ARINC_429:
|
||||
default:
|
||||
offset += block_data_length;
|
||||
}
|
||||
|
||||
proto_tree_add_item(block_tree, hf_pcapng_block_length, tvb, offset, 4, encoding);
|
||||
proto_tree_add_item(block_tree, hf_pcapng_block_length, tvb, offset, 4, info->encoding);
|
||||
offset += 4;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
#define BLOCK_TYPE_SIZE 4
|
||||
#define BYTE_ORDER_MAGIC_SIZE 4
|
||||
|
||||
static int
|
||||
dissect_pcapng(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
|
||||
|
@ -1713,12 +1765,6 @@ dissect_pcapng(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _
|
|||
static const guint8 pcapng_premagic[BLOCK_TYPE_SIZE] = {
|
||||
0x0A, 0x0D, 0x0D, 0x0A
|
||||
};
|
||||
static const guint8 pcapng_big_endian_magic[BYTE_ORDER_MAGIC_SIZE] = {
|
||||
0x1A, 0x2B, 0x3C, 0x4D
|
||||
};
|
||||
static const guint8 pcapng_little_endian_magic[BYTE_ORDER_MAGIC_SIZE] = {
|
||||
0x4D, 0x3C, 0x2B, 0x1A
|
||||
};
|
||||
gint offset = 0;
|
||||
guint32 length;
|
||||
guint32 encoding;
|
||||
|
@ -1741,6 +1787,7 @@ dissect_pcapng(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _
|
|||
info.interface_number = 0;
|
||||
info.darwin_process_event_number = 0;
|
||||
info.frame_number = 1;
|
||||
info.encoding = encoding;
|
||||
info.interfaces = wmem_array_new(wmem_packet_scope(), sizeof(struct interface_description));
|
||||
info.darwin_process_events = wmem_array_new(wmem_packet_scope(), sizeof(struct darwin_process_event_description));
|
||||
|
||||
|
@ -1749,11 +1796,17 @@ dissect_pcapng(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _
|
|||
|
||||
while (tvb_captured_length_remaining(tvb, offset)) {
|
||||
tvbuff_t *next_tvb;
|
||||
int block_length;
|
||||
|
||||
length = tvb_get_guint32(tvb, offset + 4, encoding);
|
||||
next_tvb = tvb_new_subset_length(tvb, offset, length);
|
||||
|
||||
offset += dissect_block(main_tree, pinfo, next_tvb, encoding, &info);
|
||||
block_length = dissect_block(main_tree, pinfo, next_tvb, &info);
|
||||
if (block_length == -1) {
|
||||
/* Fatal error. */
|
||||
break;
|
||||
}
|
||||
offset += block_length;
|
||||
}
|
||||
|
||||
return offset;
|
||||
|
@ -2285,6 +2338,7 @@ proto_register_pcapng(void)
|
|||
};
|
||||
|
||||
static ei_register_info ei[] = {
|
||||
{ &ei_invalid_byte_order_magic, { "pcapng.invalid_byte_order_magic", PI_PROTOCOL, PI_ERROR, "The byte-order magic number is not valid", EXPFILL }},
|
||||
{ &ei_block_length_too_short, { "pcapng.block_length_too_short", PI_PROTOCOL, PI_ERROR, "Block length is < 12 bytes", EXPFILL }},
|
||||
{ &ei_block_length_not_multiple_of_4, { "pcapng.block_length_too_short", PI_PROTOCOL, PI_ERROR, "Block length is not a multiple of 4", EXPFILL }},
|
||||
{ &ei_invalid_option_length, { "pcapng.invalid_option_length", PI_PROTOCOL, PI_ERROR, "Invalid Option Length", EXPFILL }},
|
||||
|
|
Loading…
Reference in New Issue