[Spice-devel,29/33] Handle base fields

Submitted by Frediano Ziglio on July 1, 2015, 5:10 p.m.

Details

Message ID 1435770625-1631-30-git-send-email-fziglio@redhat.com
State New
Headers show

Not browsing as part of any series.

Commit Message

Frediano Ziglio July 1, 2015, 5:10 p.m.
Add fields to base tree (so basically there is no tree).
Names is now generated from container + member name.
The check for duplicate is not that strong, should check if same field
is defined with same attributes.

Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
---
 python_modules/dissector.py | 68 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

Patch hide | download patch | download mbox

diff --git a/python_modules/dissector.py b/python_modules/dissector.py
index db78a82..23bb96a 100644
--- a/python_modules/dissector.py
+++ b/python_modules/dissector.py
@@ -175,6 +175,72 @@  def primitive_read_func(t):
         return 'tvb_get_letoh64'
     raise NotImplementedError('primitive size not supported %s %s' % (size, t))
 
+def container_hf_name(container):
+    if container.has_name():
+        hf_name = "hf_%s" % container.name
+    else:
+        hf_name = "hf_%s" % container.c_name()
+    return hf_name
+
+def member_hf_name(container, member):
+    if member.member_type.is_array():
+        hf_name = "%s_array_%s" % (container_hf_name(container), member.name)
+    else:
+        hf_name = "%s_%s" % (container_hf_name(container), member.name)
+    return hf_name
+
+def get_primitive_ft_type(t):
+    assert(t.is_primitive())
+
+    unsigned = 'U'
+    if isinstance(t, ptypes.IntegerType) and t.signed:
+        unsigned = ''
+    size = t.get_fixed_nw_size()
+    assert size in (1, 2, 4, 8)
+    return "FT_%sINT%d" % (unsigned, size * 8)
+
+# write a field
+def write_wireshark_field(writer, container, member, t, tree, size, encoding='ENC_LITTLE_ENDIAN', prefix=''):
+
+    assert(member and container)
+
+    hf_name = member_hf_name(container, member)
+
+    # compute proper type
+    f_type = 'FT_NONE'
+    base = 'BASE_NONE'
+    vals = 'NULL'
+    if encoding == 'ENC_LITTLE_ENDIAN':
+        assert(t.is_primitive())
+        base = 'BASE_DEC'
+        f_type = get_primitive_ft_type(t)
+        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)
+        elif isinstance(t, ptypes.EnumType) or isinstance(t, ptypes.EnumBaseType):
+            base = 'BASE_DEC'
+            assert(t.has_name())
+            vals = 'VALS(%s_vs)' % codegen.prefix_underscore_lower(t.name)
+
+    desc = member.name
+    ws_name = 'auto.' + hf_name[3:]
+
+    writer.statement("%sproto_tree_add_item(%s, %s, glb->tvb, offset, %s, %s)" %
+            (prefix, tree, hf_name, size, encoding))
+
+    # TODO handle better duplications
+    if hf_writer.variable_defined(hf_name):
+        return
+    hf_writer.variable_def("static int", "%s = -1" % hf_name)
+
+    hf_defs.writeln('{ &%s,' % hf_name)
+    hf_defs.writeln('  { "%s", "spice2.%s",' % (desc, ws_name))
+    hf_defs.writeln('    %s, %s, %s, 0,' % (f_type, base, vals))
+    hf_defs.writeln('    NULL, HFILL }')
+    hf_defs.writeln('},')
+
 
 # Note: during parsing, byte_size types have been converted to count during validation
 def read_array_len(writer, prefix, array, dest, scope, is_ptr):
@@ -269,6 +335,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, 'tree%d' % dest.level, nelements, 'ENC_NA')
         writer.increment("offset", nelements)
         return
 
@@ -364,6 +431,7 @@  def write_member_primitive(writer, container, member, t, dest, scope):
 
     if member.has_attr("bytes_count"):
         raise NotImplementedError("bytes_count not implemented")
+    write_wireshark_field(writer, container, member, t, 'tree%d' % dest.level, t.get_fixed_nw_size())
     if member.has_attr("bytes_count"):
         dest_var = member.attributes["bytes_count"][0]
     else: