#51 send serialized data to properly MAC

This commit is contained in:
Mikayla Fischler
2023-06-27 18:36:16 -04:00
parent fb3c7ded06
commit a8071db08e
5 changed files with 144 additions and 48 deletions

View File

@@ -149,7 +149,6 @@ function comms.scada_packet()
dest_addr = comms.BROADCAST,
seq_num = -1,
protocol = PROTOCOL.SCADA_MGMT,
mac = "",
length = 0,
payload = {}
}
@@ -170,7 +169,7 @@ function comms.scada_packet()
self.protocol = protocol
self.length = #payload
self.payload = payload
self.raw = { self.src_addr, self.dest_addr, self.seq_num, self.protocol, self.mac, self.payload }
self.raw = { self.src_addr, self.dest_addr, self.seq_num, self.protocol, self.payload }
end
-- parse in a modem message as a SCADA packet
@@ -198,24 +197,22 @@ function comms.scada_packet()
-- log.debug("comms.scada_packet.receive(): discarding packet with distance " .. distance .. " outside of trusted range")
else
if type(self.raw) == "table" then
if #self.raw == 6 then
if #self.raw == 5 then
self.src_addr = self.raw[1]
self.dest_addr = self.raw[2]
self.seq_num = self.raw[3]
self.protocol = self.raw[4]
self.mac = self.raw[5]
-- element 6 must be a table
if type(self.raw[6]) == "table" then
self.length = #self.raw[6]
self.payload = self.raw[6]
-- element 5 must be a table
if type(self.raw[5]) == "table" then
self.length = #self.raw[5]
self.payload = self.raw[5]
end
else
self.src_addr = nil
self.dest_addr = nil
self.seq_num = nil
self.protocol = nil
self.mac = ""
self.length = 0
self.payload = {}
end
@@ -228,7 +225,6 @@ function comms.scada_packet()
type(self.dest_addr) == "number" and
type(self.seq_num) == "number" and
type(self.protocol) == "number" and
type(self.mac) == "string" and
type(self.payload) == "table"
end
end
@@ -236,20 +232,12 @@ function comms.scada_packet()
return self.valid
end
-- set message authentication code
function public.set_mac(code)
self.mac = code
self.raw = { self.src_addr, self.dest_addr, self.seq_num, self.protocol, self.mac, self.payload }
end
-- public accessors --
---@nodiscard
function public.modem_event() return self.modem_msg_in end
---@nodiscard
function public.raw_sendable() return self.raw end
---@nodiscard
function public.raw_verifiable() return { self.src_addr, self.dest_addr, self.seq_num, self.protocol, "", self.payload } end
---@nodiscard
function public.local_channel() return self.modem_msg_in.s_channel end
@@ -268,8 +256,6 @@ function comms.scada_packet()
---@nodiscard
function public.protocol() return self.protocol end
---@nodiscard
function public.mac() return self.mac end
---@nodiscard
function public.length() return self.length end
---@nodiscard
function public.data() return self.payload end
@@ -277,6 +263,112 @@ function comms.scada_packet()
return public
end
-- authenticated SCADA packet object
---@nodiscard
function comms.authd_packet()
local self = {
modem_msg_in = nil, ---@type modem_message|nil
valid = false,
raw = {},
src_addr = comms.BROADCAST,
dest_addr = comms.BROADCAST,
mac = "",
payload = ""
}
---@class authd_packet
local public = {}
-- make an authenticated SCADA packet
---@param s_packet scada_packet scada packet to authenticate
---@param mac function message authentication function
function public.make(s_packet, mac)
self.valid = true
self.src_addr = s_packet.src_addr()
self.dest_addr = s_packet.dest_addr()
self.payload = textutils.serialize(s_packet.raw_sendable(), { allow_repetitions = true, compact = true })
self.mac = mac(self.payload)
self.raw = { self.src_addr, self.dest_addr, self.mac, self.payload }
end
-- parse in a modem message as an authenticated SCADA packet
---@param side string modem side
---@param sender integer sender channel
---@param reply_to integer reply channel
---@param message any message body
---@param distance integer transmission distance
---@return boolean valid valid message received
function public.receive(side, sender, reply_to, message, distance)
---@class modem_message
self.modem_msg_in = {
iface = side,
s_channel = sender,
r_channel = reply_to,
msg = message,
dist = distance
}
self.valid = false
self.raw = self.modem_msg_in.msg
if (type(max_distance) == "number") and (distance > max_distance) then
-- outside of maximum allowable transmission distance
-- log.debug("comms.authd_packet.receive(): discarding packet with distance " .. distance .. " outside of trusted range")
else
if type(self.raw) == "table" then
if #self.raw == 4 then
self.src_addr = self.raw[1]
self.dest_addr = self.raw[2]
self.mac = self.raw[3]
self.payload = self.raw[4]
else
self.src_addr = nil
self.dest_addr = nil
self.mac = ""
self.payload = ""
end
-- check if this packet is destined for this device
local is_destination = (self.dest_addr == comms.BROADCAST) or (self.dest_addr == COMPUTER_ID)
self.valid = is_destination and
type(self.src_addr) == "number" and
type(self.dest_addr) == "number" and
type(self.mac) == "string" and
type(self.payload) == "string"
end
end
return self.valid
end
-- public accessors --
---@nodiscard
function public.modem_event() return self.modem_msg_in end
---@nodiscard
function public.raw_sendable() return self.raw end
---@nodiscard
function public.local_channel() return self.modem_msg_in.s_channel end
---@nodiscard
function public.remote_channel() return self.modem_msg_in.r_channel end
---@nodiscard
function public.is_valid() return self.valid end
---@nodiscard
function public.src_addr() return self.src_addr end
---@nodiscard
function public.dest_addr() return self.dest_addr end
---@nodiscard
function public.mac() return self.mac end
---@nodiscard
function public.data() return self.payload end
return public
end
-- MODBUS packet<br>
-- modeled after MODBUS TCP packet
---@nodiscard