diff --git a/src/main/resources/assets/opencomputers/loot/Network/data/bin/arp.lua b/src/main/resources/assets/opencomputers/loot/Network/data/bin/arp.lua new file mode 100644 index 000000000..1da4adad7 --- /dev/null +++ b/src/main/resources/assets/opencomputers/loot/Network/data/bin/arp.lua @@ -0,0 +1,26 @@ +local network = require "network" + +local function fillText(text, n) + for k = 1, n - #text do + text = text .. " " + end + return text +end + +local maxlen = {8, 5} + +for interface in pairs(network.info.getInfo().interfaces) do + maxlen[2] = maxlen[2] < #interface+1 and #interface+1 or maxlen[2] + for _, host in ipairs(network.info.getArpTable(interface)) do + maxlen[1] = maxlen[1] < #host+1 and #host+1 or maxlen[1] + end +end + +print(fillText("Address", maxlen[1])..fillText("Iface", maxlen[2])) + +for interface in pairs(network.info.getInfo().interfaces) do + for _, host in ipairs(network.info.getArpTable(interface)) do + print(fillText(host, maxlen[1])..fillText(interface, maxlen[2])) + end +end + diff --git a/src/main/resources/assets/opencomputers/loot/Network/data/bin/ping.lua b/src/main/resources/assets/opencomputers/loot/Network/data/bin/ping.lua index 014c382b7..6ba9fc731 100644 --- a/src/main/resources/assets/opencomputers/loot/Network/data/bin/ping.lua +++ b/src/main/resources/assets/opencomputers/loot/Network/data/bin/ping.lua @@ -1,21 +1,107 @@ local network = require "network" local event = require "event" local computer = require "computer" +local shell = require "shell" -local args = {...} +local args, options = shell.parse(...) -if #args < 1 then +if #args < 1 or options.h or options.help then print("Usage: ping: [addr]") + print(" --c= --count=[ping count] Amount of pings to send(default 6)") + print(" --s= --size=[data size] Payload size(default 56 bytes)") + print(" --i= --interval=[seconds] Ping interval(default 1s)") + --print(" -d --duplicates Check for duplicate messages") + print(" --t= --droptime=[seconds] Amount of time after which ping is") + print(" Considered to be lost[default 8s]") + print(" -v --verbose Output more details") + return end -print("Pinging "..args[1].." with 16 bytes of data:") -local pingID = network.icmp.ping(args[1], "0123456789abcdef") -local start = computer.uptime() +local len = tonumber(options.s) or tonumber(options.size) or 56 -local e, replier, id, payload -repeat -e, replier, id, payload = event.pull("ping_reply") -until id == pingID +local function round(n,r) return math.floor(n*(10^r))/(10^r) end -print("Got reply in "..tostring(computer.uptime()-start).." seconds") +local function verbose(...) + if options.v or options.verbose then + print(...) + end +end + +local function generatePayload() + local payload = "" + for i = 1, len do + local ch = string.char(math.random(0, 255)) + ch = ch == ":" and "_" or ch --Ping matcher derps hard when it finds ':' in payload + payload = payload .. ch + end + return payload +end + + +print("PING "..args[1].." with "..tostring(len) .." bytes of data") + +local stats = { + transmitted = 0, + received = 0, + malformed = 0 +} + +local function doSleep() + + local deadline = computer.uptime() + (tonumber(options.i) or tonumber(options.interval) or 1) + repeat + event.pull(deadline - computer.uptime()) + until computer.uptime() >= deadline +end + +local function doPing() + + local payload = generatePayload() + local icmp_seq = network.icmp.ping(args[1], payload) + stats.transmitted = stats.transmitted + 1 + verbose(tostring(len).." bytes to "..args[1]..": icmp_seq="..tostring(icmp_seq)) + local start = computer.uptime() + + local deadline = start + (tonumber(options.t) or tonumber(options.droptime) or 8) + local e, replier, id, inpayload + repeat + e, replier, id, inpayload = event.pull(deadline - computer.uptime(), "ping_reply") + until computer.uptime() >= deadline or (e == "ping_reply" and id == icmp_seq) + + if computer.uptime() >= deadline and e ~= "ping_reply" then + verbose(tostring(len).." bytes lost: icmp_seq="..tostring(icmp_seq)) + elseif inpayload == payload then + stats.received = stats.received + 1 + print(tostring(len).." bytes from "..args[1]..": icmp_seq="..tostring(icmp_seq).." time="..tostring(round(computer.uptime()-start,2)).." s") + else + stats.malformed = stats.malformed + 1 + verbose(tostring(#inpayload).." bytes malformed: icmp_seq="..tostring(icmp_seq).." time="..tostring(round(computer.uptime()-start,2)).." s") + end +end + +local begin = computer.uptime() + +local function outputStats() + print("--- "..args[1].." ping statistics ---") + print(tostring(stats.transmitted) .. " packets transmitted, " + ..tostring(stats.received) .. " received, " + ..tostring(100 - math.floor((stats.received / stats.transmitted) * 100)) .. "% packet loss, time " .. tostring(round(computer.uptime()-begin,2))) +end + +local state, reason = pcall(function() + local c = 0 + repeat + doPing() + doSleep() + c = c + 1 + until c == 0 or (tonumber(options.c) and c >= tonumber(options.c)) + or (tonumber(options.count) and c >= tonumber(options.count)) + or ((not tonumber(options.c)) and (not tonumber(options.count)) and c >= 8) +end) + +if not state then + verbose("Stopped by: "..tostring(reason)) +end + +outputStats() diff --git a/src/main/resources/assets/opencomputers/loot/Network/data/bin/route.lua b/src/main/resources/assets/opencomputers/loot/Network/data/bin/route.lua new file mode 100644 index 000000000..dfb8189b4 --- /dev/null +++ b/src/main/resources/assets/opencomputers/loot/Network/data/bin/route.lua @@ -0,0 +1,25 @@ +local network = require "network" + +local function fillText(text, n) + for k = 1, n - #text do + text = text .. " " + end + return text +end + +print("MCNET routing table") +local routes = network.info.getRoutes() +local maxlen = {12, 8, 5} + +for host, route in pairs(routes) do + maxlen[1] = maxlen[1] < #host+1 and #host+1 or maxlen[1] + maxlen[2] = maxlen[2] < #route.router+1 and #route.router+1 or maxlen[2] + maxlen[3] = maxlen[3] < #route.interface+1 and #route.interface+1 or maxlen[3] +end + +print(fillText("Destination", maxlen[1])..fillText("Gateway", maxlen[2])..fillText("Iface", maxlen[3])) + +for host, route in pairs(routes) do + print(fillText(host, maxlen[1])..fillText(route.router, maxlen[2])..fillText(route.interface, maxlen[3])) +end + diff --git a/src/main/resources/assets/opencomputers/loot/Network/data/boot/80_network.lua b/src/main/resources/assets/opencomputers/loot/Network/data/boot/80_network.lua index d8f3d489b..99353840c 100644 --- a/src/main/resources/assets/opencomputers/loot/Network/data/boot/80_network.lua +++ b/src/main/resources/assets/opencomputers/loot/Network/data/boot/80_network.lua @@ -10,8 +10,8 @@ local startNetwork local dataHandler --Layer 2 data handler -local posix - +local accessibleHosts +local nodes ------------------------ --Layer 1 @@ -32,8 +32,8 @@ local function start() --------- - local accessibleHosts = {} - local nodes = {} + accessibleHosts = {} + nodes = {} --DRIVER INIT --print("Loading drivers") @@ -201,7 +201,7 @@ startNetwork = function() sendRoutedData(addr, data)--We know route, try to send it that way end else - --route is unknown, we have to request it if we havent did it already + --route is unknown, we have to request it if we haven't done so already if not routeRequests[addr] then routeRequests[addr] = {} routeRequests[addr][#routeRequests[addr]+1] = {type = "D", data = data} @@ -354,12 +354,32 @@ startNetwork = function() for k, node in pairs(getNodes())do res.interfaces[k] = {selfAddr = node.selfAddr, linkName = node.linkName} end + return res + end + + local function getRoutingTable() + local res = {} + for k,v in pairs (routes) do + if v.router then + res[k] = {router = v.router, interface = v.node} + end + end + return res + end + + local function getArpTable(interface) + local res = {} + for k in pairs(nodes[interface].hosts)do + table.insert(res, k) + end return res end network.core.setCallback("netstat", getInfo) network.core.setCallback("intstat", getInterfaceInfo) + network.core.setCallback("routetab", getRoutingTable) + network.core.setCallback("arptab", getArpTable) network.core.lockCore() end diff --git a/src/main/resources/assets/opencomputers/loot/Network/data/boot/95_hostname.lua b/src/main/resources/assets/opencomputers/loot/Network/data/boot/95_hostname.lua new file mode 100644 index 000000000..f966da1eb --- /dev/null +++ b/src/main/resources/assets/opencomputers/loot/Network/data/boot/95_hostname.lua @@ -0,0 +1,11 @@ +local network = require "network" +local event = require "event" + +event.listen("network_ready", function() + pcall(function() + for name in io.lines("/etc/hostname")do + network.ip.bind(name) + end + end) +end) + diff --git a/src/main/resources/assets/opencomputers/loot/Network/data/lib/network.lua b/src/main/resources/assets/opencomputers/loot/Network/data/lib/network.lua index a39d8c86b..d8d7e3b16 100644 --- a/src/main/resources/assets/opencomputers/loot/Network/data/lib/network.lua +++ b/src/main/resources/assets/opencomputers/loot/Network/data/lib/network.lua @@ -208,7 +208,10 @@ end) network.info = {} network.info.getInfo = function(...)return driver.netstat(...) end network.info.getInterfaceInfo = function(...)return driver.intstat(...) end +network.info.getRoutes = function(...)return driver.routetab(...) end +network.info.getArpTable = function(...)return driver.arptab(...) end ------------ return network +