Update Network stack floppy

This commit is contained in:
Łukasz Magiera 2014-12-09 23:06:58 +01:00
parent df86ebdf38
commit 62ed17f6e4
6 changed files with 186 additions and 15 deletions

View File

@ -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

View File

@ -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 len = tonumber(options.s) or tonumber(options.size) or 56
local function round(n,r) return math.floor(n*(10^r))/(10^r) end
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 e, replier, id, payload
local deadline = start + (tonumber(options.t) or tonumber(options.droptime) or 8)
local e, replier, id, inpayload
repeat
e, replier, id, payload = event.pull("ping_reply")
until id == pingID
e, replier, id, inpayload = event.pull(deadline - computer.uptime(), "ping_reply")
until computer.uptime() >= deadline or (e == "ping_reply" and id == icmp_seq)
print("Got reply in "..tostring(computer.uptime()-start).." seconds")
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()

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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