mirror of
https://github.com/Ysurac/openmptcprouter-feeds.git
synced 2025-03-09 15:40:03 +00:00
Disable processes list for now
This commit is contained in:
parent
509718c5cd
commit
0737e27eb8
27 changed files with 3496 additions and 0 deletions
175
luci-mod-status/luasrc/controller/admin/status.lua
Normal file
175
luci-mod-status/luasrc/controller/admin/status.lua
Normal file
|
@ -0,0 +1,175 @@
|
|||
-- Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
-- Copyright 2011 Jo-Philipp Wich <jow@openwrt.org>
|
||||
-- Licensed to the public under the Apache License 2.0.
|
||||
|
||||
module("luci.controller.admin.status", package.seeall)
|
||||
|
||||
function index()
|
||||
entry({"admin", "status", "overview"}, template("admin_status/index"), _("Overview"), 1)
|
||||
|
||||
entry({"admin", "status", "iptables"}, template("admin_status/iptables"), _("Firewall"), 2).leaf = true
|
||||
entry({"admin", "status", "iptables_dump"}, call("dump_iptables")).leaf = true
|
||||
entry({"admin", "status", "iptables_action"}, post("action_iptables")).leaf = true
|
||||
|
||||
entry({"admin", "status", "routes"}, template("admin_status/routes"), _("Routes"), 3)
|
||||
entry({"admin", "status", "syslog"}, call("action_syslog"), _("System Log"), 4)
|
||||
entry({"admin", "status", "dmesg"}, call("action_dmesg"), _("Kernel Log"), 5)
|
||||
--entry({"admin", "status", "processes"}, form("admin_status/processes"), _("Processes"), 6)
|
||||
|
||||
entry({"admin", "status", "realtime"}, alias("admin", "status", "realtime", "load"), _("Realtime Graphs"), 7)
|
||||
|
||||
entry({"admin", "status", "realtime", "load"}, template("admin_status/load"), _("Load"), 1).leaf = true
|
||||
entry({"admin", "status", "realtime", "load_status"}, call("action_load")).leaf = true
|
||||
|
||||
entry({"admin", "status", "realtime", "bandwidth"}, template("admin_status/bandwidth"), _("Traffic"), 2).leaf = true
|
||||
entry({"admin", "status", "realtime", "bandwidth_status"}, call("action_bandwidth")).leaf = true
|
||||
|
||||
if nixio.fs.access("/etc/config/wireless") then
|
||||
entry({"admin", "status", "realtime", "wireless"}, template("admin_status/wireless"), _("Wireless"), 3).leaf = true
|
||||
entry({"admin", "status", "realtime", "wireless_status"}, call("action_wireless")).leaf = true
|
||||
end
|
||||
|
||||
entry({"admin", "status", "realtime", "connections"}, template("admin_status/connections"), _("Connections"), 4).leaf = true
|
||||
entry({"admin", "status", "realtime", "connections_status"}, call("action_connections")).leaf = true
|
||||
|
||||
entry({"admin", "status", "nameinfo"}, call("action_nameinfo")).leaf = true
|
||||
end
|
||||
|
||||
function action_syslog()
|
||||
local syslog = luci.sys.syslog()
|
||||
luci.template.render("admin_status/syslog", {syslog=syslog})
|
||||
end
|
||||
|
||||
function action_dmesg()
|
||||
local dmesg = luci.sys.dmesg()
|
||||
luci.template.render("admin_status/dmesg", {dmesg=dmesg})
|
||||
end
|
||||
|
||||
function dump_iptables(family, table)
|
||||
local prefix = (family == "6") and "ip6" or "ip"
|
||||
local ok, lines = pcall(io.lines, "/proc/net/%s_tables_names" % prefix)
|
||||
if ok and lines then
|
||||
local s
|
||||
for s in lines do
|
||||
if s == table then
|
||||
luci.http.prepare_content("text/plain")
|
||||
luci.sys.process.exec({
|
||||
"/usr/sbin/%stables" % prefix, "-w", "-t", table,
|
||||
"--line-numbers", "-nxvL"
|
||||
}, luci.http.write)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
luci.http.status(404, "No such table")
|
||||
luci.http.prepare_content("text/plain")
|
||||
end
|
||||
|
||||
function action_iptables()
|
||||
if luci.http.formvalue("zero") then
|
||||
if luci.http.formvalue("family") == "6" then
|
||||
luci.util.exec("/usr/sbin/ip6tables -Z")
|
||||
else
|
||||
luci.util.exec("/usr/sbin/iptables -Z")
|
||||
end
|
||||
elseif luci.http.formvalue("restart") then
|
||||
luci.util.exec("/etc/init.d/firewall restart")
|
||||
end
|
||||
|
||||
luci.http.redirect(luci.dispatcher.build_url("admin/status/iptables"))
|
||||
end
|
||||
|
||||
function action_bandwidth(iface)
|
||||
luci.http.prepare_content("application/json")
|
||||
|
||||
local bwc = io.popen("luci-bwc -i %s 2>/dev/null"
|
||||
% luci.util.shellquote(iface))
|
||||
|
||||
if bwc then
|
||||
luci.http.write("[")
|
||||
|
||||
while true do
|
||||
local ln = bwc:read("*l")
|
||||
if not ln then break end
|
||||
luci.http.write(ln)
|
||||
end
|
||||
|
||||
luci.http.write("]")
|
||||
bwc:close()
|
||||
end
|
||||
end
|
||||
|
||||
function action_wireless(iface)
|
||||
luci.http.prepare_content("application/json")
|
||||
|
||||
local bwc = io.popen("luci-bwc -r %s 2>/dev/null"
|
||||
% luci.util.shellquote(iface))
|
||||
|
||||
if bwc then
|
||||
luci.http.write("[")
|
||||
|
||||
while true do
|
||||
local ln = bwc:read("*l")
|
||||
if not ln then break end
|
||||
luci.http.write(ln)
|
||||
end
|
||||
|
||||
luci.http.write("]")
|
||||
bwc:close()
|
||||
end
|
||||
end
|
||||
|
||||
function action_load()
|
||||
luci.http.prepare_content("application/json")
|
||||
|
||||
local bwc = io.popen("luci-bwc -l 2>/dev/null")
|
||||
if bwc then
|
||||
luci.http.write("[")
|
||||
|
||||
while true do
|
||||
local ln = bwc:read("*l")
|
||||
if not ln then break end
|
||||
luci.http.write(ln)
|
||||
end
|
||||
|
||||
luci.http.write("]")
|
||||
bwc:close()
|
||||
end
|
||||
end
|
||||
|
||||
function action_connections()
|
||||
local sys = require "luci.sys"
|
||||
|
||||
luci.http.prepare_content("application/json")
|
||||
|
||||
luci.http.write('{ "connections": ')
|
||||
luci.http.write_json(sys.net.conntrack())
|
||||
|
||||
local bwc = io.popen("luci-bwc -c 2>/dev/null")
|
||||
if bwc then
|
||||
luci.http.write(', "statistics": [')
|
||||
|
||||
while true do
|
||||
local ln = bwc:read("*l")
|
||||
if not ln then break end
|
||||
luci.http.write(ln)
|
||||
end
|
||||
|
||||
luci.http.write("]")
|
||||
bwc:close()
|
||||
end
|
||||
|
||||
luci.http.write(" }")
|
||||
end
|
||||
|
||||
function action_nameinfo(...)
|
||||
local util = require "luci.util"
|
||||
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(util.ubus("network.rrdns", "lookup", {
|
||||
addrs = { ... },
|
||||
timeout = 5000,
|
||||
limit = 1000
|
||||
}) or { })
|
||||
end
|
34
luci-mod-status/luasrc/model/cbi/admin_status/processes.lua
Normal file
34
luci-mod-status/luasrc/model/cbi/admin_status/processes.lua
Normal file
|
@ -0,0 +1,34 @@
|
|||
-- Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
-- Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
|
||||
-- Licensed to the public under the Apache License 2.0.
|
||||
|
||||
f = SimpleForm("processes", translate("Processes"), translate("This list gives an overview over currently running system processes and their status."))
|
||||
f.reset = false
|
||||
f.submit = false
|
||||
|
||||
t = f:section(Table, luci.sys.process.list())
|
||||
t:option(DummyValue, "PID", translate("PID"))
|
||||
t:option(DummyValue, "USER", translate("Owner"))
|
||||
t:option(DummyValue, "COMMAND", translate("Command"))
|
||||
t:option(DummyValue, "%CPU", translate("CPU usage (%)"))
|
||||
t:option(DummyValue, "%MEM", translate("Memory usage (%)"))
|
||||
|
||||
hup = t:option(Button, "_hup", translate("Hang Up"))
|
||||
hup.inputstyle = "reload"
|
||||
function hup.write(self, section)
|
||||
null, self.tag_error[section] = luci.sys.process.signal(section, 1)
|
||||
end
|
||||
|
||||
term = t:option(Button, "_term", translate("Terminate"))
|
||||
term.inputstyle = "remove"
|
||||
function term.write(self, section)
|
||||
null, self.tag_error[section] = luci.sys.process.signal(section, 15)
|
||||
end
|
||||
|
||||
kill = t:option(Button, "_kill", translate("Kill"))
|
||||
kill.inputstyle = "reset"
|
||||
function kill.write(self, section)
|
||||
null, self.tag_error[section] = luci.sys.process.signal(section, 9)
|
||||
end
|
||||
|
||||
return f
|
308
luci-mod-status/luasrc/view/admin_status/bandwidth.htm
Normal file
308
luci-mod-status/luasrc/view/admin_status/bandwidth.htm
Normal file
|
@ -0,0 +1,308 @@
|
|||
<%#
|
||||
Copyright 2010-2018 Jo-Philipp Wich <jo@mein.io>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<%-
|
||||
local ntm = require "luci.model.network".init()
|
||||
|
||||
local dev
|
||||
local devices = { }
|
||||
for _, dev in luci.util.vspairs(luci.sys.net.devices()) do
|
||||
if dev ~= "lo" and not ntm:ignore_interface(dev) then
|
||||
devices[#devices+1] = dev
|
||||
end
|
||||
end
|
||||
|
||||
local curdev = luci.http.formvalue("dev") or devices[1]
|
||||
-%>
|
||||
|
||||
<%+header%>
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
var bwxhr = new XHR();
|
||||
|
||||
var G;
|
||||
var TIME = 0;
|
||||
var RXB = 1;
|
||||
var RXP = 2;
|
||||
var TXB = 3;
|
||||
var TXP = 4;
|
||||
|
||||
var width = 760;
|
||||
var height = 300;
|
||||
var step = 5;
|
||||
|
||||
var data_wanted = Math.floor(width / step);
|
||||
var data_fill = 1;
|
||||
var data_stamp = 0;
|
||||
|
||||
var data_rx = [ ];
|
||||
var data_tx = [ ];
|
||||
|
||||
var line_rx;
|
||||
var line_tx;
|
||||
|
||||
var label_25;
|
||||
var label_50;
|
||||
var label_75;
|
||||
|
||||
var label_rx_cur;
|
||||
var label_rx_avg;
|
||||
var label_rx_peak;
|
||||
|
||||
var label_tx_cur;
|
||||
var label_tx_avg;
|
||||
var label_tx_peak;
|
||||
|
||||
var label_scale;
|
||||
|
||||
|
||||
Math.log2 = Math.log2 || function(x) { return Math.log(x) * Math.LOG2E; };
|
||||
|
||||
function bandwidth_label(bytes, br)
|
||||
{
|
||||
var uby = '<%:kB/s%>';
|
||||
var kby = (bytes / 1024);
|
||||
|
||||
if (kby >= 1024)
|
||||
{
|
||||
uby = '<%:MB/s%>';
|
||||
kby = kby / 1024;
|
||||
}
|
||||
|
||||
var ubi = '<%:kbit/s%>';
|
||||
var kbi = (bytes * 8 / 1024);
|
||||
|
||||
if (kbi >= 1024)
|
||||
{
|
||||
ubi = '<%:Mbit/s%>';
|
||||
kbi = kbi / 1024;
|
||||
}
|
||||
|
||||
return String.format("%f %s%s(%f %s)",
|
||||
kbi.toFixed(2), ubi,
|
||||
br ? '<br />' : ' ',
|
||||
kby.toFixed(2), uby
|
||||
);
|
||||
}
|
||||
|
||||
/* wait for SVG */
|
||||
window.setTimeout(
|
||||
function() {
|
||||
var svg = document.getElementById('bwsvg');
|
||||
|
||||
try {
|
||||
G = svg.getSVGDocument
|
||||
? svg.getSVGDocument() : svg.contentDocument;
|
||||
}
|
||||
catch(e) {
|
||||
G = document.embeds['bwsvg'].getSVGDocument();
|
||||
}
|
||||
|
||||
if (!G)
|
||||
{
|
||||
window.setTimeout(arguments.callee, 1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* find sizes */
|
||||
width = svg.offsetWidth - 2;
|
||||
height = svg.offsetHeight - 2;
|
||||
data_wanted = Math.ceil(width / step);
|
||||
|
||||
/* prefill datasets */
|
||||
for (var i = 0; i < data_wanted; i++)
|
||||
{
|
||||
data_rx[i] = 0;
|
||||
data_tx[i] = 0;
|
||||
}
|
||||
|
||||
/* find svg elements */
|
||||
line_rx = G.getElementById('rx');
|
||||
line_tx = G.getElementById('tx');
|
||||
|
||||
label_25 = G.getElementById('label_25');
|
||||
label_50 = G.getElementById('label_50');
|
||||
label_75 = G.getElementById('label_75');
|
||||
|
||||
label_rx_cur = document.getElementById('rx_bw_cur');
|
||||
label_rx_avg = document.getElementById('rx_bw_avg');
|
||||
label_rx_peak = document.getElementById('rx_bw_peak');
|
||||
|
||||
label_tx_cur = document.getElementById('tx_bw_cur');
|
||||
label_tx_avg = document.getElementById('tx_bw_avg');
|
||||
label_tx_peak = document.getElementById('tx_bw_peak');
|
||||
|
||||
label_scale = document.getElementById('scale');
|
||||
|
||||
|
||||
/* plot horizontal time interval lines */
|
||||
for (var i = width % (step * 60); i < width; i += step * 60)
|
||||
{
|
||||
var line = G.createElementNS('http://www.w3.org/2000/svg', 'line');
|
||||
line.setAttribute('x1', i);
|
||||
line.setAttribute('y1', 0);
|
||||
line.setAttribute('x2', i);
|
||||
line.setAttribute('y2', '100%');
|
||||
line.setAttribute('style', 'stroke:black;stroke-width:0.1');
|
||||
|
||||
var text = G.createElementNS('http://www.w3.org/2000/svg', 'text');
|
||||
text.setAttribute('x', i + 5);
|
||||
text.setAttribute('y', 15);
|
||||
text.setAttribute('style', 'fill:#eee; font-size:9pt; font-family:sans-serif; text-shadow:1px 1px 1px #000');
|
||||
text.appendChild(G.createTextNode(Math.round((width - i) / step / 60) + 'm'));
|
||||
|
||||
label_25.parentNode.appendChild(line);
|
||||
label_25.parentNode.appendChild(text);
|
||||
}
|
||||
|
||||
label_scale.innerHTML = String.format('<%:(%d minute window, %d second interval)%>', data_wanted / 60, 3);
|
||||
|
||||
/* render datasets, start update interval */
|
||||
XHR.poll(3, '<%=build_url("admin/status/realtime/bandwidth_status", curdev)%>', null,
|
||||
function(x, data)
|
||||
{
|
||||
var data_max = 0;
|
||||
var data_scale = 0;
|
||||
|
||||
var data_rx_avg = 0;
|
||||
var data_tx_avg = 0;
|
||||
|
||||
var data_rx_peak = 0;
|
||||
var data_tx_peak = 0;
|
||||
|
||||
for (var i = data_stamp ? 0 : 1; i < data.length; i++)
|
||||
{
|
||||
/* skip overlapping entries */
|
||||
if (data[i][TIME] <= data_stamp)
|
||||
continue;
|
||||
|
||||
data_fill++;
|
||||
|
||||
/* normalize difference against time interval */
|
||||
if (i > 0)
|
||||
{
|
||||
var time_delta = data[i][TIME] - data[i-1][TIME];
|
||||
if (time_delta)
|
||||
{
|
||||
data_rx.push((data[i][RXB] - data[i-1][RXB]) / time_delta);
|
||||
data_tx.push((data[i][TXB] - data[i-1][TXB]) / time_delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* cut off outdated entries */
|
||||
data_rx = data_rx.slice(data_rx.length - data_wanted, data_rx.length);
|
||||
data_tx = data_tx.slice(data_tx.length - data_wanted, data_tx.length);
|
||||
data_fill = Math.min(data_fill, data_wanted);
|
||||
|
||||
/* find peak */
|
||||
for (var i = 0; i < data_rx.length; i++)
|
||||
{
|
||||
data_max = Math.max(data_max, data_rx[i]);
|
||||
data_max = Math.max(data_max, data_tx[i]);
|
||||
|
||||
data_rx_peak = Math.max(data_rx_peak, data_rx[i]);
|
||||
data_tx_peak = Math.max(data_tx_peak, data_tx[i]);
|
||||
|
||||
data_rx_avg += data_rx[i];
|
||||
data_tx_avg += data_tx[i];
|
||||
}
|
||||
|
||||
data_rx_avg = (data_rx_avg / data_fill);
|
||||
data_tx_avg = (data_tx_avg / data_fill);
|
||||
|
||||
var size = Math.floor(Math.log2(data_max)),
|
||||
div = Math.pow(2, size - (size % 10)),
|
||||
mult = data_max / div,
|
||||
mult = (mult < 5) ? 2 : ((mult < 50) ? 10 : ((mult < 500) ? 100 : 1000));
|
||||
|
||||
data_max = data_max + (mult * div) - (data_max % (mult * div));
|
||||
|
||||
/* remember current timestamp, calculate horizontal scale */
|
||||
data_stamp = data[data.length-1][TIME];
|
||||
data_scale = height / data_max;
|
||||
|
||||
/* plot data */
|
||||
var pt_rx = '0,' + height;
|
||||
var pt_tx = '0,' + height;
|
||||
|
||||
var y_rx = 0;
|
||||
var y_tx = 0;
|
||||
|
||||
for (var i = 0; i < data_rx.length; i++)
|
||||
{
|
||||
var x = i * step;
|
||||
|
||||
y_rx = height - Math.floor(data_rx[i] * data_scale);
|
||||
y_tx = height - Math.floor(data_tx[i] * data_scale);
|
||||
|
||||
pt_rx += ' ' + x + ',' + y_rx;
|
||||
pt_tx += ' ' + x + ',' + y_tx;
|
||||
}
|
||||
|
||||
pt_rx += ' ' + width + ',' + y_rx + ' ' + width + ',' + height;
|
||||
pt_tx += ' ' + width + ',' + y_tx + ' ' + width + ',' + height;
|
||||
|
||||
|
||||
line_rx.setAttribute('points', pt_rx);
|
||||
line_tx.setAttribute('points', pt_tx);
|
||||
|
||||
label_25.firstChild.data = bandwidth_label(0.25 * data_max);
|
||||
label_50.firstChild.data = bandwidth_label(0.50 * data_max);
|
||||
label_75.firstChild.data = bandwidth_label(0.75 * data_max);
|
||||
|
||||
label_rx_cur.innerHTML = bandwidth_label(data_rx[data_rx.length-1], true);
|
||||
label_tx_cur.innerHTML = bandwidth_label(data_tx[data_tx.length-1], true);
|
||||
|
||||
label_rx_avg.innerHTML = bandwidth_label(data_rx_avg, true);
|
||||
label_tx_avg.innerHTML = bandwidth_label(data_tx_avg, true);
|
||||
|
||||
label_rx_peak.innerHTML = bandwidth_label(data_rx_peak, true);
|
||||
label_tx_peak.innerHTML = bandwidth_label(data_tx_peak, true);
|
||||
}
|
||||
);
|
||||
|
||||
XHR.run();
|
||||
}
|
||||
}, 1000
|
||||
);
|
||||
//]]></script>
|
||||
|
||||
<h2 name="content"><%:Realtime Traffic%></h2>
|
||||
|
||||
<ul class="cbi-tabmenu">
|
||||
<% for _, dev in ipairs(devices) do %>
|
||||
<li class="cbi-tab<%= dev == curdev and "" or "-disabled" %>"><a href="?dev=<%=pcdata(dev)%>"><%=pcdata(dev)%></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
|
||||
<embed id="bwsvg" style="width:100%; height:300px; border:1px solid #000000; background-color:#FFFFFF" src="<%=resource%>/bandwidth.svg" />
|
||||
<div style="text-align:right"><small id="scale">-</small></div>
|
||||
<br />
|
||||
|
||||
<div class="table" style="width:100%; table-layout:fixed" cellspacing="5">
|
||||
<div class="tr">
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong style="border-bottom:2px solid blue"><%:Inbound:%></strong></div>
|
||||
<div class="td" id="rx_bw_cur">0 <%:kbit/s%><br />(0 <%:kB/s%>)</div>
|
||||
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong><%:Average:%></strong></div>
|
||||
<div class="td" id="rx_bw_avg">0 <%:kbit/s%><br />(0 <%:kB/s%>)</div>
|
||||
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong><%:Peak:%></strong></div>
|
||||
<div class="td" id="rx_bw_peak">0 <%:kbit/s%><br />(0 <%:kB/s%>)</div>
|
||||
</div>
|
||||
<div class="tr">
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong style="border-bottom:2px solid green"><%:Outbound:%></strong></div>
|
||||
<div class="td" id="tx_bw_cur">0 <%:kbit/s%><br />(0 <%:kB/s%>)</div>
|
||||
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong><%:Average:%></strong></div>
|
||||
<div class="td" id="tx_bw_avg">0 <%:kbit/s%><br />(0 <%:kB/s%>)</div>
|
||||
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong><%:Peak:%></strong></div>
|
||||
<div class="td" id="tx_bw_peak">0 <%:kbit/s%><br />(0 <%:kB/s%>)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%+footer%>
|
405
luci-mod-status/luasrc/view/admin_status/connections.htm
Normal file
405
luci-mod-status/luasrc/view/admin_status/connections.htm
Normal file
|
@ -0,0 +1,405 @@
|
|||
<%#
|
||||
Copyright 2010-2018 Jo-Philipp Wich <jo@mein.io>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<%+header%>
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
var bwxhr = new XHR();
|
||||
|
||||
var G;
|
||||
var TIME = 0;
|
||||
var UDP = 1;
|
||||
var TCP = 2;
|
||||
var OTHER = 3;
|
||||
|
||||
var width = 760;
|
||||
var height = 300;
|
||||
var step = 5;
|
||||
|
||||
var data_wanted = Math.floor(width / step);
|
||||
var data_fill = 1;
|
||||
var data_stamp = 0;
|
||||
|
||||
var data_udp = [ ];
|
||||
var data_tcp = [ ];
|
||||
var data_otr = [ ];
|
||||
|
||||
var line_udp;
|
||||
var line_tcp;
|
||||
|
||||
var label_25;
|
||||
var label_50;
|
||||
var label_75;
|
||||
|
||||
var label_udp_cur;
|
||||
var label_udp_avg;
|
||||
var label_udp_peak;
|
||||
|
||||
var label_tcp_cur;
|
||||
var label_tcp_avg;
|
||||
var label_tcp_peak;
|
||||
|
||||
var label_otr_cur;
|
||||
var label_otr_avg;
|
||||
var label_otr_peak;
|
||||
|
||||
var label_scale;
|
||||
|
||||
var conn_table;
|
||||
|
||||
var dns_cache = { };
|
||||
|
||||
|
||||
/* wait for SVG */
|
||||
window.setTimeout(
|
||||
function() {
|
||||
var svg = document.getElementById('bwsvg');
|
||||
|
||||
try {
|
||||
G = svg.getSVGDocument
|
||||
? svg.getSVGDocument() : svg.contentDocument;
|
||||
}
|
||||
catch(e) {
|
||||
G = document.embeds['bwsvg'].getSVGDocument();
|
||||
}
|
||||
|
||||
if (!G)
|
||||
{
|
||||
window.setTimeout(arguments.callee, 1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* find sizes */
|
||||
width = svg.offsetWidth - 2;
|
||||
height = svg.offsetHeight - 2;
|
||||
data_wanted = Math.ceil(width / step);
|
||||
|
||||
/* prefill datasets */
|
||||
for (var i = 0; i < data_wanted; i++)
|
||||
{
|
||||
data_udp[i] = 0;
|
||||
data_tcp[i] = 0;
|
||||
data_otr[i] = 0;
|
||||
}
|
||||
|
||||
/* find svg elements */
|
||||
line_udp = G.getElementById('udp');
|
||||
line_tcp = G.getElementById('tcp');
|
||||
line_otr = G.getElementById('other');
|
||||
|
||||
label_25 = G.getElementById('label_25');
|
||||
label_50 = G.getElementById('label_50');
|
||||
label_75 = G.getElementById('label_75');
|
||||
|
||||
label_udp_cur = document.getElementById('lb_udp_cur');
|
||||
label_udp_avg = document.getElementById('lb_udp_avg');
|
||||
label_udp_peak = document.getElementById('lb_udp_peak');
|
||||
|
||||
label_tcp_cur = document.getElementById('lb_tcp_cur');
|
||||
label_tcp_avg = document.getElementById('lb_tcp_avg');
|
||||
label_tcp_peak = document.getElementById('lb_tcp_peak');
|
||||
|
||||
label_otr_cur = document.getElementById('lb_otr_cur');
|
||||
label_otr_avg = document.getElementById('lb_otr_avg');
|
||||
label_otr_peak = document.getElementById('lb_otr_peak');
|
||||
|
||||
label_scale = document.getElementById('scale');
|
||||
|
||||
conn_table = document.getElementById('connections');
|
||||
|
||||
|
||||
/* plot horizontal time interval lines */
|
||||
for (var i = width % (step * 60); i < width; i += step * 60)
|
||||
{
|
||||
var line = G.createElementNS('http://www.w3.org/2000/svg', 'line');
|
||||
line.setAttribute('x1', i);
|
||||
line.setAttribute('y1', 0);
|
||||
line.setAttribute('x2', i);
|
||||
line.setAttribute('y2', '100%');
|
||||
line.setAttribute('style', 'stroke:black;stroke-width:0.1');
|
||||
|
||||
var text = G.createElementNS('http://www.w3.org/2000/svg', 'text');
|
||||
text.setAttribute('x', i + 5);
|
||||
text.setAttribute('y', 15);
|
||||
text.setAttribute('style', 'fill:#eee; font-size:9pt; font-family:sans-serif; text-shadow:1px 1px 1px #000');
|
||||
text.appendChild(G.createTextNode(Math.round((width - i) / step / 60) + 'm'));
|
||||
|
||||
label_25.parentNode.appendChild(line);
|
||||
label_25.parentNode.appendChild(text);
|
||||
}
|
||||
|
||||
label_scale.innerHTML = String.format('<%:(%d minute window, %d second interval)%>', data_wanted / 60, 3);
|
||||
|
||||
var recheck_lookup_queue = {};
|
||||
|
||||
/* render datasets, start update interval */
|
||||
XHR.poll(3, '<%=build_url("admin/status/realtime/connections_status")%>', null,
|
||||
function(x, json)
|
||||
{
|
||||
|
||||
if (!json.connections)
|
||||
return;
|
||||
|
||||
var conn = json.connections;
|
||||
|
||||
var lookup_queue = [ ];
|
||||
var rows = [];
|
||||
|
||||
conn.sort(function(a, b) {
|
||||
return b.bytes - a.bytes;
|
||||
});
|
||||
|
||||
for (var i = 0; i < conn.length; i++)
|
||||
{
|
||||
var c = conn[i];
|
||||
|
||||
if ((c.src == '127.0.0.1' && c.dst == '127.0.0.1') ||
|
||||
(c.src == '::1' && c.dst == '::1'))
|
||||
continue;
|
||||
|
||||
if (!dns_cache[c.src] && lookup_queue.indexOf(c.src) == -1)
|
||||
lookup_queue.push(c.src);
|
||||
|
||||
if (!dns_cache[c.dst] && lookup_queue.indexOf(c.dst) == -1)
|
||||
lookup_queue.push(c.dst);
|
||||
|
||||
var src = dns_cache[c.src] || (c.layer3 == 'ipv6' ? '[' + c.src + ']' : c.src);
|
||||
var dst = dns_cache[c.dst] || (c.layer3 == 'ipv6' ? '[' + c.dst + ']' : c.dst);
|
||||
|
||||
rows.push([
|
||||
c.layer3.toUpperCase(),
|
||||
c.layer4.toUpperCase(),
|
||||
c.hasOwnProperty('sport') ? (src + ':' + c.sport) : src,
|
||||
c.hasOwnProperty('dport') ? (dst + ':' + c.dport) : dst,
|
||||
'%1024.2mB (%d <%:Pkts.%>)'.format(c.bytes, c.packets)
|
||||
]);
|
||||
}
|
||||
|
||||
cbi_update_table(conn_table, rows, '<em><%:No information available%></em>');
|
||||
|
||||
if (lookup_queue.length > 0) {
|
||||
var reduced_lookup_queue = lookup_queue;
|
||||
|
||||
if (lookup_queue.length > 100)
|
||||
reduced_lookup_queue = lookup_queue.slice(0, 100);
|
||||
|
||||
XHR.get('<%=build_url("admin/status/nameinfo")%>/' + reduced_lookup_queue.join('/'), null,
|
||||
function(x, json) {
|
||||
if (!json)
|
||||
return;
|
||||
|
||||
for (var index in reduced_lookup_queue) {
|
||||
var address = reduced_lookup_queue[index];
|
||||
|
||||
if (!address)
|
||||
continue;
|
||||
|
||||
if (json[address]) {
|
||||
dns_cache[address] = json[address];
|
||||
lookup_queue.splice(reduced_lookup_queue.indexOf(address),1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(recheck_lookup_queue[address] > 2) {
|
||||
dns_cache[address] = (address.match(/:/)) ? '[' + address + ']' : address;
|
||||
lookup_queue.splice(index,1);
|
||||
} else {
|
||||
recheck_lookup_queue[address] != null ? recheck_lookup_queue[address]++ : recheck_lookup_queue[address] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
var data = json.statistics;
|
||||
|
||||
var data_max = 0;
|
||||
var data_scale = 0;
|
||||
|
||||
var data_udp_avg = 0;
|
||||
var data_tcp_avg = 0;
|
||||
var data_otr_avg = 0;
|
||||
|
||||
var data_udp_peak = 0;
|
||||
var data_tcp_peak = 0;
|
||||
var data_otr_peak = 0;
|
||||
|
||||
for (var i = data_stamp ? 0 : 1; i < data.length; i++)
|
||||
{
|
||||
/* skip overlapping entries */
|
||||
if (data[i][TIME] <= data_stamp)
|
||||
continue;
|
||||
|
||||
data_fill++;
|
||||
|
||||
data_udp.push(data[i][UDP]);
|
||||
data_tcp.push(data[i][TCP]);
|
||||
data_otr.push(data[i][OTHER]);
|
||||
}
|
||||
|
||||
/* cut off outdated entries */
|
||||
data_fill = Math.min(data_fill, data_wanted);
|
||||
data_udp = data_udp.slice(data_udp.length - data_wanted, data_udp.length);
|
||||
data_tcp = data_tcp.slice(data_tcp.length - data_wanted, data_tcp.length);
|
||||
data_otr = data_otr.slice(data_otr.length - data_wanted, data_otr.length);
|
||||
|
||||
/* find peak */
|
||||
for (var i = 0; i < data_udp.length; i++)
|
||||
{
|
||||
data_max = Math.max(data_max, data_udp[i]);
|
||||
data_max = Math.max(data_max, data_tcp[i]);
|
||||
data_max = Math.max(data_max, data_otr[i]);
|
||||
|
||||
data_udp_peak = Math.max(data_udp_peak, data_udp[i]);
|
||||
data_tcp_peak = Math.max(data_tcp_peak, data_tcp[i]);
|
||||
data_otr_peak = Math.max(data_otr_peak, data_otr[i]);
|
||||
|
||||
data_udp_avg += data_udp[i];
|
||||
data_tcp_avg += data_tcp[i];
|
||||
data_otr_avg += data_otr[i];
|
||||
}
|
||||
|
||||
data_udp_avg = data_udp_avg / data_fill;
|
||||
data_tcp_avg = data_tcp_avg / data_fill;
|
||||
data_otr_avg = data_otr_avg / data_fill;
|
||||
|
||||
/* remember current timestamp, calculate horizontal scale */
|
||||
data_stamp = data[data.length-1][TIME];
|
||||
data_scale = height / (data_max * 1.1);
|
||||
|
||||
|
||||
/* plot data */
|
||||
var pt_udp = '0,' + height;
|
||||
var pt_tcp = '0,' + height;
|
||||
var pt_otr = '0,' + height;
|
||||
|
||||
var y_udp = 0;
|
||||
var y_tcp = 0;
|
||||
var y_otr = 0;
|
||||
|
||||
for (var i = 0; i < data_udp.length; i++)
|
||||
{
|
||||
var x = i * step;
|
||||
|
||||
y_udp = height - Math.floor(data_udp[i] * data_scale);
|
||||
y_tcp = height - Math.floor(data_tcp[i] * data_scale);
|
||||
y_otr = height - Math.floor(data_otr[i] * data_scale);
|
||||
|
||||
pt_udp += ' ' + x + ',' + y_udp;
|
||||
pt_tcp += ' ' + x + ',' + y_tcp;
|
||||
pt_otr += ' ' + x + ',' + y_otr;
|
||||
}
|
||||
|
||||
pt_udp += ' ' + width + ',' + y_udp + ' ' + width + ',' + height;
|
||||
pt_tcp += ' ' + width + ',' + y_tcp + ' ' + width + ',' + height;
|
||||
pt_otr += ' ' + width + ',' + y_otr + ' ' + width + ',' + height;
|
||||
|
||||
|
||||
var order = [
|
||||
[ line_udp, data_udp[data_udp.length-1] ],
|
||||
[ line_tcp, data_tcp[data_tcp.length-1] ],
|
||||
[ line_otr, data_otr[data_otr.length-1] ]
|
||||
];
|
||||
|
||||
order.sort(function(a, b) { return b[1] - a[1] });
|
||||
|
||||
for (var i = 0; i < order.length; i++)
|
||||
order[i][0].parentNode.appendChild(order[i][0]);
|
||||
|
||||
|
||||
line_udp.setAttribute('points', pt_udp);
|
||||
line_tcp.setAttribute('points', pt_tcp);
|
||||
line_otr.setAttribute('points', pt_otr);
|
||||
|
||||
label_25.firstChild.data = Math.floor(1.1 * 0.25 * data_max);
|
||||
label_50.firstChild.data = Math.floor(1.1 * 0.50 * data_max);
|
||||
label_75.firstChild.data = Math.floor(1.1 * 0.75 * data_max);
|
||||
|
||||
label_udp_cur.innerHTML = Math.floor(data_udp[data_udp.length-1]);
|
||||
label_tcp_cur.innerHTML = Math.floor(data_tcp[data_tcp.length-1]);
|
||||
label_otr_cur.innerHTML = Math.floor(data_otr[data_otr.length-1]);
|
||||
|
||||
label_udp_avg.innerHTML = Math.floor(data_udp_avg);
|
||||
label_tcp_avg.innerHTML = Math.floor(data_tcp_avg);
|
||||
label_otr_avg.innerHTML = Math.floor(data_otr_avg);
|
||||
|
||||
label_udp_peak.innerHTML = Math.floor(data_udp_peak);
|
||||
label_tcp_peak.innerHTML = Math.floor(data_tcp_peak);
|
||||
label_otr_peak.innerHTML = Math.floor(data_otr_peak);
|
||||
}
|
||||
);
|
||||
|
||||
XHR.run();
|
||||
}
|
||||
}, 1000
|
||||
);
|
||||
//]]></script>
|
||||
|
||||
<h2 name="content"><%:Realtime Connections%></h2>
|
||||
|
||||
<div class="cbi-map-descr"><%:This page gives an overview over currently active network connections.%></div>
|
||||
|
||||
<fieldset class="cbi-section" id="cbi-table-table">
|
||||
<legend><%:Active Connections%></legend>
|
||||
|
||||
<embed id="bwsvg" style="width:100%; height:300px; border:1px solid #000000; background-color:#FFFFFF" src="<%=resource%>/connections.svg" />
|
||||
<div style="text-align:right"><small id="scale">-</small></div>
|
||||
<br />
|
||||
|
||||
<div class="table">
|
||||
<div class="tr">
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong style="border-bottom:2px solid blue"><%:UDP:%></strong></div>
|
||||
<div class="td" id="lb_udp_cur">0</div>
|
||||
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong><%:Average:%></strong></div>
|
||||
<div class="td" id="lb_udp_avg">0</div>
|
||||
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong><%:Peak:%></strong></div>
|
||||
<div class="td" id="lb_udp_peak">0</div>
|
||||
</div>
|
||||
<div class="tr">
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong style="border-bottom:2px solid green"><%:TCP:%></strong></div>
|
||||
<div class="td" id="lb_tcp_cur">0</div>
|
||||
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong><%:Average:%></strong></div>
|
||||
<div class="td" id="lb_tcp_avg">0</div>
|
||||
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong><%:Peak:%></strong></div>
|
||||
<div class="td" id="lb_tcp_peak">0</div>
|
||||
</div>
|
||||
<div class="tr">
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong style="border-bottom:2px solid red"><%:Other:%></strong></div>
|
||||
<div class="td" id="lb_otr_cur">0</div>
|
||||
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong><%:Average:%></strong></div>
|
||||
<div class="td" id="lb_otr_avg">0</div>
|
||||
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong><%:Peak:%></strong></div>
|
||||
<div class="td" id="lb_otr_peak">0</div>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
|
||||
<div class="cbi-section-node">
|
||||
<div class="table" id="connections">
|
||||
<div class="tr table-titles">
|
||||
<div class="th col-2 hide-xs"><%:Network%></div>
|
||||
<div class="th col-2"><%:Protocol%></div>
|
||||
<div class="th col-7"><%:Source%></div>
|
||||
<div class="th col-7"><%:Destination%></div>
|
||||
<div class="th col-4"><%:Transfer%></div>
|
||||
</div>
|
||||
|
||||
<div class="tr placeholder">
|
||||
<div class="td">
|
||||
<em><%:Collecting data...%></em>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<%+footer%>
|
12
luci-mod-status/luasrc/view/admin_status/dmesg.htm
Normal file
12
luci-mod-status/luasrc/view/admin_status/dmesg.htm
Normal file
|
@ -0,0 +1,12 @@
|
|||
<%#
|
||||
Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<%+header%>
|
||||
<h2 name="content"><%:Kernel Log%></h2>
|
||||
<div id="content_syslog">
|
||||
<textarea style="font-size: 12px;" readonly="readonly" wrap="off" rows="<%=dmesg:cmatch("\n")+2%>" id="syslog"><%=dmesg:pcdata()%></textarea>
|
||||
</div>
|
||||
<%+footer%>
|
148
luci-mod-status/luasrc/view/admin_status/index.htm
Normal file
148
luci-mod-status/luasrc/view/admin_status/index.htm
Normal file
|
@ -0,0 +1,148 @@
|
|||
<%#
|
||||
Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
Copyright 2008-2018 Jo-Philipp Wich <jo@mein.io>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<%
|
||||
local fs = require "nixio.fs"
|
||||
local ipc = require "luci.ip"
|
||||
local util = require "luci.util"
|
||||
local stat = require "luci.tools.status"
|
||||
local ver = require "luci.version"
|
||||
|
||||
if luci.http.formvalue("status") == "1" then
|
||||
|
||||
local sysinfo = luci.util.ubus("system", "info") or { }
|
||||
|
||||
local meminfo = sysinfo.memory or {
|
||||
total = 0,
|
||||
free = 0,
|
||||
buffered = 0,
|
||||
shared = 0
|
||||
}
|
||||
|
||||
local swapinfo = sysinfo.swap or {
|
||||
total = 0,
|
||||
free = 0
|
||||
}
|
||||
|
||||
local has_dsl = fs.access("/etc/init.d/dsl_control")
|
||||
|
||||
local ntm = require "luci.model.network".init()
|
||||
local wan_nets = ntm:get_wan_networks()
|
||||
local wan6_nets = ntm:get_wan6_networks()
|
||||
|
||||
local conn_count = tonumber(
|
||||
fs.readfile("/proc/sys/net/netfilter/nf_conntrack_count") or "") or 0
|
||||
|
||||
local conn_max = tonumber(luci.sys.exec(
|
||||
"sysctl -n -e net.nf_conntrack_max net.ipv4.netfilter.ip_conntrack_max"
|
||||
):match("%d+")) or 4096
|
||||
|
||||
local rv = {
|
||||
uptime = sysinfo.uptime or 0,
|
||||
localtime = os.date(),
|
||||
loadavg = sysinfo.load or { 0, 0, 0 },
|
||||
memory = meminfo,
|
||||
swap = swapinfo,
|
||||
connmax = conn_max,
|
||||
conncount = conn_count,
|
||||
wifinets = stat.wifi_networks()
|
||||
}
|
||||
|
||||
if #wan_nets > 0 then
|
||||
local k, v
|
||||
|
||||
rv.wan = { }
|
||||
|
||||
for k, v in pairs(wan_nets) do
|
||||
local dev = v:get_interface()
|
||||
local link = dev and ipc.link(dev:name())
|
||||
|
||||
local wan_info = {
|
||||
ipaddrs = v:ipaddrs(),
|
||||
gwaddr = v:gwaddr(),
|
||||
dns = v:dnsaddrs(),
|
||||
expires = v:expires(),
|
||||
uptime = v:uptime(),
|
||||
proto = v:proto(),
|
||||
i18n = v:get_i18n(),
|
||||
ifname = v:ifname(),
|
||||
link = v:adminlink(),
|
||||
mac = dev and dev:mac(),
|
||||
type = dev and dev:type(),
|
||||
name = dev and dev:get_i18n(),
|
||||
ether = link and link.type == 1
|
||||
}
|
||||
|
||||
rv.wan[#rv.wan+1] = wan_info
|
||||
end
|
||||
end
|
||||
|
||||
if #wan6_nets > 0 then
|
||||
local k, v
|
||||
|
||||
rv.wan6 = { }
|
||||
|
||||
for k, v in pairs(wan6_nets) do
|
||||
local dev = v:get_interface()
|
||||
local link = dev and ipc.link(dev:name())
|
||||
local wan6_info = {
|
||||
ip6addrs = v:ip6addrs(),
|
||||
gw6addr = v:gw6addr(),
|
||||
dns = v:dns6addrs(),
|
||||
ip6prefix = v:ip6prefix(),
|
||||
uptime = v:uptime(),
|
||||
proto = v:proto(),
|
||||
i18n = v:get_i18n(),
|
||||
ifname = v:ifname(),
|
||||
link = v:adminlink(),
|
||||
mac = dev and dev:mac(),
|
||||
type = dev and dev:type(),
|
||||
name = dev and dev:get_i18n(),
|
||||
ether = link and link.type == 1
|
||||
}
|
||||
|
||||
rv.wan6[#rv.wan6+1] = wan6_info
|
||||
end
|
||||
end
|
||||
|
||||
if has_dsl then
|
||||
local dsl_stat = luci.sys.exec("/etc/init.d/dsl_control lucistat")
|
||||
local dsl_func = loadstring(dsl_stat)
|
||||
if dsl_func then
|
||||
rv.dsl = dsl_func()
|
||||
end
|
||||
end
|
||||
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(rv)
|
||||
|
||||
return
|
||||
end
|
||||
-%>
|
||||
|
||||
<%+header%>
|
||||
|
||||
<h2 name="content"><%:Status%></h2>
|
||||
|
||||
<%-
|
||||
local incdir = util.libpath() .. "/view/admin_status/index/"
|
||||
if fs.access(incdir) then
|
||||
local _, inc
|
||||
local includes = {}
|
||||
for inc in fs.dir(incdir) do
|
||||
if inc:match("%.htm$") then
|
||||
includes[#includes + 1] = inc:gsub("%.htm$", "")
|
||||
end
|
||||
end
|
||||
for _, inc in luci.util.vspairs(includes) do
|
||||
include("admin_status/index/" .. inc)
|
||||
end
|
||||
end
|
||||
-%>
|
||||
|
||||
<script type="text/javascript" src="<%=resource%>/view/status/index.js"></script>
|
||||
|
||||
<%+footer%>
|
29
luci-mod-status/luasrc/view/admin_status/index/10-system.htm
Normal file
29
luci-mod-status/luasrc/view/admin_status/index/10-system.htm
Normal file
|
@ -0,0 +1,29 @@
|
|||
<%#
|
||||
Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
Copyright 2008-2018 Jo-Philipp Wich <jo@mein.io>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<%
|
||||
local boardinfo = luci.util.ubus("system", "board") or { }
|
||||
local unameinfo = nixio.uname() or { }
|
||||
local ver = require "luci.version"
|
||||
%>
|
||||
|
||||
<div class="cbi-section">
|
||||
<h3><%:System%></h3>
|
||||
|
||||
<div class="table" width="100%">
|
||||
<div class="tr"><div class="td left" width="33%"><%:Hostname%></div><div class="td left"><%=luci.sys.hostname() or "?"%></div></div>
|
||||
<div class="tr"><div class="td left" width="33%"><%:Model%></div><div class="td left"><%=pcdata(boardinfo.model or "?")%></div></div>
|
||||
<div class="tr"><div class="td left" width="33%"><%:Architecture%></div><div class="td left"><%=pcdata(boardinfo.system or "?")%></div></div>
|
||||
<div class="tr"><div class="td left" width="33%"><%:Firmware Version%></div><div class="td left">
|
||||
<%=pcdata(ver.distname)%> <%=pcdata(ver.distversion)%> /
|
||||
<%=pcdata(ver.luciname)%> (<%=pcdata(ver.luciversion)%>)
|
||||
</div></div>
|
||||
<div class="tr"><div class="td left" width="33%"><%:Kernel Version%></div><div class="td left"><%=unameinfo.release or "?"%></div></div>
|
||||
<div class="tr"><div class="td left" width="33%"><%:Local Time%></div><div class="td left" id="localtime">-</div></div>
|
||||
<div class="tr"><div class="td left" width="33%"><%:Uptime%></div><div class="td left" id="uptime">-</div></div>
|
||||
<div class="tr"><div class="td left" width="33%"><%:Load Average%></div><div class="td left" id="loadavg">-</div></div>
|
||||
</div>
|
||||
</div>
|
31
luci-mod-status/luasrc/view/admin_status/index/20-memory.htm
Normal file
31
luci-mod-status/luasrc/view/admin_status/index/20-memory.htm
Normal file
|
@ -0,0 +1,31 @@
|
|||
<%#
|
||||
Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
Copyright 2008-2018 Jo-Philipp Wich <jo@mein.io>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<%
|
||||
local sysinfo = luci.util.ubus("system", "info") or { }
|
||||
local has_swap = sysinfo.swap and sysinfo.swap.total > 0 or false
|
||||
%>
|
||||
|
||||
<div class="cbi-section">
|
||||
<h3><%:Memory%></h3>
|
||||
|
||||
<div class="table" width="100%">
|
||||
<div class="tr"><div class="td left" width="33%"><%:Total Available%></div><div class="td left"><div id="memtotal" class="cbi-progressbar" title="-"><div></div></div></div></div>
|
||||
<div class="tr"><div class="td left" width="33%"><%:Free%></div><div class="td left"><div id="memfree" class="cbi-progressbar" title="-"><div></div></div></div></div>
|
||||
<div class="tr"><div class="td left" width="33%"><%:Buffered%></div><div class="td left"><div id="membuff" class="cbi-progressbar" title="-"><div></div></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% if has_swap then %>
|
||||
<div class="cbi-section">
|
||||
<h3><%:Swap%></h3>
|
||||
|
||||
<div class="table" width="100%">
|
||||
<div class="tr"><div class="td left" width="33%"><%:Total Available%></div><div class="td left"><div id="swaptotal" class="cbi-progressbar" title="-"><div></div></div></div></div>
|
||||
<div class="tr"><div class="td left" width="33%"><%:Free%></div><div class="td left"><div id="swapfree" class="cbi-progressbar" title="-"><div></div></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
|
@ -0,0 +1,17 @@
|
|||
<%#
|
||||
Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
Copyright 2008-2018 Jo-Philipp Wich <jo@mein.io>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<div class="cbi-section">
|
||||
<h3><%:Network%></h3>
|
||||
|
||||
<div id="upstream_status_table" class="network-status-table">
|
||||
<p><em><%:Collecting data...%></em></p>
|
||||
</div>
|
||||
|
||||
<div class="table" width="100%">
|
||||
<div class="tr"><div class="td left" width="33%"><%:Active Connections%></div><div class="td left"><div id="conns" class="cbi-progressbar" title="-"><div></div></div></div></div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,14 @@
|
|||
<%#
|
||||
Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
Copyright 2008-2018 Jo-Philipp Wich <jo@mein.io>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<%
|
||||
local fs = require "nixio.fs"
|
||||
local has_dhcp = fs.access("/etc/config/dhcp")
|
||||
|
||||
if has_dhcp then
|
||||
include("lease_status")
|
||||
end
|
||||
%>
|
20
luci-mod-status/luasrc/view/admin_status/index/50-dsl.htm
Normal file
20
luci-mod-status/luasrc/view/admin_status/index/50-dsl.htm
Normal file
|
@ -0,0 +1,20 @@
|
|||
<%#
|
||||
Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
Copyright 2008-2018 Jo-Philipp Wich <jo@mein.io>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<%
|
||||
local fs = require "nixio.fs"
|
||||
local has_dsl = fs.access("/etc/init.d/dsl_control")
|
||||
%>
|
||||
|
||||
<% if has_dsl then %>
|
||||
<div class="cbi-section">
|
||||
<h3><%:DSL%></h3>
|
||||
|
||||
<div id="dsl_status_table" class="network-status-table">
|
||||
<p><em><%:Collecting data...%></em></p>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
26
luci-mod-status/luasrc/view/admin_status/index/60-wifi.htm
Normal file
26
luci-mod-status/luasrc/view/admin_status/index/60-wifi.htm
Normal file
|
@ -0,0 +1,26 @@
|
|||
<%#
|
||||
Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
Copyright 2008-2018 Jo-Philipp Wich <jo@mein.io>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<%
|
||||
local fs = require "nixio.fs"
|
||||
local has_wifi = ((fs.stat("/etc/config/wireless", "size") or 0) > 0)
|
||||
%>
|
||||
|
||||
<% if has_wifi then %>
|
||||
<div class="cbi-section">
|
||||
<h3><%:Wireless%></h3>
|
||||
|
||||
<div id="wifi_status_table" class="network-status-table">
|
||||
<p><em><%:Collecting data...%></em></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cbi-section">
|
||||
<h3><%:Associated Stations%></h3>
|
||||
|
||||
<%+wifi_assoclist%>
|
||||
</div>
|
||||
<% end %>
|
73
luci-mod-status/luasrc/view/admin_status/iptables.htm
Normal file
73
luci-mod-status/luasrc/view/admin_status/iptables.htm
Normal file
|
@ -0,0 +1,73 @@
|
|||
<%#
|
||||
Copyright 2008-2009 Steven Barth <steven@midlink.org>
|
||||
Copyright 2008-2018 Jo-Philipp Wich <jo@mein.io>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<%-
|
||||
local fs = require "nixio.fs"
|
||||
local has_ip6tables = fs.access("/usr/sbin/ip6tables")
|
||||
local mode = 4
|
||||
|
||||
if has_ip6tables then
|
||||
mode = luci.dispatcher.context.requestpath
|
||||
mode = tonumber(mode[#mode] ~= "iptables" and mode[#mode]) or 4
|
||||
end
|
||||
-%>
|
||||
|
||||
<%+header%>
|
||||
|
||||
<style type="text/css">
|
||||
span.jump, .cbi-tooltip-container {
|
||||
border-bottom: 1px dotted blue;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.references {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.references .cbi-tooltip {
|
||||
left: 0 !important;
|
||||
top: 1.5em !important;
|
||||
}
|
||||
|
||||
h4 > span {
|
||||
font-size: 90%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<h2 name="content"><%:Firewall Status%></h2>
|
||||
|
||||
<% if has_ip6tables then %>
|
||||
<ul class="cbi-tabmenu">
|
||||
<li data-mode="4" class="cbi-tab<%= mode ~= 4 and "-disabled" %>">
|
||||
<a href="<%=url("admin/status/iptables/4")%>"><%:IPv4 Firewall%></a>
|
||||
</li>
|
||||
<li data-mode="6" class="cbi-tab<%= mode ~= 6 and "-disabled" %>">
|
||||
<a href="<%=url("admin/status/iptables/6")%>"><%:IPv6 Firewall%></a>
|
||||
</li>
|
||||
</ul>
|
||||
<% end %>
|
||||
|
||||
<div style="position: relative">
|
||||
<form method="post" action="<%=url("admin/status/iptables_action")%>" style="position: absolute; right: 0">
|
||||
<input type="hidden" name="token" value="<%=token%>" />
|
||||
<input type="hidden" name="family" value="<%=mode%>" />
|
||||
<input type="button" class="cbi-button" data-hide-empty="false" value="<%:Hide empty chains%>" onclick="hide_empty(this)" />
|
||||
<input type="submit" class="cbi-button" name="zero" value="<%:Reset Counters%>" />
|
||||
<input type="submit" class="cbi-button" name="restart" value="<%:Restart Firewall%>" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="iptables">
|
||||
<p><em class="spinning"><%:Collecting data...%></em></p>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="<%=resource%>/view/status/iptables.js"></script>
|
||||
|
||||
<%+footer%>
|
283
luci-mod-status/luasrc/view/admin_status/load.htm
Normal file
283
luci-mod-status/luasrc/view/admin_status/load.htm
Normal file
|
@ -0,0 +1,283 @@
|
|||
<%#
|
||||
Copyright 2010-2018 Jo-Philipp Wich <jo@mein.io>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<%+header%>
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
var bwxhr = new XHR();
|
||||
|
||||
var G;
|
||||
var TIME = 0;
|
||||
var L01 = 1;
|
||||
var L05 = 2;
|
||||
var L15 = 3;
|
||||
|
||||
var width = 760;
|
||||
var height = 300;
|
||||
var step = 5;
|
||||
|
||||
var data_wanted = Math.floor(width / step);
|
||||
var data_fill = 1;
|
||||
var data_stamp = 0;
|
||||
|
||||
var data_01 = [ ];
|
||||
var data_05 = [ ];
|
||||
var data_15 = [ ];
|
||||
|
||||
var line_01;
|
||||
var line_05;
|
||||
var line_15;
|
||||
|
||||
var label_25;
|
||||
var label_050;
|
||||
var label_75;
|
||||
|
||||
var label_01_cur;
|
||||
var label_01_avg;
|
||||
var label_01_peak;
|
||||
|
||||
var label_05_cur;
|
||||
var label_05_avg;
|
||||
var label_05_peak;
|
||||
|
||||
var label_15_cur;
|
||||
var label_15_avg;
|
||||
var label_15_peak;
|
||||
|
||||
var label_scale;
|
||||
|
||||
|
||||
/* wait for SVG */
|
||||
window.setTimeout(
|
||||
function() {
|
||||
var svg = document.getElementById('bwsvg');
|
||||
|
||||
try {
|
||||
G = svg.getSVGDocument
|
||||
? svg.getSVGDocument() : svg.contentDocument;
|
||||
}
|
||||
catch(e) {
|
||||
G = document.embeds['bwsvg'].getSVGDocument();
|
||||
}
|
||||
|
||||
if (!G)
|
||||
{
|
||||
window.setTimeout(arguments.callee, 1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* find sizes */
|
||||
width = svg.offsetWidth - 2;
|
||||
height = svg.offsetHeight - 2;
|
||||
data_wanted = Math.ceil(width / step);
|
||||
|
||||
/* prefill datasets */
|
||||
for (var i = 0; i < data_wanted; i++)
|
||||
{
|
||||
data_01[i] = 0;
|
||||
data_05[i] = 0;
|
||||
data_15[i] = 0;
|
||||
}
|
||||
|
||||
/* find svg elements */
|
||||
line_01 = G.getElementById('load01');
|
||||
line_05 = G.getElementById('load05');
|
||||
line_15 = G.getElementById('load15');
|
||||
|
||||
label_25 = G.getElementById('label_25');
|
||||
label_50 = G.getElementById('label_50');
|
||||
label_75 = G.getElementById('label_75');
|
||||
|
||||
label_01_cur = document.getElementById('lb_load01_cur');
|
||||
label_01_avg = document.getElementById('lb_load01_avg');
|
||||
label_01_peak = document.getElementById('lb_load01_peak');
|
||||
|
||||
label_05_cur = document.getElementById('lb_load05_cur');
|
||||
label_05_avg = document.getElementById('lb_load05_avg');
|
||||
label_05_peak = document.getElementById('lb_load05_peak');
|
||||
|
||||
label_15_cur = document.getElementById('lb_load15_cur');
|
||||
label_15_avg = document.getElementById('lb_load15_avg');
|
||||
label_15_peak = document.getElementById('lb_load15_peak');
|
||||
|
||||
label_scale = document.getElementById('scale');
|
||||
|
||||
|
||||
/* plot horizontal time interval lines */
|
||||
for (var i = width % (step * 60); i < width; i += step * 60)
|
||||
{
|
||||
var line = G.createElementNS('http://www.w3.org/2000/svg', 'line');
|
||||
line.setAttribute('x1', i);
|
||||
line.setAttribute('y1', 0);
|
||||
line.setAttribute('x2', i);
|
||||
line.setAttribute('y2', '100%');
|
||||
line.setAttribute('style', 'stroke:black;stroke-width:0.1');
|
||||
|
||||
var text = G.createElementNS('http://www.w3.org/2000/svg', 'text');
|
||||
text.setAttribute('x', i + 5);
|
||||
text.setAttribute('y', 15);
|
||||
text.setAttribute('style', 'fill:#eee; font-size:9pt; font-family:sans-serif; text-shadow:1px 1px 1px #000');
|
||||
text.appendChild(G.createTextNode(Math.round((width - i) / step / 60) + 'm'));
|
||||
|
||||
label_25.parentNode.appendChild(line);
|
||||
label_25.parentNode.appendChild(text);
|
||||
}
|
||||
|
||||
label_scale.innerHTML = String.format('<%:(%d minute window, %d second interval)%>', data_wanted / 60, 3);
|
||||
|
||||
/* render datasets, start update interval */
|
||||
XHR.poll(3, '<%=build_url("admin/status/realtime/load_status")%>', null,
|
||||
function(x, data)
|
||||
{
|
||||
var data_max = 0;
|
||||
var data_scale = 0;
|
||||
|
||||
var data_01_avg = 0;
|
||||
var data_05_avg = 0;
|
||||
var data_15_avg = 0;
|
||||
|
||||
var data_01_peak = 0;
|
||||
var data_05_peak = 0;
|
||||
var data_15_peak = 0;
|
||||
|
||||
for (var i = data_stamp ? 0 : 1; i < data.length; i++)
|
||||
{
|
||||
/* skip overlapping entries */
|
||||
if (data[i][TIME] <= data_stamp)
|
||||
continue;
|
||||
|
||||
data_fill++;
|
||||
|
||||
data_01.push(data[i][L01]);
|
||||
data_05.push(data[i][L05]);
|
||||
data_15.push(data[i][L15]);
|
||||
}
|
||||
|
||||
/* cut off outdated entries */
|
||||
data_fill = Math.min(data_fill, data_wanted);
|
||||
data_01 = data_01.slice(data_01.length - data_wanted, data_01.length);
|
||||
data_05 = data_05.slice(data_05.length - data_wanted, data_05.length);
|
||||
data_15 = data_15.slice(data_15.length - data_wanted, data_15.length);
|
||||
|
||||
/* find peak */
|
||||
for (var i = 0; i < data_01.length; i++)
|
||||
{
|
||||
data_max = Math.max(data_max, data_01[i]);
|
||||
data_max = Math.max(data_max, data_05[i]);
|
||||
data_max = Math.max(data_max, data_15[i]);
|
||||
|
||||
data_01_peak = Math.max(data_01_peak, data_01[i]);
|
||||
data_05_peak = Math.max(data_05_peak, data_05[i]);
|
||||
data_15_peak = Math.max(data_15_peak, data_15[i]);
|
||||
|
||||
data_01_avg += data_01[i];
|
||||
data_05_avg += data_05[i];
|
||||
data_15_avg += data_15[i];
|
||||
}
|
||||
|
||||
data_01_avg = data_01_avg / data_fill;
|
||||
data_05_avg = data_05_avg / data_fill;
|
||||
data_15_avg = data_15_avg / data_fill;
|
||||
|
||||
/* remember current timestamp, calculate horizontal scale */
|
||||
data_stamp = data[data.length-1][TIME];
|
||||
data_scale = height / (data_max * 1.1);
|
||||
|
||||
|
||||
/* plot data */
|
||||
var pt_01 = '0,' + height;
|
||||
var pt_05 = '0,' + height;
|
||||
var pt_15 = '0,' + height;
|
||||
|
||||
var y_01 = 0;
|
||||
var y_05 = 0;
|
||||
var y_15 = 0;
|
||||
|
||||
for (var i = 0; i < data_01.length; i++)
|
||||
{
|
||||
var x = i * step;
|
||||
|
||||
y_01 = height - Math.floor(data_01[i] * data_scale);
|
||||
y_05 = height - Math.floor(data_05[i] * data_scale);
|
||||
y_15 = height - Math.floor(data_15[i] * data_scale);
|
||||
|
||||
pt_01 += ' ' + x + ',' + y_01;
|
||||
pt_05 += ' ' + x + ',' + y_05;
|
||||
pt_15 += ' ' + x + ',' + y_15;
|
||||
}
|
||||
|
||||
pt_01 += ' ' + width + ',' + y_01 + ' ' + width + ',' + height;
|
||||
pt_05 += ' ' + width + ',' + y_05 + ' ' + width + ',' + height;
|
||||
pt_15 += ' ' + width + ',' + y_15 + ' ' + width + ',' + height;
|
||||
|
||||
|
||||
line_01.setAttribute('points', pt_01);
|
||||
line_05.setAttribute('points', pt_05);
|
||||
line_15.setAttribute('points', pt_15);
|
||||
|
||||
label_25.firstChild.data = (1.1 * 0.25 * data_max / 100).toFixed(2);
|
||||
label_50.firstChild.data = (1.1 * 0.50 * data_max / 100).toFixed(2);
|
||||
label_75.firstChild.data = (1.1 * 0.75 * data_max / 100).toFixed(2);
|
||||
|
||||
label_01_cur.innerHTML = (data_01[data_01.length-1] / 100).toFixed(2);
|
||||
label_05_cur.innerHTML = (data_05[data_05.length-1] / 100).toFixed(2);
|
||||
label_15_cur.innerHTML = (data_15[data_15.length-1] / 100).toFixed(2);
|
||||
|
||||
label_01_avg.innerHTML = (data_01_avg / 100).toFixed(2);
|
||||
label_05_avg.innerHTML = (data_05_avg / 100).toFixed(2);
|
||||
label_15_avg.innerHTML = (data_15_avg / 100).toFixed(2);
|
||||
|
||||
label_01_peak.innerHTML = (data_01_peak / 100).toFixed(2);
|
||||
label_05_peak.innerHTML = (data_05_peak / 100).toFixed(2);
|
||||
label_15_peak.innerHTML = (data_15_peak / 100).toFixed(2);
|
||||
}
|
||||
);
|
||||
|
||||
XHR.run();
|
||||
}
|
||||
}, 1000
|
||||
);
|
||||
//]]></script>
|
||||
|
||||
<h2 name="content"><%:Realtime Load%></h2>
|
||||
|
||||
<embed id="bwsvg" style="width:100%; height:300px; border:1px solid #000000; background-color:#FFFFFF" src="<%=resource%>/load.svg" />
|
||||
<div style="text-align:right"><small id="scale">-</small></div>
|
||||
<br />
|
||||
|
||||
<div class="table" style="width:100%; table-layout:fixed" cellspacing="5">
|
||||
<div class="tr">
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong style="border-bottom:2px solid #ff0000; white-space:nowrap"><%:1 Minute Load:%></strong></div>
|
||||
<div class="td" id="lb_load01_cur">0</div>
|
||||
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong><%:Average:%></strong></div>
|
||||
<div class="td" id="lb_load01_avg">0</div>
|
||||
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong><%:Peak:%></strong></div>
|
||||
<div class="td" id="lb_load01_peak">0</div>
|
||||
</div>
|
||||
<div class="tr">
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong style="border-bottom:2px solid #ff6600; white-space:nowrap"><%:5 Minute Load:%></strong></div>
|
||||
<div class="td" id="lb_load05_cur">0</div>
|
||||
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong><%:Average:%></strong></div>
|
||||
<div class="td" id="lb_load05_avg">0</div>
|
||||
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong><%:Peak:%></strong></div>
|
||||
<div class="td" id="lb_load05_peak">0</div>
|
||||
</div>
|
||||
<div class="tr">
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong style="border-bottom:2px solid #ffaa00; white-space:nowrap"><%:15 Minute Load:%></strong></div>
|
||||
<div class="td" id="lb_load15_cur">0</div>
|
||||
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong><%:Average:%></strong></div>
|
||||
<div class="td" id="lb_load15_avg">0</div>
|
||||
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong><%:Peak:%></strong></div>
|
||||
<div class="td" id="lb_load15_peak">0</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%+footer%>
|
156
luci-mod-status/luasrc/view/admin_status/routes.htm
Normal file
156
luci-mod-status/luasrc/view/admin_status/routes.htm
Normal file
|
@ -0,0 +1,156 @@
|
|||
<%#
|
||||
Copyright 2008-2009 Steven Barth <steven@midlink.org>
|
||||
Copyright 2008-2015 Jo-Philipp Wich <jow@openwrt.org>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<%-
|
||||
require "luci.tools.webadmin"
|
||||
require "nixio.fs"
|
||||
|
||||
local ip = require "luci.ip"
|
||||
local style = true
|
||||
local _, v
|
||||
|
||||
local rtn = {
|
||||
[255] = "local",
|
||||
[254] = "main",
|
||||
[253] = "default",
|
||||
[0] = "unspec"
|
||||
}
|
||||
|
||||
if nixio.fs.access("/etc/iproute2/rt_tables") then
|
||||
local ln
|
||||
for ln in io.lines("/etc/iproute2/rt_tables") do
|
||||
local i, n = ln:match("^(%d+)%s+(%S+)")
|
||||
if i and n then
|
||||
rtn[tonumber(i)] = n
|
||||
end
|
||||
end
|
||||
end
|
||||
-%>
|
||||
|
||||
<%+header%>
|
||||
|
||||
|
||||
<div class="cbi-map" id="cbi-network">
|
||||
<h2 name="content"><%:Routes%></h2>
|
||||
<div class="cbi-map-descr"><%:The following rules are currently active on this system.%></div>
|
||||
|
||||
<div class="cbi-section">
|
||||
<legend>ARP</legend>
|
||||
<div class="cbi-section-node">
|
||||
<div class="table">
|
||||
<div class="tr table-titles">
|
||||
<div class="th"><%_<abbr title="Internet Protocol Version 4">IPv4</abbr>-Address%></div>
|
||||
<div class="th"><%_<abbr title="Media Access Control">MAC</abbr>-Address%></div>
|
||||
<div class="th"><%:Interface%></div>
|
||||
</div>
|
||||
|
||||
<%
|
||||
for _, v in ipairs(ip.neighbors({ family = 4 })) do
|
||||
if v.mac then
|
||||
%>
|
||||
<div class="tr cbi-rowstyle-<%=(style and 1 or 2)%>">
|
||||
<div class="td"><%=v.dest%></div>
|
||||
<div class="td"><%=v.mac%></div>
|
||||
<div class="td"><%=luci.tools.webadmin.iface_get_network(v.dev) or '(' .. v.dev .. ')'%></div>
|
||||
</div>
|
||||
<%
|
||||
style = not style
|
||||
end
|
||||
end
|
||||
%>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cbi-section">
|
||||
<legend><%_Active <abbr title="Internet Protocol Version 4">IPv4</abbr>-Routes%></legend>
|
||||
<div class="cbi-section-node">
|
||||
<div class="table">
|
||||
<div class="tr table-titles">
|
||||
<div class="th"><%:Network%></div>
|
||||
<div class="th"><%:Target%></div>
|
||||
<div class="th"><%_<abbr title="Internet Protocol Version 4">IPv4</abbr>-Gateway%></div>
|
||||
<div class="th"><%:Metric%></div>
|
||||
<div class="th"><%:Table%></div>
|
||||
</div>
|
||||
<% for _, v in ipairs(ip.routes({ family = 4, type = 1 })) do %>
|
||||
<div class="tr cbi-rowstyle-<%=(style and 1 or 2)%>">
|
||||
<div class="td"><%=luci.tools.webadmin.iface_get_network(v.dev) or v.dev%></div>
|
||||
<div class="td"><%=v.dest%></div>
|
||||
<div class="td"><%=v.gw or "-"%></div>
|
||||
<div class="td"><%=v.metric or 0%></div>
|
||||
<div class="td"><%=rtn[v.table] or v.table%></div>
|
||||
</div>
|
||||
<% style = not style end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%
|
||||
if nixio.fs.access("/proc/net/ipv6_route") then
|
||||
style = true
|
||||
%>
|
||||
<div class="cbi-section">
|
||||
<legend><%_Active <abbr title="Internet Protocol Version 6">IPv6</abbr>-Routes%></legend>
|
||||
<div class="cbi-section-node">
|
||||
<div class="table">
|
||||
<div class="tr table-titles">
|
||||
<div class="th"><%:Network%></div>
|
||||
<div class="th"><%:Target%></div>
|
||||
<div class="th"><%:Source%></div>
|
||||
<div class="th"><%:Metric%></div>
|
||||
<div class="th"><%:Table%></div>
|
||||
</div>
|
||||
<%
|
||||
for _, v in ipairs(ip.routes({ family = 6, type = 1 })) do
|
||||
if v.dest and not v.dest:is6linklocal() then
|
||||
%>
|
||||
<div class="tr cbi-rowstyle-<%=(style and 1 or 2)%>">
|
||||
<div class="td"><%=luci.tools.webadmin.iface_get_network(v.dev) or '(' .. v.dev .. ')'%></div>
|
||||
<div class="td"><%=v.dest%></div>
|
||||
<div class="td"><%=v.from%></div>
|
||||
<div class="td"><%=v.metric or 0%></div>
|
||||
<div class="td"><%=rtn[v.table] or v.table%></div>
|
||||
</div>
|
||||
<%
|
||||
style = not style
|
||||
end
|
||||
end
|
||||
%>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cbi-section">
|
||||
<legend><%:IPv6 Neighbours%></legend>
|
||||
<div class="cbi-section-node">
|
||||
<div class="table">
|
||||
<div class="tr table-titles">
|
||||
<div class="th"><%:IPv6-Address%></div>
|
||||
<div class="th"><%:MAC-Address%></div>
|
||||
<div class="th"><%:Interface%></div>
|
||||
</div>
|
||||
<%
|
||||
for _, v in ipairs(ip.neighbors({ family = 6 })) do
|
||||
if v.dest and not v.dest:is6linklocal() and v.mac then
|
||||
%>
|
||||
<div class="tr cbi-rowstyle-<%=(style and 1 or 2)%>">
|
||||
<div class="td"><%=v.dest%></div>
|
||||
<div class="td"><%=v.mac%></div>
|
||||
<div class="td"><%=luci.tools.webadmin.iface_get_network(v.dev) or '(' .. v.dev .. ')'%></div>
|
||||
</div>
|
||||
<%
|
||||
style = not style
|
||||
end
|
||||
end
|
||||
%>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%+footer%>
|
12
luci-mod-status/luasrc/view/admin_status/syslog.htm
Normal file
12
luci-mod-status/luasrc/view/admin_status/syslog.htm
Normal file
|
@ -0,0 +1,12 @@
|
|||
<%#
|
||||
Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<%+header%>
|
||||
<h2 name="content"><%:System Log%></h2>
|
||||
<div id="content_syslog">
|
||||
<textarea style="font-size: 12px;" readonly="readonly" wrap="off" rows="<%=syslog:cmatch("\n")+2%>" id="syslog"><%=syslog:pcdata()%></textarea>
|
||||
</div>
|
||||
<%+footer%>
|
370
luci-mod-status/luasrc/view/admin_status/wireless.htm
Normal file
370
luci-mod-status/luasrc/view/admin_status/wireless.htm
Normal file
|
@ -0,0 +1,370 @@
|
|||
<%#
|
||||
Copyright 2011-2018 Jo-Philipp Wich <jo@mein.io>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<%-
|
||||
local ntm = require "luci.model.network".init()
|
||||
|
||||
local dev
|
||||
local devices = { }
|
||||
for _, dev in luci.util.vspairs(luci.sys.net.devices()) do
|
||||
if dev:match("^wlan%d") or dev:match("^ath%d") or dev:match("^wl%d") then
|
||||
devices[#devices+1] = dev
|
||||
end
|
||||
end
|
||||
|
||||
local curdev = luci.http.formvalue("dev") or devices[1]
|
||||
-%>
|
||||
|
||||
<%+header%>
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
var bwxhr = new XHR();
|
||||
|
||||
var G, G2;
|
||||
var TIME = 0;
|
||||
var RATE = 1;
|
||||
var RSSI = 2;
|
||||
var NOISE = 3;
|
||||
|
||||
var width = 760;
|
||||
var height = 300;
|
||||
var step = 5;
|
||||
|
||||
var data_wanted = Math.floor(width / step);
|
||||
var data_fill = 1;
|
||||
var data_stamp = 0;
|
||||
|
||||
var data_rssi = [ ];
|
||||
var data_noise = [ ];
|
||||
var data_rate = [ ];
|
||||
|
||||
var line_rssi;
|
||||
var line_noise;
|
||||
var line_rate;
|
||||
|
||||
var label_25, label_25_2;
|
||||
var label_50, label_50_2;
|
||||
var label_75, label_75_2;
|
||||
|
||||
var label_rssi_cur;
|
||||
var label_rssi_avg;
|
||||
var label_rssi_peak;
|
||||
|
||||
var label_noise_cur;
|
||||
var label_noise_avg;
|
||||
var label_noise_peak;
|
||||
|
||||
var label_rate_cur;
|
||||
var label_rate_avg;
|
||||
var label_rate_peak;
|
||||
|
||||
var label_scale;
|
||||
var label_scale_2;
|
||||
|
||||
|
||||
/* wait for SVG */
|
||||
window.setTimeout(
|
||||
function() {
|
||||
var svg = document.getElementById('iwsvg');
|
||||
var svg2 = document.getElementById('iwsvg2');
|
||||
|
||||
try {
|
||||
G = svg.getSVGDocument
|
||||
? svg.getSVGDocument() : svg.contentDocument;
|
||||
G2 = svg2.getSVGDocument
|
||||
? svg2.getSVGDocument() : svg2.contentDocument;
|
||||
}
|
||||
catch(e) {
|
||||
G = document.embeds['iwsvg'].getSVGDocument();
|
||||
G2 = document.embeds['iwsvg2'].getSVGDocument();
|
||||
}
|
||||
|
||||
if (!G || !G2)
|
||||
{
|
||||
window.setTimeout(arguments.callee, 1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* find sizes */
|
||||
width = svg.offsetWidth - 2;
|
||||
height = svg.offsetHeight - 2;
|
||||
data_wanted = Math.ceil(width / step);
|
||||
|
||||
/* prefill datasets */
|
||||
for (var i = 0; i < data_wanted; i++)
|
||||
{
|
||||
data_rssi[i] = 0;
|
||||
data_noise[i] = 0;
|
||||
data_rate[i] = 0;
|
||||
}
|
||||
|
||||
/* find svg elements */
|
||||
line_rssi = G.getElementById('rssi');
|
||||
line_noise = G.getElementById('noise');
|
||||
line_rate = G2.getElementById('rate');
|
||||
|
||||
label_25 = G.getElementById('label_25');
|
||||
label_50 = G.getElementById('label_50');
|
||||
label_75 = G.getElementById('label_75');
|
||||
label_25_2 = G2.getElementById('label_25');
|
||||
label_50_2 = G2.getElementById('label_50');
|
||||
label_75_2 = G2.getElementById('label_75');
|
||||
|
||||
label_rssi_cur = document.getElementById('rssi_bw_cur');
|
||||
label_rssi_avg = document.getElementById('rssi_bw_avg');
|
||||
label_rssi_peak = document.getElementById('rssi_bw_peak');
|
||||
|
||||
label_noise_cur = document.getElementById('noise_bw_cur');
|
||||
label_noise_avg = document.getElementById('noise_bw_avg');
|
||||
label_noise_peak = document.getElementById('noise_bw_peak');
|
||||
|
||||
label_rate_cur = document.getElementById('rate_bw_cur');
|
||||
label_rate_avg = document.getElementById('rate_bw_avg');
|
||||
label_rate_peak = document.getElementById('rate_bw_peak');
|
||||
|
||||
label_scale = document.getElementById('scale');
|
||||
label_scale_2 = document.getElementById('scale2');
|
||||
|
||||
|
||||
/* plot horizontal time interval lines */
|
||||
for (var i = width % (step * 60); i < width; i += step * 60)
|
||||
{
|
||||
var line = G.createElementNS('http://www.w3.org/2000/svg', 'line');
|
||||
line.setAttribute('x1', i);
|
||||
line.setAttribute('y1', 0);
|
||||
line.setAttribute('x2', i);
|
||||
line.setAttribute('y2', '100%');
|
||||
line.setAttribute('style', 'stroke:black;stroke-width:0.1');
|
||||
|
||||
var text = G.createElementNS('http://www.w3.org/2000/svg', 'text');
|
||||
text.setAttribute('x', i + 5);
|
||||
text.setAttribute('y', 15);
|
||||
text.setAttribute('style', 'fill:#eee; font-size:9pt; font-family:sans-serif; text-shadow:1px 1px 1px #000');
|
||||
text.appendChild(G.createTextNode(Math.round((width - i) / step / 60) + 'm'));
|
||||
|
||||
label_25.parentNode.appendChild(line);
|
||||
label_25.parentNode.appendChild(text);
|
||||
|
||||
|
||||
var line2 = G2.createElementNS('http://www.w3.org/2000/svg', 'line');
|
||||
line2.setAttribute('x1', i);
|
||||
line2.setAttribute('y1', 0);
|
||||
line2.setAttribute('x2', i);
|
||||
line2.setAttribute('y2', '100%');
|
||||
line2.setAttribute('style', 'stroke:black;stroke-width:0.1');
|
||||
|
||||
var text2 = G2.createElementNS('http://www.w3.org/2000/svg', 'text');
|
||||
text2.setAttribute('x', i + 5);
|
||||
text2.setAttribute('y', 15);
|
||||
text2.setAttribute('style', 'fill:#eee; font-size:9pt; font-family:sans-serif; text-shadow:1px 1px 1px #000');
|
||||
text2.appendChild(G.createTextNode(Math.round((width - i) / step / 60) + 'm'));
|
||||
|
||||
label_25_2.parentNode.appendChild(line2);
|
||||
label_25_2.parentNode.appendChild(text2);
|
||||
}
|
||||
|
||||
label_scale.innerHTML = String.format('<%:(%d minute window, %d second interval)%>', data_wanted / 60, 3);
|
||||
label_scale_2.innerHTML = String.format('<%:(%d minute window, %d second interval)%>', data_wanted / 60, 3);
|
||||
|
||||
/* render datasets, start update interval */
|
||||
XHR.poll(3, '<%=build_url("admin/status/realtime/wireless_status", curdev)%>', null,
|
||||
function(x, data)
|
||||
{
|
||||
var noise_floor = 255;
|
||||
var rate_floor = 60000;
|
||||
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
noise_floor = Math.min(noise_floor, data[i][NOISE]);
|
||||
rate_floor = Math.min(rate_floor, data[i][RATE]);
|
||||
}
|
||||
|
||||
noise_floor -= 5;
|
||||
|
||||
var data_max = 0;
|
||||
var data_scale = 0;
|
||||
var data_max_2 = 0;
|
||||
var data_scale_2 = 0;
|
||||
|
||||
var data_rssi_avg = 0;
|
||||
var data_noise_avg = 0;
|
||||
var data_rate_avg = 0;
|
||||
|
||||
var data_rssi_peak = 0;
|
||||
var data_noise_peak = 0;
|
||||
var data_rate_peak = 0;
|
||||
|
||||
for (var i = data_stamp ? 0 : 1; i < data.length; i++)
|
||||
{
|
||||
/* skip overlapping entries */
|
||||
if (data[i][TIME] <= data_stamp)
|
||||
continue;
|
||||
|
||||
data_fill++;
|
||||
|
||||
data_rssi.push(data[i][RSSI] - noise_floor);
|
||||
data_noise.push(data[i][NOISE] - noise_floor);
|
||||
data_rate.push(Math.floor(data[i][RATE] / 1000));
|
||||
}
|
||||
|
||||
/* cut off outdated entries */
|
||||
data_fill = Math.min(data_fill, data_wanted);
|
||||
data_rssi = data_rssi.slice(data_rssi.length - data_wanted, data_rssi.length);
|
||||
data_noise = data_noise.slice(data_noise.length - data_wanted, data_noise.length);
|
||||
data_rate = data_rate.slice(data_rate.length - data_wanted, data_rate.length);
|
||||
|
||||
/* find peak */
|
||||
for (var i = 0; i < data_rssi.length; i++)
|
||||
{
|
||||
data_max = Math.max(data_max, data_rssi[i]);
|
||||
data_max_2 = Math.max(data_max_2, data_rate[i]);
|
||||
|
||||
data_rssi_peak = Math.max(data_rssi_peak, data_rssi[i]);
|
||||
data_noise_peak = Math.max(data_noise_peak, data_noise[i]);
|
||||
data_rate_peak = Math.max(data_rate_peak, data_rate[i]);
|
||||
|
||||
data_rssi_avg += data_rssi[i];
|
||||
data_noise_avg += data_noise[i];
|
||||
data_rate_avg += data_rate[i];
|
||||
}
|
||||
|
||||
data_rssi_avg = data_rssi_avg / data_fill;
|
||||
data_noise_avg = data_noise_avg / data_fill;
|
||||
data_rate_avg = data_rate_avg / data_fill;
|
||||
|
||||
/* remember current timestamp, calculate horizontal scale */
|
||||
data_stamp = data[data.length-1][TIME];
|
||||
data_scale = (height / (data_max * 1.1)).toFixed(1);
|
||||
data_scale_2 = (height / (data_max_2 * 1.1)).toFixed(1);
|
||||
|
||||
/* plot data */
|
||||
var pt_rssi = '0,' + height;
|
||||
var pt_noise = '0,' + height;
|
||||
var pt_rate = '0,' + height;
|
||||
|
||||
var y_rssi = 0;
|
||||
var y_noise = 0;
|
||||
var y_rate = 0;
|
||||
|
||||
for (var i = 0; i < data_rssi.length; i++)
|
||||
{
|
||||
var x = i * step;
|
||||
|
||||
y_rssi = height - Math.floor(data_rssi[i] * data_scale);
|
||||
y_noise = height - Math.floor(data_noise[i] * data_scale);
|
||||
y_rate = height - Math.floor(data_rate[i] * data_scale_2);
|
||||
|
||||
y_rssi -= Math.floor(y_rssi % (1/data_scale));
|
||||
y_noise -= Math.floor(y_noise % (1/data_scale));
|
||||
|
||||
pt_rssi += ' ' + x + ',' + y_rssi;
|
||||
pt_noise += ' ' + x + ',' + y_noise;
|
||||
pt_rate += ' ' + x + ',' + y_rate;
|
||||
}
|
||||
|
||||
pt_rssi += ' ' + width + ',' + y_rssi + ' ' + width + ',' + height;
|
||||
pt_noise += ' ' + width + ',' + y_noise + ' ' + width + ',' + height;
|
||||
pt_rate += ' ' + width + ',' + y_rate + ' ' + width + ',' + height;
|
||||
|
||||
line_rssi.setAttribute('points', pt_rssi);
|
||||
line_noise.setAttribute('points', pt_noise);
|
||||
line_rate.setAttribute('points', pt_rate);
|
||||
|
||||
function wireless_label(dbm, noise)
|
||||
{
|
||||
if (noise)
|
||||
return String.format("%d <%:dBm%> (SNR %d <%:dB%>)", noise_floor + dbm - 255, dbm - noise);
|
||||
else
|
||||
return String.format("%d <%:dBm%>", noise_floor + dbm - 255);
|
||||
}
|
||||
|
||||
function rate_label(mbit)
|
||||
{
|
||||
return String.format("%d <%:Mbit/s%>", mbit);
|
||||
}
|
||||
|
||||
label_25.firstChild.data = wireless_label(1.1 * 0.25 * data_max);
|
||||
label_50.firstChild.data = wireless_label(1.1 * 0.50 * data_max);
|
||||
label_75.firstChild.data = wireless_label(1.1 * 0.75 * data_max);
|
||||
|
||||
label_25_2.firstChild.data = rate_label(1.1 * 0.25 * data_max_2);
|
||||
label_50_2.firstChild.data = rate_label(1.1 * 0.50 * data_max_2);
|
||||
label_75_2.firstChild.data = rate_label(1.1 * 0.75 * data_max_2);
|
||||
|
||||
label_rssi_cur.innerHTML = wireless_label(data_rssi[data_rssi.length-1], data_noise[data_noise.length-1]).nobr();
|
||||
label_noise_cur.innerHTML = wireless_label(data_noise[data_noise.length-1]).nobr();
|
||||
|
||||
label_rssi_avg.innerHTML = wireless_label(data_rssi_avg, data_noise_avg).nobr();
|
||||
label_noise_avg.innerHTML = wireless_label(data_noise_avg).nobr();
|
||||
|
||||
label_rssi_peak.innerHTML = wireless_label(data_rssi_peak, data_noise_peak).nobr();
|
||||
label_noise_peak.innerHTML = wireless_label(data_noise_peak).nobr();
|
||||
|
||||
label_rate_cur.innerHTML = rate_label(data_rate[data_rate.length-1]);
|
||||
label_rate_avg.innerHTML = rate_label(data_rate_avg);
|
||||
label_rate_peak.innerHTML = rate_label(data_rate_peak);
|
||||
}
|
||||
);
|
||||
|
||||
XHR.run();
|
||||
}
|
||||
}, 1000
|
||||
);
|
||||
//]]></script>
|
||||
|
||||
<h2 name="content"><%:Realtime Wireless%></h2>
|
||||
|
||||
<ul class="cbi-tabmenu">
|
||||
<% for _, dev in ipairs(devices) do %>
|
||||
<li class="cbi-tab<%= dev == curdev and "" or "-disabled" %>"><a href="?dev=<%=pcdata(dev)%>"><%=pcdata(dev)%></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
|
||||
<embed id="iwsvg" style="width:100%; height:300px; border:1px solid #000000; background-color:#FFFFFF" src="<%=resource%>/wireless.svg" />
|
||||
<div style="text-align:right"><small id="scale">-</small></div>
|
||||
<br />
|
||||
|
||||
<div class="table" style="width:100%; table-layout:fixed" cellspacing="5">
|
||||
<div class="tr">
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong style="border-bottom:2px solid blue"><%:Signal:%></strong></div>
|
||||
<div class="td" id="rssi_bw_cur">0 <%:dBm%></div>
|
||||
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong><%:Average:%></strong></div>
|
||||
<div class="td" id="rssi_bw_avg">0 <%:dBm%></div>
|
||||
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong><%:Peak:%></strong></div>
|
||||
<div class="td" id="rssi_bw_peak">0 <%:dBm%></div>
|
||||
</div>
|
||||
<div class="tr">
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong style="border-bottom:2px solid red"><%:Noise:%></strong></div>
|
||||
<div class="td" id="noise_bw_cur">0 <%:dBm%></div>
|
||||
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong><%:Average:%></strong></div>
|
||||
<div class="td" id="noise_bw_avg">0 <%:dBm%></div>
|
||||
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong><%:Peak:%></strong></div>
|
||||
<div class="td" id="noise_bw_peak">0 <%:dBm%></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<embed id="iwsvg2" style="width:100%; height:300px; border:1px solid #000000; background-color:#FFFFFF" src="<%=resource%>/wifirate.svg" />
|
||||
<div style="text-align:right"><small id="scale2">-</small></div>
|
||||
<br />
|
||||
|
||||
<div class="table" style="width:100%; table-layout:fixed" cellspacing="5">
|
||||
<div class="tr">
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong style="border-bottom:2px solid green"><%:Phy Rate:%></strong></div>
|
||||
<div class="td" id="rate_bw_cur">0 MBit/s</div>
|
||||
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong><%:Average:%></strong></div>
|
||||
<div class="td" id="rate_bw_avg">0 MBit/s</div>
|
||||
|
||||
<div class="td" style="text-align:right; vertical-align:top"><strong><%:Peak:%></strong></div>
|
||||
<div class="td" id="rate_bw_peak">0 MBit/s</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%+footer%>
|
Loading…
Add table
Add a link
Reference in a new issue