diff options
Diffstat (limited to 'solec.lua')
| -rw-r--r-- | solec.lua | 118 |
1 files changed, 75 insertions, 43 deletions
@@ -32,14 +32,14 @@ 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_Error_error_code = ProtoField.new('error_code', 'Solec.Error.error_code', ftypes.BYTES) +table.insert(proto.fields, Solec_Error_error_code) 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' @@ -49,18 +49,23 @@ function proto.dissector(tvb, pinfo, root) end -- --- SOLEC protocol uses big endian encoding. Frames uses type-length-value format. +-- SOLEC protocol. -- 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, +Solec.PayloadType = enum.Enum { + success = 1, + error = 2, + handshake = 3, + auth = 4, + message = 5, test = 255, } +Solec.ErrorType = enum.Enum { + auth_failed = 1, +} + function Solec:_init(io, tree, parent, root) KaitaiStruct._init(self, io) self._parent = parent @@ -71,43 +76,49 @@ end function Solec:_read() local _offset = self._io:pos() - self.type_payload = Solec.Type(self._io:read_u1()) + self.type_payload = Solec.PayloadType(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 + if _on == Solec.PayloadType.auth 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.payload = Solec.Auth(_io, _tree, self, self._root) + elseif _on == Solec.PayloadType.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.Ping(_io, _tree, self, self._root) - elseif _on == Solec.Type.pong then + self.payload = Solec.Handshake(_io, _tree, self, self._root) + elseif _on == Solec.PayloadType.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.Pong(_io, _tree, self, self._root) - elseif _on == Solec.Type.test then + self.payload = Solec.Test(_io, _tree, self, self._root) + elseif _on == Solec.PayloadType.error 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.payload = Solec.Error(_io, _tree, self, self._root) + elseif _on == Solec.PayloadType.success 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) + self.payload = Solec.Success(_io, _tree, self, self._root) + elseif _on == Solec.PayloadType.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) else self.payload = self._io:read_bytes(self.len_payload) end @@ -158,6 +169,22 @@ end -- +-- Send from server if operation succeded. +Solec.Success = class.class(KaitaiStruct) + +function Solec.Success:_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.Success:_read() +end + + +-- -- Binary data of unspecifed type. Solec.Binary = class.class(KaitaiStruct) @@ -179,6 +206,28 @@ function Solec.Binary:_read() end +Solec.Auth = class.class(KaitaiStruct) + +function Solec.Auth:_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.Auth:_read() + local _offset = self._io:pos() + local _tree = self._tree:add(self._io._io.tvb(_offset, 0), 'name') + self.name = 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), 'pass') + self.pass = Solec.String(self._io, _tree, self, self._root) + _tree:set_len(self._io:pos() - _offset) +end + + -- -- UTF-8 encoded string. Solec.String = class.class(KaitaiStruct) @@ -202,10 +251,10 @@ end -- --- Ping does not contain any payload. -Solec.Ping = class.class(KaitaiStruct) +-- Senf from server if operation failed. +Solec.Error = class.class(KaitaiStruct) -function Solec.Ping:_init(io, tree, parent, root) +function Solec.Error:_init(io, tree, parent, root) KaitaiStruct._init(self, io) self._parent = parent self._root = root or self @@ -213,7 +262,10 @@ function Solec.Ping:_init(io, tree, parent, root) self:_read() end -function Solec.Ping:_read() +function Solec.Error:_read() + local _offset = self._io:pos() + self.error_code = Solec.ErrorType(self._io:read_u1()) + self._tree:add(Solec_Error_error_code, self._io._io.tvb(_offset, self._io:pos() - _offset), self.error_code) end @@ -274,25 +326,5 @@ 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) |
