SOME/IP: Remove legacy datatype support

Signal PDUs over SOME/IP can be dissected since Wireshark 3.6 directly.
The workaround for SOME/IP to support signal dissection (legacy data
types) is therefore not needed anymore and is removed to cleanup the
dissector code.

This patch might make it necessary to regenerate the Wirehark config.
The Fibex-Converter was already updated.
This commit is contained in:
Dr. Lars Völker 2022-07-10 20:12:20 +02:00 committed by A Wireshark GitLab Utility
parent b1edbd337f
commit d92af30f29
1 changed files with 83 additions and 240 deletions

View File

@ -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.");
}