<%
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 wan then
+ local dev = wan:get_interface()
+ local link = dev and ipc.link(dev:name())
rv.wan = {
ipaddr = wan:ipaddr(),
gwaddr = wan:gwaddr(),
expires = wan:expires(),
uptime = wan:uptime(),
proto = wan:proto(),
+ i18n = wan:get_i18n(),
ifname = wan:ifname(),
- link = wan:adminlink()
+ link = wan:adminlink(),
+ mac = dev and dev:mac(),
+ type = dev and dev:type(),
+ name = dev and dev:get_i18n(),
+ ether = link and link.type == 1
}
end
if wan6 then
+ local dev = wan6:get_interface()
+ local link = dev and ipc.link(dev:name())
rv.wan6 = {
ip6addr = wan6:ip6addr(),
gw6addr = wan6:gw6addr(),
ip6prefix = wan6:ip6prefix(),
uptime = wan6:uptime(),
proto = wan6:proto(),
+ i18n = wan6:get_i18n(),
ifname = wan6:ifname(),
- link = wan6:adminlink()
+ link = wan6:adminlink(),
+ mac = dev and dev:mac(),
+ type = dev and dev:type(),
+ name = dev and dev:get_i18n(),
+ ether = link and link.type == 1
}
end
});
}
- XHR.poll(5, '<%=REQUEST_URI%>', { status: 1 },
- function(x, info)
- {
- if (!(npoll++ % 5))
- updateHosts();
+ function labelList(items, offset) {
+ var rv = [ ];
- var si = document.getElementById('wan4_i');
- var ss = document.getElementById('wan4_s');
- var ifc = info.wan;
+ for (var i = offset || 0; i < items.length; i += 2) {
+ var label = items[i],
+ value = items[i+1];
- if (ifc && ifc.ifname && ifc.proto != 'none')
- {
- var s = String.format(
- '<strong><%:Type%>: </strong>%s<br />' +
- '<strong><%:Address%>: </strong>%s<br />' +
- '<strong><%:Netmask%>: </strong>%s<br />' +
- '<strong><%:Gateway%>: </strong>%s<br />',
- ifc.proto,
- (ifc.ipaddr) ? ifc.ipaddr : '0.0.0.0',
- (ifc.netmask && ifc.netmask != ifc.ipaddr) ? ifc.netmask : '255.255.255.255',
- (ifc.gwaddr) ? ifc.gwaddr : '0.0.0.0'
- );
+ if (value === undefined || value === null)
+ continue;
- for (var i = 0; i < ifc.dns.length; i++)
- {
- s += String.format(
- '<strong><%:DNS%> %d: </strong>%s<br />',
- i + 1, ifc.dns[i]
- );
- }
+ if (label)
+ rv.push(E('strong', [label, ': ']));
- if (ifc.expires > -1)
- {
- s += String.format(
- '<strong><%:Expires%>: </strong>%t<br />',
- ifc.expires
- );
- }
-
- if (ifc.uptime > 0)
- {
- s += String.format(
- '<strong><%:Connected%>: </strong>%t<br />',
- ifc.uptime
- );
- }
-
- ss.innerHTML = String.format('<small>%s</small>', s);
- si.innerHTML = String.format(
- '<img src="<%=resource%>/icons/ethernet.png" />' +
- '<br /><small><a href="%s">%s</a></small>',
- ifc.link, ifc.ifname
- );
- }
- else
- {
- si.innerHTML = '<img src="<%=resource%>/icons/ethernet_disabled.png" /><br /><small>?</small>';
- ss.innerHTML = '<em><%:Not connected%></em>';
- }
+ rv.push(value, E('br'));
+ }
- <% if has_ipv6 then %>
- var si6 = document.getElementById('wan6_i');
- var ss6 = document.getElementById('wan6_s');
- var ifc6 = info.wan6;
+ return rv;
+ }
- if (ifc6 && ifc6.ifname && ifc6.proto != 'none')
- {
- var s = String.format(
- '<strong><%:Type%>: </strong>%s%s<br />',
- ifc6.proto, (ifc6.ip6prefix) ? '-pd' : ''
- );
+ function renderBox(title, active, childs) {
+ childs = childs || [];
+ childs.unshift(E('span', labelList(arguments, 3)));
- if (!ifc6.ip6prefix)
- {
- s += String.format(
- '<strong><%:Address%>: </strong>%s<br />',
- (ifc6.ip6addr) ? ifc6.ip6addr : '::'
- );
- }
- else
- {
- s += String.format(
- '<strong><%:Prefix Delegated%>: </strong>%s<br />',
- ifc6.ip6prefix
- );
- if (ifc6.ip6addr)
- {
- s += String.format(
- '<strong><%:Address%>: </strong>%s<br />',
- ifc6.ip6addr
- );
- }
- }
+ return E('div', { class: 'ifacebox' }, [
+ E('div', { class: 'ifacebox-head center ' + (active ? 'active' : '') },
+ E('strong', title)),
+ E('div', { class: 'ifacebox-body' }, childs)
+ ]);
+ }
- s += String.format(
- '<strong><%:Gateway%>: </strong>%s<br />',
- (ifc6.gw6addr) ? ifc6.gw6addr : '::'
- );
+ function renderBadge(icon, title) {
+ return E('span', { class: 'ifacebadge' }, [
+ E('img', { src: icon, title: title || '' }),
+ E('span', labelList(arguments, 2))
+ ]);
+ }
- for (var i = 0; i < ifc6.dns.length; i++)
- {
- s += String.format(
- '<strong><%:DNS%> %d: </strong>%s<br />',
- i + 1, ifc6.dns[i]
- );
- }
+ XHR.poll(5, '<%=REQUEST_URI%>', { status: 1 },
+ function(x, info)
+ {
+ if (!(npoll++ % 5))
+ updateHosts();
- if (ifc6.uptime > 0)
- {
- s += String.format(
- '<strong><%:Connected%>: </strong>%t<br />',
- ifc6.uptime
- );
- }
+ var us = document.getElementById('upstream_status_table');
+
+ while (us.lastElementChild)
+ us.removeChild(us.lastElementChild);
+
+ var ifc = info.wan || {};
+
+ us.appendChild(renderBox(
+ '<%:IPv4 Upstream%>',
+ (ifc.ifname && ifc.proto != 'none'),
+ [ renderBadge(
+ '<%=resource%>/icons/%s.png'.format((ifc && ifc.type) ? ifc.type : 'ethernet_disabled'), null,
+ '<%:Device%>', ifc ? (ifc.name || ifc.ifname || '-') : '-',
+ '<%:MAC-Address%>', (ifc && ifc.ether) ? ifc.mac : null) ],
+ '<%:Protocol%>', ifc.i18n || E('em', '<%:Not connected%>'),
+ '<%:Address%>', (ifc.ipaddr) ? ifc.ipaddr : '0.0.0.0',
+ '<%:Netmask%>', (ifc.netmask && ifc.netmask != ifc.ipaddr) ? ifc.netmask : '255.255.255.255',
+ '<%:Gateway%>', (ifc.gwaddr) ? ifc.gwaddr : '0.0.0.0',
+ '<%:DNS%> 1', (ifc.dns) ? ifc.dns[0] : null,
+ '<%:DNS%> 2', (ifc.dns) ? ifc.dns[1] : null,
+ '<%:DNS%> 3', (ifc.dns) ? ifc.dns[2] : null,
+ '<%:DNS%> 4', (ifc.dns) ? ifc.dns[3] : null,
+ '<%:DNS%> 5', (ifc.dns) ? ifc.dns[4] : null,
+ '<%:Expires%>', (ifc.expires > -1) ? '%t'.format(ifc.expires) : null,
+ '<%:Connected%>', (ifc.uptime > 0) ? '%t'.format(ifc.uptime) : null));
- ss6.innerHTML = String.format('<small>%s</small>', s);
- si6.innerHTML = String.format(
- '<img src="<%=resource%>/icons/ethernet.png" />' +
- '<br /><small><a href="%s">%s</a></small>',
- ifc6.link, ifc6.ifname
- );
- }
- else
- {
- si6.innerHTML = '<img src="<%=resource%>/icons/ethernet_disabled.png" /><br /><small>?</small>';
- ss6.innerHTML = '<em><%:Not connected%></em>';
- }
+ <% if has_ipv6 then %>
+ var ifc6 = info.wan6 || {};
+
+ us.appendChild(renderBox(
+ '<%:IPv6 Upstream%>',
+ (ifc6.ifname && ifc6.proto != 'none'),
+ [ renderBadge(
+ '<%=resource%>/icons/%s.png'.format(ifc6.type || 'ethernet_disabled'), null,
+ '<%:Device%>', ifc6 ? (ifc6.name || ifc6.ifname || '-') : '-',
+ '<%:MAC-Address%>', (ifc6 && ifc6.ether) ? ifc6.mac : null) ],
+ '<%:Protocol%>', ifc6.i18n ? (ifc6.i18n + (ifc6.proto === 'dhcp' && ifc6.ip6prefix ? '-PD' : '')) : E('em', '<%:Not connected%>'),
+ '<%:Prefix Delegated%>', ifc6.ip6prefix,
+ '<%:Address%>', (ifc6.ip6prefix) ? (ifc6.ip6addr || null) : (ifc6.ipaddr || '::'),
+ '<%:Gateway%>', (ifc6.gw6addr) ? ifc6.gw6addr : '::',
+ '<%:DNS%> 1', (ifc6.dns) ? ifc6.dns[0] : null,
+ '<%:DNS%> 2', (ifc6.dns) ? ifc6.dns[1] : null,
+ '<%:DNS%> 3', (ifc6.dns) ? ifc6.dns[2] : null,
+ '<%:DNS%> 4', (ifc6.dns) ? ifc6.dns[3] : null,
+ '<%:DNS%> 5', (ifc6.dns) ? ifc6.dns[4] : null,
+ '<%:Connected%>', (ifc6.uptime > 0) ? '%t'.format(ifc6.uptime) : null));
<% end %>
<% if has_dsl then %>
hint = host.name;
}
- ls6.appendChild(E('<div class="tr cbi-section-table-row cbi-rowstyle-%d" style="max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space: nowrap">'.format((i % 2) + 1), [
- E('<div class="td">', hint ? '<div style="max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space: nowrap">%h (%h)</div>'.format(name || '?', hint) : (name || '?')),
- E('<div class="td">', info.leases6[i].ip6addr),
- E('<div class="td">', info.leases6[i].duid),
- E('<div class="td">', timestr)
+ ls6.appendChild(E('<div class="tr cbi-section-table-row cbi-rowstyle-%d">'.format((i % 2) + 1), [
+ E('<div class="td nowrap">', hint ? '<div>%h (%h)</div>'.format(name || '?', hint) : (name || '?')),
+ E('<div class="td nowrap">', info.leases6[i].ip6addr),
+ E('<div class="td nowrap">', info.leases6[i].duid),
+ E('<div class="td nowrap">', timestr)
]));
}
for (var didx = 0; didx < info.wifinets.length; didx++)
{
var dev = info.wifinets[didx];
- var s = '';
+ var net0 = (dev.networks && dev.networks[0]) ? dev.networks[0] : {};
+ var vifs = [];
for (var nidx = 0; nidx < dev.networks.length; nidx++)
{
var net = dev.networks[nidx];
var is_assoc = (net.bssid != '00:00:00:00:00:00' && net.channel && !net.disabled);
+ var num_assoc = 0;
+
+ for (var bssid in net.assoclist)
+ {
+ var bss = net.assoclist[bssid];
+
+ bss.bssid = bssid;
+ bss.link = net.link;
+ bss.name = net.name;
+ bss.ifname = net.ifname;
+ bss.radio = dev.name;
+
+ assoclist.push(bss);
+ num_assoc++;
+ }
var icon;
if (!is_assoc)
else
icon = "<%=resource%>/icons/signal-75-100.png";
- s += String.format(
- '<div class="table"><div class="tr"><div class="td" style="text-align:center; width:32px; padding:3px">' +
- '<img src="%s" title="<%:Signal%>: %d dBm / <%:Noise%>: %d dBm" />' +
- '<br /><small>%d%%</small>' +
- '</div><div class="td" style="text-align:left; padding:3px"><small>' +
- '<strong><%:SSID%>:</strong> <a href="%s">%h</a><br />' +
- '<strong><%:Mode%>:</strong> %s<br />' +
- '<strong><%:Channel%>:</strong> %d (%.3f <%:GHz%>)<br />' +
- '<strong><%:Bitrate%>:</strong> %s <%:Mbit/s%><br />',
- icon, net.signal, net.noise,
- net.quality,
- net.link, net.ssid || '?',
- net.mode,
- net.channel, net.frequency,
- net.bitrate || '?'
- );
-
- if (is_assoc)
- {
- s += String.format(
- '<strong><%:BSSID%>:</strong> %s<br />' +
- '<strong><%:Encryption%>:</strong> %s',
- net.bssid || '?',
- net.encryption
- );
- }
- else
- {
- s += '<em><%:Wireless is disabled or not associated%></em>';
- }
-
- s += '</small></div></div></div>';
-
- for (var bssid in net.assoclist)
- {
- var bss = net.assoclist[bssid];
-
- bss.bssid = bssid;
- bss.link = net.link;
- bss.name = net.name;
- bss.ifname = net.ifname;
- bss.radio = dev.name;
-
- assoclist.push(bss);
- }
+ vifs.push(renderBadge(
+ icon,
+ '<%:Signal%>: %d dBm / <%:Quality%>: %d%%'.format(net.signal, net.quality),
+ '<%:SSID%>', E('a', { href: net.link }, [ net.ssid || '?' ]),
+ '<%:Mode%>', net.mode,
+ '<%:BSSID%>', is_assoc ? (net.bssid || '-') : null,
+ '<%:Encryption%>', is_assoc ? net.encryption : null,
+ '<%:Associations%>', is_assoc ? (num_assoc || '-') : null,
+ null, is_assoc ? null : E('em', '<%:Wireless is disabled or not associated%>')));
}
- if (!s)
- s = '<em><%:No information available%></em>';
-
- ws.appendChild(E('<div class="tr">', [
- E('<div class="td left" width="33%" style="vertical-align:top">', dev.name),
- E('<div class="td">', s)
- ]));
+ ws.appendChild(renderBox(
+ dev.device, dev.up || net0.up,
+ [ E('div', vifs) ],
+ '<%:Type%>', dev.name.replace(/^Generic | Wireless Controller .+$/g, ''),
+ '<%:Channel%>', net0.channel ? '%d (%.3f <%:GHz%>)'.format(net0.channel, net0.frequency) : '-',
+ '<%:Bitrate%>', net0.bitrate ? '%d <%:Mbit/s%>'.format(net0.bitrate) : '-'));
}
+
+ if (!ws.lastElementChild)
+ ws.appendChild(E('<em><%:No information available%></em>'));
}
var ac = document.getElementById('wifi_assoc_table');
.format(assoclist[i].link, assoclist[i].name)),
E('<div class="td">',
assoclist[i].bssid),
- E('<div class="td">',
- hint ? '<div style="max-width:200px;overflow:hidden;text-overflow:ellipsis">%h (%h)</div>'.format(name || '?', hint) : (name || '?')),
+ E('<div class="td nowrap">',
+ hint ? '<div>%h (%h)</div>'.format(name || '?', hint) : (name || '?')),
E('<div class="td"><span class="ifacebadge" title="<%:Signal%>: %d <%:dBm%> / <%:Noise%>: %d <%:dBm%> / <%:SNR%>: %d"><img src="%s" /> %d / %d <%:dBm%></span></div>'
.format(assoclist[i].signal, assoclist[i].noise, assoclist[i].signal - assoclist[i].noise, icon, assoclist[i].signal, assoclist[i].noise)),
- E('<div class="td">', [
+ E('<div class="td nowrap">', [
E('<span style="white-space:nowrap">', wifirate(assoclist[i], true)),
E('<br />'),
E('<span style="white-space:nowrap">', wifirate(assoclist[i], false))
<fieldset class="cbi-section">
<legend><%:Network%></legend>
+ <div id="upstream_status_table" class="network-status-table">
+ <em><%:Collecting data...%></em>
+ </div>
+
<div class="table" width="100%">
- <div class="tr"><div class="td left" width="33%" style="vertical-align:top"><%:IPv4 WAN Status%></div><div class="td">
- <div class="table"><div class="tr">
- <div class="td" id="wan4_i" style="width:16px; text-align:center; padding:3px"><img src="<%=resource%>/icons/ethernet_disabled.png" /><br /><small>?</small></div>
- <div class="td left" id="wan4_s" style="vertical-align:middle; padding: 3px"><em><%:Collecting data...%></em></div>
- </div></div>
- </div></div>
- <% if has_ipv6 then %>
- <div class="tr"><div class="td left" width="33%" style="vertical-align:top"><%:IPv6 WAN Status%></div><div class="td">
- <div class="table"><div class="tr">
- <div class="td" id="wan6_i" style="width:16px; text-align:center; padding:3px"><img src="<%=resource%>/icons/ethernet_disabled.png" /><br /><small>?</small></div>
- <div class="td left" id="wan6_s" style="vertical-align:middle; padding: 3px"><em><%:Collecting data...%></em></div>
- </div></div>
- </div></div>
- <% end %>
<div class="tr"><div class="td left" width="33%"><%:Active Connections%></div><div class="td left" id="conns">-</div></div>
</div>
</fieldset>
<fieldset class="cbi-section">
<legend><%:Wireless%></legend>
- <div class="table" id="wifi_status_table" width="100%">
- <div class="tr"><div class="td"><em><%:Collecting data...%></em></div></div>
+ <div id="wifi_status_table" class="network-status-table">
+ <em><%:Collecting data...%></em>
</div>
</fieldset>