diff --git a/epan/dissectors/packet-someip.c b/epan/dissectors/packet-someip.c index a72a4fc3ab..7e56fe7497 100644 --- a/epan/dissectors/packet-someip.c +++ b/epan/dissectors/packet-someip.c @@ -1947,6 +1947,18 @@ update_someip_parameter_base_type_list(void *r, char **err) { return FALSE; } + if (rec->bitlength_base_type != 8 && rec->bitlength_base_type != 16 && rec->bitlength_base_type != 32 && rec->bitlength_base_type != 64) { + *err = ws_strdup_printf("Bit length of base type may only be 8, 16, 32, or 64. Affected item: ID (%i) Name (%s).", rec->id, rec->name); + return FALSE; + } + + /* As long as we check that rec->bitlength_base_type equals rec->bitlength_encoded_type, we do not have to check that bitlength_encoded_type is 8, 16, 32, or 64. */ + + if (rec->bitlength_base_type != rec->bitlength_encoded_type) { + *err = ws_strdup_printf("Bit length of encoded type must be equal to bit length of base type. Affected item: ID (%i) Name (%s). Shortened types supported by Signal-PDU dissector.", rec->id, rec->name); + return FALSE; + } + return TRUE; } @@ -2496,12 +2508,6 @@ expert_someip_payload_config_error(proto_tree *tree, packet_info *pinfo, tvbuff_ col_append_str(pinfo->cinfo, COL_INFO, " [SOME/IP Payload: Config Error]"); } -static void -expert_someip_payload_alignment_error(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, gint offset, gint length) { - proto_tree_add_expert(tree, pinfo, &ef_someip_payload_alignment_error, tvb, offset, length); - col_append_str(pinfo->cinfo, COL_INFO, " [SOME/IP Payload: Alignment problem]"); -} - /******************************************* **************** Statistics *************** *******************************************/ @@ -2560,10 +2566,10 @@ someip_messages_stats_tree_packet(stats_tree *st, packet_info *pinfo, epan_disse *******************************************/ static int -dissect_someip_payload_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, gint offset_bits, guint8 data_type, guint32 idref, gchar *name, int *hf_id_ptr, gint wtlv_offset); +dissect_someip_payload_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, guint8 data_type, guint32 idref, gchar *name, int *hf_id_ptr, gint wtlv_offset); static int -dissect_someip_payload_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, gint offset_bits, someip_payload_parameter_item_t *items, guint32 num_of_items, gboolean wtlv); +dissect_someip_payload_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, someip_payload_parameter_item_t *items, guint32 num_of_items, gboolean wtlv); /* add a flexible size length field, -1 for error*/ static gint64 @@ -2659,75 +2665,15 @@ dissect_someip_payload_add_wtlv_if_needed(tvbuff_t *tvb, packet_info *pinfo _U_, } } -static guint64 -dissect_shifted_and_shortened_uint(tvbuff_t *tvb, gint offset, gint offset_bits, gint offset_end, gint offset_end_bits, gboolean big_endian) { - gint32 i = 0; - guint8 tmp = 0; - gint tmp_bit_count = 8; - guint64 value_guint64 = 0; - - if (!big_endian) { - /* offset and offset_end need to be included */ - for (i = offset_end; i >= offset; i--) { - - if (i != offset_end || offset_end_bits != 0) { - tmp = tvb_get_guint8(tvb, i); - tmp_bit_count = 8; - - if (i == offset_end) { - tmp = tmp & (0xff >> (8 - offset_end_bits)); - /* don't need to shift value, in the first round */ - tmp_bit_count = 0; - } - - if (i == offset) { - tmp >>= offset_bits; - tmp_bit_count = 8 - offset_bits; - } - - value_guint64 <<= (guint)tmp_bit_count; - value_guint64 |= tmp; - } - } - } else { - /* offset_end needs to be included. */ - for (i = offset; i <= offset_end; i++) { - - /* Do not read the last byte, if you do not need any bit of it. Else we read behind buffer! */ - if (i != offset_end || offset_end_bits != 0) { - tmp = tvb_get_guint8(tvb, i); - tmp_bit_count = 8; - - if (i == offset) { - tmp = tmp & (0xff >> offset_bits); - /* don't need to shift value, in the first round */ - tmp_bit_count = 0; - } - - if (i == offset_end) { - tmp >>= 8 - offset_end_bits; - tmp_bit_count = offset_end_bits; - } - - value_guint64 <<= (guint)tmp_bit_count; - value_guint64 |= tmp; - } - } - } - return value_guint64; -} - static gint -dissect_someip_payload_base_type(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset, gint offset_bits, guint8 data_type, guint32 id, gchar *name, int *hf_id_ptr, gint wtlv_offset) { +dissect_someip_payload_base_type(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset, guint8 data_type, guint32 id, gchar *name, int *hf_id_ptr, gint wtlv_offset) { someip_payload_parameter_base_type_list_t *base_type = NULL; someip_payload_parameter_enum_t *enum_config = NULL; guint32 basetype_id = 0; guint32 enum_id = 0; - gint buf_length = -1; gint param_length = -1; - guint32 bit_length = 0; proto_item *ti = NULL; @@ -2738,9 +2684,6 @@ dissect_someip_payload_base_type(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr guint32 i = 0; gchar *value_name = NULL; - gint offset_end = 0; - gint offset_end_bits = 0; - gboolean big_endian = TRUE; int hf_id = -1; @@ -2749,10 +2692,6 @@ dissect_someip_payload_base_type(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr hf_id = *hf_id_ptr; } - if (offset_bits < 0) { - return 0; - } - switch (data_type) { case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_BASE_TYPE: basetype_id = id; @@ -2775,59 +2714,30 @@ dissect_someip_payload_base_type(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr } big_endian = base_type->big_endian; - buf_length = tvb_captured_length_remaining(tvb, 0); - bit_length = base_type->bitlength_encoded_type; + param_length = (gint)((base_type->bitlength_base_type) / 8); - /* +7 to round up, if more than 0 bits */ - param_length = (gint)((offset_bits + bit_length + 7) / 8); + if (param_length > tvb_captured_length_remaining(tvb, 0) - offset) { + return 0; + } - if (param_length <= buf_length - offset) { - if (offset_bits == 0 && base_type->bitlength_base_type == bit_length && bit_length % 8 == 0) { - /* Regular (non-shortened!) SOME/IP types! */ - if (hf_id != -1) { - if (strncmp(base_type->data_type, "uint", 4) == 0) { - if (base_type->bitlength_base_type > 32) { - ti = proto_tree_add_item_ret_uint64(tree, hf_id, tvb, offset, param_length, big_endian ? ENC_BIG_ENDIAN : ENC_LITTLE_ENDIAN, &value); - } else { - ti = proto_tree_add_item_ret_uint(tree, hf_id, tvb, offset, param_length, big_endian ? ENC_BIG_ENDIAN : ENC_LITTLE_ENDIAN, &value32); - value = (guint64)value32; - } - value_set = TRUE; - } else { - ti = proto_tree_add_item(tree, hf_id, tvb, offset, param_length, big_endian ? ENC_BIG_ENDIAN : ENC_LITTLE_ENDIAN); - } + if (hf_id != -1) { + if (strncmp(base_type->data_type, "uint", 4) == 0) { + if (base_type->bitlength_base_type > 32) { + ti = proto_tree_add_item_ret_uint64(tree, hf_id, tvb, offset, param_length, big_endian ? ENC_BIG_ENDIAN : ENC_LITTLE_ENDIAN, &value); } else { - if (name == NULL) { - ti = proto_tree_add_string_format(tree, hf_payload_str_base, tvb, offset, param_length, base_type->name, "[%s]", base_type->name); - } else { - ti = proto_tree_add_string_format(tree, hf_payload_str_base, tvb, offset, param_length, base_type->name, "%s [%s]", name, base_type->name); - } - } - } else { - /* Shortened datatypes (e.g. CAN over SOME/IP) */ - offset_end = (gint)((8 * offset + offset_bits + bit_length) / 8); - offset_end_bits = (gint)((8 * offset + offset_bits + bit_length) % 8); - value = dissect_shifted_and_shortened_uint(tvb, offset, offset_bits, offset_end, offset_end_bits, big_endian); - - if (hf_id != -1) { - if (base_type->bitlength_base_type > 32) { - ti = proto_tree_add_uint64(tree, hf_id, tvb, offset, param_length, value); - } else { - ti = proto_tree_add_uint(tree, hf_id, tvb, offset, param_length, (guint32)value); - } - } else { - if (name == NULL) { - ti = proto_tree_add_string_format(tree, hf_payload_str_base, tvb, offset, param_length, base_type->name, "[%s]: %" PRIu64 " (0x%" PRIx64 ")", - base_type->name, value, value); - } else { - ti = proto_tree_add_string_format(tree, hf_payload_str_base, tvb, offset, param_length, base_type->name, "%s [%s]: %" PRIu64 " (0x%" PRIx64 ")", - name, base_type->name, value, value); - } + ti = proto_tree_add_item_ret_uint(tree, hf_id, tvb, offset, param_length, big_endian ? ENC_BIG_ENDIAN : ENC_LITTLE_ENDIAN, &value32); + value = (guint64)value32; } value_set = TRUE; + } else { + ti = proto_tree_add_item(tree, hf_id, tvb, offset, param_length, big_endian ? ENC_BIG_ENDIAN : ENC_LITTLE_ENDIAN); } } else { - return 0; + if (name == NULL) { + ti = proto_tree_add_string_format(tree, hf_payload_str_base, tvb, offset, param_length, base_type->name, "[%s]", base_type->name); + } else { + ti = proto_tree_add_string_format(tree, hf_payload_str_base, tvb, offset, param_length, base_type->name, "%s [%s]", name, base_type->name); + } } dissect_someip_payload_add_wtlv_if_needed(tvb, pinfo, wtlv_offset, ti, NULL); @@ -2844,11 +2754,11 @@ dissect_someip_payload_base_type(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr } } - return (gint)bit_length; + return param_length; } static int -dissect_someip_payload_string(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, gint offset_bits, guint32 id, gchar *name, int *hf_id_ptr, gint wtlv_offset) { +dissect_someip_payload_string(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, guint32 id, gchar *name, int *hf_id_ptr, gint wtlv_offset) { someip_payload_parameter_string_t *config = NULL; guint8 *buf = NULL; @@ -2859,7 +2769,6 @@ dissect_someip_payload_string(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre gint64 tmp = 0; guint32 length = 0; gint offset_orig = offset; - gint offset_bits_orig = offset_bits; guint str_encoding = 0; int hf_id = hf_payload_str_string; @@ -2870,7 +2779,7 @@ dissect_someip_payload_string(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre config = get_string_config(id); - if (config == NULL || offset_bits != 0) { + if (config == NULL) { return 0; } @@ -2934,11 +2843,11 @@ dissect_someip_payload_string(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre proto_item_set_end(ti, tvb, offset); - return 8 * (offset - offset_orig) + (offset_bits - offset_bits_orig); + return offset - offset_orig; } static int -dissect_someip_payload_struct(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset_orig, gint offset_bits_orig, guint32 id, gchar *name, gint wtlv_offset) { +dissect_someip_payload_struct(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset_orig, guint32 id, gchar *name, gint wtlv_offset) { someip_payload_parameter_struct_t *config = NULL; proto_tree *subtree = NULL; @@ -2947,8 +2856,6 @@ dissect_someip_payload_struct(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre gint64 length = 0; gint offset = offset_orig; - gint offset_bits = offset_bits_orig; - gint bits_parsed = 0; config = get_struct_config(id); @@ -2987,27 +2894,20 @@ dissect_someip_payload_struct(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre subtvb = tvb_new_subset_length_caplen(tvb, 0, endpos, endpos); } - bits_parsed = dissect_someip_payload_parameters(subtvb, pinfo, subtree, offset, offset_bits, config->items, config->num_of_items, config->wtlv_encoding); - offset = (8 * offset + offset_bits + bits_parsed) / 8; - offset_bits = (8 * offset + offset_bits + bits_parsed) % 8; + offset += dissect_someip_payload_parameters(subtvb, pinfo, subtree, offset, config->items, config->num_of_items, config->wtlv_encoding); if (length_of_length == 0) { - if (offset_bits == 0) { - proto_item_set_end(ti, tvb, offset); - } else { - proto_item_set_end(ti, tvb, offset + 1); - } + proto_item_set_end(ti, tvb, offset); - return 8 * (offset - offset_orig) + (offset_bits - offset_bits_orig); + return offset - offset_orig; } else { - return 8 * ((length_of_length / 8) + (guint32)length); + return (length_of_length / 8) + (guint32)length; } } static int -dissect_someip_payload_typedef(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, gint offset_bits, guint32 id, gchar *name _U_, int *hf_id, gint wtlv_offset) { +dissect_someip_payload_typedef(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, guint32 id, gchar *name _U_, int *hf_id, gint wtlv_offset) { someip_payload_parameter_typedef_t *config = NULL; - gint bits_parsed = 0; config = get_typedef_config(id); @@ -3016,9 +2916,7 @@ dissect_someip_payload_typedef(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr } /* we basically skip over the typedef for now */ - bits_parsed = dissect_someip_payload_parameter(tvb, pinfo, tree, offset, offset_bits, (guint8)config->data_type, config->id_ref, config->name, hf_id, wtlv_offset); - - return bits_parsed; + return dissect_someip_payload_parameter(tvb, pinfo, tree, offset, (guint8)config->data_type, config->id_ref, config->name, hf_id, wtlv_offset); } /* returns bytes parsed, length needs to be gint to encode "non-existing" as -1 */ @@ -3060,14 +2958,13 @@ dissect_someip_payload_array_dim_length(tvbuff_t *tvb, packet_info *pinfo, proto return offset - offset_orig; } -/* returns bits parsed, length needs to be gint to encode "non-existing" as -1 */ +/* returns bytes parsed, length needs to be gint to encode "non-existing" as -1 */ static gint dissect_someip_payload_array_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset_orig, gint length, gint lower_limit, gint upper_limit, someip_parameter_array_t *config) { tvbuff_t *subtvb = NULL; guint32 offset = offset_orig; - guint32 offset_bits = 0; - guint32 bits_parsed = 0; + guint32 bytes_parsed = 0; guint32 ret = 0; gint count = 0; @@ -3084,13 +2981,13 @@ dissect_someip_payload_array_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tr subtvb = tvb; } - while ((length == -1 && count < upper_limit) || ((gint)(8 * offset + offset_bits) < 8 * length)) { - bits_parsed = dissect_someip_payload_parameter(subtvb, pinfo, tree, offset, offset_bits, (guint8)config->data_type, config->id_ref, config->name, config->hf_id, -1); - if (bits_parsed == 0) { + while ((length == -1 && count < upper_limit) || ((gint)offset < length)) { + bytes_parsed = dissect_someip_payload_parameter(subtvb, pinfo, tree, offset, (guint8)config->data_type, config->id_ref, config->name, config->hf_id, -1); + if (bytes_parsed == 0) { + /* does this make sense? */ return 1; } - offset = (8 * offset + bits_parsed) / 8; - offset_bits = (8 * offset + bits_parsed) % 8; + offset += bytes_parsed; count++; } @@ -3101,15 +2998,15 @@ dissect_someip_payload_array_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tr } if (length != -1) { - ret = 8 * offset + offset_bits; + /* we created subtvb first and set offset to 0 */ + ret = offset; } else { - ret = 8 * (offset - offset_orig) + offset_bits; + ret = offset - offset_orig; } return ret; } -/* returns bits parsed */ static gint dissect_someip_payload_array_dim(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset_orig, gint length, gint lower_limit, gint upper_limit, someip_parameter_array_t *config, guint current_dim, gchar *name, guint32 length_of_length) { proto_item *ti = NULL; @@ -3121,12 +3018,10 @@ dissect_someip_payload_array_dim(tvbuff_t *tvb, packet_info *pinfo, proto_tree * gint sub_offset = 0; gint offset = offset_orig; - gint offset_bits = 0; - gint ret = 0; if (config->num_of_dims == current_dim + 1) { /* only payload left. :) */ - offset_bits += dissect_someip_payload_array_payload(tvb, pinfo, tree, offset, length, lower_limit, upper_limit, config); + offset += dissect_someip_payload_array_payload(tvb, pinfo, tree, offset, length, lower_limit, upper_limit, config); } else { if (length != -1) { while (offset < offset_orig + (gint)length) { @@ -3142,15 +3037,9 @@ dissect_someip_payload_array_dim(tvbuff_t *tvb, packet_info *pinfo, proto_tree * return 0; } - offset_bits += dissect_someip_payload_array_dim(tvb, pinfo, subtree, offset, sub_length, sub_lower_limit, sub_upper_limit, config, current_dim + 1, name, length_of_length); - offset = (8 * offset + offset_bits) / 8; - offset_bits = (8 * offset + offset_bits) % 8; - if (offset_bits == 0) { - proto_item_set_end(ti, tvb, offset); - } else { - proto_item_set_end(ti, tvb, offset + 1); - } + offset += dissect_someip_payload_array_dim(tvb, pinfo, subtree, offset, sub_length, sub_lower_limit, sub_upper_limit, config, current_dim + 1, name, length_of_length); + proto_item_set_end(ti, tvb, offset); } } else { /* Multi-dim static array */ @@ -3163,19 +3052,17 @@ dissect_someip_payload_array_dim(tvbuff_t *tvb, packet_info *pinfo, proto_tree * } } - ret = 8 * (offset - offset_orig) + (offset_bits - 0); - return ret; + return offset - offset_orig; } static int -dissect_someip_payload_array(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset_orig, gint offset_bits_orig, guint32 id, gchar *name, gint wtlv_offset) { +dissect_someip_payload_array(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset_orig, guint32 id, gchar *name, gint wtlv_offset) { someip_parameter_array_t *config = NULL; proto_tree *subtree; proto_item *ti = NULL; gint offset = offset_orig; - gint offset_bits = offset_bits_orig; gint length = 0; gint size_of_length = 0; @@ -3193,11 +3080,6 @@ dissect_someip_payload_array(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree return 0; } - if (offset_bits_orig != 0) { - expert_someip_payload_alignment_error(tree, pinfo, tvb, offset, 0); - return 0; - } - ti = proto_tree_add_string_format(tree, hf_payload_str_array, tvb, offset, 0, config->name, "array %s", name); subtree = proto_item_add_subtree(ti, ett_someip_array); guint32 length_of_length = dissect_someip_payload_add_wtlv_if_needed(tvb, pinfo, wtlv_offset, ti, subtree); @@ -3211,28 +3093,21 @@ dissect_someip_payload_array(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree proto_item_append_text(ti, " (elements limit: %d)", upper_limit); } - offset_bits += dissect_someip_payload_array_dim(tvb, pinfo, subtree, offset, length, lower_limit, upper_limit, config, 0, name, length_of_length); + offset += dissect_someip_payload_array_dim(tvb, pinfo, subtree, offset, length, lower_limit, upper_limit, config, 0, name, length_of_length); - offset = (8 * offset + offset_bits) / 8; - offset_bits = (8 * offset + offset_bits) % 8; - - if (offset_bits == 0) { - proto_item_set_end(ti, tvb, offset); - } else { - proto_item_set_end(ti, tvb, offset + 1); - } + proto_item_set_end(ti, tvb, offset); if (length >= 0) { /* length field present */ - return 8 * (size_of_length + length); + return size_of_length + length; } else { /* We have no length field, so we return what has been parsed! */ - return 8 * (offset - offset_orig) + (offset_bits - offset_bits_orig); + return offset - offset_orig; } } static int -dissect_someip_payload_union(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset_orig, gint offset_bits_orig, guint32 id, gchar *name, gint wtlv_offset) { +dissect_someip_payload_union(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset_orig, guint32 id, gchar *name, gint wtlv_offset) { someip_parameter_union_t *config = NULL; someip_parameter_union_item_t *item = NULL; @@ -3249,7 +3124,6 @@ dissect_someip_payload_union(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree guint32 i = 0; gint offset = offset_orig; - gint offset_bits = offset_bits_orig; config = get_union_config(id); buf_length = tvb_captured_length_remaining(tvb, 0); @@ -3259,11 +3133,6 @@ dissect_someip_payload_union(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree return 0; } - if (offset_bits_orig != 0) { - expert_someip_payload_alignment_error(tree, pinfo, tvb, offset_orig, 0); - return 0; - } - if (wtlv_offset >= 0) { ti = proto_tree_add_string_format(tree, hf_payload_str_union, tvb, wtlv_offset, 0, name, "union %s [%s]", name, config->name); } else { @@ -3284,14 +3153,14 @@ dissect_someip_payload_union(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree tmp = dissect_someip_payload_length_field(tvb, pinfo, subtree, offset_orig, length_of_length); if (tmp == -1) { - return 8 * (offset - offset_orig) + (offset_bits - 0); + return offset - offset_orig; } else { length = (guint32)tmp; } tmp = dissect_someip_payload_type_field(tvb, pinfo, subtree, offset_orig + length_of_length / 8, config->length_of_type); if (tmp == -1) { - return 8 * (offset - offset_orig) + (offset_bits - 0); + return offset - offset_orig; } else { type = (guint32)tmp; } @@ -3308,38 +3177,37 @@ dissect_someip_payload_union(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree if (item != NULL) { subtvb = tvb_new_subset_length_caplen(tvb, offset, length, length); - dissect_someip_payload_parameter(subtvb, pinfo, subtree, 0, 0, (guint8)item->data_type, item->id_ref, item->name, item->hf_id, -1); + dissect_someip_payload_parameter(subtvb, pinfo, subtree, 0, (guint8)item->data_type, item->id_ref, item->name, item->hf_id, -1); } else { expert_someip_payload_config_error(tree, pinfo, tvb, offset, 0, "Union type not configured"); } - /* there might be some padding present, if 8*length != bits_parsed */ - return 8 * length + config->length_of_type + length_of_length; + return length + (config->length_of_type + length_of_length) / 8; } static int -dissect_someip_payload_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, gint offset_bits, guint8 data_type, guint32 idref, gchar *name, int *hf_id_ptr, gint wtlv_offset) { - gint bits_parsed = 0; +dissect_someip_payload_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, guint8 data_type, guint32 idref, gchar *name, int *hf_id_ptr, gint wtlv_offset) { + gint bytes_parsed = 0; switch (data_type) { case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_TYPEDEF: - bits_parsed = dissect_someip_payload_typedef(tvb, pinfo, tree, offset, offset_bits, idref, name, hf_id_ptr, wtlv_offset); + bytes_parsed = dissect_someip_payload_typedef(tvb, pinfo, tree, offset, idref, name, hf_id_ptr, wtlv_offset); break; case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_BASE_TYPE: case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_ENUM: - bits_parsed = dissect_someip_payload_base_type(tvb, pinfo, tree, offset, offset_bits, data_type, idref, name, hf_id_ptr, wtlv_offset); + bytes_parsed = dissect_someip_payload_base_type(tvb, pinfo, tree, offset, data_type, idref, name, hf_id_ptr, wtlv_offset); break; case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_STRING: - bits_parsed = dissect_someip_payload_string(tvb, pinfo, tree, offset, offset_bits, idref, name, hf_id_ptr, wtlv_offset); + bytes_parsed = dissect_someip_payload_string(tvb, pinfo, tree, offset, idref, name, hf_id_ptr, wtlv_offset); break; case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_ARRAY: - bits_parsed = dissect_someip_payload_array(tvb, pinfo, tree, offset, offset_bits, idref, name, wtlv_offset); + bytes_parsed = dissect_someip_payload_array(tvb, pinfo, tree, offset, idref, name, wtlv_offset); break; case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_STRUCT: - bits_parsed = dissect_someip_payload_struct(tvb, pinfo, tree, offset, offset_bits, idref, name, wtlv_offset); + bytes_parsed = dissect_someip_payload_struct(tvb, pinfo, tree, offset, idref, name, wtlv_offset); break; case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_UNION: - bits_parsed = dissect_someip_payload_union(tvb, pinfo, tree, offset, offset_bits, idref, name, wtlv_offset); + bytes_parsed = dissect_someip_payload_union(tvb, pinfo, tree, offset, idref, name, wtlv_offset); break; default: proto_tree_add_expert_format(tree, pinfo, &ef_someip_payload_config_error, tvb, offset, 0, @@ -3349,7 +3217,7 @@ dissect_someip_payload_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree * break; } - return bits_parsed; + return bytes_parsed; } /* @@ -3429,12 +3297,10 @@ static int dissect_someip_payload_peek_length_of_length(proto_tree *tree, packet } static int -dissect_someip_payload_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, gint offset_bits, someip_payload_parameter_item_t *items, guint32 num_of_items, gboolean wtlv) { +dissect_someip_payload_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, someip_payload_parameter_item_t *items, guint32 num_of_items, gboolean wtlv) { someip_payload_parameter_item_t *item; gint offset_orig = offset; - gint offset_orig_bits = offset_bits; - gint bits_parsed = 0; if (items == NULL && !someip_deserializer_wtlv_default) { return 0; @@ -3442,12 +3308,6 @@ dissect_someip_payload_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree if (wtlv) { while (tvb_captured_length_remaining(tvb, offset) >= 2) { - /* WTLV only works if payload is aligned to bytes */ - if (offset_bits != 0) { - expert_someip_payload_malformed(tree, pinfo, tvb, offset, 0); - return offset - offset_orig; - } - guint64 tagdata = tvb_get_guint16(tvb, offset, ENC_BIG_ENDIAN); guint wiretype = (tagdata & SOMEIP_WTLV_MASK_WIRE_TYPE) >> 12; guint param_id = tagdata & SOMEIP_WTLV_MASK_DATA_ID; @@ -3508,14 +3368,13 @@ dissect_someip_payload_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree tvbuff_t *subtvb = tvb_new_subset_length_caplen(tvb, offset - 2, param_length + 2, param_length + 2); if (item != NULL) { - dissect_someip_payload_parameter(subtvb, pinfo, tree, 2, 0, (guint8)item->data_type, item->id_ref, item->name, item->hf_id, 0); + dissect_someip_payload_parameter(subtvb, pinfo, tree, 2, (guint8)item->data_type, item->id_ref, item->name, item->hf_id, 0); } else { proto_item *ti = proto_tree_add_item(tree, hf_payload_unparsed, subtvb, 2, param_length, ENC_NA); dissect_someip_payload_add_wtlv_if_needed(tvb, pinfo, offset - 2, ti, NULL); } offset += param_length; } - bits_parsed = 8 * (offset - offset_orig); } else { if (items == NULL) { return 0; @@ -3523,14 +3382,11 @@ dissect_someip_payload_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree guint32 i; for (i = 0; i < num_of_items; i++) { item = &(items[i]); - bits_parsed = dissect_someip_payload_parameter(tvb, pinfo, tree, offset, offset_bits, (guint8)item->data_type, item->id_ref, item->name, item->hf_id, -1); - offset = (8 * offset + offset_bits + bits_parsed) / 8; - offset_bits = (8 * offset + offset_bits + bits_parsed) % 8; + offset += dissect_someip_payload_parameter(tvb, pinfo, tree, offset, (guint8)item->data_type, item->id_ref, item->name, item->hf_id, -1); } - bits_parsed = 8 * (offset - offset_orig) + (offset_bits + offset_orig_bits); } - return bits_parsed; + return offset - offset_orig; } static void @@ -3539,8 +3395,6 @@ dissect_someip_payload(tvbuff_t* tvb, packet_info* pinfo, proto_item *ti, guint1 gint length = -1; gint offset = 0; - gint offset_bits = 0; - gint bits_parsed = 0; proto_tree *tree = NULL; @@ -3561,22 +3415,12 @@ dissect_someip_payload(tvbuff_t* tvb, packet_info* pinfo, proto_item *ti, guint1 if (paramlist == NULL) { if (someip_deserializer_wtlv_default) { - bits_parsed = dissect_someip_payload_parameters(tvb, pinfo, tree, offset, offset_bits, NULL, 0, TRUE); + offset += dissect_someip_payload_parameters(tvb, pinfo, tree, offset, NULL, 0, TRUE); } else { return; } } else { - bits_parsed = dissect_someip_payload_parameters(tvb, pinfo, tree, offset, offset_bits, paramlist->items, paramlist->num_of_items, paramlist->wtlv_encoding); - } - - offset = (8 * offset + offset_bits + bits_parsed) / 8; - offset_bits = (8 * offset + offset_bits + bits_parsed) % 8; - - if (offset_bits != 0) { - expert_someip_payload_malformed(tree, pinfo, tvb, offset, 0); - - /* align to byte */ - offset += 1; + offset += dissect_someip_payload_parameters(tvb, pinfo, tree, offset, paramlist->items, paramlist->num_of_items, paramlist->wtlv_encoding); } if (length > offset) { @@ -3791,8 +3635,7 @@ dissect_someip_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void if (someip_deserializer_activated) { dissect_someip_payload(subtvb, pinfo, ti, (guint16)someip_serviceid, (guint16)someip_methodid, (guint8)version, (guint8)(~SOMEIP_MSGTYPE_TP_MASK)&msgtype); - } - else { + } else { proto_tree* payload_dissection_disabled_info_sub_tree = proto_item_add_subtree(ti, ett_someip_payload); proto_tree_add_text_internal(payload_dissection_disabled_info_sub_tree, subtvb, 0, tvb_length, "Dissection of payload is disabled. It can be enabled via protocol preferences."); }