Instead of only showing the hexadecimal value show all bits. Every bit is displayed as a different field (usually displayed in a different line indented under the main one). This also allows to use wireshark filter to target specific bits. Signed-off-by: Frediano Ziglio <fziglio@xxxxxxxxxx> --- codegen/Makefile.am | 1 + codegen/check_dissector | 3 ++ codegen/dissector_test.c | 22 +++++++++ codegen/out_base1.txt | 81 +++++++++++++++++++++++++++++---- codegen/out_flags1.txt | 107 ++++++++++++++++++++++++++++++++++++++++++++ codegen/test.proto | 10 +++++ python_modules/dissector.py | 92 ++++++++++++++++++++++++++++++++++--- 7 files changed, 300 insertions(+), 16 deletions(-) create mode 100644 codegen/out_flags1.txt diff --git a/codegen/Makefile.am b/codegen/Makefile.am index a361bd9..0cf9f63 100644 --- a/codegen/Makefile.am +++ b/codegen/Makefile.am @@ -63,6 +63,7 @@ EXTRA_DIST = \ out_array_raw.txt \ out_array_struct.txt \ out_channel.txt \ + out_flags1.txt \ $(NULL) CLEANFILES = test.c test.h enums.h dissector.c dissector.h *.trs check_dissector.txt diff --git a/codegen/check_dissector b/codegen/check_dissector index e2d06b5..94ce0bc 100755 --- a/codegen/check_dissector +++ b/codegen/check_dissector @@ -62,4 +62,7 @@ check data_u16s 1 102 out_array_struct.txt --client check data_base1 1 2 out_channel.txt +# flags and descriptions +check data_base1 1 3 out_flags1.txt + exit 0 diff --git a/codegen/dissector_test.c b/codegen/dissector_test.c index dcc0134..96b3107 100644 --- a/codegen/dissector_test.c +++ b/codegen/dissector_test.c @@ -254,6 +254,28 @@ expert_add_info_format(packet_info *pinfo, proto_item *pi, expert_field *eiindex return; } +WS_DLL_PUBLIC proto_tree* proto_item_add_subtree(proto_item *ti, const gint idx) +{ + proto_tree *res; + + assert(idx >= first_tree_registered); + assert(idx <= last_tree_registered); + if (!ti) + return NULL; + + assert(ti->tree_data == NULL); + assert(ti->first_child == NULL); + assert(ti->last_child == NULL); + res = calloc(1, sizeof(*res)); + assert(res); + res->tree_data = (void *) res; + ti->first_child = res; + ti->last_child = res; + check_tree(res); + check_item(ti); + return res; +} + struct all_ti { proto_item ti; diff --git a/codegen/out_base1.txt b/codegen/out_base1.txt index 7921afd..66b42bc 100644 --- a/codegen/out_base1.txt +++ b/codegen/out_base1.txt @@ -66,20 +66,83 @@ Type: FT_UINT32 Base: BASE_DEC --- item - Text: H (1) - Name: f8 - Abbrev: spice2.auto.msg_base_Base1_f8 + Text: 1 (0x1) + Name: F8 + Abbrev: spice2.f8_flags Type: FT_UINT8 Base: BASE_HEX + --- tree + --- item + Text: Not set + Name: K + Abbrev: spice2.F8_k + Type: FT_BOOLEAN + Base: 4 + --- item + Text: Not set + Name: J + Abbrev: spice2.F8_j + Type: FT_BOOLEAN + Base: 4 + --- item + Text: Not set + Name: I + Abbrev: spice2.F8_i + Type: FT_BOOLEAN + Base: 4 + --- item + Text: Set + Name: H + Abbrev: spice2.F8_h + Type: FT_BOOLEAN + Base: 4 --- item - Text: L (1) - Name: f16 - Abbrev: spice2.auto.msg_base_Base1_f16 + Text: 1 (0x1) + Name: F16 + Abbrev: spice2.f16_flags Type: FT_UINT16 Base: BASE_HEX + --- tree + --- item + Text: Not set + Name: M + Abbrev: spice2.F16_m + Type: FT_BOOLEAN + Base: 2 + --- item + Text: Set + Name: L + Abbrev: spice2.F16_l + Type: FT_BOOLEAN + Base: 2 --- item - Text: N (1) - Name: f32 - Abbrev: spice2.auto.msg_base_Base1_f32 + Text: 1 (0x1) + Name: F32 + Abbrev: spice2.f32_flags Type: FT_UINT32 Base: BASE_HEX + --- tree + --- item + Text: Not set + Name: Q + Abbrev: spice2.F32_q + Type: FT_BOOLEAN + Base: 4 + --- item + Text: Not set + Name: P + Abbrev: spice2.F32_p + Type: FT_BOOLEAN + Base: 4 + --- item + Text: Not set + Name: O + Abbrev: spice2.F32_o + Type: FT_BOOLEAN + Base: 4 + --- item + Text: Set + Name: N + Abbrev: spice2.F32_n + Type: FT_BOOLEAN + Base: 4 diff --git a/codegen/out_flags1.txt b/codegen/out_flags1.txt new file mode 100644 index 0000000..0776300 --- /dev/null +++ b/codegen/out_flags1.txt @@ -0,0 +1,107 @@ +--- tree + --- item + Text: 130 (0x82) + Name: Test flags + Abbrev: spice2.tests_flag + Type: FT_UINT8 + Base: BASE_DEC_HEX + --- tree + --- item + Text: Not set + Name: Z + Abbrev: spice2.test_flags_z + Type: FT_BOOLEAN + Base: 3 + --- item + Text: Set + Name: Y + Abbrev: spice2.test_flags_y + Type: FT_BOOLEAN + Base: 3 + --- item + Text: Not set + Name: X + Abbrev: spice2.test_flags_x + Type: FT_BOOLEAN + Base: 3 + --- item + Text: 129 (0x81) + Name: Test flags override + Abbrev: spice2.tests_flag_override + Type: FT_UINT8 + Base: BASE_HEX_DEC + --- tree + --- item + Text: Not set + Name: Z + Abbrev: spice2.test_flags_z + Type: FT_BOOLEAN + Base: 3 + --- item + Text: Not set + Name: Y + Abbrev: spice2.test_flags_y + Type: FT_BOOLEAN + Base: 3 + --- item + Text: Set + Name: X + Abbrev: spice2.test_flags_x + Type: FT_BOOLEAN + Base: 3 + --- item + Text: 1 (0x1) + Name: Test flags + Abbrev: spice2.tests_flag + Type: FT_UINT8 + Base: BASE_HEX_DEC + --- tree + --- item + Text: Not set + Name: Z + Abbrev: spice2.test_flags_z + Type: FT_BOOLEAN + Base: 3 + --- item + Text: Not set + Name: Y + Abbrev: spice2.test_flags_y + Type: FT_BOOLEAN + Base: 3 + --- item + Text: Set + Name: X + Abbrev: spice2.test_flags_x + Type: FT_BOOLEAN + Base: 3 + --- item + Text: 131 (0x83) + Name: flags4 + Abbrev: spice2.auto.msg_base_Flags1_flags4 + Type: FT_UINT8 + Base: BASE_HEX_DEC + --- tree + --- item + Text: Not set + Name: K + Abbrev: spice2.F8_k + Type: FT_BOOLEAN + Base: 4 + --- item + Text: Not set + Name: J + Abbrev: spice2.F8_j + Type: FT_BOOLEAN + Base: 4 + --- item + Text: Set + Name: I + Abbrev: spice2.F8_i + Type: FT_BOOLEAN + Base: 4 + --- item + Text: Set + Name: H + Abbrev: spice2.F8_h + Type: FT_BOOLEAN + Base: 4 diff --git a/codegen/test.proto b/codegen/test.proto index 0f14125..6d97317 100644 --- a/codegen/test.proto +++ b/codegen/test.proto @@ -30,6 +30,10 @@ flags32 F32 { N, O, P, Q }; +flags8 test_flags { + X, Y, Z +} @ws("Test flags", tests_flag) @ws_base(DEC_HEX); + struct Dummy { uint16 dummy; }; @@ -67,6 +71,12 @@ channel BaseChannel { message { uint8 channel @ws_type(CHANNEL); } Channel; + message { + test_flags flags1; + test_flags flags2 @ws("Test flags override", tests_flag_override) @ws_base(HEX_DEC); + test_flags flags3 @ws_base(HEX_DEC); + F8 flags4 @ws_base(HEX_DEC); + } Flags1; Empty empty = 100; client: diff --git a/python_modules/dissector.py b/python_modules/dissector.py index 6898a13..1bcefa3 100644 --- a/python_modules/dissector.py +++ b/python_modules/dissector.py @@ -289,7 +289,7 @@ def get_primitive_ft_type(t): return "FT_%sINT%d" % (unsigned, size * 8) # write a field -def write_wireshark_field(writer, container, member, t, ws, tree, size, encoding='ENC_LITTLE_ENDIAN', prefix=''): +def write_wireshark_field(writer, container, member, t, ws, tree, dest, size, encoding='ENC_LITTLE_ENDIAN', prefix=''): assert(member and container) @@ -305,10 +305,15 @@ def write_wireshark_field(writer, container, member, t, ws, tree, size, encoding f_type = get_primitive_ft_type(t) size_name = str(t.get_fixed_nw_size() * 8) if isinstance(t, ptypes.FlagsType): - # show flag as hexadecimal for now - base = 'BASE_HEX' - assert(t.has_name()) - vals = 'VALS(%s_vs)' % codegen.prefix_underscore_lower(t.name) + # if the attribute unique_flag is not set must compute + # all flags writing a HF for each bit + if t.has_attr('unique_flag'): + base = 'BASE_HEX' + assert(t.has_name()) + vals = 'VALS(%s_vs)' % codegen.prefix_underscore_lower(t.name) + else: + write_flags(writer, container, member, t, ws, tree, dest) + return elif isinstance(t, ptypes.EnumType) or isinstance(t, ptypes.EnumBaseType): base = 'BASE_DEC' assert(t.has_name()) @@ -448,7 +453,7 @@ def write_array(writer, container, member, nelements, array, dest, scope): element_type = array.element_type if element_type == ptypes.uint8 or element_type == ptypes.int8: - write_wireshark_field(writer, container, member, array, ws, dest.level.tree, nelements, 'ENC_NA') + write_wireshark_field(writer, container, member, array, ws, dest.level.tree, dest, nelements, 'ENC_NA') writer.increment("offset", nelements) return @@ -538,13 +543,86 @@ def write_struct(writer, member, t, index, dest, scope): write_struct_func(writer, t, func_name, index) writer.assign('offset', '%s(glb, %s, offset, %s)' % (func_name, dest.level.tree, index)) + +def write_flags_func(writer, t, ws, tree, ti): + size = t.get_fixed_nw_size() + hf_name = 'hf_%s_flag%d' % (t.name, size*8) + func_name = 'dissect_flags%d_%s' % (size*8, t.name) + stmt = '%s(glb, %s, offset, %s)' % (func_name, tree, ti) + + if writer.is_generated("flags", t.name): + return stmt + writer.set_is_generated("flags", t.name) + + writer = writer.function_helper() + scope = writer.function(func_name, "proto_item *", "GlobalInfo *glb _U_, proto_tree *tree _U_, guint32 offset, proto_item *ti", True) + dest = RootDestination(scope) + + desc = ws.desc if ws.desc else t.name + hf = HF(hf_name, desc) + hf.ws_name = ws.name if ws.name else '%s_flags' % (t.name.lower()) + hf.f_type = get_primitive_ft_type(t) + hf.base = 'BASE_%s' % (ws.base if ws.base else 'HEX') + hf.vals = 'NULL' + hf.create() + + with writer.if_block('ti == NULL'): + writer.assign('ti', 'proto_tree_add_item(tree, %s, glb->tvb, offset, %d, ENC_LITTLE_ENDIAN)' % (hf_name, size)) + writer.assign('tree', 'proto_item_add_subtree(ti, %s)' % new_ett(writer)) + + values = list(t.names.keys()) + values.sort() + values.reverse() + bits = max(values) + 1 + for v in values: + name = hf_name + '_' + t.names[v].lower() + + desc = t.descs[v] if t.descs[v] else t.names[v] + hf = HF(name, desc) + hf.ws_name = '%s_%s' % (t.name, t.names[v].lower()) + hf.f_type = 'FT_BOOLEAN' + hf.base = str(bits) + hf.vals = 'TFS(&tfs_set_notset)' + hf.mask = t.c_enumname(v) + hf.create() + + writer.statement('proto_tree_add_item(tree, %s, glb->tvb, offset, %d, ENC_LITTLE_ENDIAN)' % (name, size)) + + writer.statement('return ti'); + writer.end_block() + + return stmt + + +def write_flags(writer, container, member, t, ws, tree, dest): + if ws.type: + assert False, "Attribute ws_type for member %s flag %s are ignored" % (member.name, t.name) + + ws_func = WSAttributes(t) + + own_ti = ws.name != ws_func.name or ws.desc != ws_func.desc or ws.base != ws_func.base + if not own_ti: + stmt = write_flags_func(writer, t, ws_func, tree, 'NULL') + writer.statement(stmt) + return + + tree = dest.level.tree + with writer.block() as scope, dest.level: + scope.variable_def('proto_item *', dest.level.ti) + size = t.get_fixed_nw_size() + int_type = ptypes.IntegerType(size*8, False) + write_wireshark_field(writer, container, member, int_type, ws, tree, dest, size, prefix=dest.level.ti + ' = ') + stmt = write_flags_func(writer, t, ws_func, tree, dest.level.ti) + writer.statement(stmt) + + def write_member_primitive(writer, container, member, t, ws, dest, scope): assert(t.is_primitive()) if member.has_attr("bytes_count"): raise NotImplementedError("bytes_count not implemented") - write_wireshark_field(writer, container, member, t, ws, dest.level.tree, t.get_fixed_nw_size()) + write_wireshark_field(writer, container, member, t, ws, dest.level.tree, dest, t.get_fixed_nw_size()) if member.has_attr("bytes_count"): dest_var = member.attributes["bytes_count"][0] else: -- 2.1.0 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel