1
0
Fork 0
mirror of https://github.com/Ysurac/openmptcprouter-feeds.git synced 2025-03-09 15:40:03 +00:00

Use master package instead of some customs

This commit is contained in:
Ycarus (Yannick Chabanois) 2019-10-20 21:08:46 +02:00
parent 043502dada
commit 2f918b6f54
292 changed files with 0 additions and 239852 deletions

View file

@ -1,17 +0,0 @@
#
# Copyright (C) 2008-2014 The LuCI Team <luci@lists.subsignal.org>
#
# This is free software, licensed under the Apache License, Version 2.0 .
#
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI Network Administration
LUCI_DEPENDS:=+luci-base +libiwinfo-lua
PKG_LICENSE:=Apache-2.0
include ../luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature

View file

@ -1,419 +0,0 @@
'use strict';
'require rpc';
'require uci';
'require form';
var callHostHints, callDUIDHints, callDHCPLeases, CBILeaseStatus;
callHostHints = rpc.declare({
object: 'luci',
method: 'getHostHints',
expect: { '': {} }
});
callDUIDHints = rpc.declare({
object: 'luci',
method: 'getDUIDHints',
expect: { '': {} }
});
callDHCPLeases = rpc.declare({
object: 'luci',
method: 'getDHCPLeases',
params: [ 'family' ],
expect: { dhcp_leases: [] }
});
CBILeaseStatus = form.DummyValue.extend({
renderWidget: function(section_id, option_id, cfgvalue) {
return E([
E('h4', _('Active DHCP Leases')),
E('div', { 'id': 'lease_status_table', 'class': 'table' }, [
E('div', { 'class': 'tr table-titles' }, [
E('div', { 'class': 'th' }, _('Hostname')),
E('div', { 'class': 'th' }, _('IPv4-Address')),
E('div', { 'class': 'th' }, _('MAC-Address')),
E('div', { 'class': 'th' }, _('Leasetime remaining'))
]),
E('div', { 'class': 'tr placeholder' }, [
E('div', { 'class': 'td' }, E('em', _('Collecting data...')))
])
])
]);
}
});
return L.view.extend({
load: function() {
return Promise.all([
callHostHints(),
callDUIDHints()
]);
},
render: function(hosts_duids) {
var hosts = hosts_duids[0],
duids = hosts_duids[1],
m, s, o, ss, so;
m = new form.Map('dhcp', _('DHCP and DNS'), _('Dnsmasq is a combined <abbr title="Dynamic Host Configuration Protocol">DHCP</abbr>-Server and <abbr title="Domain Name System">DNS</abbr>-Forwarder for <abbr title="Network Address Translation">NAT</abbr> firewalls'));
s = m.section(form.TypedSection, 'dnsmasq', _('Server Settings'));
s.anonymous = true;
s.addremove = false;
s.tab('general', _('General Settings'));
s.tab('files', _('Resolv and Hosts Files'));
s.tab('tftp', _('TFTP Settings'));
s.tab('advanced', _('Advanced Settings'));
s.tab('leases', _('Static Leases'));
s.taboption('general', form.Flag, 'domainneeded',
_('Domain required'),
_('Don\'t forward <abbr title="Domain Name System">DNS</abbr>-Requests without <abbr title="Domain Name System">DNS</abbr>-Name'));
s.taboption('general', form.Flag, 'authoritative',
_('Authoritative'),
_('This is the only <abbr title="Dynamic Host Configuration Protocol">DHCP</abbr> in the local network'));
s.taboption('files', form.Flag, 'readethers',
_('Use <code>/etc/ethers</code>'),
_('Read <code>/etc/ethers</code> to configure the <abbr title="Dynamic Host Configuration Protocol">DHCP</abbr>-Server'));
s.taboption('files', form.Value, 'leasefile',
_('Leasefile'),
_('file where given <abbr title="Dynamic Host Configuration Protocol">DHCP</abbr>-leases will be stored'));
s.taboption('files', form.Flag, 'noresolv',
_('Ignore resolve file')).optional = true;
o = s.taboption('files', form.Value, 'resolvfile',
_('Resolve file'),
_('local <abbr title="Domain Name System">DNS</abbr> file'));
o.depends('noresolv', '');
o.optional = true;
s.taboption('files', form.Flag, 'nohosts',
_('Ignore <code>/etc/hosts</code>')).optional = true;
s.taboption('files', form.DynamicList, 'addnhosts',
_('Additional Hosts files')).optional = true;
o = s.taboption('advanced', form.Flag, 'quietdhcp',
_('Suppress logging'),
_('Suppress logging of the routine operation of these protocols'));
o.optional = true;
o = s.taboption('advanced', form.Flag, 'sequential_ip',
_('Allocate IP sequentially'),
_('Allocate IP addresses sequentially, starting from the lowest available address'));
o.optional = true;
o = s.taboption('advanced', form.Flag, 'boguspriv',
_('Filter private'),
_('Do not forward reverse lookups for local networks'));
o.default = o.enabled;
s.taboption('advanced', form.Flag, 'filterwin2k',
_('Filter useless'),
_('Do not forward requests that cannot be answered by public name servers'));
s.taboption('advanced', form.Flag, 'localise_queries',
_('Localise queries'),
_('Localise hostname depending on the requesting subnet if multiple IPs are available'));
//local have_dnssec_support = luci.util.checklib('/usr/sbin/dnsmasq', 'libhogweed.so');
var have_dnssec_support = true;
if (have_dnssec_support) {
o = s.taboption('advanced', form.Flag, 'dnssec',
_('DNSSEC'));
o.optional = true;
o = s.taboption('advanced', form.Flag, 'dnsseccheckunsigned',
_('DNSSEC check unsigned'),
_('Requires upstream supports DNSSEC; verify unsigned domain responses really come from unsigned domains'));
o.optional = true;
}
s.taboption('general', form.Value, 'local',
_('Local server'),
_('Local domain specification. Names matching this domain are never forwarded and are resolved from DHCP or hosts files only'));
s.taboption('general', form.Value, 'domain',
_('Local domain'),
_('Local domain suffix appended to DHCP names and hosts file entries'));
s.taboption('advanced', form.Flag, 'expandhosts',
_('Expand hosts'),
_('Add local domain suffix to names served from hosts files'));
s.taboption('advanced', form.Flag, 'nonegcache',
_('No negative cache'),
_('Do not cache negative replies, e.g. for not existing domains'));
s.taboption('advanced', form.Value, 'serversfile',
_('Additional servers file'),
_('This file may contain lines like \'server=/domain/1.2.3.4\' or \'server=1.2.3.4\' for domain-specific or full upstream <abbr title="Domain Name System">DNS</abbr> servers.'));
s.taboption('advanced', form.Flag, 'strictorder',
_('Strict order'),
_('<abbr title="Domain Name System">DNS</abbr> servers will be queried in the order of the resolvfile')).optional = true;
s.taboption('advanced', form.Flag, 'allservers',
_('All Servers'),
_('Query all available upstream <abbr title="Domain Name System">DNS</abbr> servers')).optional = true;
o = s.taboption('advanced', form.DynamicList, 'bogusnxdomain', _('Bogus NX Domain Override'),
_('List of hosts that supply bogus NX domain results'));
o.optional = true;
o.placeholder = '67.215.65.132';
s.taboption('general', form.Flag, 'logqueries',
_('Log queries'),
_('Write received DNS requests to syslog')).optional = true;
o = s.taboption('general', form.DynamicList, 'server', _('DNS forwardings'),
_('List of <abbr title="Domain Name System">DNS</abbr> servers to forward requests to'));
o.optional = true;
o.placeholder = '/example.org/10.1.2.3';
o = s.taboption('general', form.Flag, 'rebind_protection',
_('Rebind protection'),
_('Discard upstream RFC1918 responses'));
o.rmempty = false;
o = s.taboption('general', form.Flag, 'rebind_localhost',
_('Allow localhost'),
_('Allow upstream responses in the 127.0.0.0/8 range, e.g. for RBL services'));
o.depends('rebind_protection', '1');
o = s.taboption('general', form.DynamicList, 'rebind_domain',
_('Domain whitelist'),
_('List of domains to allow RFC1918 responses for'));
o.optional = true;
o.depends('rebind_protection', '1');
o.datatype = 'host(1)';
o.placeholder = 'ihost.netflix.com';
o = s.taboption('advanced', form.Value, 'port',
_('<abbr title="Domain Name System">DNS</abbr> server port'),
_('Listening port for inbound DNS queries'));
o.optional = true;
o.datatype = 'port';
o.placeholder = 53;
o = s.taboption('advanced', form.Value, 'queryport',
_('<abbr title="Domain Name System">DNS</abbr> query port'),
_('Fixed source port for outbound DNS queries'));
o.optional = true;
o.datatype = 'port';
o.placeholder = _('any');
o = s.taboption('advanced', form.Value, 'dhcpleasemax',
_('<abbr title="maximal">Max.</abbr> <abbr title="Dynamic Host Configuration Protocol">DHCP</abbr> leases'),
_('Maximum allowed number of active DHCP leases'));
o.optional = true;
o.datatype = 'uinteger';
o.placeholder = _('unlimited');
o = s.taboption('advanced', form.Value, 'ednspacket_max',
_('<abbr title="maximal">Max.</abbr> <abbr title="Extension Mechanisms for Domain Name System">EDNS0</abbr> packet size'),
_('Maximum allowed size of EDNS.0 UDP packets'));
o.optional = true;
o.datatype = 'uinteger';
o.placeholder = 1280;
o = s.taboption('advanced', form.Value, 'dnsforwardmax',
_('<abbr title="maximal">Max.</abbr> concurrent queries'),
_('Maximum allowed number of concurrent DNS queries'));
o.optional = true;
o.datatype = 'uinteger';
o.placeholder = 150;
o = s.taboption('advanced', form.Value, 'cachesize',
_('Size of DNS query cache'),
_('Number of cached DNS entries (max is 10000, 0 is no caching)'));
o.optional = true;
o.datatype = 'range(0,10000)';
o.placeholder = 150;
s.taboption('tftp', form.Flag, 'enable_tftp',
_('Enable TFTP server')).optional = true;
o = s.taboption('tftp', form.Value, 'tftp_root',
_('TFTP server root'),
_('Root directory for files served via TFTP'));
o.optional = true;
o.depends('enable_tftp', '1');
o.placeholder = '/';
o = s.taboption('tftp', form.Value, 'dhcp_boot',
_('Network boot image'),
_('Filename of the boot image advertised to clients'));
o.optional = true;
o.depends('enable_tftp', '1');
o.placeholder = 'pxelinux.0';
o = s.taboption('general', form.Flag, 'localservice',
_('Local Service Only'),
_('Limit DNS service to subnets interfaces on which we are serving DNS.'));
o.optional = false;
o.rmempty = false;
o = s.taboption('general', form.Flag, 'nonwildcard',
_('Non-wildcard'),
_('Bind dynamically to interfaces rather than wildcard address (recommended as linux default)'));
o.optional = false;
o.rmempty = true;
o = s.taboption('general', form.DynamicList, 'interface',
_('Listen Interfaces'),
_('Limit listening to these interfaces, and loopback.'));
o.optional = true;
o = s.taboption('general', form.DynamicList, 'notinterface',
_('Exclude interfaces'),
_('Prevent listening on these interfaces.'));
o.optional = true;
o = s.taboption('leases', form.SectionValue, '__leases__', form.GridSection, 'host', null,
_('Static leases are used to assign fixed IP addresses and symbolic hostnames to DHCP clients. They are also required for non-dynamic interface configurations where only hosts with a corresponding lease are served.') + '<br />' +
_('Use the <em>Add</em> Button to add a new lease entry. The <em>MAC-Address</em> identifies the host, the <em>IPv4-Address</em> specifies the fixed address to use, and the <em>Hostname</em> is assigned as a symbolic name to the requesting host. The optional <em>Lease time</em> can be used to set non-standard host-specific lease time, e.g. 12h, 3d or infinite.'));
ss = o.subsection;
ss.addremove = true;
ss.anonymous = true;
so = ss.option(form.Value, 'name', _('Hostname'));
so.datatype = 'hostname("strict")';
so.rmempty = true;
so.write = function(section, value) {
uci.set('dhcp', section, 'name', value);
uci.set('dhcp', section, 'dns', '1');
};
so.remove = function(section) {
uci.unset('dhcp', section, 'name');
uci.unset('dhcp', section, 'dns');
};
so = ss.option(form.Value, 'mac', _('<abbr title="Media Access Control">MAC</abbr>-Address'));
so.datatype = 'list(unique(macaddr))';
so.rmempty = true;
so.cfgvalue = function(section) {
var macs = uci.get('dhcp', section, 'mac'),
result = [];
if (!Array.isArray(macs))
macs = (macs != null && macs != '') ? macs.split(/\ss+/) : [];
for (var i = 0, mac; (mac = macs[i]) != null; i++)
if (/^([0-9a-fA-F]{1,2}):([0-9a-fA-F]{1,2}):([0-9a-fA-F]{1,2}):([0-9a-fA-F]{1,2}):([0-9a-fA-F]{1,2}):([0-9a-fA-F]{1,2})$/.test(mac))
result.push('%02X:%02X:%02X:%02X:%02X:%02X'.format(
parseInt(RegExp.$1, 16), parseInt(RegExp.$2, 16),
parseInt(RegExp.$3, 16), parseInt(RegExp.$4, 16),
parseInt(RegExp.$5, 16), parseInt(RegExp.$6, 16)));
return result.length ? result.join(' ') : null;
};
Object.keys(hosts).forEach(function(mac) {
so.value(mac);
});
so = ss.option(form.Value, 'ip', _('<abbr title="Internet Protocol Version 4">IPv4</abbr>-Address'));
so.datatype = 'or(ip4addr,"ignore")';
so.validate = function(section, value) {
var mac = this.map.lookupOption('mac', section),
name = this.map.lookupOption('name', section),
m = mac ? mac[0].formvalue(section) : null,
n = name ? name[0].formvalue(section) : null;
if ((m == null || m == '') && (n == null || n == ''))
return _('One of hostname or mac address must be specified!');
return true;
};
Object.keys(hosts).forEach(function(mac) {
if (hosts[mac].ipv4)
so.value(hosts[mac].ipv4);
});
so = ss.option(form.Value, 'gw', _('Gateway IPv4 Address'));
so.rmempty = true;
so.datatype = 'or(ip4addr,"ignore")';
Object.keys(hosts).forEach(function(mac) {
if (hosts[mac].ipv4)
so.value(hosts[mac].ipv4);
});
so = ss.option(form.Value, 'leasetime', _('Lease time'));
so.rmempty = true;
so = ss.option(form.Value, 'duid', _('<abbr title="The DHCP Unique Identifier">DUID</abbr>'));
so.datatype = 'and(rangelength(20,36),hexstring)';
Object.keys(duids).forEach(function(duid) {
so.value(duid, '%s (%s)'.format(duid, duids[duid].name || '?'));
});
so = ss.option(form.Value, 'hostid', _('<abbr title="Internet Protocol Version 6">IPv6</abbr>-Suffix (hex)'));
o = s.taboption('leases', CBILeaseStatus, '__status__');
return m.render().then(function(mapEl) {
L.Poll.add(function() {
return callDHCPLeases(4).then(function(leases) {
cbi_update_table(mapEl.querySelector('#lease_status_table'),
leases.map(function(lease) {
var exp;
if (lease.expires === false)
exp = E('em', _('unlimited'));
else if (lease.expires <= 0)
exp = E('em', _('expired'));
else
exp = '%t'.format(lease.expires);
return [
lease.hostname || '?',
lease.ipaddr,
lease.macaddr,
exp
];
}),
E('em', _('There are no active leases')));
});
});
return mapEl;
});
}
});

View file

@ -1,42 +0,0 @@
'use strict';
'require rpc';
'require form';
return L.view.extend({
callHostHints: rpc.declare({
object: 'luci',
method: 'getHostHints',
expect: { '': {} }
}),
load: function() {
return this.callHostHints();
},
render: function(hosts) {
var m, s, o;
m = new form.Map('dhcp', _('Hostnames'));
s = m.section(form.GridSection, 'domain', _('Host entries'));
s.addremove = true;
s.anonymous = true;
s.sortable = true;
o = s.option(form.Value, 'name', _('Hostname'));
o.datatype = 'hostname';
o.rmempty = true;
o = s.option(form.Value, 'ip', _('IP address'));
o.datatype = 'ipaddr';
o.rmempty = true;
L.sortedKeys(hosts, 'ipv4', 'addr').forEach(function(mac) {
o.value(hosts[mac].ipv4, '%s (%s)'.format(
hosts[mac].ipv4,
hosts[mac].name || mac
));
});
return m.render();
}
});

View file

@ -1,42 +0,0 @@
requestAnimationFrame(function() {
document.querySelectorAll('[data-iface-status]').forEach(function(container) {
var network = container.getAttribute('data-iface-status'),
icon = container.querySelector('img'),
info = container.querySelector('span');
L.poll(5, L.url('admin/network/iface_status', network), null, function(xhr, ifaces) {
var ifc = Array.isArray(ifaces) ? ifaces[0] : null;
if (!ifc)
return;
L.itemlist(info, [
_('Device'), ifc.ifname,
_('Uptime'), ifc.is_up ? '%t'.format(ifc.uptime) : null,
_('MAC'), ifc.ifname ? ifc.macaddr : null,
_('RX'), ifc.ifname ? '%.2mB (%d %s)'.format(ifc.rx_bytes, ifc.rx_packets, _('Pkts.')) : null,
_('TX'), ifc.ifname ? '%.2mB (%d %s)'.format(ifc.tx_bytes, ifc.tx_packets, _('Pkts.')) : null,
_('IPv4'), ifc.ipaddrs ? ifc.ipaddrs[0] : null,
_('IPv4'), ifc.ipaddrs ? ifc.ipaddrs[1] : null,
_('IPv4'), ifc.ipaddrs ? ifc.ipaddrs[2] : null,
_('IPv4'), ifc.ipaddrs ? ifc.ipaddrs[3] : null,
_('IPv4'), ifc.ipaddrs ? ifc.ipaddrs[4] : null,
_('IPv6'), ifc.ip6addrs ? ifc.ip6addrs[0] : null,
_('IPv6'), ifc.ip6addrs ? ifc.ip6addrs[1] : null,
_('IPv6'), ifc.ip6addrs ? ifc.ip6addrs[2] : null,
_('IPv6'), ifc.ip6addrs ? ifc.ip6addrs[3] : null,
_('IPv6'), ifc.ip6addrs ? ifc.ip6addrs[4] : null,
_('IPv6'), ifc.ip6addrs ? ifc.ip6addrs[5] : null,
_('IPv6'), ifc.ip6addrs ? ifc.ip6addrs[6] : null,
_('IPv6'), ifc.ip6addrs ? ifc.ip6addrs[7] : null,
_('IPv6'), ifc.ip6addrs ? ifc.ip6addrs[8] : null,
_('IPv6'), ifc.ip6addrs ? ifc.ip6addrs[9] : null,
_('IPv6-PD'), ifc.ip6prefix,
null, ifc.ifname ? null : E('em', _('Interface not present or not connected yet.'))
]);
icon.src = L.resource('icons/%s%s.png').format(ifc.type, ifc.is_up ? '' : '_disabled');
});
L.run();
});
});

View file

@ -1,136 +0,0 @@
function iface_reconnect(id) {
L.halt();
L.dom.content(document.getElementById(id + '-ifc-description'), E('em', _('Interface is reconnecting...')));
L.post(L.url('admin/network/iface_reconnect', id), null, L.run);
}
function iface_delete(ev) {
if (!confirm(_('Really delete this interface? The deletion cannot be undone! You might lose access to this device if you are connected via this interface'))) {
ev.preventDefault();
return false;
}
ev.target.previousElementSibling.value = '1';
return true;
}
var networks = [];
document.querySelectorAll('[data-network]').forEach(function(n) {
networks.push(n.getAttribute('data-network'));
});
function render_iface(ifc) {
return E('span', { class: 'cbi-tooltip-container' }, [
E('img', { 'class' : 'middle', 'src': L.resource('icons/%s%s.png').format(
ifc.is_alias ? 'alias' : ifc.type,
ifc.is_up ? '' : '_disabled') }),
E('span', { 'class': 'cbi-tooltip ifacebadge large' }, [
E('img', { 'src': L.resource('icons/%s%s.png').format(
ifc.type, ifc.is_up ? '' : '_disabled') }),
L.itemlist(E('span', { 'class': 'left' }), [
_('Type'), ifc.typename,
_('Device'), ifc.ifname,
_('Connected'), ifc.is_up ? _('yes') : _('no'),
_('MAC'), ifc.macaddr,
_('RX'), '%.2mB (%d %s)'.format(ifc.rx_bytes, ifc.rx_packets, _('Pkts.')),
_('TX'), '%.2mB (%d %s)'.format(ifc.tx_bytes, ifc.tx_packets, _('Pkts.'))
])
])
]);
}
L.poll(5, L.url('admin/network/iface_status', networks.join(',')), null,
function(x, ifcs) {
if (ifcs) {
for (var idx = 0; idx < ifcs.length; idx++) {
var ifc = ifcs[idx];
var s = document.getElementById(ifc.id + '-ifc-devices');
if (s) {
var c = [ render_iface(ifc) ];
if (ifc.subdevices && ifc.subdevices.length)
{
var sifs = [ ' (' ];
for (var j = 0; j < ifc.subdevices.length; j++)
sifs.push(render_iface(ifc.subdevices[j]));
sifs.push(')');
c.push(E('span', {}, sifs));
}
c.push(E('br'));
c.push(E('small', {}, ifc.is_alias ? _('Alias of "%s"').format(ifc.is_alias) : ifc.name));
L.dom.content(s, c);
}
var d = document.getElementById(ifc.id + '-ifc-description');
if (d && ifc.proto && ifc.ifname) {
var desc = null, c = [];
if (ifc.is_dynamic)
desc = _('Virtual dynamic interface');
else if (ifc.is_alias)
desc = _('Alias Interface');
if (ifc.desc)
desc = desc ? '%s (%s)'.format(desc, ifc.desc) : ifc.desc;
L.itemlist(d, [
_('Protocol'), desc || '?',
_('Uptime'), ifc.is_up ? '%t'.format(ifc.uptime) : null,
_('MAC'), (!ifc.is_dynamic && !ifc.is_alias && ifc.macaddr) ? ifc.macaddr : null,
_('RX'), (!ifc.is_dynamic && !ifc.is_alias) ? '%.2mB (%d %s)'.format(ifc.rx_bytes, ifc.rx_packets, _('Pkts.')) : null,
_('TX'), (!ifc.is_dynamic && !ifc.is_alias) ? '%.2mB (%d %s)'.format(ifc.tx_bytes, ifc.tx_packets, _('Pkts.')) : null,
_('IPv4'), ifc.ipaddrs ? ifc.ipaddrs[0] : null,
_('IPv4'), ifc.ipaddrs ? ifc.ipaddrs[1] : null,
_('IPv4'), ifc.ipaddrs ? ifc.ipaddrs[2] : null,
_('IPv4'), ifc.ipaddrs ? ifc.ipaddrs[3] : null,
_('IPv4'), ifc.ipaddrs ? ifc.ipaddrs[4] : null,
_('IPv6'), ifc.ip6addrs ? ifc.ip6addrs[0] : null,
_('IPv6'), ifc.ip6addrs ? ifc.ip6addrs[1] : null,
_('IPv6'), ifc.ip6addrs ? ifc.ip6addrs[2] : null,
_('IPv6'), ifc.ip6addrs ? ifc.ip6addrs[3] : null,
_('IPv6'), ifc.ip6addrs ? ifc.ip6addrs[4] : null,
_('IPv6'), ifc.ip6addrs ? ifc.ip6addrs[5] : null,
_('IPv6'), ifc.ip6addrs ? ifc.ip6addrs[6] : null,
_('IPv6'), ifc.ip6addrs ? ifc.ip6addrs[7] : null,
_('IPv6'), ifc.ip6addrs ? ifc.ip6addrs[8] : null,
_('IPv6'), ifc.ip6addrs ? ifc.ip6addrs[9] : null,
_('IPv6-PD'), ifc.ip6prefix,
_('Information'), ifc.is_auto ? null : _('Not started on boot'),
_('Error'), ifc.errors ? ifc.errors[0] : null,
_('Error'), ifc.errors ? ifc.errors[1] : null,
_('Error'), ifc.errors ? ifc.errors[2] : null,
_('Error'), ifc.errors ? ifc.errors[3] : null,
_('Error'), ifc.errors ? ifc.errors[4] : null,
]);
}
else if (d && !ifc.proto) {
var e = document.getElementById(ifc.id + '-ifc-edit');
if (e) e.disabled = true;
var link = L.url('admin/system/opkg') + '?query=luci-proto';
L.dom.content(d, [
E('em', _('Unsupported protocol type.')), E('br'),
E('a', { href: link }, _('Install protocol extensions...'))
]);
}
else if (d && !ifc.ifname) {
var link = L.url('admin/network/network', ifc.name) + '?tab.network.%s=physical'.format(ifc.name);
L.dom.content(d, [
E('em', _('Network without interfaces.')), E('br'),
E('a', { href: link }, _('Assign interfaces...'))
]);
}
else if (d) {
L.dom.content(d, E('em' ,_('Interface not present or not connected yet.')));
}
}
}
}
);

View file

@ -1,102 +0,0 @@
'use strict';
'require form';
'require network';
'require tools.widgets as widgets';
return L.view.extend({
load: function() {
return network.getDevices();
},
render: function(netdevs) {
var m, s, o;
m = new form.Map('network', _('Routes'), _('Routes specify over which interface and gateway a certain host or network can be reached.'));
m.tabbed = true;
for (var i = 4; i <= 6; i += 2) {
s = m.section(form.GridSection, (i == 4) ? 'route' : 'route6', (i == 4) ? _('Static IPv4 Routes') : _('Static IPv6 Routes'));
s.anonymous = true;
s.addremove = true;
s.sortable = true;
s.tab('general', _('General Settings'));
s.tab('advanced', _('Advanced Settings'));
o = s.taboption('general', widgets.NetworkSelect, 'interface', _('Interface'));
o.rmempty = false;
o.nocreate = true;
o = s.taboption('general', form.Value, 'target', _('Target'), (i == 4) ? _('Host-<abbr title="Internet Protocol Address">IP</abbr> or Network') : _('<abbr title="Internet Protocol Version 6">IPv6</abbr>-Address or Network (CIDR)'));
o.datatype = (i == 4) ? 'ip4addr' : 'ip6addr';
o.rmempty = false;
if (i == 4) {
o = s.taboption('general', form.Value, 'netmask', _('<abbr title="Internet Protocol Version 4">IPv4</abbr>-Netmask'), _('if target is a network'));
o.placeholder = '255.255.255.255';
o.datatype = 'ip4addr';
o.rmempty = true;
}
o = s.taboption('general', form.Value, 'gateway', (i == 4) ? _('<abbr title="Internet Protocol Version 4">IPv4</abbr>-Gateway') : _('<abbr title="Internet Protocol Version 6">IPv6</abbr>-Gateway'));
o.datatype = (i == 4) ? 'ip4addr' : 'ip6addr';
o.rmempty = true;
o = s.taboption('advanced', form.Value, 'metric', _('Metric'));
o.placeholder = 0;
o.datatype = (i == 4) ? 'range(0,255)' : 'range(0,65535)';
o.rmempty = true;
o.textvalue = function(section_id) {
return this.cfgvalue(section_id) || 0;
};
o = s.taboption('advanced', form.Value, 'mtu', _('MTU'));
o.placeholder = 1500;
o.datatype = 'range(64,9000)';
o.rmempty = true;
o.modalonly = true;
o = s.taboption('advanced', form.ListValue, 'type', _('Route type'));
o.value('', 'unicast');
o.value('local');
o.value('broadcast');
o.value('multicast');
o.value('unreachable');
o.value('prohibit');
o.value('blackhole');
o.value('anycast');
o.default = '';
o.rmempty = true;
o.modalonly = true;
o = s.taboption('advanced', form.Value, 'table', _('Route table'));
o.value('local', 'local (255)');
o.value('main', 'main (254)');
o.value('default', 'default (253)');
o.rmempty = true;
o.modalonly = true;
o.cfgvalue = function(section_id) {
var cfgvalue = this.super('cfgvalue', [section_id]);
return cfgvalue || 'main';
};
o = s.taboption('advanced', form.Value, 'source', _('Source Address'));
o.placeholder = E('em', _('automatic'));
for (var j = 0; j < netdevs.length; j++) {
var addrs = netdevs[j].getIPAddrs();
for (var k = 0; k < addrs.length; k++)
o.value(addrs[k].split('/')[0]);
}
o.datatype = (i == 4) ? 'ip4addr' : 'ip6addr';
o.default = '';
o.rmempty = true;
o.modalonly = true;
o = s.taboption('advanced', form.Flag, 'onlink', _('On-Link route'));
o.default = o.disabled;
o.rmempty = true;
}
return m.render();
}
});

View file

@ -1,159 +0,0 @@
var poll = null;
function format_signal(bss) {
var qval = bss.quality || 0,
qmax = bss.quality_max || 100,
scale = 100 / qmax * qval,
range = 'none';
if (!bss.bssid || bss.bssid == '00:00:00:00:00:00')
range = 'none';
else if (scale < 15)
range = '0';
else if (scale < 35)
range = '0-25';
else if (scale < 55)
range = '25-50';
else if (scale < 75)
range = '50-75';
else
range = '75-100';
return E('span', {
class: 'ifacebadge',
title: '%s: %d%s / %s: %d/%d'.format(_('Signal'), bss.signal, _('dB'), _('Quality'), qval, qmax)
}, [
E('img', { src: L.resource('icons/signal-%s.png').format(range) }),
' %d%%'.format(scale)
]);
}
function format_encryption(bss) {
var enc = bss.encryption || { }
if (enc.wep === true)
return 'WEP';
else if (enc.wpa > 0)
return E('abbr', {
title: 'Pairwise: %h / Group: %h'.format(
enc.pair_ciphers.join(', '),
enc.group_ciphers.join(', '))
},
'%h - %h'.format(
(enc.wpa === 3) ? _('mixed WPA/WPA2') : (enc.wpa === 2 ? 'WPA2' : 'WPA'),
enc.auth_suites.join(', ')));
else
return E('em', enc.enabled ? _('unknown') : _('open'));
}
function format_actions(dev, type, bss) {
var enc = bss.encryption || { },
input = [
E('input', { type: 'submit', class: 'cbi-button cbi-button-action important', value: _('Join Network') }),
E('input', { type: 'hidden', name: 'token', value: L.env.token }),
E('input', { type: 'hidden', name: 'device', value: dev }),
E('input', { type: 'hidden', name: 'join', value: bss.ssid }),
E('input', { type: 'hidden', name: 'mode', value: bss.mode }),
E('input', { type: 'hidden', name: 'bssid', value: bss.bssid }),
E('input', { type: 'hidden', name: 'channel', value: bss.channel }),
E('input', { type: 'hidden', name: 'clbridge', value: type === 'wl' ? 1 : 0 }),
E('input', { type: 'hidden', name: 'wep', value: enc.wep ? 1 : 0 })
];
if (enc.wpa) {
input.push(E('input', { type: 'hidden', name: 'wpa_version', value: enc.wpa }));
enc.auth_suites.forEach(function(s) {
input.push(E('input', { type: 'hidden', name: 'wpa_suites', value: s }));
});
enc.group_ciphers.forEach(function(s) {
input.push(E('input', { type: 'hidden', name: 'wpa_group', value: s }));
});
enc.pair_ciphers.forEach(function(s) {
input.push(E('input', { type: 'hidden', name: 'wpa_pairwise', value: s }));
});
}
return E('form', {
class: 'inline',
method: 'post',
action: L.url('admin/network/wireless_join')
}, input);
}
function fade(bss, content) {
if (bss.stale)
return E('span', { style: 'opacity:0.5' }, content);
else
return content;
}
function flush() {
L.stop(poll);
L.halt();
scan();
}
function scan() {
var tbl = document.querySelector('[data-wifi-scan]'),
dev = tbl.getAttribute('data-wifi-scan'),
type = tbl.getAttribute('data-wifi-type');
cbi_update_table(tbl, [], E('em', { class: 'spinning' }, _('Starting wireless scan...')));
L.post(L.url('admin/network/wireless_scan_trigger', dev), null, function(s) {
if (s.status !== 204) {
cbi_update_table(tbl, [], E('em', _('Scan request failed')));
return;
}
var count = 0;
poll = L.poll(3, L.url('admin/network/wireless_scan_results', dev), null, function(s, results) {
if (Array.isArray(results)) {
var bss = [];
results.sort(function(a, b) {
var diff = (b.quality - a.quality) || (a.channel - b.channel);
if (diff)
return diff;
if (a.ssid < b.ssid)
return -1;
else if (a.ssid > b.ssid)
return 1;
if (a.bssid < b.bssid)
return -1;
else if (a.bssid > b.bssid)
return 1;
}).forEach(function(res) {
bss.push([
fade(res, format_signal(res)),
fade(res, res.ssid ? '%h'.format(res.ssid) : E('em', {}, _('hidden'))),
fade(res, res.channel),
fade(res, res.mode),
fade(res, res.bssid),
fade(res, format_encryption(res)),
format_actions(dev, type, res)
]);
});
cbi_update_table(tbl, bss, E('em', { class: 'spinning' }, _('No scan results available yet...')));
}
if (count++ >= 3) {
count = 0;
L.post(L.url('admin/network/wireless_scan_trigger', dev, 1), null, function() {});
}
});
L.run();
});
}
document.addEventListener('DOMContentLoaded', scan);

View file

@ -1,59 +0,0 @@
requestAnimationFrame(function() {
document.querySelectorAll('[data-wifi-status]').forEach(function(container) {
var ifname = container.getAttribute('data-wifi-status'),
small = container.querySelector('small'),
info = container.querySelector('span');
L.poll(5, L.url('admin/network/wireless_status', ifname), null, function(xhr, iws) {
var iw = Array.isArray(iws) ? iws[0] : null;
if (!iw)
return;
var is_assoc = (iw.bssid && iw.bssid != '00:00:00:00:00:00' && iw.channel && !iw.disabled);
var p = iw.quality;
var q = iw.disabled ? -1 : p;
var icon;
if (q < 0)
icon = L.resource('icons/signal-none.png');
else if (q == 0)
icon = L.resource('icons/signal-0.png');
else if (q < 25)
icon = L.resource('icons/signal-0-25.png');
else if (q < 50)
icon = L.resource('icons/signal-25-50.png');
else if (q < 75)
icon = L.resource('icons/signal-50-75.png');
else
icon = L.resource('icons/signal-75-100.png');
L.dom.content(small, [
E('img', {
src: icon,
title: '%s: %d %s / %s: %d %s'.format(
_('Signal'), iw.signal, _('dBm'),
_('Noise'), iw.noise, _('dBm'))
}),
'\u00a0', E('br'), '%d%%\u00a0'.format(p)
]);
L.itemlist(info, [
_('Mode'), iw.mode,
_('SSID'), iw.ssid || '?',
_('BSSID'), is_assoc ? iw.bssid : null,
_('Encryption'), is_assoc ? iw.encryption || _('None') : null,
_('Channel'), is_assoc ? '%d (%.3f %s)'.format(iw.channel, iw.frequency || 0, _('GHz')) : null,
_('Tx-Power'), is_assoc ? '%d %s'.format(iw.txpower, _('dBm')) : null,
_('Signal'), is_assoc ? '%d %s'.format(iw.signal, _('dBm')) : null,
_('Noise'), is_assoc ? '%d %s'.format(iw.noise, _('dBm')) : null,
_('Bitrate'), is_assoc ? '%.1f %s'.format(iw.bitrate || 0, _('Mbit/s')) : null,
_('Country'), is_assoc ? iw.country : null
], [ ' | ', E('br'), E('br'), E('br'), E('br'), E('br'), ' | ', E('br'), ' | ' ]);
if (!is_assoc)
L.dom.append(info, E('em', iw.disabled ? _('Wireless is disabled') : _('Wireless is not associated')));
});
L.run();
});
});

View file

@ -1,93 +0,0 @@
function wifi_delete(ev) {
if (!confirm(_('Really delete this wireless network? The deletion cannot be undone! You might lose access to this device if you are connected via this network.'))) {
ev.preventDefault();
return false;
}
ev.target.previousElementSibling.value = '1';
return true;
}
function wifi_restart(ev) {
L.halt();
findParent(ev.target, '.table').querySelectorAll('[data-disabled="false"]').forEach(function(s) {
L.dom.content(s, E('em', _('Wireless is restarting...')));
});
L.post(L.url('admin/network/wireless_reconnect', ev.target.getAttribute('data-radio')), L.run);
}
var networks = [ ];
document.querySelectorAll('[data-network]').forEach(function(n) {
networks.push(n.getAttribute('data-network'));
});
L.poll(5, L.url('admin/network/wireless_status', networks.join(',')), null,
function(x, st) {
if (st) {
var rowstyle = 1;
var radiostate = { };
st.forEach(function(s) {
var r = radiostate[s.device.device] || (radiostate[s.device.device] = {});
s.is_assoc = (s.bssid && s.bssid != '00:00:00:00:00:00' && s.channel && s.mode != 'Unknown' && !s.disabled);
r.up = r.up || s.is_assoc;
r.channel = r.channel || s.channel;
r.bitrate = r.bitrate || s.bitrate;
r.frequency = r.frequency || s.frequency;
});
for (var i = 0; i < st.length; i++) {
var iw = st[i],
sig = document.getElementById(iw.id + '-iw-signal'),
info = document.getElementById(iw.id + '-iw-status'),
disabled = (info && info.getAttribute('data-disabled') === 'true');
var p = iw.quality;
var q = disabled ? -1 : p;
var icon;
if (q < 0)
icon = L.resource('icons/signal-none.png');
else if (q == 0)
icon = L.resource('icons/signal-0.png');
else if (q < 25)
icon = L.resource('icons/signal-0-25.png');
else if (q < 50)
icon = L.resource('icons/signal-25-50.png');
else if (q < 75)
icon = L.resource('icons/signal-50-75.png');
else
icon = L.resource('icons/signal-75-100.png');
L.dom.content(sig, E('span', {
class: 'ifacebadge',
title: '%s %d %s / %s: %d %s'.format(_('Signal'), iw.signal, _('dBm'), _('Noise'), iw.noise, _('dBm'))
}, [ E('img', { src: icon }), ' %d%%'.format(p) ]));
L.itemlist(info, [
_('SSID'), iw.ssid || '?',
_('Mode'), iw.mode,
_('BSSID'), iw.is_assoc ? iw.bssid : null,
_('Encryption'), iw.is_assoc ? iw.encryption || _('None') : null,
null, iw.is_assoc ? null : E('em', disabled ? _('Wireless is disabled') : _('Wireless is not associated'))
], [ ' | ', E('br') ]);
}
for (var dev in radiostate) {
var img = document.getElementById(dev + '-iw-upstate');
if (img) img.src = L.resource('icons/wifi' + (radiostate[dev].up ? '' : '_disabled') + '.png');
var stat = document.getElementById(dev + '-iw-devinfo');
L.itemlist(stat, [
_('Channel'), '%s (%s %s)'.format(radiostate[dev].channel || '?', radiostate[dev].frequency || '?', _('GHz')),
_('Bitrate'), '%s %s'.format(radiostate[dev].bitrate || '?', _('Mbit/s'))
], ' | ');
}
}
}
);

View file

@ -1,437 +0,0 @@
-- Copyright 2008 Steven Barth <steven@midlink.org>
-- Copyright 2011-2018 Jo-Philipp Wich <jo@mein.io>
-- Copyright 2019 Ycarus (Yannick Chabanois) <ycarus@zugaina.org> for OpenMPTCProuter project
-- Licensed to the public under the Apache License 2.0.
module("luci.controller.admin.network", package.seeall)
function index()
local uci = require("luci.model.uci").cursor()
local page
-- if page.inreq then
local has_switch = false
uci:foreach("network", "switch",
function(s)
has_switch = true
return false
end)
if has_switch then
page = node("admin", "network", "vlan")
page.target = cbi("admin_network/vlan")
page.title = _("Switch")
page.order = 20
page = entry({"admin", "network", "switch_status"}, call("switch_status"), nil)
page.leaf = true
end
local has_wifi = false
uci:foreach("wireless", "wifi-device",
function(s)
has_wifi = true
return false
end)
if has_wifi then
page = entry({"admin", "network", "wireless_join"}, post("wifi_join"), nil)
page.leaf = true
page = entry({"admin", "network", "wireless_add"}, post("wifi_add"), nil)
page.leaf = true
page = entry({"admin", "network", "wireless_status"}, call("wifi_status"), nil)
page.leaf = true
page = entry({"admin", "network", "wireless_reconnect"}, post("wifi_reconnect"), nil)
page.leaf = true
page = entry({"admin", "network", "wireless_scan_trigger"}, post("wifi_scan_trigger"), nil)
page.leaf = true
page = entry({"admin", "network", "wireless_scan_results"}, call("wifi_scan_results"), nil)
page.leaf = true
page = entry({"admin", "network", "wireless"}, arcombine(cbi("admin_network/wifi_overview"), cbi("admin_network/wifi")), _("Wireless"), 15)
page.leaf = true
page.subindex = true
if page.inreq then
local wdev
local net = require "luci.model.network".init(uci)
for _, wdev in ipairs(net:get_wifidevs()) do
local wnet
for _, wnet in ipairs(wdev:get_wifinets()) do
entry(
{"admin", "network", "wireless", wnet:id()},
alias("admin", "network", "wireless"),
wdev:name() .. ": " .. wnet:shortname()
)
end
end
end
end
page = entry({"admin", "network", "iface_add"}, form("admin_network/iface_add"), nil)
page.leaf = true
page = entry({"admin", "network", "iface_status"}, call("iface_status"), nil)
page.leaf = true
page = entry({"admin", "network", "iface_reconnect"}, post("iface_reconnect"), nil)
page.leaf = true
page = entry({"admin", "network", "network"}, arcombine(cbi("admin_network/network"), cbi("admin_network/ifaces")), _("Interfaces"), 10)
page.leaf = true
page.subindex = true
if page.inreq then
uci:foreach("network", "interface",
function (section)
local ifc = section[".name"]
if ifc ~= "loopback" then
entry({"admin", "network", "network", ifc},
true, ifc:upper())
end
end)
end
if nixio.fs.access("/etc/config/dhcp") then
page = node("admin", "network", "dhcp")
--page.target = cbi("admin_network/dhcp")
page.target = view("network/dhcp")
page.title = _("DHCP and DNS")
page.order = 30
page = node("admin", "network", "hosts")
--page.target = cbi("admin_network/hosts")
page.target = view("network/hosts")
page.title = _("Hostnames")
page.order = 40
end
page = node("admin", "network", "routes")
--page.target = cbi("admin_network/routes")
page.target = view("network/routes")
page.title = _("Static Routes")
page.order = 50
page = node("admin", "network", "diagnostics")
page.target = template("admin_network/diagnostics")
page.title = _("Diagnostics")
page.order = 60
page = entry({"admin", "network", "diag_ping"}, post("diag_ping"), nil)
page.leaf = true
page = entry({"admin", "network", "diag_nslookup"}, post("diag_nslookup"), nil)
page.leaf = true
page = entry({"admin", "network", "diag_traceroute"}, post("diag_traceroute"), nil)
page.leaf = true
page = entry({"admin", "network", "diag_ping6"}, post("diag_ping6"), nil)
page.leaf = true
page = entry({"admin", "network", "diag_getip"}, post("diag_getip"), nil)
page.leaf = true
page = entry({"admin", "network", "diag_netstat"}, post("diag_netstat"), nil)
page.leaf = true
page = entry({"admin", "network", "diag_traceroute6"}, post("diag_traceroute6"), nil)
page.leaf = true
-- end
end
function wifi_join()
local tpl = require "luci.template"
local http = require "luci.http"
local dev = http.formvalue("device")
local ssid = http.formvalue("join")
if dev and ssid then
local cancel = (http.formvalue("cancel") or http.formvalue("cbi.cancel"))
if not cancel then
local cbi = require "luci.cbi"
local map = luci.cbi.load("admin_network/wifi_add")[1]
if map:parse() ~= cbi.FORM_DONE then
tpl.render("header")
map:render()
tpl.render("footer")
end
return
end
end
tpl.render("admin_network/wifi_join")
end
function wifi_add()
local dev = luci.http.formvalue("device")
local ntm = require "luci.model.network".init()
dev = dev and ntm:get_wifidev(dev)
if dev then
local net = dev:add_wifinet({
mode = "ap",
ssid = "OpenWrt",
encryption = "none",
disabled = 1
})
ntm:save("wireless")
luci.http.redirect(net:adminlink())
end
end
function iface_status(ifaces)
local netm = require "luci.model.network".init()
local rv = { }
local iface
for iface in ifaces:gmatch("[%w%.%-_]+") do
local net = netm:get_network(iface)
local device = net and net:get_interface()
if device then
local data = {
id = iface,
desc = net:get_i18n(),
proto = net:proto(),
uptime = net:uptime(),
gwaddr = net:gwaddr(),
ipaddrs = net:ipaddrs(),
ip6addrs = net:ip6addrs(),
dnsaddrs = net:dnsaddrs(),
ip6prefix = net:ip6prefix(),
errors = net:errors(),
name = device:shortname(),
type = device:type(),
typename = device:get_type_i18n(),
ifname = device:name(),
macaddr = device:mac(),
is_up = net:is_up() and device:is_up(),
is_alias = net:is_alias(),
is_dynamic = net:is_dynamic(),
is_auto = net:is_auto(),
rx_bytes = device:rx_bytes(),
tx_bytes = device:tx_bytes(),
rx_packets = device:rx_packets(),
tx_packets = device:tx_packets(),
subdevices = { }
}
for _, device in ipairs(net:get_interfaces() or {}) do
data.subdevices[#data.subdevices+1] = {
name = device:shortname(),
type = device:type(),
typename = device:get_type_i18n(),
ifname = device:name(),
macaddr = device:mac(),
is_up = device:is_up(),
rx_bytes = device:rx_bytes(),
tx_bytes = device:tx_bytes(),
rx_packets = device:rx_packets(),
tx_packets = device:tx_packets(),
}
end
rv[#rv+1] = data
else
rv[#rv+1] = {
id = iface,
name = iface,
type = "ethernet"
}
end
end
if #rv > 0 then
luci.http.prepare_content("application/json")
luci.http.write_json(rv)
return
end
luci.http.status(404, "No such device")
end
function iface_reconnect(iface)
local netmd = require "luci.model.network".init()
local net = netmd:get_network(iface)
if net then
luci.sys.call("env -i /sbin/ifup %s >/dev/null 2>/dev/null"
% luci.util.shellquote(iface))
luci.http.status(200, "Reconnected")
return
end
luci.http.status(404, "No such interface")
end
function wifi_status(devs)
local s = require "luci.tools.status"
local rv = { }
if type(devs) == "string" then
local dev
for dev in devs:gmatch("[%w%.%-]+") do
rv[#rv+1] = s.wifi_network(dev)
end
end
if #rv > 0 then
luci.http.prepare_content("application/json")
luci.http.write_json(rv)
return
end
luci.http.status(404, "No such device")
end
function wifi_reconnect(radio)
local rc = luci.sys.call("env -i /sbin/wifi up %s" % luci.util.shellquote(radio))
if rc == 0 then
luci.http.status(200, "Reconnected")
else
luci.http.status(500, "Error")
end
end
local function _wifi_get_scan_results(cache_key)
local results = luci.util.ubus("session", "get", {
ubus_rpc_session = luci.model.uci:get_session_id(),
keys = { cache_key }
})
if type(results) == "table" and
type(results.values) == "table" and
type(results.values[cache_key]) == "table"
then
return results.values[cache_key]
end
return { }
end
function wifi_scan_trigger(radio, update)
local iw = radio and luci.sys.wifi.getiwinfo(radio)
if not iw then
luci.http.status(404, "No such radio device")
return
end
luci.http.status(204, "Scan scheduled")
if nixio.fork() == 0 then
io.stderr:close()
io.stdout:close()
local _, bss
local data, bssids = { }, { }
local cache_key = "scan_%s" % radio
luci.util.ubus("session", "set", {
ubus_rpc_session = luci.model.uci:get_session_id(),
values = { [cache_key] = nil }
})
for _, bss in ipairs(iw.scanlist or { }) do
data[_] = bss
bssids[bss.bssid] = bss
end
if update then
for _, bss in ipairs(_wifi_get_scan_results(cache_key)) do
if not bssids[bss.bssid] then
bss.stale = true
data[#data + 1] = bss
end
end
end
luci.util.ubus("session", "set", {
ubus_rpc_session = luci.model.uci:get_session_id(),
values = { [cache_key] = data }
})
end
end
function wifi_scan_results(radio)
local results = radio and _wifi_get_scan_results("scan_%s" % radio)
if results and #results > 0 then
luci.http.prepare_content("application/json")
luci.http.write_json(results)
else
luci.http.status(404, "No wireless scan results")
end
end
function switch_status(switches)
local s = require "luci.tools.status"
luci.http.prepare_content("application/json")
luci.http.write_json(s.switch_status(switches))
end
function diag_command(cmd, addr)
if addr and addr:match("^[a-zA-Z0-9%-%.:_]+$") then
luci.http.prepare_content("text/plain")
local util = io.popen(cmd % luci.util.shellquote(addr))
if util then
while true do
local ln = util:read("*l")
if not ln then break end
luci.http.write(ln)
luci.http.write("\n")
end
util:close()
end
return
end
luci.http.status(500, "Bad address")
end
function diag_ping(addr)
diag_command("ping -c 5 -W 1 %s 2>&1", addr)
end
function diag_traceroute(addr)
diag_command("traceroute -q 1 -w 1 -n %s 2>&1", addr)
end
function diag_nslookup(addr)
diag_command("nslookup %s 2>&1", addr)
end
function diag_ping6(addr)
diag_command("ping6 -c 5 %s 2>&1", addr)
end
function diag_traceroute6(addr)
diag_command("traceroute6 -q 1 -w 2 -n %s 2>&1", addr)
end
function diag_getip(addr)
diag_command("wget -4 -qO- -T 2 %s 2>&1", addr)
end
function diag_netstat()
diag_command("netstat -lapute 2>&1","http://www.none.com/")
end

View file

@ -1,347 +0,0 @@
-- Copyright 2008 Steven Barth <steven@midlink.org>
-- Licensed to the public under the Apache License 2.0.
local ipc = require "luci.ip"
local sys = require "luci.sys"
local o
require "luci.util"
m = Map("dhcp", translate("DHCP and DNS"),
translate("Dnsmasq is a combined <abbr title=\"Dynamic Host Configuration Protocol" ..
"\">DHCP</abbr>-Server and <abbr title=\"Domain Name System\">DNS</abbr>-" ..
"Forwarder for <abbr title=\"Network Address Translation\">NAT</abbr> " ..
"firewalls"))
s = m:section(TypedSection, "dnsmasq", translate("Server Settings"))
s.anonymous = true
s.addremove = false
s:tab("general", translate("General Settings"))
s:tab("files", translate("Resolv and Hosts Files"))
s:tab("tftp", translate("TFTP Settings"))
s:tab("advanced", translate("Advanced Settings"))
s:taboption("general", Flag, "domainneeded",
translate("Domain required"),
translate("Don't forward <abbr title=\"Domain Name System\">DNS</abbr>-Requests without " ..
"<abbr title=\"Domain Name System\">DNS</abbr>-Name"))
s:taboption("general", Flag, "authoritative",
translate("Authoritative"),
translate("This is the only <abbr title=\"Dynamic Host Configuration Protocol\">DHCP</" ..
"abbr> in the local network"))
s:taboption("files", Flag, "readethers",
translate("Use <code>/etc/ethers</code>"),
translate("Read <code>/etc/ethers</code> to configure the <abbr title=\"Dynamic Host " ..
"Configuration Protocol\">DHCP</abbr>-Server"))
s:taboption("files", Value, "leasefile",
translate("Leasefile"),
translate("file where given <abbr title=\"Dynamic Host Configuration Protocol\">DHCP</" ..
"abbr>-leases will be stored"))
s:taboption("files", Flag, "noresolv",
translate("Ignore resolve file")).optional = true
rf = s:taboption("files", Value, "resolvfile",
translate("Resolve file"),
translate("local <abbr title=\"Domain Name System\">DNS</abbr> file"))
rf:depends("noresolv", "")
rf.optional = true
s:taboption("files", Flag, "nohosts",
translate("Ignore <code>/etc/hosts</code>")).optional = true
s:taboption("files", DynamicList, "addnhosts",
translate("Additional Hosts files")).optional = true
qu = s:taboption("advanced", Flag, "quietdhcp",
translate("Suppress logging"),
translate("Suppress logging of the routine operation of these protocols"))
qu.optional = true
se = s:taboption("advanced", Flag, "sequential_ip",
translate("Allocate IP sequentially"),
translate("Allocate IP addresses sequentially, starting from the lowest available address"))
se.optional = true
bp = s:taboption("advanced", Flag, "boguspriv",
translate("Filter private"),
translate("Do not forward reverse lookups for local networks"))
bp.default = bp.enabled
s:taboption("advanced", Flag, "filterwin2k",
translate("Filter useless"),
translate("Do not forward requests that cannot be answered by public name servers"))
s:taboption("advanced", Flag, "localise_queries",
translate("Localise queries"),
translate("Localise hostname depending on the requesting subnet if multiple IPs are available"))
local have_dnssec_support = luci.util.checklib("/usr/sbin/dnsmasq", "libhogweed.so")
if have_dnssec_support then
o = s:taboption("advanced", Flag, "dnssec",
translate("DNSSEC"))
o.optional = true
o = s:taboption("advanced", Flag, "dnsseccheckunsigned",
translate("DNSSEC check unsigned"),
translate("Requires upstream supports DNSSEC; verify unsigned domain responses really come from unsigned domains"))
o.optional = true
end
s:taboption("general", Value, "local",
translate("Local server"),
translate("Local domain specification. Names matching this domain are never forwarded and are resolved from DHCP or hosts files only"))
s:taboption("general", Value, "domain",
translate("Local domain"),
translate("Local domain suffix appended to DHCP names and hosts file entries"))
s:taboption("advanced", Flag, "expandhosts",
translate("Expand hosts"),
translate("Add local domain suffix to names served from hosts files"))
s:taboption("advanced", Flag, "nonegcache",
translate("No negative cache"),
translate("Do not cache negative replies, e.g. for not existing domains"))
s:taboption("advanced", Value, "serversfile",
translate("Additional servers file"),
translate("This file may contain lines like 'server=/domain/1.2.3.4' or 'server=1.2.3.4' for"..
"domain-specific or full upstream <abbr title=\"Domain Name System\">DNS</abbr> servers."))
s:taboption("advanced", Flag, "strictorder",
translate("Strict order"),
translate("<abbr title=\"Domain Name System\">DNS</abbr> servers will be queried in the " ..
"order of the resolvfile")).optional = true
s:taboption("advanced", Flag, "allservers",
translate("All Servers"),
translate("Query all available upstream <abbr title=\"Domain Name System\">DNS</abbr> servers")).optional = true
bn = s:taboption("advanced", DynamicList, "bogusnxdomain", translate("Bogus NX Domain Override"),
translate("List of hosts that supply bogus NX domain results"))
bn.optional = true
bn.placeholder = "67.215.65.132"
s:taboption("general", Flag, "logqueries",
translate("Log queries"),
translate("Write received DNS requests to syslog")).optional = true
df = s:taboption("general", DynamicList, "server", translate("DNS forwardings"),
translate("List of <abbr title=\"Domain Name System\">DNS</abbr> " ..
"servers to forward requests to"))
df.optional = true
df.placeholder = "/example.org/10.1.2.3"
rp = s:taboption("general", Flag, "rebind_protection",
translate("Rebind protection"),
translate("Discard upstream RFC1918 responses"))
rp.rmempty = false
rl = s:taboption("general", Flag, "rebind_localhost",
translate("Allow localhost"),
translate("Allow upstream responses in the 127.0.0.0/8 range, e.g. for RBL services"))
rl:depends("rebind_protection", "1")
rd = s:taboption("general", DynamicList, "rebind_domain",
translate("Domain whitelist"),
translate("List of domains to allow RFC1918 responses for"))
rd.optional = true
rd:depends("rebind_protection", "1")
rd.datatype = "host(1)"
rd.placeholder = "ihost.netflix.com"
pt = s:taboption("advanced", Value, "port",
translate("<abbr title=\"Domain Name System\">DNS</abbr> server port"),
translate("Listening port for inbound DNS queries"))
pt.optional = true
pt.datatype = "port"
pt.placeholder = 53
qp = s:taboption("advanced", Value, "queryport",
translate("<abbr title=\"Domain Name System\">DNS</abbr> query port"),
translate("Fixed source port for outbound DNS queries"))
qp.optional = true
qp.datatype = "port"
qp.placeholder = translate("any")
lm = s:taboption("advanced", Value, "dhcpleasemax",
translate("<abbr title=\"maximal\">Max.</abbr> <abbr title=\"Dynamic Host Configuration " ..
"Protocol\">DHCP</abbr> leases"),
translate("Maximum allowed number of active DHCP leases"))
lm.optional = true
lm.datatype = "uinteger"
lm.placeholder = translate("unlimited")
em = s:taboption("advanced", Value, "ednspacket_max",
translate("<abbr title=\"maximal\">Max.</abbr> <abbr title=\"Extension Mechanisms for " ..
"Domain Name System\">EDNS0</abbr> packet size"),
translate("Maximum allowed size of EDNS.0 UDP packets"))
em.optional = true
em.datatype = "uinteger"
em.placeholder = 1280
cq = s:taboption("advanced", Value, "dnsforwardmax",
translate("<abbr title=\"maximal\">Max.</abbr> concurrent queries"),
translate("Maximum allowed number of concurrent DNS queries"))
cq.optional = true
cq.datatype = "uinteger"
cq.placeholder = 150
cs = s:taboption("advanced", Value, "cachesize",
translate("Size of DNS query cache"),
translate("Number of cached DNS entries (max is 10000, 0 is no caching)"))
cs.optional = true
cs.datatype = "range(0,10000)"
cs.placeholder = 150
s:taboption("tftp", Flag, "enable_tftp",
translate("Enable TFTP server")).optional = true
tr = s:taboption("tftp", Value, "tftp_root",
translate("TFTP server root"),
translate("Root directory for files served via TFTP"))
tr.optional = true
tr:depends("enable_tftp", "1")
tr.placeholder = "/"
db = s:taboption("tftp", Value, "dhcp_boot",
translate("Network boot image"),
translate("Filename of the boot image advertised to clients"))
db.optional = true
db:depends("enable_tftp", "1")
db.placeholder = "pxelinux.0"
o = s:taboption("general", Flag, "localservice",
translate("Local Service Only"),
translate("Limit DNS service to subnets interfaces on which we are serving DNS."))
o.optional = false
o.rmempty = false
o = s:taboption("general", Flag, "nonwildcard",
translate("Non-wildcard"),
translate("Bind dynamically to interfaces rather than wildcard address (recommended as linux default)"))
o.optional = false
o.rmempty = true
o = s:taboption("general", DynamicList, "interface",
translate("Listen Interfaces"),
translate("Limit listening to these interfaces, and loopback."))
o.optional = true
o = s:taboption("general", DynamicList, "notinterface",
translate("Exclude interfaces"),
translate("Prevent listening on these interfaces."))
o.optional = true
m:section(SimpleSection).template = "lease_status"
s = m:section(TypedSection, "host", translate("Static Leases"),
translate("Static leases are used to assign fixed IP addresses and symbolic hostnames to " ..
"DHCP clients. They are also required for non-dynamic interface configurations where " ..
"only hosts with a corresponding lease are served.") .. "<br />" ..
translate("Use the <em>Add</em> Button to add a new lease entry. The <em>MAC-Address</em> " ..
"identifies the host, the <em>IPv4-Address</em> specifies the fixed address to " ..
"use, and the <em>Hostname</em> is assigned as a symbolic name to the requesting host. " ..
"The optional <em>Lease time</em> can be used to set non-standard host-specific " ..
"lease time, e.g. 12h, 3d or infinite."))
s.addremove = true
s.anonymous = true
s.template = "cbi/tblsection"
name = s:option(Value, "name", translate("Hostname"))
name.datatype = "hostname('strict')"
name.rmempty = true
function name.write(self, section, value)
Value.write(self, section, value)
m:set(section, "dns", "1")
end
function name.remove(self, section)
Value.remove(self, section)
m:del(section, "dns")
end
mac = s:option(Value, "mac", translate("<abbr title=\"Media Access Control\">MAC</abbr>-Address"))
mac.datatype = "list(unique(macaddr))"
mac.rmempty = true
function mac.cfgvalue(self, section)
local val = Value.cfgvalue(self, section)
return ipc.checkmac(val) or val
end
ip = s:option(Value, "ip", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Address"))
ip.datatype = "or(ip4addr,'ignore')"
gw = s:option(Value, "gw", translate("Gateway IPv4 Address"))
gw.datatype = "or(ip4addr,'ignore')"
time = s:option(Value, "leasetime", translate("Lease time"))
time.rmempty = true
duid = s:option(Value, "duid", translate("<abbr title=\"The DHCP Unique Identifier\">DUID</abbr>"))
duid.datatype = "and(rangelength(20,36),hexstring)"
fp = io.open("/var/hosts/odhcpd")
if fp then
for line in fp:lines() do
local net_val, duid_val = string.match(line, "# (%S+)%s+(%S+)")
if duid_val then
duid:value(duid_val, duid_val)
end
end
fp:close()
end
hostid = s:option(Value, "hostid", translate("<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Suffix (hex)"))
sys.net.host_hints(function(m, v4, v6, name)
if m and v4 then
ip:value(v4)
mac:value(m, "%s (%s)" %{ m, name or v4 })
end
end)
function ip.validate(self, value, section)
local m = mac:formvalue(section) or ""
local n = name:formvalue(section) or ""
if value and #n == 0 and #m == 0 then
return nil, translate("One of hostname or mac address must be specified!")
end
return Value.validate(self, value, section)
end
return m

View file

@ -1,31 +0,0 @@
-- Copyright 2008 Steven Barth <steven@midlink.org>
-- Copyright 2010-2015 Jo-Philipp Wich <jow@openwrt.org>
-- Licensed to the public under the Apache License 2.0.
local ipc = require "luci.ip"
local sys = require "luci.sys"
m = Map("dhcp", translate("Hostnames"))
s = m:section(TypedSection, "domain", translate("Host entries"))
s.addremove = true
s.anonymous = true
s.template = "cbi/tblsection"
hn = s:option(Value, "name", translate("Hostname"))
hn.datatype = "hostname"
hn.rmempty = true
ip = s:option(Value, "ip", translate("IP address"))
ip.datatype = "ipaddr"
ip.rmempty = true
sys.net.host_hints(function(mac, v4, v6, name)
v6 = v6 and ipc.IPv6(v6)
if v4 or (v6 and not v6:is6linklocal()) then
ip:value(tostring(v4 or v6), "%s (%s)" %{ tostring(v4 or v6), name or mac })
end
end)
return m

View file

@ -1,115 +0,0 @@
-- Copyright 2009-2010 Jo-Philipp Wich <jow@openwrt.org>
-- Licensed to the public under the Apache License 2.0.
local nw = require "luci.model.network".init()
local fw = require "luci.model.firewall".init()
local utl = require "luci.util"
local uci = require "luci.model.uci".cursor()
m = SimpleForm("network", translate("Create Interface"))
m.redirect = luci.dispatcher.build_url("admin/network/network")
m.reset = false
function m.on_cancel()
luci.http.redirect(luci.dispatcher.build_url("admin/network/network"))
end
newnet = m:field(Value, "_netname", translate("Name of the new interface"),
translate("The allowed characters are: <code>A-Z</code>, <code>a-z</code>, " ..
"<code>0-9</code> and <code>_</code>"
))
newnet:depends("_attach", "")
newnet.default = arg[1] and "net_" .. arg[1]:gsub("[^%w_]+", "_")
newnet.datatype = "and(uciname,maxlength(15))"
advice = m:field(DummyValue, "d1", translate("Note: interface name length"),
translate("Maximum length of the name is 15 characters including " ..
"the automatic protocol/bridge prefix (br-, 6in4-, pppoe- etc.)"
))
newproto = m:field(ListValue, "_netproto", translate("Protocol of the new interface"))
--netbridge = m:field(Flag, "_bridge", translate("Create a bridge over multiple interfaces"))
newtype = m:field(ListValue, "_type", translate("Type of the new interface"))
newtype:value("", translate("Default"))
newtype:value("macvlan", translate("Create a macvlan sub interface"))
newtype:value("bridge", translate("Create a bridge over multiple interfaces"))
sifname = m:field(Value, "_ifname", translate("Cover the following interface"))
sifname.widget = "radio"
sifname.template = "cbi/network_ifacelist"
sifname.nobridges = true
mifname = m:field(Value, "_ifnames", translate("Cover the following interfaces"))
mifname.widget = "checkbox"
mifname.template = "cbi/network_ifacelist"
mifname.nobridges = true
vifname = m:field(Value, "_vifname", translate("Cover the following interface"))
vifname.default = "eth0"
local _, p
for _, p in ipairs(nw:get_protocols()) do
if p:is_installed() then
newproto:value(p:proto(), p:get_i18n())
--if not p:is_virtual() then netbridge:depends("_netproto", p:proto()) end
if not p:is_virtual() then newtype:depends("_netproto", p:proto()) end
if not p:is_floating() then
--sifname:depends({ _bridge = "", _netproto = p:proto()})
--mifname:depends({ _bridge = "1", _netproto = p:proto()})
sifname:depends({ _type = "", _netproto = p:proto() })
mifname:depends({ _type = "bridge", _netproto = p:proto() })
vifname:depends({ _type = "macvlan", _netproto = p:proto() })
end
end
end
function newproto.validate(self, value, section)
local name = newnet:formvalue(section)
if not name or #name == 0 then
newnet:add_error(section, translate("No network name specified"))
elseif m:get(name) then
newnet:add_error(section, translate("The given network name is not unique"))
end
local proto = nw:get_protocol(value)
if proto and not proto:is_floating() then
--local br = (netbridge:formvalue(section) == "1")
--local ifn = br and mifname:formvalue(section) or sifname:formvalue(section)
local ifn = ( (newtype:formvalue(section) == "macvlan" and name) or (newtype:formvalue(section) == "bridge" and mifname:formvalue(section)) or sifname:formvalue(section) )
for ifn in utl.imatch(ifn) do
return value
end
return nil, translate("The selected protocol needs a device assigned")
end
return value
end
function newproto.write(self, section, value)
local name = newnet:formvalue(section)
if name and #name > 0 then
--local br = (netbridge:formvalue(section) == "1") and "bridge" or nil
--local net = nw:add_network(name, { proto = value, type = br })
local isBridge = (newtype:formvalue(section) == "bridge") or nil
local isMacvlan = (newtype:formvalue(section) == "macvlan") or nil
local net = nw:add_network(name, { proto = value, type = newtype:formvalue(section), interface = isMacvlan and vifname:formvalue(section) or nil })
if net then
local ifn
for ifn in utl.imatch(
(isMacvlan and name) or (isBridge and mifname:formvalue(section)) or (sifname:formvalue(section))
--br and mifname:formvalue(section) or sifname:formvalue(section)
) do
net:add_interface(ifn)
end
nw:save("network")
nw:save("wireless")
end
luci.http.redirect(luci.dispatcher.build_url("admin/network/network", name))
end
end
return m

View file

@ -1,591 +0,0 @@
-- Copyright 2008 Steven Barth <steven@midlink.org>
-- Copyright 2008-2011 Jo-Philipp Wich <jow@openwrt.org>
-- Licensed to the public under the Apache License 2.0.
local fs = require "nixio.fs"
local ut = require "luci.util"
local pt = require "luci.tools.proto"
local nw = require "luci.model.network"
local fw = require "luci.model.firewall"
arg[1] = arg[1] or ""
local has_dnsmasq = fs.access("/etc/config/dhcp")
local has_firewall = fs.access("/etc/config/firewall")
m = Map("network", translate("Interfaces") .. " - " .. arg[1]:upper(), translate("On this page you can configure the network interfaces. You can bridge several interfaces by ticking the \"bridge interfaces\" field and enter the names of several network interfaces separated by spaces. You can also use <abbr title=\"Virtual Local Area Network\">VLAN</abbr> notation <samp>INTERFACE.VLANNR</samp> (<abbr title=\"for example\">e.g.</abbr>: <samp>eth0.1</samp>)."))
m.redirect = luci.dispatcher.build_url("admin", "network", "network")
m:chain("wireless")
m:chain("luci")
if has_firewall then
m:chain("firewall")
end
nw.init(m.uci)
fw.init(m.uci)
local net = nw:get_network(arg[1])
local function set_ifstate(name, option, value)
local found = false
m.uci:foreach("luci", "ifstate", function (s)
if s.interface == name then
m.uci:set("luci", s[".name"], option, value)
found = true
return false
end
end)
if not found then
local sid = m.uci:add("luci", "ifstate")
m.uci:set("luci", sid, "interface", name)
m.uci:set("luci", sid, option, value)
end
m.uci:save("luci")
end
local function get_ifstate(name, option)
local val
m.uci:foreach("luci", "ifstate", function (s)
if s.interface == name then
val = s[option]
return false
end
end)
return val
end
local function backup_ifnames(is_bridge)
if not net:is_floating() and not get_ifstate(net:name(), "ifname") then
local ifcs = net:get_interfaces() or { net:get_interface() }
if ifcs then
local _, ifn
local ifns = { }
for _, ifn in ipairs(ifcs) do
local wif = ifn:get_wifinet()
ifns[#ifns+1] = wif and wif:id() or ifn:name()
end
if #ifns > 0 then
set_ifstate(net:name(), "ifname", table.concat(ifns, " "))
set_ifstate(net:name(), "bridge", tostring(net:is_bridge()))
end
end
end
end
-- redirect to overview page if network does not exist anymore (e.g. after a revert)
if not net then
luci.http.redirect(luci.dispatcher.build_url("admin/network/network"))
return
end
-- protocol switch was requested, rebuild interface config and reload page
if m:formvalue("cbid.network.%s._switch" % net:name()) then
-- get new protocol
local ptype = m:formvalue("cbid.network.%s.proto" % net:name()) or "-"
local proto = nw:get_protocol(ptype, net:name())
if proto then
-- backup default
backup_ifnames()
-- if current proto is not floating and target proto is not floating,
-- then attempt to retain the ifnames
--error(net:proto() .. " > " .. proto:proto())
if not net:is_floating() and not proto:is_floating() then
-- if old proto is a bridge and new proto not, then clip the
-- interface list to the first ifname only
if net:is_bridge() and proto:is_virtual() then
local _, ifn
local first = true
for _, ifn in ipairs(net:get_interfaces() or { net:get_interface() }) do
if first then
first = false
else
net:del_interface(ifn)
end
end
m:del(net:name(), "type")
end
-- if the current proto is floating, the target proto not floating,
-- then attempt to restore ifnames from backup
elseif net:is_floating() and not proto:is_floating() then
-- if we have backup data, then re-add all orphaned interfaces
-- from it and restore the bridge choice
local br = (get_ifstate(net:name(), "bridge") == "true")
local ifn
local ifns = { }
for ifn in ut.imatch(get_ifstate(net:name(), "ifname")) do
ifn = nw:get_interface(ifn)
if ifn and not ifn:get_network() then
proto:add_interface(ifn)
if not br then
break
end
end
end
if br then
m:set(net:name(), "type", "bridge")
end
-- in all other cases clear the ifnames
else
local _, ifc
for _, ifc in ipairs(net:get_interfaces() or { net:get_interface() }) do
net:del_interface(ifc)
end
m:del(net:name(), "type")
end
-- clear options
local k, v
for k, v in pairs(m:get(net:name())) do
if k:sub(1,1) ~= "." and
k ~= "type" and
k ~= "ifname"
then
m:del(net:name(), k)
end
end
-- set proto
m:set(net:name(), "proto", proto:proto())
m.uci:save("network")
m.uci:save("wireless")
-- reload page
luci.http.redirect(luci.dispatcher.build_url("admin/network/network", arg[1]))
return
end
end
-- dhcp setup was requested, create section and reload page
if m:formvalue("cbid.dhcp._enable._enable") then
m.uci:section("dhcp", "dhcp", arg[1], {
interface = arg[1],
start = "100",
limit = "150",
leasetime = "12h"
})
m.uci:save("dhcp")
luci.http.redirect(luci.dispatcher.build_url("admin/network/network", arg[1]))
return
end
local ifc = net:get_interface()
s = m:section(NamedSection, arg[1], "interface", translate("Common Configuration"))
s.addremove = false
s:tab("general", translate("General Setup"))
s:tab("advanced", translate("Advanced Settings"))
s:tab("physical", translate("Physical Settings"))
if has_firewall then
s:tab("firewall", translate("Firewall Settings"))
end
st = s:taboption("general", DummyValue, "__status", translate("Status"))
local function set_status()
-- if current network is empty, print a warning
if not net:is_floating() and net:is_empty() then
st.template = "cbi/dvalue"
st.network = nil
st.value = translate("There is no device assigned yet, please attach a network device in the \"Physical Settings\" tab")
else
st.template = "admin_network/iface_status"
st.network = arg[1]
st.value = nil
end
end
m.on_init = set_status
m.on_after_save = set_status
l = s:taboption("general", Value, "label", translate("Label"))
l.rmempty = true
l:depends("multipath", "on")
l:depends("multipath", "master")
l:depends("multipath", "backup")
l:depends("multipath", "handover")
p = s:taboption("general", ListValue, "proto", translate("Protocol"))
p.default = net:proto()
if not net:is_installed() then
p_install = s:taboption("general", Button, "_install")
p_install.title = translate("Protocol support is not installed")
p_install.inputtitle = translate("Install package %q" % net:opkg_package())
p_install.inputstyle = "apply"
p_install:depends("proto", net:proto())
function p_install.write()
return luci.http.redirect(
luci.dispatcher.build_url("admin/system/opkg") ..
"?query=%s" % net:opkg_package()
)
end
end
p_switch = s:taboption("general", Button, "_switch")
p_switch.title = translate("Really switch protocol?")
p_switch.inputtitle = translate("Switch protocol")
p_switch.inputstyle = "apply"
local _, pr
for _, pr in ipairs(nw:get_protocols()) do
p:value(pr:proto(), pr:get_i18n())
if pr:proto() ~= net:proto() then
p_switch:depends("proto", pr:proto())
end
end
auto = s:taboption("advanced", Flag, "auto", translate("Bring up on boot"))
auto.default = (net:proto() == "none") and auto.disabled or auto.enabled
-- Add MPTCP
if fs.access("/proc/sys/net/mptcp") then
mptcp = s:taboption("advanced", ListValue, "multipath", translate("Multipath TCP"), translate("One interface must be set as master"))
mptcp:value("on", translate("enabled"))
mptcp:value("off", translate("disabled"))
mptcp:value("master", translate("master"))
mptcp:value("backup", translate("backup"))
mptcp:value("handover", translate("handover"))
mptcp.default = "off"
end
delegate = s:taboption("advanced", Flag, "delegate", translate("Use builtin IPv6-management"))
delegate.default = delegate.enabled
force_link = s:taboption("advanced", Flag, "force_link",
translate("Force link"),
translate("Set interface properties regardless of the link carrier (If set, carrier sense events do not invoke hotplug handlers)."))
force_link.default = (net:proto() == "static") and force_link.enabled or force_link.disabled
if not net:is_virtual() then
--br = s:taboption("physical", Flag, "type", translate("Bridge interfaces"), translate("creates a bridge over specified interface(s)"))
--br.enabled = "bridge"
--br.rmempty = true
--br:depends("proto", "static")
--br:depends("proto", "dhcp")
--br:depends("proto", "none")
iftype = s:taboption("physical", ListValue, "type", translate("Type of the interface"))
iftype:value("", translate("Default"))
iftype:value("macvlan", translate("Create a macvlan sub interface"))
iftype:value("bridge", translate("Create a bridge over multiple interfaces"))
iftype:depends("proto", "static")
iftype:depends("proto", "dhcp")
iftype:depends("proto", "none")
stp = s:taboption("physical", Flag, "stp", translate("Enable <abbr title=\"Spanning Tree Protocol\">STP</abbr>"),
translate("Enables the Spanning Tree Protocol on this bridge"))
stp:depends("type", "bridge")
stp.rmempty = true
igmp = s:taboption("physical", Flag, "igmp_snooping", translate("Enable <abbr title=\"Internet Group Management Protocol\">IGMP</abbr> snooping"),
translate("Enables IGMP snooping on this bridge"))
igmp:depends("type", "bridge")
igmp.rmempty = true
end
macvlanmaster = s:taboption("physical", Value, "masterintf", translate("Master interface"))
macvlanmaster.default = "eth0"
macvlanmaster:depends("type", "macvlan")
if not net:is_floating() then
ifname_single = s:taboption("physical", Value, "ifname_single", translate("Interface"))
ifname_single.template = "cbi/network_ifacelist"
ifname_single.widget = "radio"
ifname_single.nobridges = net:is_bridge()
ifname_single.noaliases = false
ifname_single.rmempty = false
ifname_single.network = arg[1]
ifname_single:depends("type", "")
function ifname_single.cfgvalue(self, s)
-- let the template figure out the related ifaces through the network model
return nil
end
function ifname_single.write(self, s, val)
local _, i
local new_ifs = { }
local old_ifs = { }
local alias = net:is_alias()
if alias then
old_ifs[1] = '@' .. alias
else
for _, i in ipairs(net:get_interfaces() or { net:get_interface() }) do
old_ifs[#old_ifs+1] = i:name()
end
end
for i in ut.imatch(val) do
new_ifs[#new_ifs+1] = i
-- if this is not a bridge, only assign first interface
if self.option == "ifname_single" then
break
end
end
table.sort(old_ifs)
table.sort(new_ifs)
for i = 1, math.max(#old_ifs, #new_ifs) do
if old_ifs[i] ~= new_ifs[i] then
backup_ifnames()
for i = 1, #old_ifs do
net:del_interface(old_ifs[i])
end
for i = 1, #new_ifs do
net:add_interface(new_ifs[i])
end
break
end
end
end
end
if not net:is_virtual() then
ifname_multi = s:taboption("physical", Value, "ifname_multi", translate("Interface"))
ifname_multi.template = "cbi/network_ifacelist"
ifname_multi.nobridges = net:is_bridge()
ifname_multi.noaliases = true
ifname_multi.rmempty = false
ifname_multi.network = arg[1]
ifname_multi.widget = "checkbox"
ifname_multi:depends("type", "bridge")
ifname_multi.cfgvalue = ifname_single.cfgvalue
ifname_multi.write = ifname_single.write
end
if has_firewall then
fwzone = s:taboption("firewall", Value, "_fwzone",
translate("Create / Assign firewall-zone"),
translate("Choose the firewall zone you want to assign to this interface. Select <em>unspecified</em> to remove the interface from the associated zone or fill out the <em>create</em> field to define a new zone and attach the interface to it."))
fwzone.template = "cbi/firewall_zonelist"
fwzone.network = arg[1]
function fwzone.cfgvalue(self, section)
self.iface = section
local z = fw:get_zone_by_network(section)
return z and z:name()
end
function fwzone.write(self, section, value)
local zone = fw:get_zone(value) or fw:add_zone(value)
if zone then
fw:del_network(section)
zone:add_network(section)
end
end
function fwzone.remove(self, section)
fw:del_network(section)
end
end
function p.write() end
function p.remove() end
function p.validate(self, value, section)
if value == net:proto() then
if not net:is_floating() and net:is_empty() then
local ifn = ((br and (br:formvalue(section) == "bridge"))
and ifname_multi:formvalue(section)
or ifname_single:formvalue(section))
for ifn in ut.imatch(ifn) do
return value
end
return nil, translate("The selected protocol needs a device assigned")
end
end
return value
end
local form, ferr = loadfile(
ut.libpath() .. "/model/cbi/admin_network/proto_%s.lua" % net:proto()
)
if not form then
s:taboption("general", DummyValue, "_error",
translate("Missing protocol extension for proto %q" % net:proto())
).value = ferr
else
setfenv(form, getfenv(1))(m, s, net)
end
local _, field
for _, field in ipairs(s.children) do
if field ~= st and field ~= p and field ~= p_install and field ~= p_switch then
if next(field.deps) then
local _, dep
for _, dep in ipairs(field.deps) do
dep.proto = net:proto()
end
else
field:depends("proto", net:proto())
end
end
end
--
-- Display DNS settings if dnsmasq is available
--
if has_dnsmasq and net:proto() == "static" then
m2 = Map("dhcp", "", "")
local has_section = false
m2.uci:foreach("dhcp", "dhcp", function(s)
if s.interface == arg[1] then
has_section = true
return false
end
end)
if not has_section and has_dnsmasq then
s = m2:section(TypedSection, "dhcp", translate("DHCP Server"))
s.anonymous = true
s.cfgsections = function() return { "_enable" } end
x = s:option(Button, "_enable")
x.title = translate("No DHCP Server configured for this interface")
x.inputtitle = translate("Setup DHCP Server")
x.inputstyle = "apply"
elseif has_section then
s = m2:section(TypedSection, "dhcp", translate("DHCP Server"))
s.addremove = false
s.anonymous = true
s:tab("general", translate("General Setup"))
s:tab("advanced", translate("Advanced Settings"))
s:tab("ipv6", translate("IPv6 Settings"))
function s.filter(self, section)
return m2.uci:get("dhcp", section, "interface") == arg[1]
end
local ignore = s:taboption("general", Flag, "ignore",
translate("Ignore interface"),
translate("Disable <abbr title=\"Dynamic Host Configuration Protocol\">DHCP</abbr> for " ..
"this interface."))
local start = s:taboption("general", Value, "start", translate("Start"),
translate("Lowest leased address as offset from the network address."))
start.optional = true
start.datatype = "or(uinteger,ip4addr)"
start.default = "100"
local limit = s:taboption("general", Value, "limit", translate("Limit"),
translate("Maximum number of leased addresses."))
limit.optional = true
limit.datatype = "uinteger"
limit.default = "150"
local ltime = s:taboption("general", Value, "leasetime", translate("Lease time"),
translate("Expiry time of leased addresses, minimum is 2 minutes (<code>2m</code>)."))
ltime.rmempty = true
ltime.default = "12h"
local dd = s:taboption("advanced", Flag, "dynamicdhcp",
translate("Dynamic <abbr title=\"Dynamic Host Configuration Protocol\">DHCP</abbr>"),
translate("Dynamically allocate DHCP addresses for clients. If disabled, only " ..
"clients having static leases will be served."))
dd.default = dd.enabled
s:taboption("advanced", Flag, "force", translate("Force"),
translate("Force DHCP on this network even if another server is detected."))
-- XXX: is this actually useful?
--s:taboption("advanced", Value, "name", translate("Name"),
-- translate("Define a name for this network."))
mask = s:taboption("advanced", Value, "netmask",
translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"),
translate("Override the netmask sent to clients. Normally it is calculated " ..
"from the subnet that is served."))
mask.optional = true
mask.datatype = "ip4addr"
s:taboption("advanced", DynamicList, "dhcp_option", translate("DHCP-Options"),
translate("Define additional DHCP options, for example \"<code>6,192.168.2.1," ..
"192.168.2.2</code>\" which advertises different DNS servers to clients."))
for i, n in ipairs(s.children) do
if n ~= ignore then
n:depends("ignore", "")
end
end
o = s:taboption("ipv6", ListValue, "ra", translate("Router Advertisement-Service"))
o:value("", translate("disabled"))
o:value("server", translate("server mode"))
o:value("relay", translate("relay mode"))
o:value("hybrid", translate("hybrid mode"))
o = s:taboption("ipv6", ListValue, "dhcpv6", translate("DHCPv6-Service"))
o:value("", translate("disabled"))
o:value("server", translate("server mode"))
o:value("relay", translate("relay mode"))
o:value("hybrid", translate("hybrid mode"))
o = s:taboption("ipv6", ListValue, "ndp", translate("NDP-Proxy"))
o:value("", translate("disabled"))
o:value("relay", translate("relay mode"))
o:value("hybrid", translate("hybrid mode"))
o = s:taboption("ipv6", ListValue, "ra_management", translate("DHCPv6-Mode"),
translate("Default is stateless + stateful"))
o:value("0", translate("stateless"))
o:value("1", translate("stateless + stateful"))
o:value("2", translate("stateful-only"))
o:depends("dhcpv6", "server")
o:depends("dhcpv6", "hybrid")
o.default = "1"
o = s:taboption("ipv6", Flag, "ra_default", translate("Always announce default router"),
translate("Announce as default router even if no public prefix is available."))
o:depends("ra", "server")
o:depends("ra", "hybrid")
s:taboption("ipv6", DynamicList, "dns", translate("Announced DNS servers"))
s:taboption("ipv6", DynamicList, "domain", translate("Announced DNS domains"))
else
m2 = nil
end
end
return m, m2

View file

@ -1,236 +0,0 @@
-- 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.
local fs = require "nixio.fs"
local tpl = require "luci.template"
local ntm = require "luci.model.network".init()
local fwm = require "luci.model.firewall".init()
local json = require "luci.jsonc"
local sys = require "luci.sys"
m = Map("network", translate("Interfaces"))
m:chain("wireless")
m:chain("firewall")
m:chain("dhcp")
m.pageaction = false
local _, net
local ifaces, netlist = { }, { }
for _, net in ipairs(ntm:get_networks()) do
if net:name() ~= "loopback" then
local zn = net:zonename()
local z = zn and fwm:get_zone(zn) or fwm:get_zone_by_network(net:name())
local w = 1
if net:is_alias() then
w = 2
elseif net:is_dynamic() then
w = 3
end
ifaces[#ifaces+1] = net:name()
netlist[#netlist+1] = {
net:name(), z and z:name() or "-", z, net, w
}
end
end
table.sort(netlist,
function(a, b)
if a[2] ~= b[2] then
return a[2] < b[2]
elseif a[5] ~= b[5] then
return a[5] < b[5]
else
return a[1] < b[1]
end
end)
s = m:section(TypedSection, "interface", translate("Interface Overview"))
s.template = "admin_network/iface_overview"
s.netlist = netlist
function s.cfgsections(self)
local _, net, sl = nil, nil, { }
for _, net in ipairs(netlist) do
sl[#sl+1] = net[1]
end
return sl
end
o = s:option(Value, "__disable__")
function o.write(self, sid, value)
if value ~= "1" then
m:set(sid, "auto", "")
else
m:set(sid, "auto", "0")
end
end
o.remove = o.write
o = s:option(Value, "__delete__")
function o.write(self, sid, value)
ntm:del_network(sid)
end
if fs.access("/etc/init.d/dsl_control") then
local ok, boarddata = pcall(json.parse, fs.readfile("/etc/board.json"))
local modemtype = (ok == true)
and (type(boarddata) == "table")
and (type(boarddata.dsl) == "table")
and (type(boarddata.dsl.modem) == "table")
and boarddata.dsl.modem.type
dsl = m:section(TypedSection, "dsl", translate("DSL"))
dsl.anonymous = true
annex = dsl:option(ListValue, "annex", translate("Annex"))
annex:value("a", translate("Annex A + L + M (all)"))
annex:value("b", translate("Annex B (all)"))
annex:value("j", translate("Annex J (all)"))
annex:value("m", translate("Annex M (all)"))
annex:value("bdmt", translate("Annex B G.992.1"))
annex:value("b2", translate("Annex B G.992.3"))
annex:value("b2p", translate("Annex B G.992.5"))
annex:value("at1", translate("ANSI T1.413"))
annex:value("admt", translate("Annex A G.992.1"))
annex:value("alite", translate("Annex A G.992.2"))
annex:value("a2", translate("Annex A G.992.3"))
annex:value("a2p", translate("Annex A G.992.5"))
annex:value("l", translate("Annex L G.992.3 POTS 1"))
annex:value("m2", translate("Annex M G.992.3"))
annex:value("m2p", translate("Annex M G.992.5"))
tone = dsl:option(ListValue, "tone", translate("Tone"))
tone:value("", translate("auto"))
tone:value("a", translate("A43C + J43 + A43"))
tone:value("av", translate("A43C + J43 + A43 + V43"))
tone:value("b", translate("B43 + B43C"))
tone:value("bv", translate("B43 + B43C + V43"))
if modemtype == "vdsl" then
xfer_mode = dsl:option(ListValue, "xfer_mode", translate("Encapsulation mode"))
xfer_mode:value("", translate("auto"))
xfer_mode:value("atm", translate("ATM (Asynchronous Transfer Mode)"))
xfer_mode:value("ptm", translate("PTM/EFM (Packet Transfer Mode)"))
line_mode = dsl:option(ListValue, "line_mode", translate("DSL line mode"))
line_mode:value("", translate("auto"))
line_mode:value("adsl", translate("ADSL"))
line_mode:value("vdsl", translate("VDSL"))
ds_snr = dsl:option(ListValue, "ds_snr_offset", translate("Downstream SNR offset"))
ds_snr.default = "0"
for i = -100, 100, 5 do
ds_snr:value(i, translatef("%.1f dB", i / 10))
end
end
firmware = dsl:option(Value, "firmware", translate("Firmware File"))
m.pageaction = true
end
-- Show ATM bridge section if we have the capabilities
if fs.access("/usr/sbin/br2684ctl") then
atm = m:section(TypedSection, "atm-bridge", translate("ATM Bridges"),
translate("ATM bridges expose encapsulated ethernet in AAL5 " ..
"connections as virtual Linux network interfaces which can " ..
"be used in conjunction with DHCP or PPP to dial into the " ..
"provider network."))
atm.addremove = true
atm.anonymous = true
atm.create = function(self, section)
local sid = TypedSection.create(self, section)
local max_unit = -1
m.uci:foreach("network", "atm-bridge",
function(s)
local u = tonumber(s.unit)
if u ~= nil and u > max_unit then
max_unit = u
end
end)
m.uci:set("network", sid, "unit", max_unit + 1)
m.uci:set("network", sid, "atmdev", 0)
m.uci:set("network", sid, "encaps", "llc")
m.uci:set("network", sid, "payload", "bridged")
m.uci:set("network", sid, "vci", 35)
m.uci:set("network", sid, "vpi", 8)
return sid
end
atm:tab("general", translate("General Setup"))
atm:tab("advanced", translate("Advanced Settings"))
vci = atm:taboption("general", Value, "vci", translate("ATM Virtual Channel Identifier (VCI)"))
vpi = atm:taboption("general", Value, "vpi", translate("ATM Virtual Path Identifier (VPI)"))
encaps = atm:taboption("general", ListValue, "encaps", translate("Encapsulation mode"))
encaps:value("llc", translate("LLC"))
encaps:value("vc", translate("VC-Mux"))
atmdev = atm:taboption("advanced", Value, "atmdev", translate("ATM device number"))
unit = atm:taboption("advanced", Value, "unit", translate("Bridge unit number"))
payload = atm:taboption("advanced", ListValue, "payload", translate("Forwarding mode"))
payload:value("bridged", translate("bridged"))
payload:value("routed", translate("routed"))
m.pageaction = true
end
local network = require "luci.model.network"
if network:has_ipv6() then
local s = m:section(NamedSection, "globals", "globals", translate("Global network options"))
local o = s:option(Value, "ula_prefix", translate("IPv6 ULA-Prefix"))
o.datatype = "ip6addr"
o.rmempty = true
m.pageaction = true
end
if fs.access("/proc/sys/net/mptcp") then
local uname = nixio.uname()
local mtcp = s:option(ListValue, "multipath", translate("Multipath TCP"))
mtcp:value("enable", translate("enable"))
mtcp:value("disable", translate("disable"))
local mtcpck = s:option(ListValue, "mptcp_checksum", translate("Multipath TCP checksum"))
mtcpck:value(1, translate("enable"))
mtcpck:value(0, translate("disable"))
local mtcppm = s:option(ListValue, "mptcp_path_manager", translate("Multipath TCP path-manager"))
mtcppm:value("default", translate("default"))
mtcppm:value("fullmesh", translate("fullmesh"))
mtcppm:value("ndiffports", translate("ndiffports"))
mtcppm:value("blinder", translate("blinder"))
if uname.release:sub(1,4) == "4.19" then
mtcppm:value("netlink", translate("Netlink"))
end
local mtcpsch = s:option(ListValue, "mptcp_scheduler", translate("Multipath TCP scheduler"))
mtcpsch:value("default", translate("default"))
mtcpsch:value("roundrobin", translate("round-robin"))
mtcpsch:value("redundant", translate("redundant"))
if uname.release:sub(1,4) == "4.19" then
mtcpsch:value("blest", translate("BLEST"))
end
local mtcpsyn = s:option(Value, "mptcp_syn_retries", translate("Multipath TCP SYN retries"))
mtcpsyn.datatype = "uinteger"
mtcpsyn.rmempty = false
local congestion = s:option(ListValue, "congestion", translate("Congestion Control"))
local availablecong = sys.exec("sysctl net.ipv4.tcp_available_congestion_control | awk -F'= ' '{print $NF}'")
for cong in string.gmatch(availablecong, "[^%s]+") do
congestion:value(cong, translate(cong))
end
m.pageaction = true
end
return m

View file

@ -1,102 +0,0 @@
-- Copyright 2008 Steven Barth <steven@midlink.org>
-- Licensed to the public under the Apache License 2.0.
local wa = require "luci.tools.webadmin"
local fs = require "nixio.fs"
m = Map("network",
translate("Routes"),
translate("Routes specify over which interface and gateway a certain host or network " ..
"can be reached."))
s = m:section(TypedSection, "route", translate("Static IPv4 Routes"))
s.addremove = true
s.anonymous = true
s.template = "cbi/tblsection"
iface = s:option(ListValue, "interface", translate("Interface"))
wa.cbi_add_networks(iface)
t = s:option(Value, "target", translate("Target"), translate("Host-<abbr title=\"Internet Protocol Address\">IP</abbr> or Network"))
t.datatype = "ip4addr"
t.rmempty = false
n = s:option(Value, "netmask", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"), translate("if target is a network"))
n.placeholder = "255.255.255.255"
n.datatype = "ip4addr"
n.rmempty = true
g = s:option(Value, "gateway", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Gateway"))
g.datatype = "ip4addr"
g.rmempty = true
metric = s:option(Value, "metric", translate("Metric"))
metric.placeholder = 0
metric.datatype = "range(0,255)"
metric.size = 5
metric.rmempty = true
mtu = s:option(Value, "mtu", translate("MTU"))
mtu.placeholder = 1500
mtu.datatype = "range(64,9000)"
mtu.size = 5
mtu.rmempty = true
routetype = s:option(Value, "type", translate("Route type"))
routetype:value("", "unicast")
routetype:value("local", "local")
routetype:value("broadcast", "broadcast")
routetype:value("multicast", "multicast")
routetype:value("unreachable", "unreachable")
routetype:value("prohibit", "prohibit")
routetype:value("blackhole", "blackhole")
routetype:value("anycast", "anycast")
routetype.default = ""
routetype.rmempty = true
if fs.access("/proc/net/ipv6_route") then
s = m:section(TypedSection, "route6", translate("Static IPv6 Routes"))
s.addremove = true
s.anonymous = true
s.template = "cbi/tblsection"
iface = s:option(ListValue, "interface", translate("Interface"))
wa.cbi_add_networks(iface)
t = s:option(Value, "target", translate("Target"), translate("<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Address or Network (CIDR)"))
t.datatype = "ip6addr"
t.rmempty = false
g = s:option(Value, "gateway", translate("<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Gateway"))
g.datatype = "ip6addr"
g.rmempty = true
metric = s:option(Value, "metric", translate("Metric"))
metric.placeholder = 0
metric.datatype = "range(0,65535)" -- XXX: not sure
metric.size = 5
metric.rmempty = true
mtu = s:option(Value, "mtu", translate("MTU"))
mtu.placeholder = 1500
mtu.datatype = "range(64,9000)"
mtu.size = 5
mtu.rmempty = true
routetype = s:option(Value, "type", translate("Route type"))
routetype:value("", "unicast")
routetype:value("local", "local")
routetype:value("broadcast", "broadcast")
routetype:value("multicast", "multicast")
routetype:value("unreachable", "unreachable")
routetype:value("prohibit", "prohibit")
routetype:value("blackhole", "blackhole")
routetype:value("anycast", "anycast")
routetype.default = ""
routetype.rmempty = true
end
return m

View file

@ -1,389 +0,0 @@
-- Copyright 2008 Steven Barth <steven@midlink.org>
-- Copyright 2010-2011 Jo-Philipp Wich <jow@openwrt.org>
-- Licensed to the public under the Apache License 2.0.
m = Map("network", translate("Switch"), translate("The network ports on this device can be combined to several <abbr title=\"Virtual Local Area Network\">VLAN</abbr>s in which computers can communicate directly with each other. <abbr title=\"Virtual Local Area Network\">VLAN</abbr>s are often used to separate different network segments. Often there is by default one Uplink port for a connection to the next greater network like the internet and other ports for a local network."))
local fs = require "nixio.fs"
local ut = require "luci.util"
local nw = require "luci.model.network"
local switches = { }
nw.init(m.uci)
local topologies = nw:get_switch_topologies() or {}
local update_interfaces = function(old_ifname, new_ifname)
local info = { }
m.uci:foreach("network", "interface", function(section)
local old_ifnames = section.ifname
local new_ifnames = { }
local cur_ifname
local changed = false
for cur_ifname in luci.util.imatch(old_ifnames) do
if cur_ifname == old_ifname then
new_ifnames[#new_ifnames+1] = new_ifname
changed = true
else
new_ifnames[#new_ifnames+1] = cur_ifname
end
end
if changed then
m.uci:set("network", section[".name"], "ifname", table.concat(new_ifnames, " "))
info[#info+1] = translatef("Interface %q device auto-migrated from %q to %q.",
section[".name"], old_ifname, new_ifname)
end
end)
if #info > 0 then
m.message = (m.message and m.message .. "\n" or "") .. table.concat(info, "\n")
end
end
local vlan_already_created
m.uci:foreach("network", "switch",
function(x)
local sid = x['.name']
local switch_name = x.name or sid
local has_vlan = nil
local has_learn = nil
local has_vlan4k = nil
local has_jumbo3 = nil
local has_mirror = nil
local min_vid = 0
local max_vid = 16
local num_vlans = 16
local switch_title
local enable_vlan4k = false
local topo = topologies[switch_name]
if not topo then
m.message = translatef("Switch %q has an unknown topology - the VLAN settings might not be accurate.", switch_name)
topo = {
ports = {
{ num = 0, label = "Port 1" },
{ num = 1, label = "Port 2" },
{ num = 2, label = "Port 3" },
{ num = 3, label = "Port 4" },
{ num = 4, label = "Port 5" },
{ num = 5, label = "CPU (eth0)", tagged = false }
}
}
end
-- Parse some common switch properties from swconfig help output.
local swc = io.popen("swconfig dev %s help 2>/dev/null" % ut.shellquote(switch_name))
if swc then
local is_port_attr = false
local is_vlan_attr = false
while true do
local line = swc:read("*l")
if not line then break end
if line:match("^%s+%-%-vlan") then
is_vlan_attr = true
elseif line:match("^%s+%-%-port") then
is_vlan_attr = false
is_port_attr = true
elseif line:match("cpu @") then
switch_title = line:match("^switch%d: %w+%((.-)%)")
num_vlans = tonumber(line:match("vlans: (%d+)")) or 16
min_vid = 1
elseif line:match(": pvid") or line:match(": tag") or line:match(": vid") then
if is_vlan_attr then has_vlan4k = line:match(": (%w+)") end
elseif line:match(": enable_vlan4k") then
enable_vlan4k = true
elseif line:match(": enable_vlan") then
has_vlan = "enable_vlan"
elseif line:match(": enable_learning") then
has_learn = "enable_learning"
elseif line:match(": enable_mirror_rx") then
has_mirror = "enable_mirror_rx"
elseif line:match(": max_length") then
has_jumbo3 = "max_length"
end
end
swc:close()
end
-- Switch properties
s = m:section(NamedSection, x['.name'], "switch",
switch_title and translatef("Switch %q (%s)", switch_name, switch_title)
or translatef("Switch %q", switch_name))
s.addremove = false
if has_vlan then
s:option(Flag, has_vlan, translate("Enable VLAN functionality"))
end
if has_learn then
x = s:option(Flag, has_learn, translate("Enable learning and aging"))
x.default = x.enabled
end
if has_jumbo3 then
x = s:option(Flag, has_jumbo3, translate("Enable Jumbo Frame passthrough"))
x.enabled = "3"
x.rmempty = true
end
-- Does this switch support port mirroring?
if has_mirror then
s:option(Flag, "enable_mirror_rx", translate("Enable mirroring of incoming packets"))
s:option(Flag, "enable_mirror_tx", translate("Enable mirroring of outgoing packets"))
local sp = s:option(ListValue, "mirror_source_port", translate("Mirror source port"))
local mp = s:option(ListValue, "mirror_monitor_port", translate("Mirror monitor port"))
sp:depends("enable_mirror_tx", "1")
sp:depends("enable_mirror_rx", "1")
mp:depends("enable_mirror_tx", "1")
mp:depends("enable_mirror_rx", "1")
local _, pt
for _, pt in ipairs(topo.ports) do
sp:value(pt.num, pt.label)
mp:value(pt.num, pt.label)
end
end
-- VLAN table
s = m:section(TypedSection, "switch_vlan",
switch_title and translatef("VLANs on %q (%s)", switch_name, switch_title)
or translatef("VLANs on %q", switch_name))
s.template = "cbi/tblsection"
s.addremove = true
s.anonymous = true
-- Filter by switch
s.filter = function(self, section)
local device = m:get(section, "device")
return (device and device == switch_name)
end
-- Override cfgsections callback to enforce row ordering by vlan id.
s.cfgsections = function(self)
local osections = TypedSection.cfgsections(self)
local sections = { }
local section
for _, section in luci.util.spairs(
osections,
function(a, b)
return (tonumber(m:get(osections[a], has_vlan4k or "vlan")) or 9999)
< (tonumber(m:get(osections[b], has_vlan4k or "vlan")) or 9999)
end
) do
sections[#sections+1] = section
end
return sections
end
-- When creating a new vlan, preset it with the highest found vid + 1.
s.create = function(self, section, origin)
-- VLAN has already been created for another switch
if vlan_already_created then
return
-- VLAN add button was pressed in an empty VLAN section so only
-- accept the create event if our switch is without existing VLANs
elseif origin == "" then
local is_empty_switch = true
m.uci:foreach("network", "switch_vlan",
function(s)
if s.device == switch_name then
is_empty_switch = false
return false
end
end)
if not is_empty_switch then
return
end
-- VLAN was created for another switch
elseif m:get(origin, "device") ~= switch_name then
return
end
local sid = TypedSection.create(self, section)
local max_nr = 0
local max_id = 0
m.uci:foreach("network", "switch_vlan",
function(s)
if s.device == switch_name then
local nr = tonumber(s.vlan)
local id = has_vlan4k and tonumber(s[has_vlan4k])
if nr ~= nil and nr > max_nr then max_nr = nr end
if id ~= nil and id > max_id then max_id = id end
end
end)
m:set(sid, "device", switch_name)
m:set(sid, "vlan", max_nr + 1)
if has_vlan4k then
m:set(sid, has_vlan4k, max_id + 1)
end
vlan_already_created = true
return sid
end
local port_opts = { }
local untagged = { }
-- Parse current tagging state from the "ports" option.
local portvalue = function(self, section)
local pt
for pt in (m:get(section, "ports") or ""):gmatch("%w+") do
local pc, tu = pt:match("^(%d+)([tu]*)")
if pc == self.option then return (#tu > 0) and tu or "u" end
end
return ""
end
-- Validate port tagging. Ensure that a port is only untagged once,
-- bail out if not.
local portvalidate = function(self, value, section)
-- ensure that the ports appears untagged only once
if value == "u" then
if not untagged[self.option] then
untagged[self.option] = true
else
return nil,
translatef("%s is untagged in multiple VLANs!", self.title)
end
end
return value
end
local vid = s:option(Value, has_vlan4k or "vlan", "VLAN ID")
local mx_vid = has_vlan4k and 4094 or (num_vlans - 1)
vid.rmempty = false
vid.forcewrite = true
vid.vlan_used = { }
vid.datatype = "and(uinteger,range("..min_vid..","..mx_vid.."))"
-- Validate user provided VLAN ID, make sure its within the bounds
-- allowed by the switch.
vid.validate = function(self, value, section)
local v = tonumber(value)
local m = has_vlan4k and 4094 or (num_vlans - 1)
if v ~= nil and v >= min_vid and v <= m then
if not self.vlan_used[v] then
self.vlan_used[v] = true
return value
else
return nil,
translatef("Invalid VLAN ID given! Only unique IDs are allowed")
end
else
return nil,
translatef("Invalid VLAN ID given! Only IDs between %d and %d are allowed.", min_vid, m)
end
end
-- When writing the "vid" or "vlan" option, serialize the port states
-- as well and write them as "ports" option to uci.
vid.write = function(self, section, new_vid)
local o
local p = { }
for _, o in ipairs(port_opts) do
local new_tag = o:formvalue(section)
if new_tag == "t" then
p[#p+1] = o.option .. new_tag
elseif new_tag == "u" then
p[#p+1] = o.option
end
if o.info and o.info.device then
local old_tag = o:cfgvalue(section)
local old_vid = self:cfgvalue(section)
if old_tag ~= new_tag or old_vid ~= new_vid then
local old_ifname = (old_tag == "u") and o.info.device
or "%s.%s" %{ o.info.device, old_vid }
local new_ifname = (new_tag == "u") and o.info.device
or "%s.%s" %{ o.info.device, new_vid }
if old_ifname ~= new_ifname then
update_interfaces(old_ifname, new_ifname)
end
end
end
end
if enable_vlan4k then
m:set(sid, "enable_vlan4k", "1")
end
m:set(section, "ports", table.concat(p, " "))
return Value.write(self, section, new_vid)
end
-- Fallback to "vlan" option if "vid" option is supported but unset.
vid.cfgvalue = function(self, section)
return m:get(section, has_vlan4k or "vlan")
or m:get(section, "vlan")
end
local _, pt
for _, pt in ipairs(topo.ports) do
local po = s:option(ListValue, tostring(pt.num), pt.label)
po:value("", translate("off"))
if not pt.tagged then
po:value("u", translate("untagged"))
end
po:value("t", translate("tagged"))
po.cfgvalue = portvalue
po.validate = portvalidate
po.write = function() end
po.info = pt
port_opts[#port_opts+1] = po
end
table.sort(port_opts, function(a, b) return a.option < b.option end)
switches[#switches+1] = switch_name
end
)
-- Switch status template
s = m:section(SimpleSection)
s.template = "admin_network/switch_status"
s.switches = switches
return m

File diff suppressed because it is too large Load diff

View file

@ -1,168 +0,0 @@
-- Copyright 2009 Jo-Philipp Wich <jow@openwrt.org>
-- Licensed to the public under the Apache License 2.0.
local fs = require "nixio.fs"
local nw = require "luci.model.network"
local fw = require "luci.model.firewall"
local uci = require "luci.model.uci".cursor()
local http = require "luci.http"
local iw = luci.sys.wifi.getiwinfo(http.formvalue("device"))
local has_firewall = fs.access("/etc/config/firewall")
if not iw then
luci.http.redirect(luci.dispatcher.build_url("admin/network/wireless"))
return
end
m = SimpleForm("network", translatef("Joining Network: %q", http.formvalue("join")))
m.cancel = translate("Back to scan results")
m.reset = false
function m.on_cancel()
local dev = http.formvalue("device")
http.redirect(luci.dispatcher.build_url(
dev and "admin/network/wireless_join?device=" .. dev
or "admin/network/wireless"
))
end
nw.init(uci)
fw.init(uci)
m.hidden = {
device = http.formvalue("device"),
join = http.formvalue("join"),
channel = http.formvalue("channel"),
mode = http.formvalue("mode"),
bssid = http.formvalue("bssid"),
wep = http.formvalue("wep"),
wpa_suites = http.formvalue("wpa_suites"),
wpa_version = http.formvalue("wpa_version")
}
if iw and iw.mbssid_support then
replace = m:field(Flag, "replace", translate("Replace wireless configuration"),
translate("Check this option to delete the existing networks from this radio."))
function replace.cfgvalue() return "0" end
else
replace = m:field(DummyValue, "replace", translate("Replace wireless configuration"))
replace.default = translate("The hardware is not multi-SSID capable and the existing " ..
"configuration will be replaced if you proceed.")
function replace.formvalue() return "1" end
end
if http.formvalue("wep") == "1" then
key = m:field(Value, "key", translate("WEP passphrase"),
translate("Specify the secret encryption key here."))
key.password = true
key.datatype = "wepkey"
elseif (tonumber(m.hidden.wpa_version) or 0) > 0 and
(m.hidden.wpa_suites == "PSK" or m.hidden.wpa_suites == "PSK2")
then
key = m:field(Value, "key", translate("WPA passphrase"),
translate("Specify the secret encryption key here."))
key.password = true
key.datatype = "wpakey"
--m.hidden.wpa_suite = (tonumber(http.formvalue("wpa_version")) or 0) >= 2 and "psk2" or "psk"
end
newnet = m:field(Value, "_netname_new", translate("Name of the new network"),
translate("The allowed characters are: <code>A-Z</code>, <code>a-z</code>, " ..
"<code>0-9</code> and <code>_</code>"
))
newnet.default = m.hidden.mode == "Ad-Hoc" and "mesh" or "wwan"
newnet.datatype = "uciname"
if has_firewall then
fwzone = m:field(Value, "_fwzone",
translate("Create / Assign firewall-zone"),
translate("Choose the firewall zone you want to assign to this interface. Select <em>unspecified</em> to remove the interface from the associated zone or fill out the <em>create</em> field to define a new zone and attach the interface to it."))
fwzone.template = "cbi/firewall_zonelist"
fwzone.default = m.hidden.mode == "Ad-Hoc" and "mesh" or "wan"
end
function newnet.parse(self, section)
local net, zone
if has_firewall then
local value = fwzone:formvalue(section)
if value and #value > 0 then
zone = fw:get_zone(value) or fw:add_zone(value)
end
end
local wdev = nw:get_wifidev(m.hidden.device)
wdev:set("disabled", false)
wdev:set("channel", m.hidden.channel)
if replace:formvalue(section) then
local n
for _, n in ipairs(wdev:get_wifinets()) do
wdev:del_wifinet(n)
end
end
local wconf = {
device = m.hidden.device,
ssid = m.hidden.join,
mode = (m.hidden.mode == "Ad-Hoc" and "adhoc" or "sta")
}
if m.hidden.wep == "1" then
wconf.encryption = "wep-open"
wconf.key = "1"
wconf.key1 = key and key:formvalue(section) or ""
elseif (tonumber(m.hidden.wpa_version) or 0) > 0 then
wconf.encryption = (tonumber(m.hidden.wpa_version) or 0) >= 2 and "psk2" or "psk"
wconf.key = key and key:formvalue(section) or ""
else
wconf.encryption = "none"
end
if wconf.mode == "adhoc" or wconf.mode == "sta" then
wconf.bssid = m.hidden.bssid
end
local value = self:formvalue(section)
net = nw:add_network(value, { proto = "dhcp" })
if not net then
self.error = { [section] = "missing" }
else
wconf.network = net:name()
local wnet = wdev:add_wifinet(wconf)
if wnet then
if zone then
fw:del_network(net:name())
zone:add_network(net:name())
end
uci:save("wireless")
uci:save("network")
uci:save("firewall")
luci.http.redirect(wnet:adminlink())
end
end
end
if has_firewall then
function fwzone.cfgvalue(self, section)
self.iface = section
local z = fw:get_zone_by_network(section)
return z and z:name()
end
end
return m

View file

@ -1,153 +0,0 @@
-- Copyright 2018 Jo-Philipp Wich <jo@mein.io>
-- Licensed to the public under the Apache License 2.0.
local fs = require "nixio.fs"
local utl = require "luci.util"
local tpl = require "luci.template"
local ntm = require "luci.model.network"
local has_iwinfo = pcall(require, "iwinfo")
function guess_wifi_hw(dev)
local bands = ""
local ifname = dev:name()
local name, idx = ifname:match("^([a-z]+)(%d+)")
idx = tonumber(idx)
if has_iwinfo then
local bl = dev.iwinfo.hwmodelist
if bl and next(bl) then
if bl.a then bands = bands .. "a" end
if bl.b then bands = bands .. "b" end
if bl.g then bands = bands .. "g" end
if bl.n then bands = bands .. "n" end
if bl.ac then bands = bands .. "ac" end
end
local hw = dev.iwinfo.hardware_name
if hw then
return "%s 802.11%s" %{ hw, bands }
end
end
-- wl.o
if name == "wl" then
local name = translatef("Broadcom 802.11%s Wireless Controller", bands)
local nm = 0
local fd = nixio.open("/proc/bus/pci/devices", "r")
if fd then
local ln
for ln in fd:linesource() do
if ln:match("wl$") then
if nm == idx then
local version = ln:match("^%S+%s+%S%S%S%S([0-9a-f]+)")
name = translatef(
"Broadcom BCM%04x 802.11 Wireless Controller",
tonumber(version, 16)
)
break
else
nm = nm + 1
end
end
end
fd:close()
end
return name
-- dunno yet
else
return translatef("Generic 802.11%s Wireless Controller", bands)
end
end
m = Map("wireless", translate("Wireless Overview"))
m:chain("network")
m.pageaction = false
if not has_iwinfo then
s = m:section(NamedSection, "__warning__")
function s.render(self)
tpl.render_string([[
<div class="alert-message warning">
<h4><%:Package libiwinfo required!%></h4>
<p><%_The <em>libiwinfo-lua</em> package is not installed. You must install this component for working wireless configuration!%></p>
</div>
]])
end
end
local _, dev, net
for _, dev in ipairs(ntm:get_wifidevs()) do
s = m:section(TypedSection)
s.template = "admin_network/wifi_overview"
s.wnets = dev:get_wifinets()
s.dev = dev
s.hw = guess_wifi_hw(dev)
function s.cfgsections(self)
local _, net, sl = nil, nil, { }
for _, net in ipairs(self.wnets) do
sl[#sl+1] = net:name()
self.wnets[net:name()] = net
end
return sl
end
o = s:option(Value, "__disable__")
function o.cfgvalue(self, sid)
local wnet = self.section.wnets[sid]
local wdev = wnet:get_device()
return ((wnet and wnet:get("disabled") == "1") or
(wdev and wdev:get("disabled") == "1")) and "1" or "0"
end
function o.write(self, sid, value)
local wnet = self.section.wnets[sid]
local wdev = wnet:get_device()
if value ~= "1" then
wnet:set("disabled", nil)
wdev:set("disabled", nil)
else
wnet:set("disabled", "1")
end
end
o.remove = o.write
o = s:option(Value, "__delete__")
function o.write(self, sid, value)
local wnet = self.section.wnets[sid]
local nets = wnet:get_networks()
ntm:del_wifinet(wnet:id())
local _, net
for _, net in ipairs(nets) do
if net:is_empty() then
ntm:del_network(net:name())
end
end
end
end
s = m:section(NamedSection, "__assoclist__")
function s.render(self, sid)
tpl.render_string([[
<h2><%:Associated Stations%></h2>
<%+wifi_assoclist%>
]])
end
return m

View file

@ -1,132 +0,0 @@
<%#
Copyright 2010 Jo-Philipp Wich <jow@openwrt.org>
Copyright 2019 Ycarus (Yannick Chabanois) <ycarus@zugaina.org> for OpenMPTCProuter project
Licensed to the public under the Apache License 2.0.
-%>
<%+header%>
<%
local fs = require "nixio.fs"
local has_ping6 = fs.access("/bin/ping6") or fs.access("/usr/bin/ping6")
local has_traceroute6 = fs.access("/bin/traceroute6") or fs.access("/usr/bin/traceroute6")
local has_speedtest = fs.access("/usr/sbin/speedtestc")
local has_wget = fs.access("/usr/bin/wget")
local has_netstat = fs.access("/bin/netstat")
local dns_host = luci.config.diag and luci.config.diag.dns or "dev.openwrt.org"
local ping_host = luci.config.diag and luci.config.diag.ping or "dev.openwrt.org"
local route_host = luci.config.diag and luci.config.diag.route or "dev.openwrt.org"
local getip_host = luci.config.diag and luci.config.diag.getip or "ifconfig.co"
%>
<script type="text/javascript">//<![CDATA[
var stxhr = new XHR();
function update_status(field, proto)
{
var tool = field.name;
var addr = field.value;
var protocol = proto ? "6" : "";
var legend = document.getElementById('diag-rc-legend');
var output = document.getElementById('diag-rc-output');
if (legend && output)
{
output.innerHTML =
'<img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" /> ' +
'<%:Waiting for command to complete...%>'
;
legend.parentNode.style.display = 'block';
legend.style.display = 'inline';
stxhr.post('<%=url('admin/network')%>/diag_' + tool + protocol + '/' + addr, { token: '<%=token%>' },
function(x)
{
if (x.responseText)
{
legend.style.display = 'none';
output.innerHTML = String.format('<pre>%h</pre>', x.responseText);
}
else
{
legend.style.display = 'none';
output.innerHTML = '<span class="error"><%:Bad address specified!%></span>';
}
}
);
}
}
//]]></script>
<form method="post" action="<%=url('admin/network/diagnostics')%>">
<div class="cbi-map">
<h2 name="content"><%:Diagnostics%></h2>
<div class="cbi-section">
<legend><%:Network Utilities%></legend>
<div class="table">
<div class="tr">
<div class="td left">
<input style="margin: 5px 0" type="text" value="<%=ping_host%>" name="ping" /><br />
<% if has_ping6 then %>
<select name="ping_proto" style="width:auto">
<option value="" selected="selected"><%:IPv4%></option>
<option value="6"><%:IPv6%></option>
</select>
<input type="button" value="<%:Ping%>" class="cbi-button cbi-button-apply" onclick="update_status(this.form.ping, this.form.ping_proto.selectedIndex)" />
<% else %>
<input type="button" value="<%:Ping%>" class="cbi-button cbi-button-apply" onclick="update_status(this.form.ping)" />
<% end %>
</div>
<div class="td left">
<input style="margin: 5px 0" type="text" value="<%=route_host%>" name="traceroute" /><br />
<% if has_traceroute6 then %>
<select name="traceroute_proto" style="width:auto">
<option value="" selected="selected"><%:IPv4%></option>
<option value="6"><%:IPv6%></option>
</select>
<input type="button" value="<%:Traceroute%>" class="cbi-button cbi-button-apply" onclick="update_status(this.form.traceroute, this.form.traceroute_proto.selectedIndex)" />
<% else %>
<input type="button" value="<%:Traceroute%>" class="cbi-button cbi-button-apply" onclick="update_status(this.form.traceroute)" />
<% end %>
<% if not has_traceroute6 then %>
<p>&#160;</p>
<p><%:Install iputils-traceroute6 for IPv6 traceroute%></p>
<% end %>
</div>
<div class="td left">
<input style="margin: 5px 0" type="text" value="<%=dns_host%>" name="nslookup" /><br />
<input type="button" value="<%:Nslookup%>" class="cbi-button cbi-button-apply" onclick="update_status(this.form.nslookup)" />
</div>
<% if has_wget then %>
<div class="td left">
<input style="margin: 5px 0" type="hidden" value="<%=getip_host%>" name="getip" /><br />
<input type="button" value="<%:Get public IP%>" class="cbi-button cbi-button-apply" onclick="update_status(this.form.getip)" />
</div>
<% end %>
<% if has_netstat then %>
<div class="td left">
<input style="margin: 5px 0" type="hidden" value="" name="netstat" /><br />
<input type="button" value="<%:Netstat%>" class="cbi-button cbi-button-apply" onclick="update_status(this.form.netstat)" />
</div>
<% end %>
</div>
</div>
</div>
</div>
<div class="cbi-section" style="display:none">
<strong id="diag-rc-legend"></strong>
<span id="diag-rc-output"></span>
</div>
</form>
<%+footer%>

View file

@ -1,53 +0,0 @@
<div class="cbi-section-node">
<div class="table">
<%
for i, net in ipairs(self.netlist) do
local z = net[3]
local c = z and z:get_color() or "#EEEEEE"
local t = z and translate("Part of zone %q") % z:name() or translate("No zone assigned")
local disabled = (net[4]:get("auto") == "0")
local dynamic = net[4]:is_dynamic()
%>
<div class="tr cbi-rowstyle-<%=i % 2 + 1%>">
<div class="td col-3 center middle">
<div class="ifacebox">
<div class="ifacebox-head" style="background-color:<%=c%>" title="<%=pcdata(t)%>">
<strong><%=net[1]:upper()%></strong>
</div>
<div class="ifacebox-body" id="<%=net[1]%>-ifc-devices" data-network="<%=net[1]%>">
<img src="<%=resource%>/icons/ethernet_disabled.png" style="width:16px; height:16px" /><br />
<small>?</small>
</div>
</div>
</div>
<div class="td col-5 left middle" id="<%=net[1]%>-ifc-description">
<em><%:Collecting data...%></em>
</div>
<div class="td cbi-section-actions">
<div>
<input type="button" class="cbi-button cbi-button-neutral" onclick="iface_reconnect('<%=net[1]%>')" title="<%:Reconnect this interface%>" value="<%:Restart%>"<%=ifattr(disabled or dynamic, "disabled", "disabled")%> />
<% if disabled then %>
<input type="hidden" name="cbid.network.<%=net[1]%>.__disable__" value="1" />
<input type="submit" name="cbi.apply" class="cbi-button cbi-button-neutral" onclick="this.previousElementSibling.value='0'" title="<%:Reconnect this interface%>" value="<%:Connect%>"<%=ifattr(dynamic, "disabled", "disabled")%> />
<% else %>
<input type="hidden" name="cbid.network.<%=net[1]%>.__disable__" value="0" />
<input type="submit" name="cbi.apply" class="cbi-button cbi-button-neutral" onclick="this.previousElementSibling.value='1'" title="<%:Shutdown this interface%>" value="<%:Stop%>"<%=ifattr(dynamic, "disabled", "disabled")%> />
<% end %>
<input type="button" class="cbi-button cbi-button-action important" onclick="location.href='<%=url("admin/network/network", net[1])%>'" title="<%:Edit this interface%>" value="<%:Edit%>" id="<%=net[1]%>-ifc-edit"<%=ifattr(dynamic, "disabled", "disabled")%> />
<input type="hidden" name="cbid.network.<%=net[1]%>.__delete__" value="" />
<input type="submit" name="cbi.apply" class="cbi-button cbi-button-negative" onclick="iface_delete(event)" value="<%:Delete%>"<%=ifattr(dynamic, "disabled", "disabled")%> />
</div>
</div>
</div>
<% end %>
</div>
</div>
<div class="cbi-section-create">
<input type="button" class="cbi-button cbi-button-add" value="<%:Add new interface...%>" onclick="location.href='<%=url("admin/network/iface_add")%>'" />
</div>
<script type="text/javascript" src="<%=resource%>/view/network/network.js"></script>

View file

@ -1,12 +0,0 @@
<%+cbi/valueheader%>
<span class="ifacebadge large"<%=attr("data-iface-status", self.network)%>>
<img src="<%=resource%>/icons/ethernet_disabled.png" />
<span>
<em class="spinning"><%:Collecting data...%></em>
</span>
</span>
<script type="text/javascript" src="<%=resource%>/view/network/iface_status.js"></script>
<%+cbi/valuefooter%>

View file

@ -1,62 +0,0 @@
<script type="text/javascript">//<![CDATA[
var switches = [ '<%=table.concat(self.switches, "', '")%>' ],
tables = document.querySelectorAll('.cbi-section-table');
function add_status_row(table) {
var first_row = table.querySelector('.cbi-section-table-row');
if (first_row.classList.contains('port-status'))
return first_row;
var status_row = first_row.parentNode.insertBefore(
E('div', { 'class': first_row.className }), first_row);
first_row.querySelectorAll('.td').forEach(function(td) {
status_row.appendChild(td.cloneNode(false));
status_row.lastElementChild.removeAttribute('data-title');
});
status_row.firstElementChild.innerHTML = '<%:Port status:%>';
status_row.classList.add('port-status') ;
return status_row;
}
XHR.poll(-1, '<%=url('admin/network/switch_status')%>/' + switches.join(','), null,
function(x, st)
{
for (var i = 0; i < switches.length; i++)
{
var ports = st[switches[i]];
var tr = add_status_row(tables[i]);
if (tr && ports && ports.length)
{
for (var j = 0; j < ports.length; j++)
{
var th = tr.querySelector('[data-name="%d"]'.format(j));
if (!th)
continue;
if (ports[j].link)
{
th.innerHTML = String.format(
'<small><img src="<%=resource%>/icons/port_up.png" />' +
'<br />%d<%:baseT%><br />%s</small>',
ports[j].speed, ports[j].duplex
? '<%:full-duplex%>' : '<%:half-duplex%>'
);
}
else
{
th.innerHTML = String.format(
'<small><img src="<%=resource%>/icons/port_down.png" />' +
'<br /><%:no link%></small>'
);
}
}
}
}
}
);
//]]></script>

View file

@ -1,59 +0,0 @@
<%#
Copyright 2009-2015 Jo-Philipp Wich <jow@openwrt.org>
Licensed to the public under the Apache License 2.0.
-%>
<%-
local sys = require "luci.sys"
local utl = require "luci.util"
local dev = luci.http.formvalue("device")
local iw = luci.sys.wifi.getiwinfo(dev)
if not iw then
luci.http.redirect(luci.dispatcher.build_url("admin/network/wireless"))
return
end
-%>
<%+header%>
<h2 name="content"><%:Join Network: Wireless Scan%></h2>
<div class="cbi-map">
<div class="cbi-section">
<div class="table"<%=attr("data-wifi-scan", dev) .. attr("data-wifi-type", iw.type)%>>
<div class="tr table-titles">
<div class="th col-2 middle center"><%:Signal%></div>
<div class="th col-4 middle left"><%:SSID%></div>
<div class="th col-2 middle center hide-xs"><%:Channel%></div>
<div class="th col-2 middle left hide-xs"><%:Mode%></div>
<div class="th col-3 middle left hide-xs"><%:BSSID%></div>
<div class="th col-3 middle left"><%:Encryption%></div>
<div class="th cbi-section-actions">&#160;</div>
</div>
<div class="tr placeholder">
<div class="td">
<img src="<%=resource%>/icons/loading.gif" class="middle" />
<em><%:Collecting data...%></em>
</div>
</div>
</div>
</div>
</div>
<div class="cbi-page-actions right">
<form class="inline" action="<%=url("admin/network/wireless")%>" method="get">
<input class="cbi-button cbi-button-neutral" type="submit" value="<%:Back to overview%>" />
</form>
<form class="inline" action="<%=url('admin/network/wireless_join')%>" method="post">
<input type="hidden" name="token" value="<%=token%>" />
<input type="hidden" name="device" value="<%=utl.pcdata(dev)%>" />
<input type="button" class="cbi-button cbi-button-action" value="<%:Repeat scan%>" onclick="flush()" />
</form>
</div>
<script type="text/javascript" src="<%=resource%>/view/network/wifi_join.js"></script>
<%+footer%>

View file

@ -1,61 +0,0 @@
<div class="cbi-section-node">
<div class="table">
<!-- physical device -->
<div class="tr cbi-rowstyle-2">
<div class="td col-2 center middle">
<span class="ifacebadge"><img src="<%=resource%>/icons/wifi_disabled.png" id="<%=self.dev:name()%>-iw-upstate" /> <%=self.dev:name()%></span>
</div>
<div class="td col-7 left middle">
<big><strong><%=self.hw%></strong></big><br />
<span id="<%=self.dev:name()%>-iw-devinfo"></span>
</div>
<div class="td middle cbi-section-actions">
<div>
<input type="button" class="cbi-button cbi-button-neutral" title="<%:Restart radio interface%>" value="<%:Restart%>" data-radio="<%=self.dev:name()%>" onclick="wifi_restart(event)" />
<input type="button" class="cbi-button cbi-button-action important" title="<%:Find and join network%>" value="<%:Scan%>" onclick="cbi_submit(this, 'device', '<%=self.dev:name()%>', '<%=url('admin/network/wireless_join')%>')" />
<input type="button" class="cbi-button cbi-button-add" title="<%:Provide new network%>" value="<%:Add%>" onclick="cbi_submit(this, 'device', '<%=self.dev:name()%>', '<%=url('admin/network/wireless_add')%>')" />
</div>
</div>
</div>
<!-- /physical device -->
<!-- network list -->
<% if #self.wnets > 0 then %>
<% for i, net in ipairs(self.wnets) do local disabled = (self.dev:get("disabled") == "1" or net:get("disabled") == "1") %>
<div class="tr cbi-rowstyle-<%=1 + ((i-1) % 2)%>">
<div class="td col-2 center middle" id="<%=net:id()%>-iw-signal">
<span class="ifacebadge" title="<%:Not associated%>"><img src="<%=resource%>/icons/signal-<%= disabled and "none" or "0" %>.png" /> 0%</span>
</div>
<div class="td col-7 left middle" id="<%=net:id()%>-iw-status" data-network="<%=net:id()%>" data-disabled="<%= disabled and "true" or "false" %>">
<em><%= disabled and translate("Wireless is disabled") or translate("Collecting data...") %></em>
</div>
<div class="td middle cbi-section-actions">
<div>
<% if disabled then %>
<input name="cbid.wireless.<%=net:name()%>.__disable__" type="hidden" value="1" />
<input name="cbi.apply" type="submit" class="cbi-button cbi-button-neutral" title="<%:Enable this network%>" value="<%:Enable%>" onclick="this.previousElementSibling.value='0'" />
<% else %>
<input name="cbid.wireless.<%=net:name()%>.__disable__" type="hidden" value="0" />
<input name="cbi.apply" type="submit" class="cbi-button cbi-button-neutral" title="<%:Disable this network%>" value="<%:Disable%>" onclick="this.previousElementSibling.value='1'" />
<% end %>
<input type="button" class="cbi-button cbi-button-action important" onclick="location.href='<%=net:adminlink()%>'" title="<%:Edit this network%>" value="<%:Edit%>" />
<input name="cbid.wireless.<%=net:name()%>.__delete__" type="hidden" value="" />
<input name="cbi.apply" type="submit" class="cbi-button cbi-button-negative" title="<%:Delete this network%>" value="<%:Remove%>" onclick="wifi_delete(event)" />
</div>
</div>
</div>
<% end %>
<% else %>
<div class="tr placeholder">
<div class="td">
<em><%:No network configured on this device%></em>
</div>
</div>
<% end %>
<!-- /network list -->
</div>
</div>
<script type="text/javascript" src="<%=resource%>/view/network/wireless.js"></script>

View file

@ -1,14 +0,0 @@
<%+cbi/valueheader%>
<span class="ifacebadge large"<%=attr("data-wifi-status", self.ifname)%>>
<small>
<img src="<%=resource%>/icons/signal-none.png" title="<%:Not associated%>" />&#160;
</small>
<span>
<em class="spinning"><%:Collecting data...%></em>
</span>
</span>
<script type="text/javascript" src="<%=resource%>/view/network/wifi_status.js"></script>
<%+cbi/valuefooter%>

View file

@ -1,121 +0,0 @@
#!/bin/sh /etc/rc.common
START=4
USE_PROCD=1
_setup_macaddr() {
uci -q get "network.$1_dev.macaddr" >/dev/null && return
uci -q set "network.$1_dev.macaddr=$2"
}
_save_macaddr() {
local _ifname
local _macaddr
uci -q get "network.$1_dev.ifname" >/dev/null && {
_ifname=$(uci -q get "network.$1.ifname")
if [ -n "$(uci -q get network.$1.macaddr)" ] && [ "$(uci -q get network.$1.macaddr)" != "$(uci -q get network.$1_dev.macaddr)" ]; then
uci -q set network.$1_dev.macaddr="$(uci -q get network.$1.macaddr)"
else
_macaddr=$(ip link show dev $_ifname 2>/dev/null | grep link | awk '{print $2}')
[ -n "$_macaddr" ] && {
uci -q set network.$1_dev.macaddr=$_macaddr
uci -q set network.$1.macaddr=$_macaddr
}
fi
}
[ -z "$(uci -q get network.$1.macaddr)" ] && {
_ifname=$(uci -q get "network.$1.ifname")
[ -n "$_ifname" ] && {
_macaddr=$(ip link show dev $_ifname 2>/dev/null | grep link | awk '{print $2}')
[ -n "$_macaddr" ] && {
uci -q set network.$1.macaddr=$_macaddr
}
}
}
}
# Configuration by interface
_setup_interface() {
local _ifname
config_get _ifname "$1" ifname
[ -z "$_ifname" ] && config_get _ifname "$1" ifname
# do not create macvlan for vlan
#case "$_ifname" in
# eth*.*) return ;;
#esac
[ "$(echo $1 | grep _dev)" != "" ] && {
local _intfdev=$(sed 's/_dev//' $1)
uci -q get "network.$_intfdev.ifname" >/dev/null || {
logger -t "macvlan" "Remove network.$1"
uci -q batch <<-EOF
delete network.$1
commit network
EOF
}
return
}
local _type
config_get _type "$1" type
uci -q get "network.$1_dev.ifname" >/dev/null && {
uci -q set network.$1_dev.mtu=$(uci -q get network.$1.mtu)
[ -z "$(uci -q get network.$1.masterintf)" ] && uci -q set network.$1.masterintf=$(uci -q get network.$1_dev.ifname)
[ -n "$(uci -q get network.$1.masterintf)" ] && uci -q set network.$1_dev.ifname=$(uci -q get network.$1.masterintf)
[ -z "$(uci -q get network.$1.macaddr)" ] && uci -q set network.$1_dev.macaddr=$(uci -q get network.$1.macaddr)
[ "$_type" = "macvlan" ] || {
logger -t "macvlan" "Remove network.$1_dev"
uci -q batch <<-EOF
delete network.$1_dev
EOF
}
[ "$_type" = "macvlan" ] && {
local interface
config_get _interface "$1" interface
[ -n "$_interface" ] && {
logger -t "macvlan" "Remove network.$1_dev"
uci -q batch <<-EOF
delete network.$1.interface
set network.$1_dev.ifname=$_interface
EOF
}
}
uci -q commit network
return 0
}
[ "$_type" = "macvlan" ] || return 0
uci -q batch <<-EOF
set network.$1_dev=device
set network.$1_dev.name=$1
set network.$1_dev.type=macvlan
set network.$1_dev.ifname=$_ifname
set network.$1.ifname=$1
set network.$1.masterintf=$_ifname
set network.$1.type=macvlan
set network.$1.defaultroute=0
EOF
_macaddr=$(uci -q get "network.$1.macaddr")
_setup_macaddr "$1" "${_macaddr:-auto$(date +%s)}"
uci -q set network.$1_dev.mtu=$(uci -q get network.$1.mtu)
uci -q commit network
}
start_service() {
. /lib/functions.sh
config_load network
config_foreach _setup_interface interface
config_foreach _save_macaddr interface
uci -q commit network
}
reload_service() {
start
}
service_triggers() {
procd_add_reload_trigger network
}

View file

@ -1,22 +0,0 @@
#!/bin/sh
if [ "$(uci -q get luci.diag)" != "internal" ]; then
host=""
if [ -s /etc/os-release ]; then
. /etc/os-release
host="${HOME_URL:-${BUG_URL:-$OPENWRT_DEVICE_MANUFACTURER_URL}}"
host="${host#*://}"
host="${host%%/*}"
fi
uci -q batch <<-EOF >/dev/null
set luci.diag=internal
set luci.diag.dns='openmptcprouter.com'
set luci.diag.ping='openmptcprouter.com'
set luci.diag.route='openmptcprouter.com'
commit luci
EOF
fi
exit 0

View file

@ -1,14 +0,0 @@
#!/bin/sh
uci -q batch <<-EOF >/dev/null
delete ucitrack.@macvlan[-1]
add ucitrack macvlan
set ucitrack.@macvlan[-1].init=macvlan
commit ucitrack
EOF
if [ "$(uci -q get ucitrack.@network[-1].affects | grep macvlan)" = "" ]; then
uci -q batch <<-EOF >/dev/null
add_list ucitrack.@network[-1].affects=macvlan
commit ucitrack
EOF
fi
exit 0