diff options
| author | bt <bt@rctt.net> | 2026-03-10 22:50:53 +0100 |
|---|---|---|
| committer | bt <bt@rctt.net> | 2026-03-10 22:53:32 +0100 |
| commit | 7cdd5c04d5e966b3c90a3d86720e0823b4f7ee2c (patch) | |
| tree | 2da446610bed492542c1c3fe31145fcc1ca82081 /solec.lua | |
| parent | 69192d956aa2b6b3dbf87bac0e265e718b49dd70 (diff) | |
| download | solec-7cdd5c04d5e966b3c90a3d86720e0823b4f7ee2c.tar.gz solec-7cdd5c04d5e966b3c90a3d86720e0823b4f7ee2c.zip | |
Update spec
Diffstat (limited to 'solec.lua')
| -rw-r--r-- | solec.lua | 111 |
1 files changed, 89 insertions, 22 deletions
@@ -9,10 +9,10 @@ require("kaitaistruct") local proto = Proto('solec', 'Solec') proto.fields = {} local enum = require("enum") -local Solec_payload_type = ProtoField.new('payload_type', 'Solec.payload_type', ftypes.BYTES) -table.insert(proto.fields, Solec_payload_type) -local Solec_payload_length = ProtoField.new('payload_length', 'Solec.payload_length', ftypes.UINT32) -table.insert(proto.fields, Solec_payload_length) +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) @@ -36,6 +36,8 @@ local Solec_Handshake_proto_ver_major = ProtoField.new('proto_ver_major', 'Solec 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) @@ -46,6 +48,9 @@ function proto.dissector(tvb, pinfo, root) 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 { @@ -66,29 +71,45 @@ end function Solec:_read() local _offset = self._io:pos() - self.payload_type = Solec.Type(self._io:read_u1()) - self._tree:add(Solec_payload_type, self._io._io.tvb(_offset, self._io:pos() - _offset)) + 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.payload_length = self._io:read_u2be() - self._tree:add(Solec_payload_length, self._io._io.tvb(_offset, self._io:pos() - _offset), self.payload_length) + 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.payload_type - if _on == Solec.Type.handshake then - local _tree = self._tree:add(self._io._io.tvb(_offset, 0), 'payload') - self.payload = Solec.Handshake(self._io, _tree, self, self._root) - _tree:set_len(self._io:pos() - _offset) + 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 - local _tree = self._tree:add(self._io._io.tvb(_offset, 0), 'payload') - self.payload = Solec.Ping(self._io, _tree, self, self._root) - _tree:set_len(self._io:pos() - _offset) + 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 - local _tree = self._tree:add(self._io._io.tvb(_offset, 0), 'payload') - self.payload = Solec.Pong(self._io, _tree, self, self._root) - _tree:set_len(self._io:pos() - _offset) + 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 - local _tree = self._tree:add(self._io._io.tvb(_offset, 0), 'payload') - self.payload = Solec.Test(self._io, _tree, self, self._root) - _tree:set_len(self._io:pos() - _offset) + 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 @@ -136,6 +157,8 @@ function Solec.Test:_read() end +-- +-- Binary data of unspecifed type. Solec.Binary = class.class(KaitaiStruct) function Solec.Binary:_init(io, tree, parent, root) @@ -156,6 +179,8 @@ function Solec.Binary:_read() end +-- +-- UTF-8 encoded string. Solec.String = class.class(KaitaiStruct) function Solec.String:_init(io, tree, parent, root) @@ -176,6 +201,8 @@ function Solec.String:_read() end +-- +-- Ping does not contain any payload. Solec.Ping = class.class(KaitaiStruct) function Solec.Ping:_init(io, tree, parent, root) @@ -190,6 +217,10 @@ 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) @@ -210,6 +241,39 @@ function Solec.Handshake:_read() 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) @@ -226,6 +290,9 @@ function Solec.Pong:_read() 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) |
