Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --Variables
- local networkDeviceSide = "left" --Change this to where network device is
- deviceType = "terminal"
- ipAddress = {-1,-1,-1}
- routerID = -1 --The computer ID of the router, allowing for responses to be returned
- message = {}
- packet = {}
- localFunctions = {}
- logs = {} --Saves what would normally be printed to the console
- commandLog = {} --Saves all the run commands
- version = "1.2"
- waitingForCommand = true
- --[[
- All data packets have a set structure made of four sections
- First Section - IP Address of target system
- Second Section - IP Address of sending system
- Third Section - Type of packet being sent (what protocol does packet follow)
- Fourth Section - The main data the packet is transporting
- For testing, the IP address will be the same as the device ID.
- In the future this will be changed to allow for proper routing and
- security measures.
- The protocol the packet follows is a string in all caps
- (CDP,ERP,DRP,UPP,etc) to allow for universal understanding (and style)
- An IP address of 0 for the target system means that the packet is for
- the router to work with. Trying to assign a different device this IP will fail
- as the router will intercept all packets with that IP.
- --]]
- local function printToLog(printed)
- --Add a string to the log
- table.insert(logs,printed)
- end
- local function sendPacket (
- targetIP, --table
- protocol, --String
- data --Any
- )
- --[[
- This function sends a packet to an IP address in the network.
- Each packet needs to follow the rules of packet construction.
- If the target IP is 0 then the packet will be sent to the default router.
- If the sending IP is -1 then that means the IP hasn't been set yet
- and will need to be to recieve packets from devices other than the router.
- --]]
- --Checking if there is a default router to send packet to, otherwise skip all code
- if routerID == -1 then
- printToLog("Default router not set")
- goto skip
- end
- --Checking if packet components have the right data types, otherwise skip all code
- if not (type(targetIP) == "table") or not (type(protocol) == "string") then
- printToLog("Improperly formatted packet")
- goto skip
- end
- --Packet construction
- local packet = {
- targetIP,
- ipAddress,
- protocol,
- data
- }
- --Sending packet
- printToLog(targetIP[1].."."..targetIP[2].."."..targetIP[3] .. " " .. ipAddress[1].."."..ipAddress[2].."."..ipAddress[3] .. " " .. protocol .. " " .. data)
- rednet.send(routerID,packet)
- ::skip::
- end
- local function responseRDP ()
- --[[
- Router Discovery Protocol
- Used by a router to discover other routers and build up a internetwork routing table.
- After recieving a routing table, start adding it to router routing table
- Routing table info:
- 1 - IP of router
- 2 - ID of next hop
- 3 - IP of next hop? (for future tracert)
- 4 - Number of hops to IP (To find shortest route)
- Routers will not have themselves on their own routing tables
- --]]
- end
- local function responseCDP ()
- --[[
- Computer Discovery Protocol
- Used by a router to discover devices on the network then assign them IP addresses
- and set itself as the device's default router. Devices already with an IP and
- default router do not respond to CDP packets to avoid confusion on the side of
- the router.
- --]]
- --If the device already has an IP and assigned Router then skip all code
- if not (ipAddress == -1) and not (routerID == -1) then goto skip end
- printToLog(routerID)
- --Sets the device's default router to the device ID that sent the packet
- routerID = message[1]
- printToLog(routerID)
- --Send CDP packet to router (IP 0) with the ID of the device
- sendPacket({0,0,0},"CDP",os.getComputerID())
- --An IP packet should be sent in the near future to this device to assign IP
- ::skip::
- end
- local function responseERP ()
- --[[
- Echo Request Protocol is used to see if an IP address is responding.
- Sending an ERP packet will cause the device to send a return packet back to the
- source device.
- --]]
- if packet[4] == "Ping" then
- sendPacket(packet[2],"ERP","pong")
- else
- print("Response from "..packet[2][1].."."..packet[2][2].."."..packet[2][3])
- end
- end
- local function responseDRP ()
- --Device Request Protocol
- if type(packet[4]) == "table" then
- for index = 1, #packet[4], 1 do
- print(packet[4][index][1].." "..packet[4][index][2])
- end
- end
- end
- local function responseUPP ()
- --Unknown Packet Protocol
- end
- local function responseIP ()
- --[[
- Internet Protocol
- Used by router to give a device an IP address. Will only be accepted if the
- router is the default router the device knows. If the default router is
- unassigned then the IP packet is dropped. The data on the packet should
- be a number.
- --]]
- --Checking if routerID is assigned
- printToLog(routerID)
- if routerID == -1 then goto skip end
- --Checking if routerID is the same as the message sender
- if not (routerID == message[1]) then goto skip end
- --Setting the IP of the device to the one sent by the router
- ipAddress = packet[4]
- --Sending IP packet with the device type to the router
- sendPacket({0,0,0},"IP",deviceType)
- ::skip::
- end
- local function responseDP ()
- --Data Packet
- if type(packet[4]) == "string" then
- printToLog("DP packet: "..packet[4])
- elseif type(packet[4]) == "table" then
- local tempString = ""
- for index = 1, #packet[4], 1 do
- tempString = tempString .. packet[4][index]
- end
- printToLog("DP packet: "..tempString)
- end
- end
- local function responseAP ()
- --Acknowledgement Packet
- end
- local function stripString(inputString, splitChar)
- --[[
- Takes in a string, removes all characters that match the
- splitChar, and outputs a table of strings from where the
- splitChar was.
- --]]
- local outputTable = {}
- local tempString = ""
- if not type(inputString) == "string" then
- print("stripString: input not string")
- goto skip
- end
- for index = 1, #inputString, 1 do
- if string.sub(inputString,index,index) == splitChar then
- table.insert(outputTable,tempString)
- tempString = ""
- goto continue
- end
- tempString = tempString .. string.sub(inputString,index,index)
- ::continue::
- end
- table.insert(outputTable,tempString)
- ::skip::
- return outputTable
- end
- local function commandLine()
- --[[
- The Command Line Interface allows a user to run commands on this
- system. This can include sending pings to other systems, sending
- custom packages to other systems, seeing rednet logs, etc.
- Currently all commands are network based, but others may be made
- later.
- --]]
- local command = read()
- --print(command)
- local commandTable = stripString(command," ")
- command = table.remove(commandTable,1)
- --Setting the command string to all uppercase
- command = string.upper(command)
- --print("command"..command)
- if localFunctions["command"..command] then
- --If protocol exists
- table.insert(commandLog,{command,commandTable})
- localFunctions["command"..command](commandTable)
- --table.insert(dataQueue,packet)
- else
- print("Unrecognized command")
- end
- waitingForCommand = false
- end
- local function commandPRINTLOGS (options)
- --[[
- Prints out the log to the console
- --]]
- for index = 1, #logs, 1 do
- print(logs[index])
- end
- end
- local function commandPING (options)
- --[[
- Uses ERP/ICMP to send a ping message to target IP.
- --]]
- --print(#options)
- tempIP = stripString(options[1],".")
- if not (#tempIP == 3) then goto skip end
- options[1] = {tonumber(tempIP[1]),tonumber(tempIP[2]),tonumber(tempIP[3])}
- if options then
- --For right now, first option is just IP address for Ping
- sendPacket(options[1],"ERP","Ping")
- else
- print([[
- Weh
- ]])
- end
- ::skip::
- end
- local function commandIPCONFIG (options)
- --[[
- Prints all network related information
- --]]
- print("Device type: "..deviceType.."\n".."IP address: "..ipAddress[1].."."..ipAddress[2].."."..ipAddress[3].."\n".."Router ID: "..routerID)
- end
- local function commandHELP (options)
- print("Ping <IP address>, PrintLogs, IPconfig, Packet <TargetIP> <Protocol> <Data>")
- end
- local function commandPACKET (options)
- --Makes a custom packet to send to an IP
- local tempIP = stripString(options[1],".")
- local tempString = ""
- if not (#options >= 3) then goto skip end
- if not (#tempIP == 3) then goto skip end
- options[1] = {tonumber(tempIP[1]),tonumber(tempIP[2]),tonumber(tempIP[3])}
- if not ((type(options[1]) == "table") and (type(options[2]) == "string")) then goto skip end
- if not (options[1][1] < 0) then
- if #options > 3 then
- for index = 3, #options, 1 do
- tempString = tempString.." "..options[index]
- end
- else
- tempString = options[3]
- end
- sendPacket(options[1],options[2],tempString)
- else
- rednet.broadcast({options[1],ipAddress,options[2],options[3]})
- end
- ::skip::
- end
- local function responseNetwork()
- while waitingForCommand do
- --[[
- Listens for rednet messages and runs responses
- --]]
- --printToLog("Ready to recieve message")
- --Wait until rednet message recieved
- message = {rednet.receive(1)}
- --Pulling out the packet inside of the message
- packet = (message[2])
- if not packet then goto continue end
- --Checking if packet is properly formatted, if it is not then drop packet and continue loop
- if #packet < 4 then goto continue end
- if packet[3] == "RDP" then goto continue end
- if not (packet[3] == "CDP") then
- printToLog("Packet Type: " .. packet[3])
- end
- if localFunctions["response"..packet[3]] then
- --If protocol exists
- if not (packet[3] == "CDP") then
- printToLog("Running response "..packet[3])
- end
- localFunctions["response"..packet[3]]()
- --table.insert(dataQueue,packet)
- else
- --Send UPP packet to source device if protocol is unknown
- printToLog("Unknown")
- sendPacket(packet[1],"UPP","Unknown Packet Type: "..packet[3])
- end
- --]]
- ::continue::
- --End of cycle upkeep
- --Resetting last received message and packet back to their default states
- message = {}
- packet = {}
- end
- waitingForCommand = true
- end
- function mainLoop ()
- --This function runs continuously and allows the device to respond to requests and packets
- while true do
- parallel.waitForAll(responseNetwork,commandLine)
- end
- end
- --Finding all of the local functions and storing them
- index = 1
- while true do
- key, data = debug.getlocal(1,index)
- if not key then break end
- --(key)
- if type(data) == "function" then
- if debug.getinfo(data, "S").what == "Lua" then
- localFunctions[key] = data
- end
- end
- index = index + 1
- end
- --Turning on the network capabilities of the device
- peripheralNames = peripheral.getNames()
- for i = 1, #peripheralNames, 1 do
- if peripheral.hasType(peripheralNames[i],"modem") then
- rednet.open(peripheralNames[i])
- end
- end
- --Calling the mainLoop to start program
- print("Starting Command Line Interface")
- print("Terminal version: "..version)
- print("To find out more about commands type: 'help'")
- mainLoop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement