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; 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; 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]"); 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 *************** **************** Statistics ***************
*******************************************/ *******************************************/
@ -2560,10 +2566,10 @@ someip_messages_stats_tree_packet(stats_tree *st, packet_info *pinfo, epan_disse
*******************************************/ *******************************************/
static int 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 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*/ /* add a flexible size length field, -1 for error*/
static gint64 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 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_base_type_list_t *base_type = NULL;
someip_payload_parameter_enum_t *enum_config = NULL; someip_payload_parameter_enum_t *enum_config = NULL;
guint32 basetype_id = 0; guint32 basetype_id = 0;
guint32 enum_id = 0; guint32 enum_id = 0;
gint buf_length = -1;
gint param_length = -1; gint param_length = -1;
guint32 bit_length = 0;
proto_item *ti = NULL; 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; guint32 i = 0;
gchar *value_name = NULL; gchar *value_name = NULL;
gint offset_end = 0;
gint offset_end_bits = 0;
gboolean big_endian = TRUE; gboolean big_endian = TRUE;
int hf_id = -1; 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; hf_id = *hf_id_ptr;
} }
if (offset_bits < 0) {
return 0;
}
switch (data_type) { switch (data_type) {
case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_BASE_TYPE: case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_BASE_TYPE:
basetype_id = id; basetype_id = id;
@ -2775,15 +2714,12 @@ dissect_someip_payload_base_type(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr
} }
big_endian = base_type->big_endian; big_endian = base_type->big_endian;
buf_length = tvb_captured_length_remaining(tvb, 0); param_length = (gint)((base_type->bitlength_base_type) / 8);
bit_length = base_type->bitlength_encoded_type;
/* +7 to round up, if more than 0 bits */ if (param_length > tvb_captured_length_remaining(tvb, 0) - offset) {
param_length = (gint)((offset_bits + bit_length + 7) / 8); 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 (hf_id != -1) {
if (strncmp(base_type->data_type, "uint", 4) == 0) { if (strncmp(base_type->data_type, "uint", 4) == 0) {
if (base_type->bitlength_base_type > 32) { if (base_type->bitlength_base_type > 32) {
@ -2803,32 +2739,6 @@ dissect_someip_payload_base_type(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr
ti = proto_tree_add_string_format(tree, hf_payload_str_base, tvb, offset, param_length, base_type->name, "%s [%s]", name, base_type->name); 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);
}
}
value_set = TRUE;
}
} else {
return 0;
}
dissect_someip_payload_add_wtlv_if_needed(tvb, pinfo, wtlv_offset, ti, NULL); 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 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; someip_payload_parameter_string_t *config = NULL;
guint8 *buf = NULL; guint8 *buf = NULL;
@ -2859,7 +2769,6 @@ dissect_someip_payload_string(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
gint64 tmp = 0; gint64 tmp = 0;
guint32 length = 0; guint32 length = 0;
gint offset_orig = offset; gint offset_orig = offset;
gint offset_bits_orig = offset_bits;
guint str_encoding = 0; guint str_encoding = 0;
int hf_id = hf_payload_str_string; 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); config = get_string_config(id);
if (config == NULL || offset_bits != 0) { if (config == NULL) {
return 0; 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); proto_item_set_end(ti, tvb, offset);
return 8 * (offset - offset_orig) + (offset_bits - offset_bits_orig); return offset - offset_orig;
} }
static int 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; someip_payload_parameter_struct_t *config = NULL;
proto_tree *subtree = 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; gint64 length = 0;
gint offset = offset_orig; gint offset = offset_orig;
gint offset_bits = offset_bits_orig;
gint bits_parsed = 0;
config = get_struct_config(id); 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); 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 += dissect_someip_payload_parameters(subtvb, pinfo, subtree, offset, 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;
if (length_of_length == 0) { if (length_of_length == 0) {
if (offset_bits == 0) {
proto_item_set_end(ti, tvb, offset); proto_item_set_end(ti, tvb, offset);
} else {
proto_item_set_end(ti, tvb, offset + 1);
}
return 8 * (offset - offset_orig) + (offset_bits - offset_bits_orig); return offset - offset_orig;
} else { } else {
return 8 * ((length_of_length / 8) + (guint32)length); return (length_of_length / 8) + (guint32)length;
} }
} }
static int 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; someip_payload_parameter_typedef_t *config = NULL;
gint bits_parsed = 0;
config = get_typedef_config(id); 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 */ /* 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 dissect_someip_payload_parameter(tvb, pinfo, tree, offset, (guint8)config->data_type, config->id_ref, config->name, hf_id, wtlv_offset);
return bits_parsed;
} }
/* returns bytes 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 */
@ -3060,14 +2958,13 @@ dissect_someip_payload_array_dim_length(tvbuff_t *tvb, packet_info *pinfo, proto
return offset - offset_orig; 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 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, 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) { someip_parameter_array_t *config) {
tvbuff_t *subtvb = NULL; tvbuff_t *subtvb = NULL;
guint32 offset = offset_orig; guint32 offset = offset_orig;
guint32 offset_bits = 0; guint32 bytes_parsed = 0;
guint32 bits_parsed = 0;
guint32 ret = 0; guint32 ret = 0;
gint count = 0; gint count = 0;
@ -3084,13 +2981,13 @@ dissect_someip_payload_array_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tr
subtvb = tvb; subtvb = tvb;
} }
while ((length == -1 && count < upper_limit) || ((gint)(8 * offset + offset_bits) < 8 * length)) { while ((length == -1 && count < upper_limit) || ((gint)offset < 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); bytes_parsed = dissect_someip_payload_parameter(subtvb, pinfo, tree, offset, (guint8)config->data_type, config->id_ref, config->name, config->hf_id, -1);
if (bits_parsed == 0) { if (bytes_parsed == 0) {
/* does this make sense? */
return 1; return 1;
} }
offset = (8 * offset + bits_parsed) / 8; offset += bytes_parsed;
offset_bits = (8 * offset + bits_parsed) % 8;
count++; count++;
} }
@ -3101,15 +2998,15 @@ dissect_someip_payload_array_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tr
} }
if (length != -1) { if (length != -1) {
ret = 8 * offset + offset_bits; /* we created subtvb first and set offset to 0 */
ret = offset;
} else { } else {
ret = 8 * (offset - offset_orig) + offset_bits; ret = offset - offset_orig;
} }
return ret; return ret;
} }
/* returns bits parsed */
static gint 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) { 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; 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 sub_offset = 0;
gint offset = offset_orig; gint offset = offset_orig;
gint offset_bits = 0;
gint ret = 0;
if (config->num_of_dims == current_dim + 1) { if (config->num_of_dims == current_dim + 1) {
/* only payload left. :) */ /* 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 { } else {
if (length != -1) { if (length != -1) {
while (offset < offset_orig + (gint)length) { 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; 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 += 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);
}
proto_item_set_end(ti, tvb, offset);
} }
} else { } else {
/* Multi-dim static array */ /* 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 offset - offset_orig;
return ret;
} }
static int 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; someip_parameter_array_t *config = NULL;
proto_tree *subtree; proto_tree *subtree;
proto_item *ti = NULL; proto_item *ti = NULL;
gint offset = offset_orig; gint offset = offset_orig;
gint offset_bits = offset_bits_orig;
gint length = 0; gint length = 0;
gint size_of_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; 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); 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); 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); 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); 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); proto_item_set_end(ti, tvb, offset);
} else {
proto_item_set_end(ti, tvb, offset + 1);
}
if (length >= 0) { if (length >= 0) {
/* length field present */ /* length field present */
return 8 * (size_of_length + length); return size_of_length + length;
} else { } else {
/* We have no length field, so we return what has been parsed! */ /* 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 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_t *config = NULL;
someip_parameter_union_item_t *item = 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; guint32 i = 0;
gint offset = offset_orig; gint offset = offset_orig;
gint offset_bits = offset_bits_orig;
config = get_union_config(id); config = get_union_config(id);
buf_length = tvb_captured_length_remaining(tvb, 0); 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; return 0;
} }
if (offset_bits_orig != 0) {
expert_someip_payload_alignment_error(tree, pinfo, tvb, offset_orig, 0);
return 0;
}
if (wtlv_offset >= 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); ti = proto_tree_add_string_format(tree, hf_payload_str_union, tvb, wtlv_offset, 0, name, "union %s [%s]", name, config->name);
} else { } 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); tmp = dissect_someip_payload_length_field(tvb, pinfo, subtree, offset_orig, length_of_length);
if (tmp == -1) { if (tmp == -1) {
return 8 * (offset - offset_orig) + (offset_bits - 0); return offset - offset_orig;
} else { } else {
length = (guint32)tmp; length = (guint32)tmp;
} }
tmp = dissect_someip_payload_type_field(tvb, pinfo, subtree, offset_orig + length_of_length / 8, config->length_of_type); tmp = dissect_someip_payload_type_field(tvb, pinfo, subtree, offset_orig + length_of_length / 8, config->length_of_type);
if (tmp == -1) { if (tmp == -1) {
return 8 * (offset - offset_orig) + (offset_bits - 0); return offset - offset_orig;
} else { } else {
type = (guint32)tmp; type = (guint32)tmp;
} }
@ -3308,38 +3177,37 @@ dissect_someip_payload_union(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
if (item != NULL) { if (item != NULL) {
subtvb = tvb_new_subset_length_caplen(tvb, offset, length, length); 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 { } else {
expert_someip_payload_config_error(tree, pinfo, tvb, offset, 0, "Union type not configured"); 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 length + (config->length_of_type + length_of_length) / 8;
return 8 * length + config->length_of_type + length_of_length;
} }
static int 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) {
gint bits_parsed = 0; gint bytes_parsed = 0;
switch (data_type) { switch (data_type) {
case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_TYPEDEF: 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; break;
case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_BASE_TYPE: case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_BASE_TYPE:
case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_ENUM: 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; break;
case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_STRING: 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; break;
case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_ARRAY: 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; break;
case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_STRUCT: 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; break;
case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_UNION: 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; break;
default: default:
proto_tree_add_expert_format(tree, pinfo, &ef_someip_payload_config_error, tvb, offset, 0, 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; 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 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; someip_payload_parameter_item_t *item;
gint offset_orig = offset; gint offset_orig = offset;
gint offset_orig_bits = offset_bits;
gint bits_parsed = 0;
if (items == NULL && !someip_deserializer_wtlv_default) { if (items == NULL && !someip_deserializer_wtlv_default) {
return 0; return 0;
@ -3442,12 +3308,6 @@ dissect_someip_payload_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree
if (wtlv) { if (wtlv) {
while (tvb_captured_length_remaining(tvb, offset) >= 2) { 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); guint64 tagdata = tvb_get_guint16(tvb, offset, ENC_BIG_ENDIAN);
guint wiretype = (tagdata & SOMEIP_WTLV_MASK_WIRE_TYPE) >> 12; guint wiretype = (tagdata & SOMEIP_WTLV_MASK_WIRE_TYPE) >> 12;
guint param_id = tagdata & SOMEIP_WTLV_MASK_DATA_ID; 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); tvbuff_t *subtvb = tvb_new_subset_length_caplen(tvb, offset - 2, param_length + 2, param_length + 2);
if (item != NULL) { 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 { } else {
proto_item *ti = proto_tree_add_item(tree, hf_payload_unparsed, subtvb, 2, param_length, ENC_NA); 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); dissect_someip_payload_add_wtlv_if_needed(tvb, pinfo, offset - 2, ti, NULL);
} }
offset += param_length; offset += param_length;
} }
bits_parsed = 8 * (offset - offset_orig);
} else { } else {
if (items == NULL) { if (items == NULL) {
return 0; return 0;
@ -3523,14 +3382,11 @@ dissect_someip_payload_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree
guint32 i; guint32 i;
for (i = 0; i < num_of_items; i++) { for (i = 0; i < num_of_items; i++) {
item = &(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 += dissect_someip_payload_parameter(tvb, pinfo, tree, offset, (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;
} }
bits_parsed = 8 * (offset - offset_orig) + (offset_bits + offset_orig_bits);
} }
return bits_parsed; return offset - offset_orig;
} }
static void static void
@ -3539,8 +3395,6 @@ dissect_someip_payload(tvbuff_t* tvb, packet_info* pinfo, proto_item *ti, guint1
gint length = -1; gint length = -1;
gint offset = 0; gint offset = 0;
gint offset_bits = 0;
gint bits_parsed = 0;
proto_tree *tree = NULL; 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 (paramlist == NULL) {
if (someip_deserializer_wtlv_default) { 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 { } else {
return; return;
} }
} else { } else {
bits_parsed = dissect_someip_payload_parameters(tvb, pinfo, tree, offset, offset_bits, paramlist->items, paramlist->num_of_items, paramlist->wtlv_encoding); offset += dissect_someip_payload_parameters(tvb, pinfo, tree, offset, 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;
} }
if (length > offset) { if (length > offset) {
@ -3791,8 +3635,7 @@ dissect_someip_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
if (someip_deserializer_activated) { if (someip_deserializer_activated) {
dissect_someip_payload(subtvb, pinfo, ti, (guint16)someip_serviceid, (guint16)someip_methodid, (guint8)version, (guint8)(~SOMEIP_MSGTYPE_TP_MASK)&msgtype); 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* 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."); 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.");
} }