This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
darkrising's profile picture

Rednet Computer ID / spoof id?

Started by darkrising, 01 January 2013 - 01:56 AM
darkrising #1
Posted 01 January 2013 - 02:56 AM
Hello, I've been playing with Immibis's Peripherals's Lan Cables and noticed a useful function that you are able to "spoof" computer ids, this can be incredibly useful when it comes to making routers and other things.

My question: is it possible to do the same with rednet?

I've been looking through the rednet api but I'm not sure which bit relates to the sender Id. Instead of rednet.send(<id> <message>) I would like to change it (if possible) to rednet.send(<id> <message> <spoof id>), this might invalid some security programs (like my own) but the feature would be nice to have.
zekesonxx #2
Posted 01 January 2013 - 03:23 AM
That would be a giant security flaw. Unless you're using some kind of pre-instated routing network, it's also impossible with vanilla CC.
darkrising #3
Posted 01 January 2013 - 03:46 AM
After looking through /rom/apis/rednet I've noticed a few things:

looks like the rednet modem bridges bundled cables, i never knew that.

I'm still trying to find the computer id part.

edit: I just found the computer id part… *herp derp*

/rom/apis/rednet
Spoiler

local tOpen = {}
local tBusy = {}
local tRoutes = {}
local tPortPeripheral = {}
local tValid = { left = true, right = true, top = true, bottom = true, front = true, back = true }

local function portSleep( sPort, _nTime )
if not tOpen[sPort] then
return
end

local t = os.startTimer( _nTime )
repeat
local e,p = os.pullEventRaw()
if e == "close" then
tOpen[sPort] = nil
return
end
until e == "timer" and p == t
end

local function isPortBusy( sPort )
return tBusy[sPort] or rs.getBundledInput( sPort ) ~= 0
end

local function sendOnPort( sPort, nClockRate, nRecipient, sMessage, nTimeout )

-- Use peripheral if present
local peripheral = tPortPeripheral[ sPort ]
if peripheral ~= nil then
if nRecipient ~= nil then
peripheral.send( nRecipient, sMessage )
else
peripheral.broadcast( sMessage )
end
return true
end

-- Else, use redstone
local nSleep = 1 / nClockRate

-- Offer some data
if nRecipient ~= nil then
rs.setBundledOutput( sPort, colors.black + (nRecipient + 1))
else
rs.setBundledOutput( sPort, colors.black + 0 )
end

-- Wait for "data accepted"
local timer = nil
if nTimeout ~= nil then
timer = os.startTimer( nTimeout )
end
while not rs.testBundledInput( sPort, colors.red ) do
local event, p1 = os.pullEventRaw()
if event == "close" or
  event == "timer" and p1 == timer then
rs.setBundledOutput( sPort, 0 )
if nRecipient ~= nil and tRoutes[nRecipient] == sPort then
tRoutes[nRecipient] = nil
end
return false
end
end

-- Remember that we can receive from this nRecipient on this port
if nRecipient ~= nil then
tRoutes[nRecipient] = sPort
end

-- Start sending the data
rs.setBundledOutput( sPort, colors.black + 0 )
portSleep( sPort, nSleep * 2 )

local lastData = nil
local function sendData( data )
if data == lastData then
-- Send a blank packet so the receiver sees a change
rs.setBundledOutput( sPort, colors.black + 0 )
portSleep( sPort, nSleep)
end
lastData = data

-- Send the data
rs.setBundledOutput( sPort, colors.black + data )
portSleep( sPort, nSleep)
end

-- Send our ID first
sendData( os.computerID() + 1 )

-- Then send the message
local pendingData = nil
for n=1,string.len( sMessage ) do
-- Check for receiver disconnect
if not tOpen[sPort] or not rs.testBundledInput( sPort, colors.red ) then
rs.setBundledOutput( sPort, 0 )
return false
end

-- Build the packet
local data = string.byte( sMessage, n )
if data < 128 then
if pendingData == nil then
pendingData = data
else
data = bit.blshift(data, 7) + pendingData
pendingData = nil
sendData( data )
end
end
end
if pendingData ~= nil then
sendData( pendingData )
end

-- We're done
rs.setBundledOutput( sPort, 0 )
return true
end

local function queryData( sPort )
-- Use peripheral if present
local peripheral = tPortPeripheral[ sPort ]
if peripheral ~= nil then
return false
end

if rs.testBundledInput( sPort, colors.black) then
local wire = rs.getBundledInput( sPort )
local id = colors.subtract( wire, colors.black, colors.red )
if id == 0 or id == (os.computerID() + 1) then
return true
end
end
return false
end

local function receiveOnPort( sPort )
-- Send data accepted
rs.setBundledOutput( sPort, colors.red )

local function readData()
local back = rs.getBundledInput( sPort )
return colors.subtract( back, colors.black, colors.red )
end

-- Wait for a zero before starting
local lastData = nil
while lastData ~= 0 do
lastData = readData()
if lastData ~= 0 then
os.pullEventRaw( "redstone" )
end
end

-- Read the senders ID
local nSender = nil
while nSender == nil do
local data = readData()
if data ~= lastData then
nSender = data - 1
lastData = data
else
os.pullEventRaw( "redstone" )
end
end

-- Remember that we can receive from this sender on this port
tRoutes[nSender] = sPort

-- Pull in the damn data
local nStartTime = os.clock()
local sText = ""
while tOpen[sPort] and rs.testBundledInput( sPort, colors.black ) do
local data = readData()
if data ~= lastData then
if data > 0 then
local function getByte( byte )
if byte > 0 then
local char = string.char(byte)
sText = sText..char
end
end

getByte( bit.band( data, 127 ) )
getByte( bit.band( bit.brshift(data, 7), 127 ) )
end
lastData = data
end

local e = os.pullEventRaw()
if e == "close" then
tOpen[sPort] = false
end
end

-- We're done
local nBitRate = (string.len(sText)) / (os.clock() - nStartTime)
rs.setBundledOutput( sPort, 0 )

if tOpen[sPort] then
return true, nSender, sText
end
return false
end

local function runPort( sPort, nClockRate )
-- Open the port
tOpen[sPort] = true
rs.setBundledOutput( sPort, 0 )

-- Locate peripheral
local function findPeriph()
local sPeriph = peripheral.getType( sPort )
if sPeriph == "modem" then
tPortPeripheral[sPort] = peripheral.wrap( sPort )
tPortPeripheral[sPort].open()
else
tPortPeripheral[sPort] = nil
end
end
findPeriph()

-- Run the port until it's closed
while tOpen[sPort] do
local event, p1, p2, p3, p4 = os.pullEventRaw()
if event == "close" then
-- Close the port
if tPortPeripheral[sPort] ~= nil then
tPortPeripheral[sPort].close()
tPortPeripheral[sPort] = nil
end
tOpen[sPort] = nil

elseif event == "peripheral" or event == "peripheral_detach" then
findPeriph()

elseif event == "send" then
-- Send some text
local nRecipient = p2
local sMessage = p3

tBusy[ sPort ] = true
local success = sendOnPort( sPort, nClockRate, nRecipient, sMessage, 2 )
if success then
-- something?
end
tBusy[ sPort ] = false

else
-- See if there's anything to receive
if queryData( sPort ) then
tBusy[ sPort ] = true
local success, nSender, sMessage = receiveOnPort( sPort )
if success and string.len(sMessage) > 0 and nSender ~= os.computerID() then
os.queueEvent( "rednet_message", nSender, sMessage )
end
tBusy[ sPort ] = false
end

end
end
end

local runRoutine = nil

function run()
if runRoutine ~= nil then
error( "rednet is already running" )
end
local c = coroutine.running()
runRoutine = function( ... )
local ok, p = coroutine.resume( c, ... )
if not ok then
error( p )
end
end
bFinish = false

local portRoutines = {}
while true do
local e, p1, p2, p3, p4, p5 = os.pullEventRaw()
if e == "timer" or e == "redstone" then
for n,portRoutine in pairs( portRoutines ) do
portRoutine( e, p1, p2, p3, p4, p5 )
end
elseif e == "open" then
local sSide = p1
if portRoutines[sSide] == nil then
local nClockRate = p2
portRoutines[sSide] = coroutine.wrap( function()
runPort( sSide, nClockRate )
portRoutines[sSide] = nil
end )
portRoutines[sSide]()
end
elseif e == "close" or e == "send" or
	  e == "peripheral" or e == "peripheral_detach" then
local sSide = p1
if portRoutines[sSide] then
portRoutines[sSide]( e, p1, p2, p3, p4, p5 )
end
end
end

runRoutine = nil
end

function open( sSide, nClockRate )
if type( sSide ) ~= "string" then
error( "string expected" )
end
if not tValid[sSide] then
error( "Invalid side" )
end
nClockRate = math.min( nClockRate or 15, 25 )
if type( nClockRate ) ~= "number" or nClockRate <= 0 then
error( "positive number expected" )
end
runRoutine( "open", sSide, nClockRate )
end

function close( sSide )
if type( sSide ) ~= "string" then
error( "string expected" )
end
if not tValid[sSide] then
error( "Invalid side" )
end
runRoutine( "close", sSide )
end

function isOpen( sSide )
if type( sSide ) ~= "string" then
error( "string expected" )
end
if not tValid[sSide] then
error( "Invalid side" )
end
return tOpen[sSide]
end

function send( nRecipient, sMessage, bWaitUntilPortOpen )
if nRecipient ~= nil and (type( nRecipient ) ~= "number" or nRecipient < 0) then
error( "positive number expected" )
end
if type( sMessage ) ~= "string" then
error( "string expected" )
end

local function send()
local sSide = nil
if nRecipient ~= nil then
sSide = tRoutes[nRecipient]
end

-- Offer on the known route first
if sSide then
if tOpen[sSide] and not isPortBusy( sSide ) then
runRoutine( "send", sSide, nRecipient, sMessage )
return true
end
end

-- Else, broadcast on all ports
local nPorts = 0
for n,sSide in ipairs( redstone.getSides() ) do
if tOpen[sSide] and not isPortBusy( sSide ) then
runRoutine( "send", sSide, nRecipient, sMessage )
nPorts = nPorts + 1
end
end
return (nPorts > 0)
end

if bWaitUntilPortOpen then
while not send() do
os.pullEvent( "redstone" )
end
return true
else
return send()
end
end

function broadcast( sMessage, bWaitUntilPortOpen )
return send( nil, sMessage )
end

function announce( bWaitUntilPortOpen )
return broadcast( "" )
end

function receive( nTimeout )
local timer = nil
local sEvent = "rednet_message"
if nTimeout then
timer = os.startTimer( nTimeout )
sEvent = nil
end
while true do
local e, p1, p2, p3 = os.pullEvent( sEvent )
if e == "rednet_message" then
return p1, p2, p3
elseif e == "timer" and p1 == timer then
return nil, nil, nil
end
end
end
PixelToast #4
Posted 01 January 2013 - 03:52 AM
as far as i know its only possible to spoof / sniff a bundled cable
and on modems its impossible
darkrising #5
Posted 01 January 2013 - 04:00 AM
After thinking about it more, the messages going through a router would have to include the id as the receiving wireless computer couldn't send a message back unless it knew the id of the router,

But still, I've learned a few things today :)/>