summaryrefslogtreecommitdiffstats
path: root/solec.lua
diff options
context:
space:
mode:
Diffstat (limited to 'solec.lua')
-rw-r--r--solec.lua111
1 files changed, 89 insertions, 22 deletions
diff --git a/solec.lua b/solec.lua
index e4c8514..a06a429 100644
--- a/solec.lua
+++ b/solec.lua
@@ -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)