block = tonumber(address:sub(borderl, borderh - 1), 16)
if block and block <= 0xFFFF then
- table.insert(data, block)
+ data[#data+1] = block
else
if zeroh or borderh - borderl > 1 then return nil end
zeroh = #data + 1
block = tonumber(chunk, 16)
if not block or block > 0xFFFF then return nil end
- table.insert(data, block)
+ data[#data+1] = block
elseif #chunk > 4 then
if #data == 7 or #chunk > 15 then return nil end
borderl = 1
if not block or block > 255 then return nil end
if i == 1 or i == 3 then
- table.insert(data, block * 256)
+ data[#data+1] = block * 256
else
data[#data] = data[#data] + block
end
for i = 1, ( len / 4 ), 4 do
local n = tonumber( hex:sub( i, i+3 ), 16 )
if n then
- table.insert( data, n )
+ data[#data+1] = n
else
return nil
end
if mask then
prefix = 0
+
local stop = false
- local obj = self:is4() and IPv4(mask) or IPv6(mask)
+ local obj = type(mask) ~= "table"
+ and ( self:is4() and IPv4(mask) or IPv6(mask) ) or mask
- if not obj then
- return nil
- end
+ if not obj then return nil end
- for i, block in ipairs(obj[2]) do
- local pos = bit.lshift(1, 15)
- for i=15, 0, -1 do
- if bit.band(block, pos) == pos then
- if not stop then
- prefix = prefix + 1
- else
- return nil
- end
- else
- stop = true
+ for _, word in ipairs(obj[2]) do
+ if word == 0xFFFF then
+ prefix = prefix + 16
+ else
+ local bitmask = bit.lshift(1, 15)
+ while bit.band(word, bitmask) == bitmask do
+ prefix = prefix + 1
+ bitmask = bit.lshift(1, 15 - (prefix % 16))
end
- pos = bit.rshift(pos, 1)
+
+ break
end
end
end
bits = bits or self[3]
for i = 1, math.floor( bits / 16 ) do
- table.insert( data, self[2][i] )
+ data[#data+1] = self[2][i]
end
if #data < #self[2] then
- table.insert( data, bit.band( self[2][1+#data], __mask16(bits) ) )
+ data[#data+1] = bit.band( self[2][1+#data], __mask16(bits) )
for i = #data + 1, #self[2] do
- table.insert( data, 0 )
+ data[#data+1] = 0
end
end
bits = bits or self[3]
for i = 1, math.floor( bits / 16 ) do
- table.insert( data, 0xFFFF )
+ data[#data+1] = 0xFFFF
end
if #data < #self[2] then
- table.insert( data, __mask16(bits) )
+ data[#data+1] = __mask16(bits)
for i = #data + 1, #self[2] do
- table.insert( data, 0 )
+ data[#data+1] = 0
end
end
return connt
end
---- Determine the current default route.
+--- Determine the current IPv4 default route. If multiple default routes exist,
+-- return the one with the lowest metric.
-- @return Table with the properties of the current default route.
-- The following fields are defined:
--- { "Mask", "RefCnt", "Iface", "Flags", "Window", "IRTT",
--- "MTU", "Gateway", "Destination", "Metric", "Use" }
+-- { "dest", "gateway", "metric", "refcount", "usecount", "irtt",
+-- "flags", "device" }
function net.defaultroute()
- local routes = net.routes()
local route = nil
-
- for i, r in pairs(luci.sys.net.routes()) do
- if r.Destination == "00000000" and (not route or route.Metric > r.Metric) then
+ for _, r in pairs(net.routes()) do
+ if r.dest:prefix() == 0 and (not route or route.metric > r.metric) then
route = r
end
end
+ return route
+end
+--- Determine the current IPv6 default route. If multiple default routes exist,
+-- return the one with the lowest metric.
+-- @return Table with the properties of the current default route.
+-- The following fields are defined:
+-- { "source", "dest", "nexthop", "metric", "refcount", "usecount",
+-- "flags", "device" }
+function net.defaultroute6()
+ local route = nil
+ for _, r in pairs(net.routes6()) do
+ if r.dest:prefix() == 0 and (not route or route.metric > r.metric) then
+ route = r
+ end
+ end
return route
end
--- Returns the current kernel routing table entries.
-- @return Table of tables with properties of the corresponding routes.
-- The following fields are defined for route entry tables:
--- { "Mask", "RefCnt", "Iface", "Flags", "Window", "IRTT",
--- "MTU", "Gateway", "Destination", "Metric", "Use" }
+-- { "dest", "gateway", "metric", "refcount", "usecount", "irtt",
+-- "flags", "device" }
function net.routes()
- return _parse_delimited_table(io.lines("/proc/net/route"))
+ local routes = { }
+
+ for line in io.lines("/proc/net/route") do
+
+ local dev, dst_ip, gateway, flags, refcnt, usecnt, metric,
+ dst_mask, mtu, win, irtt = line:match(
+ "([^%s]+)\t([A-F0-9]+)\t([A-F0-9]+)\t([A-F0-9]+)\t" ..
+ "(%d+)\t(%d+)\t(%d+)\t([A-F0-9]+)\t(%d+)\t(%d+)\t(%d+)"
+ )
+
+ if dev then
+ gateway = luci.ip.Hex( gateway, 32, luci.ip.FAMILY_INET4 )
+ dst_mask = luci.ip.Hex( dst_mask, 32, luci.ip.FAMILY_INET4 )
+ dst_ip = luci.ip.Hex(
+ dst_ip, dst_mask:prefix(dst_mask), luci.ip.FAMILY_INET4
+ )
+
+ routes[#routes+1] = {
+ dest = dst_ip,
+ gateway = gateway,
+ metric = tonumber(metric),
+ refcount = tonumber(refcnt),
+ usecount = tonumber(usecnt),
+ mtu = tonumber(mtu),
+ window = tonumber(window),
+ irtt = tonumber(irtt),
+ flags = tonumber(flags, 16),
+ device = dev
+ }
+ end
+ end
+
+ return routes
end
--- Returns the current ipv6 kernel routing table entries.
-- @return Table of tables with properties of the corresponding routes.
-- The following fields are defined for route entry tables:
--- { "src_ip", "src_prefix", "dst_ip", "dst_prefix", "nexthop_ip",
--- "metric", "refcount", "usecount", "flags", "device" }
+-- { "source", "dest", "nexthop", "metric", "refcount", "usecount",
+-- "flags", "device" }
function net.routes6()
local routes = { }
"([a-f0-9]+) ([a-f0-9]+) " ..
"([a-f0-9]+) ([a-f0-9]+) " ..
"([a-f0-9]+) ([a-f0-9]+) " ..
- "([^%s]+) +([^%s]+)"
+ "([a-f0-9]+) +([^%s]+)"
)
src_ip = luci.ip.Hex(
- src_ip, tonumber(src_prefix, 16),
- luci.ip.FAMILY_INET6, false
+ src_ip, tonumber(src_prefix, 16), luci.ip.FAMILY_INET6, false
)
dst_ip = luci.ip.Hex(
- dst_ip, tonumber(dst_prefix, 16),
- luci.ip.FAMILY_INET6, false
+ dst_ip, tonumber(dst_prefix, 16), luci.ip.FAMILY_INET6, false
)
nexthop = luci.ip.Hex( nexthop, 128, luci.ip.FAMILY_INET6, false )
routes[#routes+1] = {
- src_ip = src_ip:host():string(),
- src_prefix = src_ip:prefix(),
- dst_ip = dst_ip:host():string(),
- dst_prefix = dst_ip:prefix(),
- nexthop_ip = nexthop:string(),
- metric = tonumber(metric, 16),
- refcount = tonumber(refcnt, 16),
- usecount = tonumber(usecnt, 16),
- flags = tonumber(flags), -- hex?
- device = dev
+ source = src_ip,
+ dest = dst_ip,
+ nexthop = nexthop,
+ metric = tonumber(metric, 16),
+ refcount = tonumber(refcnt, 16),
+ usecount = tonumber(usecnt, 16),
+ flags = tonumber(flags, 16),
+ device = dev
}
end
for i, l in pairs(luci.util.split(luci.util.trim(cnt), "\n")) do
for j, f in pairs(luci.util.split(luci.util.trim(l), delimiter, nil, true)) do
- local k, x, v = f:match('([^%s][^:=]+) *([:=]*) *"*([^\n"]*)"*')
+ local k, x, v = f:match('([^%s][^:=]+) *([:=]*) *"*([^\n"]*)"*')
- if k then
+ if k then
if x == "" then
table.insert(flags, k)
else
- data[k] = v
+ data[k] = v
end
- end
- end
+ end
+ end
end
- return data, flags
+ return data, flags
end
local stat, err = util.copcall(dispatch, context.request)
if not stat then
+ luci.util.perror(err)
error500(err)
end
local c = _create_node({...})
c.module = getfenv(2)._NAME
+ c.path = arg
c.auto = nil
return c
local c = cache[name]
if not c then
- local new = {nodes={}, auto=true, path=util.clone(path)}
local last = table.remove(path)
-
c = _create_node(path, cache)
+ local new = {nodes={}, auto=true}
c.nodes[last] = new
cache[name] = new
end
--- Create a CBI model dispatching target.
--- @param model CBI model tpo be rendered
+-- @param model CBI model to be rendered
function cbi(model, config)
config = config or {}
return function(...)
end
end
+ if config.on_valid_to and state and state > 0 and state < 2 then
+ luci.http.redirect(config.on_valid_to)
+ return
+ end
+
+ if config.on_changed_to and state and state > 1 then
+ luci.http.redirect(config.on_changed_to)
+ return
+ end
+
+ if config.on_success_to and state and state > 0 then
+ luci.http.redirect(config.on_success_to)
+ return
+ end
+
+ if config.state_handler then
+ if not config.state_handler(state, maps) then
+ return
+ end
+ end
+
+ local pageaction = true
http.header("X-CBI-State", state or 0)
luci.template.render("cbi/header", {state = state})
for i, res in ipairs(maps) do
res:render()
+ if res.pageaction == false then
+ pageaction = false
+ end
end
- luci.template.render("cbi/footer", {state = state, autoapply = config.autoapply})
+ luci.template.render("cbi/footer", {pageaction=pageaction, state = state, autoapply = config.autoapply})
end
end
net = v:option(DummyValue, "iface", translate("network"))
function net.cfgvalue(self, section)
- return luci.tools.webadmin.iface_get_network(routes[section].Iface)
- or routes[section].Iface
+ return luci.tools.webadmin.iface_get_network(routes[section].device)
+ or routes[section].device
end
target = v:option(DummyValue, "target", translate("target"))
function target.cfgvalue(self, section)
- return luci.ip.Hex(routes[section].Destination, 32):string()
+ return routes[section].dest:network():string()
end
netmask = v:option(DummyValue, "netmask", translate("netmask"))
function netmask.cfgvalue(self, section)
- return luci.ip.Hex(routes[section].Mask, 32):string()
+ return routes[section].dest:mask():string()
end
gateway = v:option(DummyValue, "gateway", translate("gateway"))
function gateway.cfgvalue(self, section)
- return luci.ip.Hex(routes[section].Gateway, 32):string()
+ return routes[section].gateway:string()
end
metric = v:option(DummyValue, "Metric", translate("metric"))
target = v:option(DummyValue, "target", translate("target"))
function target.cfgvalue(self, section)
- return routes6[section].dst_ip .. "/" .. routes6[section].dst_prefix
+ return routes6[section].dest:string()
end
gateway = v:option(DummyValue, "gateway", translate("gateway6"))
function gateway.cfgvalue(self, section)
- return routes6[section].src_ip .. "/" .. routes6[section].src_prefix
+ return routes6[section].source:string()
end
metric = v:option(DummyValue, "Metric", translate("metric"))
page.setuser = "nobody"
page.setgroup = "nogroup"
page.i18n = "freifunk"
-
+
local page = node("freifunk", "index")
page.target = template("freifunk/index")
page.title = "Übersicht"
page.order = 10
-
+
local page = node("freifunk", "index", "contact")
page.target = template("freifunk/contact")
page.title = "Kontakt"
-
-
+
+
local page = node("freifunk", "status")
page.target = call("action_status")
page.title = "Status"
page.order = 20
page.setuser = false
page.setgroup = false
-
+
assign({"freifunk", "status", "iwscan"}, {"admin", "status", "iwscan"}, "WLAN-Scan", 20)
assign({"freifunk", "olsr"}, {"admin", "status", "olsr"}, "OLSR", 30)
-
+
if luci.fs.isfile("/etc/config/luci_statistics") then
assign({"freifunk", "statistics"}, {"admin", "statistics", "graph"}, i18n("stat_statistics", "Statistiken"), 40)
end
-
+
local page = node("admin", "index", "freifunk")
page.target = cbi("freifunk/freifunk")
page.title = "Freifunk"
page.order = 30
-
+
local page = node("admin", "index", "contact")
page.target = cbi("freifunk/contact")
page.title = "Kontakt"
page.order = 40
end
-
-function action_status()
- local data = {}
-
- data.system, data.model, data.memtotal, data.memcached, data.membuffers, data.memfree = luci.sys.sysinfo()
- data.perc_memfree = math.floor((data.memfree/data.memtotal)*100)
- data.perc_membuffers = math.floor((data.membuffers/data.memtotal)*100)
- data.perc_memcached = math.floor((data.memcached/data.memtotal)*100)
-
- data.wifi = luci.sys.wifi.getiwconfig()
-
- data.routes = {}
- for i, r in pairs(luci.sys.net.routes()) do
- if r.Destination == "00000000" then
- table.insert(data.routes, r)
- end
- end
-
-
- luci.template.render("public_status/index", data)
-end
\ No newline at end of file