-- This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild -- -- This file is compatible with Lua 5.3 package.path = "kaitai_struct_lua_runtime/?.lua" .. package.path local class = require("class") require("tvbstream") require("kaitaistruct") local proto = Proto('solec', 'Solec') proto.fields = {} local enum = require("enum") local Solec_type_payload = ProtoField.new('type_payload', 'Solec.type_payload', ftypes.BYTES) table.insert(proto.fields, Solec_type_payload) local Solec_len_payload = ProtoField.new('len_payload', 'Solec.len_payload', ftypes.UINT32) table.insert(proto.fields, Solec_len_payload) local Solec_Test_num1 = ProtoField.new('num1', 'Solec.Test.num1', ftypes.UINT8) table.insert(proto.fields, Solec_Test_num1) local Solec_Test_time1 = ProtoField.new('time1', 'Solec.Test.time1', ftypes.UINT32) table.insert(proto.fields, Solec_Test_time1) local Solec_Test_num2 = ProtoField.new('num2', 'Solec.Test.num2', ftypes.UINT32) table.insert(proto.fields, Solec_Test_num2) local Solec_Test_num3 = ProtoField.new('num3', 'Solec.Test.num3', ftypes.UINT32) table.insert(proto.fields, Solec_Test_num3) local Solec_Test_num4 = ProtoField.new('num4', 'Solec.Test.num4', ftypes.UINT32) table.insert(proto.fields, Solec_Test_num4) local Solec_Binary_len_payload = ProtoField.new('len_payload', 'Solec.Binary.len_payload', ftypes.UINT32) table.insert(proto.fields, Solec_Binary_len_payload) local Solec_Binary_payload = ProtoField.new('payload', 'Solec.Binary.payload', ftypes.BYTES) table.insert(proto.fields, Solec_Binary_payload) local Solec_String_len_payload = ProtoField.new('len_payload', 'Solec.String.len_payload', ftypes.UINT32) table.insert(proto.fields, Solec_String_len_payload) local str_decode = require("string_decode") local Solec_String_payload = ProtoField.new('payload', 'Solec.String.payload', ftypes.STRINGZ) table.insert(proto.fields, Solec_String_payload) local Solec_Handshake_proto_ver_major = ProtoField.new('proto_ver_major', 'Solec.Handshake.proto_ver_major', ftypes.UINT8) table.insert(proto.fields, Solec_Handshake_proto_ver_major) local Solec_Handshake_proto_ver_minor = ProtoField.new('proto_ver_minor', 'Solec.Handshake.proto_ver_minor', ftypes.UINT8) table.insert(proto.fields, Solec_Handshake_proto_ver_minor) local Solec_Message_timestamp = ProtoField.new('timestamp', 'Solec.Message.timestamp', ftypes.UINT32) table.insert(proto.fields, Solec_Message_timestamp) local Solec_Pong_timestamp = ProtoField.new('timestamp', 'Solec.Pong.timestamp', ftypes.UINT32) table.insert(proto.fields, Solec_Pong_timestamp) function proto.dissector(tvb, pinfo, root) pinfo.cols.protocol = 'Solec' local tree = root:add(proto, tvb(), 'Solec') local io = KaitaiStream(TVBStream(tvb)) local obj = Solec(io, tree) end -- -- SOLEC protocol uses big endian encoding. Frames uses type-length-value format. -- See also: Source (https://git.sr.ht/~rctt/solec/blob/main/solec.svg) Solec = class.class(KaitaiStruct) Solec.Type = enum.Enum { handshake = 1, ping = 2, pong = 3, message = 4, test = 255, } function Solec:_init(io, tree, parent, root) KaitaiStruct._init(self, io) self._parent = parent self._root = root or self self._tree = tree self:_read() end function Solec:_read() local _offset = self._io:pos() self.type_payload = Solec.Type(self._io:read_u1()) self._tree:add(Solec_type_payload, self._io._io.tvb(_offset, self._io:pos() - _offset)) local _offset = self._io:pos() self.len_payload = self._io:read_u2be() self._tree:add(Solec_len_payload, self._io._io.tvb(_offset, self._io:pos() - _offset), self.len_payload) local _offset = self._io:pos() local _on = self.type_payload if _on == Solec.Type.message then self._raw_payload = self._io:read_bytes(self.len_payload) local _tvb = self._io._io.tvb(_offset, self._io:pos() - _offset) local _io = KaitaiStream(TVBStream(_tvb)) local _tree = self._tree:add(_tvb, 'payload') self.payload = Solec.Message(_io, _tree, self, self._root) elseif _on == Solec.Type.ping then self._raw_payload = self._io:read_bytes(self.len_payload) local _tvb = self._io._io.tvb(_offset, self._io:pos() - _offset) local _io = KaitaiStream(TVBStream(_tvb)) local _tree = self._tree:add(_tvb, 'payload') self.payload = Solec.Ping(_io, _tree, self, self._root) elseif _on == Solec.Type.pong then self._raw_payload = self._io:read_bytes(self.len_payload) local _tvb = self._io._io.tvb(_offset, self._io:pos() - _offset) local _io = KaitaiStream(TVBStream(_tvb)) local _tree = self._tree:add(_tvb, 'payload') self.payload = Solec.Pong(_io, _tree, self, self._root) elseif _on == Solec.Type.test then self._raw_payload = self._io:read_bytes(self.len_payload) local _tvb = self._io._io.tvb(_offset, self._io:pos() - _offset) local _io = KaitaiStream(TVBStream(_tvb)) local _tree = self._tree:add(_tvb, 'payload') self.payload = Solec.Test(_io, _tree, self, self._root) elseif _on == Solec.Type.handshake then self._raw_payload = self._io:read_bytes(self.len_payload) local _tvb = self._io._io.tvb(_offset, self._io:pos() - _offset) local _io = KaitaiStream(TVBStream(_tvb)) local _tree = self._tree:add(_tvb, 'payload') self.payload = Solec.Handshake(_io, _tree, self, self._root) else self.payload = self._io:read_bytes(self.len_payload) end end -- -- Test payload, used for parsers testing. Solec.Test = class.class(KaitaiStruct) function Solec.Test:_init(io, tree, parent, root) KaitaiStruct._init(self, io) self._parent = parent self._root = root or self self._tree = tree self:_read() end function Solec.Test:_read() local _offset = self._io:pos() self.num1 = self._io:read_u1() self._tree:add(Solec_Test_num1, self._io._io.tvb(_offset, self._io:pos() - _offset), self.num1) local _offset = self._io:pos() self.time1 = self._io:read_u8be() self._tree:add(Solec_Test_time1, self._io._io.tvb(_offset, self._io:pos() - _offset), self.time1) local _offset = self._io:pos() local _tree = self._tree:add(self._io._io.tvb(_offset, 0), 'str1') self.str1 = Solec.String(self._io, _tree, self, self._root) _tree:set_len(self._io:pos() - _offset) local _offset = self._io:pos() self.num2 = self._io:read_u2be() self._tree:add(Solec_Test_num2, self._io._io.tvb(_offset, self._io:pos() - _offset), self.num2) local _offset = self._io:pos() local _tree = self._tree:add(self._io._io.tvb(_offset, 0), 'bin1') self.bin1 = Solec.Binary(self._io, _tree, self, self._root) _tree:set_len(self._io:pos() - _offset) local _offset = self._io:pos() self.num3 = self._io:read_u4be() self._tree:add(Solec_Test_num3, self._io._io.tvb(_offset, self._io:pos() - _offset), self.num3) local _offset = self._io:pos() local _tree = self._tree:add(self._io._io.tvb(_offset, 0), 'str2') self.str2 = Solec.String(self._io, _tree, self, self._root) _tree:set_len(self._io:pos() - _offset) local _offset = self._io:pos() self.num4 = self._io:read_u8be() self._tree:add(Solec_Test_num4, self._io._io.tvb(_offset, self._io:pos() - _offset), self.num4) end -- -- Binary data of unspecifed type. Solec.Binary = class.class(KaitaiStruct) function Solec.Binary:_init(io, tree, parent, root) KaitaiStruct._init(self, io) self._parent = parent self._root = root or self self._tree = tree self:_read() end function Solec.Binary:_read() local _offset = self._io:pos() self.len_payload = self._io:read_u2be() self._tree:add(Solec_Binary_len_payload, self._io._io.tvb(_offset, self._io:pos() - _offset), self.len_payload) local _offset = self._io:pos() self.payload = self._io:read_bytes(self.len_payload) self._tree:add(Solec_Binary_payload, self._io._io.tvb(_offset, self._io:pos() - _offset), self.payload) end -- -- UTF-8 encoded string. Solec.String = class.class(KaitaiStruct) function Solec.String:_init(io, tree, parent, root) KaitaiStruct._init(self, io) self._parent = parent self._root = root or self self._tree = tree self:_read() end function Solec.String:_read() local _offset = self._io:pos() self.len_payload = self._io:read_u2be() self._tree:add(Solec_String_len_payload, self._io._io.tvb(_offset, self._io:pos() - _offset), self.len_payload) local _offset = self._io:pos() self.payload = str_decode.decode(self._io:read_bytes(self.len_payload), "UTF-8") self._tree:add(Solec_String_payload, self._io._io.tvb(_offset, self._io:pos() - _offset), self.payload) end -- -- Ping does not contain any payload. Solec.Ping = class.class(KaitaiStruct) function Solec.Ping:_init(io, tree, parent, root) KaitaiStruct._init(self, io) self._parent = parent self._root = root or self self._tree = tree self:_read() end function Solec.Ping:_read() end -- -- Handshake is sent by the client during connection initialization. -- If protocol_ver_major is different than version used by the server -- connection will be aborted. Solec.Handshake = class.class(KaitaiStruct) function Solec.Handshake:_init(io, tree, parent, root) KaitaiStruct._init(self, io) self._parent = parent self._root = root or self self._tree = tree self:_read() end function Solec.Handshake:_read() local _offset = self._io:pos() self.proto_ver_major = self._io:read_u1() self._tree:add(Solec_Handshake_proto_ver_major, self._io._io.tvb(_offset, self._io:pos() - _offset), self.proto_ver_major) local _offset = self._io:pos() self.proto_ver_minor = self._io:read_u1() self._tree:add(Solec_Handshake_proto_ver_minor, self._io._io.tvb(_offset, self._io:pos() - _offset), self.proto_ver_minor) end -- -- Source and target fields are addresses in user@server format. Solec.Message = class.class(KaitaiStruct) function Solec.Message:_init(io, tree, parent, root) KaitaiStruct._init(self, io) self._parent = parent self._root = root or self self._tree = tree self:_read() end function Solec.Message:_read() local _offset = self._io:pos() local _tree = self._tree:add(self._io._io.tvb(_offset, 0), 'source') self.source = Solec.String(self._io, _tree, self, self._root) _tree:set_len(self._io:pos() - _offset) local _offset = self._io:pos() local _tree = self._tree:add(self._io._io.tvb(_offset, 0), 'target') self.target = Solec.String(self._io, _tree, self, self._root) _tree:set_len(self._io:pos() - _offset) local _offset = self._io:pos() self.timestamp = self._io:read_u8be() self._tree:add(Solec_Message_timestamp, self._io._io.tvb(_offset, self._io:pos() - _offset), self.timestamp) local _offset = self._io:pos() local _tree = self._tree:add(self._io._io.tvb(_offset, 0), 'content') self.content = Solec.String(self._io, _tree, self, self._root) _tree:set_len(self._io:pos() - _offset) end -- -- Set just before sending the message. Solec.Pong = class.class(KaitaiStruct) function Solec.Pong:_init(io, tree, parent, root) KaitaiStruct._init(self, io) self._parent = parent self._root = root or self self._tree = tree self:_read() end function Solec.Pong:_read() local _offset = self._io:pos() self.timestamp = self._io:read_u8be() self._tree:add(Solec_Pong_timestamp, self._io._io.tvb(_offset, self._io:pos() - _offset), self.timestamp) end -- -- Timestamp is set just before sending the pong message. It can be used -- to meassure packet's travel time between server and client. local tcp_port = DissectorTable.get("tcp.port") tcp_port:add(9999, proto)