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:
parent
043502dada
commit
2f918b6f54
292 changed files with 0 additions and 239852 deletions
|
@ -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
|
||||
|
|
@ -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;
|
||||
});
|
||||
}
|
||||
});
|
|
@ -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();
|
||||
}
|
||||
});
|
|
@ -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();
|
||||
});
|
||||
});
|
|
@ -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.')));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
|
@ -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();
|
||||
}
|
||||
});
|
|
@ -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);
|
|
@ -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();
|
||||
});
|
||||
});
|
|
@ -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'))
|
||||
], ' | ');
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
@ -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
|
|
@ -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
|
|
@ -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> </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%>
|
|
@ -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>
|
|
@ -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%>
|
|
@ -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>
|
|
@ -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"> </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%>
|
|
@ -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>
|
|
@ -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%>" /> 
|
||||
</small>
|
||||
<span>
|
||||
<em class="spinning"><%:Collecting data...%></em>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<script type="text/javascript" src="<%=resource%>/view/network/wifi_status.js"></script>
|
||||
|
||||
<%+cbi/valuefooter%>
|
|
@ -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
|
||||
}
|
|
@ -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
|
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue