traintastic/utils/wireshark/traintastic.lua
2019-11-01 21:35:54 +01:00

112 Zeilen
3.3 KiB
Lua

--[[
Traintastic protocol dissector for WireShark
Copyright (c) 2019 Reinder Feenstra
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
]]
local default_settings =
{
port = 5740
}
local traintastic = Proto("traintastic", "Traintastic protocol")
local commands = {
[0] = "Invalid",
[1] = "Ping",
[2] = "Login",
[3] = "NewSession",
-- [4] = "RestoreSession",
-- [5] = "NewWorld",
-- [6] = "GetWorldList",
-- [7] = "LoadWorld",
-- [8] = "SaveWorld",
-- [9] = "ImportWorld",
-- [10] = "ExportWorld",
-- [11] = "CreateObject",
-- [12] = "DeleteObject",
-- [13] = "IsObject",
[14] = "GetObject",
-- [15] = "ReleaseObject",
-- [16] = "SetProperty",
-- [17] = "PropertyChanged",
[18] = "GetView",
[255] = "Discover",
}
local flag_types = {
[1] = "Request",
[2] = "Response",
[3] = "Event",
}
local pf_command = ProtoField.uint8("traintastic.command", "Command", base.HEX, commands)
local pf_type = ProtoField.uint8("traintastic.flags.type", "Type", base.DEC, flag_types, 0xc0)
local pf_errorcode = ProtoField.uint8("traintastic.error_code", "Error code", base.DEC, nil, 0x3f)
local pf_requestid = ProtoField.uint16("traintastic.request_id", "Request id")
local pf_datasize = ProtoField.uint32("traintastic.data_size", "Data size")
local pf_data = ProtoField.bytes("traintastic.data", "Data")
traintastic.fields = {
pf_command,
pf_type,
pf_errorcode,
pf_requestid,
pf_datasize,
pf_data,
}
traintastic.prefs.port = Pref.uint("Port number", default_settings.port, "The TCP/UDP port number for Traintastic protocol")
function traintastic.prefs_changed()
if default_settings.port ~= traintastic.prefs.port then
if default_settings.port ~= 0 then
DissectorTable.get("tcp.port"):remove(default_settings.port, traintastic)
end
default_settings.port = traintastic.prefs.port
if default_settings.port ~= 0 then
DissectorTable.get("tcp.port"):add(default_settings.port, traintastic)
end
end
end
local TRAINTASTIC_HDR_LEN = 8
function traintastic.dissector(tvbuf, pktinfo, root)
pktinfo.cols.protocol:set("Traintastic")
while tvbuf:reported_length_remaining() >= TRAINTASTIC_HDR_LEN do
local data_size = tvbuf:range(4, 4)
local tree = root:add(traintastic, tvbuf:range(0, TRAINTASTIC_HDR_LEN + data_size:le_uint()))
tree:add_le(pf_command, tvbuf:range(0, 1))
local flags = tvbuf:range(1, 1)
tree:add(pf_type, flags)
tree:add(pf_errorcode, flags)
tree:add_le(pf_requestid, tvbuf:range(2, 2))
tree:add_le(pf_datasize, data_size)
tvbuf = tvbuf:range(TRAINTASTIC_HDR_LEN + data_size:le_uint()):tvb()
end
end
DissectorTable.get("tcp.port"):add(default_settings.port, traintastic)
DissectorTable.get("udp.port"):add(default_settings.port, traintastic)