diff options
Diffstat (limited to 'protocols')
49 files changed, 2472 insertions, 1945 deletions
diff --git a/protocols/luci-proto-3g/htdocs/luci-static/resources/protocol/3g.js b/protocols/luci-proto-3g/htdocs/luci-static/resources/protocol/3g.js new file mode 100644 index 0000000000..07bed36c23 --- /dev/null +++ b/protocols/luci-proto-3g/htdocs/luci-static/resources/protocol/3g.js @@ -0,0 +1,161 @@ +'use strict'; +'require rpc'; +'require uci'; +'require form'; +'require network'; + +var callFileList = rpc.declare({ + object: 'file', + method: 'list', + params: [ 'path' ], + expect: { entries: [] }, + filter: function(list, params) { + var rv = []; + for (var i = 0; i < list.length; i++) + if (list[i].name.match(/^tty[A-Z]/) || list[i].name.match(/^cdc-wdm/) || list[i].name.match(/^[0-9]+$/)) + rv.push(params.path + list[i].name); + return rv.sort(); + } +}); + +network.registerPatternVirtual(/^3g-.+$/); + +function write_keepalive(section_id, value) { + var f_opt = this.map.lookupOption('_keepalive_failure', section_id), + i_opt = this.map.lookupOption('_keepalive_interval', section_id), + f = (f_opt != null) ? +f_opt[0].formvalue(section_id) : null, + i = (i_opt != null) ? +i_opt[0].formvalue(section_id) : null; + + if (f == null || f == '' || isNaN(f)) + f = 0; + + if (i == null || i == '' || isNaN(i) || i < 1) + i = 1; + + if (f > 0) + uci.set('network', section_id, 'keepalive', '%d %d'.format(f, i)); + else + uci.unset('network', section_id, 'keepalive'); +} + +return network.registerProtocol('3g', { + getI18n: function() { + return _('UMTS/GPRS/EV-DO'); + }, + + getIfname: function() { + return this._ubus('l3_device') || '3g-%s'.format(this.sid); + }, + + getOpkgPackage: function() { + return 'comgt'; + }, + + isFloating: function() { + return true; + }, + + isVirtual: function() { + return true; + }, + + getDevices: function() { + return null; + }, + + containsDevice: function(ifname) { + return (network.getIfnameOf(ifname) == this.getIfname()); + }, + + renderFormOptions: function(s) { + var o; + + o = s.taboption('general', form.Value, 'device', _('Modem device')); + o.rmempty = false; + o.load = function(section_id) { + return callFileList('/dev/').then(L.bind(function(devices) { + for (var i = 0; i < devices.length; i++) + this.value(devices[i]); + return callFileList('/dev/tts/'); + }, this)).then(L.bind(function(devices) { + for (var i = 0; i < devices.length; i++) + this.value(devices[i]); + return form.Value.prototype.load.apply(this, [section_id]); + }, this)); + }; + + o = s.taboption('general', form.Value, 'service', _('Service Type')); + o.value('', _('-- Please choose --')); + o.value('umts', 'UMTS/GPRS'); + o.value('umts_only', _('UMTS only')); + o.value('gprs_only', _('GPRS only')); + o.value('evdo', 'CDMA/EV-DO'); + + s.taboption('general', form.Value, 'apn', _('APN')); + s.taboption('general', form.Value, 'pincode', _('PIN')); + s.taboption('general', form.Value, 'username', _('PAP/CHAP username')); + + o = s.taboption('general', form.Value, 'password', _('PAP/CHAP password')); + o.password = true; + + o = s.taboption('general', form.Value, 'dialnumber', _('Dial number')); + o.placeholder = '*99***1#'; + + if (L.hasSystemFeature('ipv6')) { + o = s.taboption('advanced', form.ListValue, 'ipv6', _('Obtain IPv6-Address')); + o.value('auto', _('Automatic')); + o.value('0', _('Disabled')); + o.value('1', _('Manual')); + o.default = 'auto'; + } + + o = s.taboption('advanced', form.Value, 'delay', _('Modem init timeout'), _('Maximum amount of seconds to wait for the modem to become ready')); + o.placeholder = '10'; + o.datatype = 'min(1)'; + + o = s.taboption('advanced', form.Flag, 'defaultroute', _('Use default gateway'), _('If unchecked, no default route is configured')); + o.default = o.enabled; + + o = s.taboption('advanced', form.Value, 'metric', _('Use gateway metric')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + o.depends('defaultroute', '1'); + + o = s.taboption('advanced', form.Flag, 'peerdns', _('Use DNS servers advertised by peer'), _('If unchecked, the advertised DNS server addresses are ignored')); + o.default = o.enabled; + + o = s.taboption('advanced', form.DynamicList, 'dns', _('Use custom DNS servers')); + o.depends('peerdns', '0'); + o.datatype = 'ipaddr'; + + o = s.taboption('advanced', form.Value, '_keepalive_failure', _('LCP echo failure threshold'), _('Presume peer to be dead after given amount of LCP echo failures, use 0 to ignore failures')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + o.write = write_keepalive; + o.remove = write_keepalive; + o.cfgvalue = function(section_id) { + var v = uci.get('network', section_id, 'keepalive'); + if (typeof(v) == 'string' && v != '') { + var m = v.match(/^(\d+)[ ,]\d+$/); + return m ? m[1] : v; + } + }; + + o = s.taboption('advanced', form.Value, '_keepalive_interval', _('LCP echo interval'), _('Send LCP echo requests at the given interval in seconds, only effective in conjunction with failure threshold')); + o.placeholder = '5'; + o.datatype = 'min(1)'; + o.write = write_keepalive; + o.remove = write_keepalive; + o.cfgvalue = function(section_id) { + var v = uci.get('network', section_id, 'keepalive'); + if (typeof(v) == 'string' && v != '') { + var m = v.match(/^\d+[ ,](\d+)$/); + return m ? m[1] : v; + } + }; + + o = s.taboption('advanced', form.Value, 'demand', _('Inactivity timeout'), _('Close inactive connection after the given amount of seconds, use 0 to persist connection')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + } +}); diff --git a/protocols/luci-proto-3g/luasrc/model/cbi/admin_network/proto_3g.lua b/protocols/luci-proto-3g/luasrc/model/cbi/admin_network/proto_3g.lua deleted file mode 100644 index 85c5cd6042..0000000000 --- a/protocols/luci-proto-3g/luasrc/model/cbi/admin_network/proto_3g.lua +++ /dev/null @@ -1,149 +0,0 @@ --- Copyright 2011 Jo-Philipp Wich <jow@openwrt.org> --- Licensed to the public under the Apache License 2.0. - -local map, section, net = ... - -local device, apn, service, pincode, username, password, dialnumber -local ipv6, delay, defaultroute, metric, peerdns, dns, - keepalive_failure, keepalive_interval, demand - - -device = section:taboption("general", Value, "device", translate("Modem device")) -device.rmempty = false - -local device_suggestions = nixio.fs.glob("/dev/tty[A-Z]*") - or nixio.fs.glob("/dev/tts/*") - -if device_suggestions then - local node - for node in device_suggestions do - device:value(node) - end -end - - -service = section:taboption("general", Value, "service", translate("Service Type")) -service:value("", translate("-- Please choose --")) -service:value("umts", "UMTS/GPRS") -service:value("umts_only", translate("UMTS only")) -service:value("gprs_only", translate("GPRS only")) -service:value("evdo", "CDMA/EV-DO") - - -apn = section:taboption("general", Value, "apn", translate("APN")) - - -pincode = section:taboption("general", Value, "pincode", translate("PIN")) - - -username = section:taboption("general", Value, "username", translate("PAP/CHAP username")) - - -password = section:taboption("general", Value, "password", translate("PAP/CHAP password")) -password.password = true - -dialnumber = section:taboption("general", Value, "dialnumber", translate("Dial number")) -dialnumber.placeholder = "*99***1#" - -if luci.model.network:has_ipv6() then - - ipv6 = section:taboption("advanced", ListValue, "ipv6", - translate("Obtain IPv6-Address")) - - ipv6:value("auto", translate("Automatic")) - ipv6:value("0", translate("Disabled")) - ipv6:value("1", translate("Manual")) - ipv6.default = "auto" - -end - - -delay = section:taboption("advanced", Value, "delay", - translate("Modem init timeout"), - translate("Maximum amount of seconds to wait for the modem to become ready")) - -delay.placeholder = "10" -delay.datatype = "min(1)" - - -defaultroute = section:taboption("advanced", Flag, "defaultroute", - translate("Use default gateway"), - translate("If unchecked, no default route is configured")) - -defaultroute.default = defaultroute.enabled - - -metric = section:taboption("advanced", Value, "metric", - translate("Use gateway metric")) - -metric.placeholder = "0" -metric.datatype = "uinteger" -metric:depends("defaultroute", defaultroute.enabled) - - -peerdns = section:taboption("advanced", Flag, "peerdns", - translate("Use DNS servers advertised by peer"), - translate("If unchecked, the advertised DNS server addresses are ignored")) - -peerdns.default = peerdns.enabled - - -dns = section:taboption("advanced", DynamicList, "dns", - translate("Use custom DNS servers")) - -dns:depends("peerdns", "") -dns.datatype = "ipaddr" -dns.cast = "string" - - -keepalive_failure = section:taboption("advanced", Value, "_keepalive_failure", - translate("LCP echo failure threshold"), - translate("Presume peer to be dead after given amount of LCP echo failures, use 0 to ignore failures")) - -function keepalive_failure.cfgvalue(self, section) - local v = m:get(section, "keepalive") - if v and #v > 0 then - return tonumber(v:match("^(%d+)[ ,]+%d+") or v) - end -end - -function keepalive_failure.write() end -function keepalive_failure.remove() end - -keepalive_failure.placeholder = "0" -keepalive_failure.datatype = "uinteger" - - -keepalive_interval = section:taboption("advanced", Value, "_keepalive_interval", - translate("LCP echo interval"), - translate("Send LCP echo requests at the given interval in seconds, only effective in conjunction with failure threshold")) - -function keepalive_interval.cfgvalue(self, section) - local v = m:get(section, "keepalive") - if v and #v > 0 then - return tonumber(v:match("^%d+[ ,]+(%d+)")) - end -end - -function keepalive_interval.write(self, section, value) - local f = tonumber(keepalive_failure:formvalue(section)) or 0 - local i = tonumber(value) or 5 - if i < 1 then i = 1 end - if f > 0 then - m:set(section, "keepalive", "%d %d" %{ f, i }) - else - m:del(section, "keepalive") - end -end - -keepalive_interval.remove = keepalive_interval.write -keepalive_interval.placeholder = "5" -keepalive_interval.datatype = "min(1)" - - -demand = section:taboption("advanced", Value, "demand", - translate("Inactivity timeout"), - translate("Close inactive connection after the given amount of seconds, use 0 to persist connection")) - -demand.placeholder = "0" -demand.datatype = "uinteger" diff --git a/protocols/luci-proto-3g/luasrc/model/network/proto_3g.lua b/protocols/luci-proto-3g/luasrc/model/network/proto_3g.lua index b2454838f9..60d8e2ebae 100644 --- a/protocols/luci-proto-3g/luasrc/model/network/proto_3g.lua +++ b/protocols/luci-proto-3g/luasrc/model/network/proto_3g.lua @@ -38,7 +38,7 @@ function proto.get_interfaces(self) return nil end -function proto.contains_interface(self, ifname) +function proto.contains_interface(self, ifc) if self:is_floating() then return (netmod:ifnameof(ifc) == self:ifname()) else diff --git a/protocols/luci-proto-hnet/htdocs/luci-static/resources/protocol/hnet.js b/protocols/luci-proto-hnet/htdocs/luci-static/resources/protocol/hnet.js new file mode 100644 index 0000000000..84396ede08 --- /dev/null +++ b/protocols/luci-proto-hnet/htdocs/luci-static/resources/protocol/hnet.js @@ -0,0 +1,48 @@ +'use strict'; +'require form'; +'require network'; + +return network.registerProtocol('hnet', { + getI18n: function() { + return _('Automatic Homenet (HNCP)'); + }, + + getOpkgPackage: function() { + return 'hnet-full'; + }, + + renderFormOptions: function(s) { + var dev = this.getL2Device() || this.getDevice(), o; + + o = s.taboption('general', form.ListValue, 'mode', _('Category')); + o.value('auto', _('Automatic')); + o.value('external', _('External')); + o.value('internal', _('Internal')); + o.value('leaf', _('Leaf')); + o.value('guest', _('Guest')); + o.value('adhoc', _('Ad-Hoc')); + o.value('hybrid', _('Hybrid')); + o.default = 'auto'; + + o = s.taboption('advanced', form.Value, 'ip6assign', _('IPv6 assignment length'), _('Assign a part of given length of every public IPv6-prefix to this interface')); + o.datatype = 'max(128)'; + o.default = '64'; + + s.taboption('advanced', form.Value, 'link_id', _('IPv6 assignment hint'), _('Assign prefix parts using this hexadecimal subprefix ID for this interface.')); + + o = s.taboption('advanced', form.Value, 'ip4assign', _('IPv4 assignment length')); + o.datatype = 'max(32)'; + o.default = '24'; + + o = s.taboption('advanced', form.Value, 'dnsname', _('DNS-Label / FQDN')); + o.default = s.section; + + o = s.taboption('advanced', form.Value, 'macaddr', _('Override MAC address')); + o.datatype = 'macaddr'; + o.placeholder = dev ? (dev.getMAC() || '') : ''; + + o = s.taboption('advanced', form.Value, 'mtu', _('Override MTU')); + o.datatype = 'max(9200)'; + o.placeholder = dev ? (dev.getMTU() || '1500') : '1500'; + } +}); diff --git a/protocols/luci-proto-hnet/luasrc/model/cbi/admin_network/proto_hnet.lua b/protocols/luci-proto-hnet/luasrc/model/cbi/admin_network/proto_hnet.lua deleted file mode 100644 index 2ed34faf71..0000000000 --- a/protocols/luci-proto-hnet/luasrc/model/cbi/admin_network/proto_hnet.lua +++ /dev/null @@ -1,37 +0,0 @@ --- Copyright 2013 Steven Barth <steven@midlink.org> --- Licensed to the public under the Apache License 2.0. - -local map, section, net = ... - -local mode = section:taboption("general", ListValue, "mode", translate("Category")) -mode:value("auto", translate("Automatic")) -mode:value("external", translate("External")) -mode:value("internal", translate("Internal")) -mode:value("leaf", translate("Leaf")) -mode:value("guest", translate("Guest")) -mode:value("adhoc", translate("Ad-Hoc")) -mode:value("hybrid", translate("Hybrid")) -mode.default = "auto" - - - -local plen = section:taboption("advanced", Value, "ip6assign", translate("IPv6 assignment length"), - translate("Assign a part of given length of every public IPv6-prefix to this interface")) -plen.datatype = "max(128)" -plen.default = "64" - -section:taboption("advanced", Value, "link_id", translate("IPv6 assignment hint"), - translate("Assign prefix parts using this hexadecimal subprefix ID for this interface.")) - -plen = section:taboption("advanced", Value, "ip4assign", translate("IPv4 assignment length")) -plen.datatype = "max(32)" -plen.default = "24" - -local o = section:taboption("advanced", Value, "dnsname", translate("DNS-Label / FQDN")) -o.default = map.name - -luci.tools.proto.opt_macaddr(section, ifc, translate("Override MAC address")) - -o = section:taboption("advanced", Value, "mtu", translate("Override MTU")) -o.placeholder = "1500" -o.datatype = "max(9200)" diff --git a/protocols/luci-proto-ipip/htdocs/luci-static/resources/protocol/ipip.js b/protocols/luci-proto-ipip/htdocs/luci-static/resources/protocol/ipip.js new file mode 100644 index 0000000000..7423a08585 --- /dev/null +++ b/protocols/luci-proto-ipip/htdocs/luci-static/resources/protocol/ipip.js @@ -0,0 +1,69 @@ +'use strict'; +'require form'; +'require network'; +'require tools.widgets as widgets'; + +network.registerPatternVirtual(/^ipip-.+$/); + +return network.registerProtocol('ipip', { + getI18n: function() { + return _('IPv4-in-IPv4 (RFC2003)'); + }, + + getIfname: function() { + return this._ubus('l3_device') || 'ipip-%s'.format(this.sid); + }, + + getOpkgPackage: function() { + return 'ipip'; + }, + + isFloating: function() { + return true; + }, + + isVirtual: function() { + return true; + }, + + getDevices: function() { + return null; + }, + + containsDevice: function(ifname) { + return (network.getIfnameOf(ifname) == this.getIfname()); + }, + + renderFormOptions: function(s) { + var o; + + o = s.taboption('general', form.Value, 'peeraddr', _('Remote IPv4 address or FQDN'), _('The IPv4 address or the fully-qualified domain name of the remote tunnel end.')); + o.optional = false; + o.datatype = 'or(hostname,ip4addr("nomask"))'; + + o = s.taboption('general', form.Value, 'ipaddr', _('Local IPv4 address'), _('The local IPv4 address over which the tunnel is created (optional).')); + o.optional = true; + o.datatype = 'ip4addr("nomask")'; + + o = s.taboption('general', widgets.NetworkSelect, 'tunlink', _('Bind interface'), _('Bind the tunnel to this interface (optional).')); + o.exclude = s.section; + o.nocreate = true; + o.optional = true; + + o = s.taboption('advanced', form.Value, 'mtu', _('Override MTU'), _('Specify an MTU (Maximum Transmission Unit) other than the default (1280 bytes).')); + o.optional = true; + o.placeholder = 1280; + o.datatype = 'range(68, 9200)'; + + o = s.taboption('advanced', form.Value, 'ttl', _('Override TTL'), _('Specify a TTL (Time to Live) for the encapsulating packet other than the default (64).')); + o.optional = true; + o.placeholder = 64; + o.datatype = 'min(1)'; + + o = s.taboption('advanced', form.Value, 'tos', _('Override TOS'), _('Specify a TOS (Type of Service).')); + o.optional = true; + o.datatype = 'range(0, 255)'; + + s.taboption('advanced', form.Flag, 'df', _("Don't Fragment"), _("Enable the DF (Don't Fragment) flag of the encapsulating packets.")); + } +}); diff --git a/protocols/luci-proto-ipip/luasrc/model/cbi/admin_network/proto_ipip.lua b/protocols/luci-proto-ipip/luasrc/model/cbi/admin_network/proto_ipip.lua deleted file mode 100644 index 8817f18d6d..0000000000 --- a/protocols/luci-proto-ipip/luasrc/model/cbi/admin_network/proto_ipip.lua +++ /dev/null @@ -1,34 +0,0 @@ --- Copyright 2016 Roger Pueyo Centelles <roger.pueyo@guifi.net> --- Licensed to the public under the Apache License 2.0. - -local map, section, net = ... - -local peeraddr, ipaddr, ttl, tos, df, mtu, tunlink - -peeraddr = section:taboption("general", Value, "peeraddr", translate("Remote IPv4 address or FQDN"), translate("The IPv4 address or the fully-qualified domain name of the remote tunnel end.")) -peeraddr.optional = false -peeraddr.datatype = "or(hostname,ip4addr)" - -ipaddr = section:taboption("general", Value, "ipaddr", translate("Local IPv4 address"), translate("The local IPv4 address over which the tunnel is created (optional).")) -ipaddr.optional = true -ipaddr.datatype = "ip4addr" - -tunlink = section:taboption("general", Value, "tunlink", translate("Bind interface"), translate("Bind the tunnel to this interface (optional).")) -ipaddr.optional = true - - -mtu = section:taboption("advanced", Value, "mtu", translate("Override MTU"), translate("Specify an MTU (Maximum Transmission Unit) other than the default (1280 bytes).")) -mtu.optional = true -mtu.placeholder = 1280 -mtu.datatype = "range(68, 9200)" - -ttl = section:taboption("advanced", Value, "ttl", translate("Override TTL"), translate("Specify a TTL (Time to Live) for the encapsulating packet other than the default (64).")) -ttl.optional = true -ttl.placeholder = 64 -ttl.datatype = "min(1)" - -tos = section:taboption("advanced", Value, "tos", translate("Override TOS"), translate("Specify a TOS (Type of Service).")) -tos.optional = true -tos.datatype = "range(0, 255)" - -df = section:taboption("advanced", Flag, "df", translate("Don't Fragment"), translate("Enable the DF (Don't Fragment) flag of the encapsulating packets.")) diff --git a/protocols/luci-proto-ipv6/htdocs/luci-static/resources/protocol/464xlat.js b/protocols/luci-proto-ipv6/htdocs/luci-static/resources/protocol/464xlat.js new file mode 100644 index 0000000000..a74708fd01 --- /dev/null +++ b/protocols/luci-proto-ipv6/htdocs/luci-static/resources/protocol/464xlat.js @@ -0,0 +1,60 @@ +'use strict'; +'require form'; +'require network'; +'require tools.widgets as widgets'; + +network.registerPatternVirtual(/^464-.+$/); +network.registerErrorCode('CLAT_CONFIG_FAILED', _('CLAT configuration failed')); + +return network.registerProtocol('464xlat', { + getI18n: function() { + return _('464XLAT (CLAT)'); + }, + + getIfname: function() { + return this._ubus('l3_device') || '464-%s'.format(this.sid); + }, + + getOpkgPackage: function() { + return '464xlat'; + }, + + isFloating: function() { + return true; + }, + + isVirtual: function() { + return true; + }, + + getDevices: function() { + return null; + }, + + containsDevice: function(ifname) { + return (network.getIfnameOf(ifname) == this.getIfname()); + }, + + renderFormOptions: function(s) { + var o; + + o = s.taboption('general', form.Value, 'ip6prefix', _('NAT64 Prefix'), _('Leave empty to autodetect')); + o.datatype = 'cidr6'; + + o = s.taboption('advanced', widgets.NetworkSelect, 'tunlink', _('Tunnel Link')); + o.nocreate = true; + o.exclude = s.section; + + o = s.taboption('advanced', form.Flag, 'defaultroute', _('Default gateway'), _('If unchecked, no default route is configured')); + o.default = o.enabled; + + o = s.taboption('advanced', form.Value, 'metric', _('Use gateway metric')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + o.depends('defaultroute', '1'); + + o = s.taboption('advanced', form.Value, 'mtu', _('Use MTU on tunnel interface')); + o.placeholder = '1280'; + o.datatype = 'max(9200)'; + } +}); diff --git a/protocols/luci-proto-ipv6/htdocs/luci-static/resources/protocol/6in4.js b/protocols/luci-proto-ipv6/htdocs/luci-static/resources/protocol/6in4.js new file mode 100644 index 0000000000..f26ced7b40 --- /dev/null +++ b/protocols/luci-proto-ipv6/htdocs/luci-static/resources/protocol/6in4.js @@ -0,0 +1,101 @@ +'use strict'; +'require uci'; +'require form'; +'require network'; + +network.registerPatternVirtual(/^6in4-.+$/); + +return network.registerProtocol('6in4', { + getI18n: function() { + return _('IPv6-in-IPv4 (RFC4213)'); + }, + + getIfname: function() { + return this._ubus('l3_device') || '6in4-%s'.format(this.sid); + }, + + getOpkgPackage: function() { + return '6in4'; + }, + + isFloating: function() { + return true; + }, + + isVirtual: function() { + return true; + }, + + getDevices: function() { + return null; + }, + + containsDevice: function(ifname) { + return (network.getIfnameOf(ifname) == this.getIfname()); + }, + + renderFormOptions: function(s) { + var o; + + o = s.taboption('general', form.Value, 'ipaddr', _('Local IPv4 address'), _('Leave empty to use the current WAN address')); + o.datatype = 'ip4addr("nomask")'; + o.load = function(section_id) { + return network.getWANNetworks().then(L.bind(function(nets) { + if (nets.length) + this.placeholder = nets[0].getIPAddr(); + return form.Value.prototype.load.apply(this, [section_id]); + }, this)); + }; + + o = s.taboption('general', form.Value, 'peeraddr', _('Remote IPv4 address'), _('This is usually the address of the nearest PoP operated by the tunnel broker')); + o.rmempty = false; + o.datatype = 'ip4addr("nomask")'; + + o = s.taboption('general', form.Value, 'ip6addr', _('Local IPv6 address'), _('This is the local endpoint address assigned by the tunnel broker, it usually ends with <code>...:2/64</code>')); + o.datatype = 'cidr6'; + + o = s.taboption('general', form.DynamicList, 'ip6prefix', _('IPv6 routed prefix'), _('This is the prefix routed to you by the tunnel broker for use by clients')); + o.datatype = 'cidr6'; + + o = s.taboption('general', form.Flag, '_update', _('Dynamic tunnel'), _('Enable HE.net dynamic endpoint update')); + o.enabled = '1'; + o.disabled = '0'; + o.write = function() {}; + o.remove = function() {}; + o.cfgvalue = function(section_id) { + return !isNaN(+uci.get('network', section_id, 'tunnelid')) ? this.enabled : this.disabled; + }; + + o = s.taboption('general', form.Value, 'tunnelid', _('Tunnel ID')); + o.datatype = 'uinteger'; + o.depends('_update', '1'); + + o = s.taboption('general', form.Value, 'username', _('HE.net username'), _('This is the plain username for logging into the account')); + o.depends('_update', '1'); + o.validate = function(section_id, value) { + if (/^[a-fA-F0-9]{32}$/.test(value)) + return _('The HE.net endpoint update configuration changed, you must now use the plain username instead of the user ID!'); + return true; + }; + + o = s.taboption('general', form.Value, 'password', _('HE.net password'), _('This is either the "Update Key" configured for the tunnel or the account password if no update key has been configured')); + o.password = true; + o.depends('_update', '1'); + + o = s.taboption('advanced', form.Flag, 'defaultroute', _('Default gateway'), _('If unchecked, no default route is configured')); + o.default = o.enabled; + + o = s.taboption('advanced', form.Value, 'metric', _('Use gateway metric')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + o.depends('defaultroute', '1'); + + o = s.taboption('advanced', form.Value, 'ttl', _('Use TTL on tunnel interface')); + o.placeholder = '64'; + o.datatype = 'range(1,255)'; + + o = s.taboption('advanced', form.Value, 'mtu', _('Use MTU on tunnel interface')); + o.placeholder = '1280'; + o.datatype = 'max(9200)'; + } +}); diff --git a/protocols/luci-proto-ipv6/htdocs/luci-static/resources/protocol/6rd.js b/protocols/luci-proto-ipv6/htdocs/luci-static/resources/protocol/6rd.js new file mode 100644 index 0000000000..6a8f506bc9 --- /dev/null +++ b/protocols/luci-proto-ipv6/htdocs/luci-static/resources/protocol/6rd.js @@ -0,0 +1,81 @@ +'use strict'; +'require form'; +'require network'; + +network.registerPatternVirtual(/^6rd-.+$/); + +return network.registerProtocol('6rd', { + getI18n: function() { + return _('IPv6-over-IPv4 (6rd)'); + }, + + getIfname: function() { + return this._ubus('l3_device') || '6rd-%s'.format(this.sid); + }, + + getOpkgPackage: function() { + return '6rd'; + }, + + isFloating: function() { + return true; + }, + + isVirtual: function() { + return true; + }, + + getDevices: function() { + return null; + }, + + containsDevice: function(ifname) { + return (network.getIfnameOf(ifname) == this.getIfname()); + }, + + renderFormOptions: function(s) { + var o; + + o = s.taboption('general', form.Value, 'ipaddr', _('Local IPv4 address'), _('Leave empty to use the current WAN address')); + o.datatype = 'ip4addr("nomask")'; + o.load = function(section_id) { + return network.getWANNetworks().then(L.bind(function(nets) { + if (nets.length) + this.placeholder = nets[0].getIPAddr(); + return form.Value.prototype.load.apply(this, [section_id]); + }, this)); + }; + + o = s.taboption('general', form.Value, 'peeraddr', _('Remote IPv4 address'), _('This IPv4 address of the relay')); + o.rmempty = false; + o.datatype = 'ip4addr("nomask")'; + + o = s.taboption('general', form.Value, 'ip6prefix', _('IPv6 prefix'), _('The IPv6 prefix assigned to the provider, usually ends with <code>::</code>')); + o.rmempty = false; + o.datatype = 'ip6addr'; + + o = s.taboption('general', form.Value, 'ip6prefixlen', _('IPv6 prefix length'), _('The length of the IPv6 prefix in bits')); + o.placeholder = '16'; + o.datatype = 'range(0,128)'; + + o = s.taboption('general', form.Value, 'ip4prefixlen', _('IPv4 prefix length'), _('The length of the IPv4 prefix in bits, the remainder is used in the IPv6 addresses.')); + o.placeholder = '0'; + o.datatype = 'range(0,32)'; + + o = s.taboption('advanced', form.Flag, 'defaultroute', _('Default gateway'), _('If unchecked, no default route is configured')); + o.default = o.enabled; + + o = s.taboption('advanced', form.Value, 'metric', _('Use gateway metric')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + o.depends('defaultroute', '1'); + + o = s.taboption('advanced', form.Value, 'ttl', _('Use TTL on tunnel interface')); + o.placeholder = '64'; + o.datatype = 'range(1,255)'; + + o = s.taboption('advanced', form.Value, 'mtu', _('Use MTU on tunnel interface')); + o.placeholder = '1280'; + o.datatype = 'max(9200)'; + } +}); diff --git a/protocols/luci-proto-ipv6/htdocs/luci-static/resources/protocol/6to4.js b/protocols/luci-proto-ipv6/htdocs/luci-static/resources/protocol/6to4.js new file mode 100644 index 0000000000..abfe1c8fc4 --- /dev/null +++ b/protocols/luci-proto-ipv6/htdocs/luci-static/resources/protocol/6to4.js @@ -0,0 +1,65 @@ +'use strict'; +'require form'; +'require network'; + +network.registerPatternVirtual(/^6to4-.+$/); + +return network.registerProtocol('6to4', { + getI18n: function() { + return _('IPv6-over-IPv4 (6to4)'); + }, + + getIfname: function() { + return this._ubus('l3_device') || '6to4-%s'.format(this.sid); + }, + + getOpkgPackage: function() { + return '6rd'; + }, + + isFloating: function() { + return true; + }, + + isVirtual: function() { + return true; + }, + + getDevices: function() { + return null; + }, + + containsDevice: function(ifname) { + return (network.getIfnameOf(ifname) == this.getIfname()); + }, + + renderFormOptions: function(s) { + var o; + + o = s.taboption('general', form.Value, 'ipaddr', _('Local IPv4 address'), _('Leave empty to use the current WAN address')); + o.datatype = 'ip4addr("nomask")'; + o.load = function(section_id) { + return network.getWANNetworks().then(L.bind(function(nets) { + if (nets.length) + this.placeholder = nets[0].getIPAddr(); + return form.Value.prototype.load.apply(this, [section_id]); + }, this)); + }; + + o = s.taboption('advanced', form.Flag, 'defaultroute', _('Default gateway'), _('If unchecked, no default route is configured')); + o.default = o.enabled; + + o = s.taboption('advanced', form.Value, 'metric', _('Use gateway metric')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + o.depends('defaultroute', '1'); + + o = s.taboption('advanced', form.Value, 'ttl', _('Use TTL on tunnel interface')); + o.placeholder = '64'; + o.datatype = 'range(1,255)'; + + o = s.taboption('advanced', form.Value, 'mtu', _('Use MTU on tunnel interface')); + o.placeholder = '1280'; + o.datatype = 'max(9200)'; + } +}); diff --git a/protocols/luci-proto-ipv6/htdocs/luci-static/resources/protocol/dhcpv6.js b/protocols/luci-proto-ipv6/htdocs/luci-static/resources/protocol/dhcpv6.js new file mode 100644 index 0000000000..eba58f4248 --- /dev/null +++ b/protocols/luci-proto-ipv6/htdocs/luci-static/resources/protocol/dhcpv6.js @@ -0,0 +1,58 @@ +'use strict'; +'require form'; +'require network'; + +return network.registerProtocol('dhcpv6', { + getI18n: function() { + return _('DHCPv6 client'); + }, + + getOpkgPackage: function() { + return 'odhcp6c'; + }, + + renderFormOptions: function(s) { + var dev = this.getL2Device() || this.getDevice(), o; + + o = s.taboption('general', form.ListValue, 'reqaddress', _('Request IPv6-address')); + o.value('try'); + o.value('force'); + o.value('none', 'disabled'); + o.default = 'try'; + + o = s.taboption('general', form.Value, 'reqprefix', _('Request IPv6-prefix of length')); + o.value('auto', _('Automatic')); + o.value('no', _('disabled')); + o.value('48'); + o.value('52'); + o.value('56'); + o.value('60'); + o.value('64'); + o.default = 'auto'; + + o = s.taboption('advanced', form.Flag, 'defaultroute', _('Use default gateway'), _('If unchecked, no default route is configured')); + o.default = o.enabled; + + o = s.taboption('advanced', form.DynamicList, 'ip6prefix', _('Custom delegated IPv6-prefix')); + o.datatype = 'cidr6'; + + o = s.taboption('advanced', form.Flag, 'peerdns', _('Use DNS servers advertised by peer'), _('If unchecked, the advertised DNS server addresses are ignored')); + o.default = o.enabled; + + o = s.taboption('advanced', form.DynamicList, 'dns', _('Use custom DNS servers')); + o.depends('peerdns', '0'); + o.datatype = 'ipaddr'; + o.cast = 'string'; + + o = s.taboption('advanced', form.Value, 'clientid', _('Client ID to send when requesting DHCP')); + o.datatype = 'hexstring'; + + o = s.taboption('advanced', form.Value, 'macaddr', _('Override MAC address')); + o.datatype = 'macaddr'; + o.placeholder = dev ? (dev.getMAC() || '') : ''; + + o = s.taboption('advanced', form.Value, 'mtu', _('Override MTU')); + o.placeholder = dev ? (dev.getMTU() || '1500') : '1500'; + o.datatype = 'max(9200)'; + } +}); diff --git a/protocols/luci-proto-ipv6/htdocs/luci-static/resources/protocol/dslite.js b/protocols/luci-proto-ipv6/htdocs/luci-static/resources/protocol/dslite.js new file mode 100644 index 0000000000..fa0e68ddc3 --- /dev/null +++ b/protocols/luci-proto-ipv6/htdocs/luci-static/resources/protocol/dslite.js @@ -0,0 +1,79 @@ +'use strict'; +'require form'; +'require network'; +'require tools.widgets as widgets'; + +network.registerPatternVirtual(/^ds-.+$/); +network.registerErrorCode('AFTR_DNS_FAIL', _('Unable to resolve AFTR host name')); + +return network.registerProtocol('dslite', { + getI18n: function() { + return _('Dual-Stack Lite (RFC6333)'); + }, + + getIfname: function() { + return this._ubus('l3_device') || 'ds-%s'.format(this.sid); + }, + + getOpkgPackage: function() { + return 'ds-lite'; + }, + + isFloating: function() { + return true; + }, + + isVirtual: function() { + return true; + }, + + getDevices: function() { + return null; + }, + + containsDevice: function(ifname) { + return (network.getIfnameOf(ifname) == this.getIfname()); + }, + + renderFormOptions: function(s) { + var o; + + o = s.taboption('general', form.Value, 'peeraddr', _('DS-Lite AFTR address')); + o.rmempty = false; + o.datatype = 'or(hostname,ip6addr("nomask"))'; + + o = s.taboption('general', form.Value, 'ip6addr', _('Local IPv6 address'), _('Leave empty to use the current WAN address')); + o.datatype = 'ip6addr("nomask")'; + o.load = function(section_id) { + return network.getWAN6Networks().then(L.bind(function(nets) { + if (Array.isArray(nets) && nets.length) + this.placeholder = nets[0].getIP6Addr(); + return form.Value.prototype.load.apply(this, [section_id]); + }, this)); + }; + + o = s.taboption('advanced', widgets.NetworkSelect, 'tunlink', _('Tunnel Link')); + o.nocreate = true; + o.exclude = s.section; + + o = s.taboption('advanced', form.ListValue, 'encaplimit', _('Encapsulation limit')); + o.rmempty = false; + o.default = 'ignore'; + o.datatype = 'or("ignore",range(0,255))'; + o.value('ignore', _('ignore')); + for (var i = 0; i < 256; i++) + o.value(i); + + o = s.taboption('advanced', form.Flag, 'defaultroute', _('Default gateway'), _('If unchecked, no default route is configured')); + o.default = o.enabled; + + o = s.taboption('advanced', form.Value, 'metric', _('Use gateway metric')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + o.depends('defaultroute', '1'); + + o = s.taboption('advanced', form.Value, 'mtu', _('Use MTU on tunnel interface')); + o.placeholder = '1280'; + o.datatype = 'max(9200)'; + } +}); diff --git a/protocols/luci-proto-ipv6/htdocs/luci-static/resources/protocol/map.js b/protocols/luci-proto-ipv6/htdocs/luci-static/resources/protocol/map.js new file mode 100644 index 0000000000..006ebfbf08 --- /dev/null +++ b/protocols/luci-proto-ipv6/htdocs/luci-static/resources/protocol/map.js @@ -0,0 +1,96 @@ +'use strict'; +'require form'; +'require network'; +'require tools.widgets as widgets'; + +network.registerPatternVirtual(/^map-.+$/); +network.registerErrorCode('INVALID_MAP_RULE', _('MAP rule is invalid')); +network.registerErrorCode('NO_MATCHING_PD', _('No matching prefix delegation')); +network.registerErrorCode('UNSUPPORTED_TYPE', _('Unsupported MAP type')); + +return network.registerProtocol('map', { + getI18n: function() { + return _('MAP / LW4over6'); + }, + + getIfname: function() { + return this._ubus('l3_device') || 'map-%s'.format(this.sid); + }, + + getOpkgPackage: function() { + return 'map-t'; + }, + + isFloating: function() { + return true; + }, + + isVirtual: function() { + return true; + }, + + getDevices: function() { + return null; + }, + + containsDevice: function(ifname) { + return (network.getIfnameOf(ifname) == this.getIfname()); + }, + + renderFormOptions: function(s) { + var o; + + o = s.taboption('general', form.ListValue, 'type', _('Type')); + o.value('map-e', 'MAP-E'); + o.value('map-t', 'MAP-T'); + o.value('lw4o6', 'LW4over6'); + + o = s.taboption('general', form.Value, 'peeraddr', _('BR / DMR / AFTR')); + o.rmempty = false; + o.datatype = 'ip6addr'; + + o = s.taboption('general', form.Value, 'ipaddr', _('IPv4 prefix')); + o.datatype = 'ip4addr'; + + o = s.taboption('general', form.Value, 'ip4prefixlen', _('IPv4 prefix length'), _('The length of the IPv4 prefix in bits, the remainder is used in the IPv6 addresses.')); + o.placeholder = '32'; + o.datatype = 'range(0,32)'; + + o = s.taboption('general', form.Value, 'ip6prefix', _('IPv6 prefix'), _('The IPv6 prefix assigned to the provider, usually ends with <code>::</code>')); + o.rmempty = false; + o.datatype = 'ip6addr'; + + o = s.taboption('general', form.Value, 'ip6prefixlen', _('IPv6 prefix length'), _('The length of the IPv6 prefix in bits')); + o.placeholder = '16'; + o.datatype = 'range(0,64)'; + + o = s.taboption('general', form.Value, 'ealen', _('EA-bits length')); + o.datatype = 'range(0,48)'; + + o = s.taboption('general', form.Value, 'psidlen', _('PSID-bits length')); + o.datatype = 'range(0,16)'; + + o = s.taboption('general', form.Value, 'offset', _('PSID offset')); + o.datatype = 'range(0,16)'; + + o = s.taboption('advanced', widgets.NetworkSelect, 'tunlink', _('Tunnel Link')); + o.nocreate = true; + o.exclude = s.section; + + o = s.taboption('advanced', form.Flag, 'defaultroute', _('Default gateway'), _('If unchecked, no default route is configured')); + o.default = o.enabled; + + o = s.taboption('advanced', form.Value, 'metric', _('Use gateway metric')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + o.depends('defaultroute', '1'); + + o = s.taboption('advanced', form.Value, 'ttl', _('Use TTL on tunnel interface')); + o.placeholder = '64'; + o.datatype = 'range(1,255)'; + + o = s.taboption('advanced', form.Value, 'mtu', _('Use MTU on tunnel interface')); + o.placeholder = '1280'; + o.datatype = 'max(9200)'; + } +}); diff --git a/protocols/luci-proto-ipv6/luasrc/model/cbi/admin_network/proto_464xlat.lua b/protocols/luci-proto-ipv6/luasrc/model/cbi/admin_network/proto_464xlat.lua deleted file mode 100644 index 5a37582faf..0000000000 --- a/protocols/luci-proto-ipv6/luasrc/model/cbi/admin_network/proto_464xlat.lua +++ /dev/null @@ -1,33 +0,0 @@ --- Copyright 2011 Jo-Philipp Wich <jow@openwrt.org> --- Copyright 2013 Steven Barth <steven@midlink.org> --- Licensed to the public under the Apache License 2.0. - -local map, section, net = ... -local tunlink, defaultroute, metric, mtu - -section:taboption("general", Value, "ip6prefix", - translate("NAT64 Prefix"), translate("Leave empty to autodetect")) - -tunlink = section:taboption("advanced", DynamicList, "tunlink", translate("Tunnel Link")) -tunlink.template = "cbi/network_netlist" -tunlink.nocreate = true - - -defaultroute = section:taboption("advanced", Flag, "defaultroute", - translate("Default gateway"), - translate("If unchecked, no default route is configured")) - -defaultroute.default = defaultroute.enabled - - -metric = section:taboption("advanced", Value, "metric", - translate("Use gateway metric")) - -metric.placeholder = "0" -metric.datatype = "uinteger" -metric:depends("defaultroute", defaultroute.enabled) - - -mtu = section:taboption("advanced", Value, "mtu", translate("Use MTU on tunnel interface")) -mtu.placeholder = "1280" -mtu.datatype = "max(9200)" diff --git a/protocols/luci-proto-ipv6/luasrc/model/cbi/admin_network/proto_6in4.lua b/protocols/luci-proto-ipv6/luasrc/model/cbi/admin_network/proto_6in4.lua deleted file mode 100644 index 3c9f41f6b5..0000000000 --- a/protocols/luci-proto-ipv6/luasrc/model/cbi/admin_network/proto_6in4.lua +++ /dev/null @@ -1,102 +0,0 @@ --- Copyright 2011 Jo-Philipp Wich <jow@openwrt.org> --- Licensed to the public under the Apache License 2.0. - -local map, section, net = ... - -local ipaddr, peeraddr, ip6addr, tunnelid, username, password -local defaultroute, metric, ttl, mtu - - -ipaddr = s:taboption("general", Value, "ipaddr", - translate("Local IPv4 address"), - translate("Leave empty to use the current WAN address")) - -ipaddr.datatype = "ip4addr" - - -peeraddr = s:taboption("general", Value, "peeraddr", - translate("Remote IPv4 address"), - translate("This is usually the address of the nearest PoP operated by the tunnel broker")) - -peeraddr.rmempty = false -peeraddr.datatype = "ip4addr" - - -ip6addr = s:taboption("general", Value, "ip6addr", - translate("Local IPv6 address"), - translate("This is the local endpoint address assigned by the tunnel broker, it usually ends with <code>...:2/64</code>")) - -ip6addr.datatype = "ip6addr" - - -local ip6prefix = s:taboption("general", Value, "ip6prefix", - translate("IPv6 routed prefix"), - translate("This is the prefix routed to you by the tunnel broker for use by clients")) - -ip6prefix.datatype = "list(ip6addr)" - - -local update = section:taboption("general", Flag, "_update", - translate("Dynamic tunnel"), - translate("Enable HE.net dynamic endpoint update")) - -update.enabled = "1" -update.disabled = "0" - -function update.write() end -function update.remove() end -function update.cfgvalue(self, section) - return (tonumber(m:get(section, "tunnelid")) ~= nil) - and self.enabled or self.disabled -end - - -tunnelid = section:taboption("general", Value, "tunnelid", translate("Tunnel ID")) -tunnelid.datatype = "uinteger" -tunnelid:depends("_update", update.enabled) - - -username = section:taboption("general", Value, "username", - translate("HE.net username"), - translate("This is the plain username for logging into the account")) - -username:depends("_update", update.enabled) -username.validate = function(self, val, sid) - if type(val) == "string" and #val == 32 and val:match("^[a-fA-F0-9]+$") then - return nil, translate("The HE.net endpoint update configuration changed, you must now use the plain username instead of the user ID!") - end - return val -end - - -password = section:taboption("general", Value, "password", - translate("HE.net password"), - translate("This is either the \"Update Key\" configured for the tunnel or the account password if no update key has been configured")) - -password.password = true -password:depends("_update", update.enabled) - - -defaultroute = section:taboption("advanced", Flag, "defaultroute", - translate("Default gateway"), - translate("If unchecked, no default route is configured")) - -defaultroute.default = defaultroute.enabled - - -metric = section:taboption("advanced", Value, "metric", - translate("Use gateway metric")) - -metric.placeholder = "0" -metric.datatype = "uinteger" -metric:depends("defaultroute", defaultroute.enabled) - - -ttl = section:taboption("advanced", Value, "ttl", translate("Use TTL on tunnel interface")) -ttl.placeholder = "64" -ttl.datatype = "range(1,255)" - - -mtu = section:taboption("advanced", Value, "mtu", translate("Use MTU on tunnel interface")) -mtu.placeholder = "1280" -mtu.datatype = "max(9200)" diff --git a/protocols/luci-proto-ipv6/luasrc/model/cbi/admin_network/proto_6rd.lua b/protocols/luci-proto-ipv6/luasrc/model/cbi/admin_network/proto_6rd.lua deleted file mode 100644 index 708a9c5add..0000000000 --- a/protocols/luci-proto-ipv6/luasrc/model/cbi/admin_network/proto_6rd.lua +++ /dev/null @@ -1,72 +0,0 @@ --- Copyright 2011-2012 Jo-Philipp Wich <jow@openwrt.org> --- Licensed to the public under the Apache License 2.0. - -local map, section, net = ... - -local ipaddr, peeraddr, ip6addr, tunnelid, username, password -local defaultroute, metric, ttl, mtu - - -ipaddr = s:taboption("general", Value, "ipaddr", - translate("Local IPv4 address"), - translate("Leave empty to use the current WAN address")) - -ipaddr.datatype = "ip4addr" - - -peeraddr = s:taboption("general", Value, "peeraddr", - translate("Remote IPv4 address"), - translate("This IPv4 address of the relay")) - -peeraddr.rmempty = false -peeraddr.datatype = "ip4addr" - - -ip6addr = s:taboption("general", Value, "ip6prefix", - translate("IPv6 prefix"), - translate("The IPv6 prefix assigned to the provider, usually ends with <code>::</code>")) - -ip6addr.rmempty = false -ip6addr.datatype = "ip6addr" - - -ip6prefixlen = s:taboption("general", Value, "ip6prefixlen", - translate("IPv6 prefix length"), - translate("The length of the IPv6 prefix in bits")) - -ip6prefixlen.placeholder = "16" -ip6prefixlen.datatype = "range(0,128)" - - -ip6prefixlen = s:taboption("general", Value, "ip4prefixlen", - translate("IPv4 prefix length"), - translate("The length of the IPv4 prefix in bits, the remainder is used in the IPv6 addresses.")) - -ip6prefixlen.placeholder = "0" -ip6prefixlen.datatype = "range(0,32)" - - - -defaultroute = section:taboption("advanced", Flag, "defaultroute", - translate("Default gateway"), - translate("If unchecked, no default route is configured")) - -defaultroute.default = defaultroute.enabled - - -metric = section:taboption("advanced", Value, "metric", - translate("Use gateway metric")) - -metric.placeholder = "0" -metric.datatype = "uinteger" -metric:depends("defaultroute", defaultroute.enabled) - - -ttl = section:taboption("advanced", Value, "ttl", translate("Use TTL on tunnel interface")) -ttl.placeholder = "64" -ttl.datatype = "range(1,255)" - - -mtu = section:taboption("advanced", Value, "mtu", translate("Use MTU on tunnel interface")) -mtu.placeholder = "1280" -mtu.datatype = "max(9200)" diff --git a/protocols/luci-proto-ipv6/luasrc/model/cbi/admin_network/proto_6to4.lua b/protocols/luci-proto-ipv6/luasrc/model/cbi/admin_network/proto_6to4.lua deleted file mode 100644 index 50a706974d..0000000000 --- a/protocols/luci-proto-ipv6/luasrc/model/cbi/admin_network/proto_6to4.lua +++ /dev/null @@ -1,37 +0,0 @@ --- Copyright 2011 Jo-Philipp Wich <jow@openwrt.org> --- Licensed to the public under the Apache License 2.0. - -local map, section, net = ... - -local ipaddr, defaultroute, metric, ttl, mtu - - -ipaddr = section:taboption("general", Value, "ipaddr", - translate("Local IPv4 address"), - translate("Leave empty to use the current WAN address")) - -ipaddr.datatype = "ip4addr" - -defaultroute = section:taboption("advanced", Flag, "defaultroute", - translate("Use default gateway"), - translate("If unchecked, no default route is configured")) - -defaultroute.default = defaultroute.enabled - - -metric = section:taboption("advanced", Value, "metric", - translate("Use gateway metric")) - -metric.placeholder = "0" -metric.datatype = "uinteger" -metric:depends("defaultroute", defaultroute.enabled) - - -ttl = section:taboption("advanced", Value, "ttl", translate("Use TTL on tunnel interface")) -ttl.placeholder = "64" -ttl.datatype = "range(1,255)" - - -mtu = section:taboption("advanced", Value, "mtu", translate("Use MTU on tunnel interface")) -mtu.placeholder = "1280" -mtu.datatype = "max(9200)" diff --git a/protocols/luci-proto-ipv6/luasrc/model/cbi/admin_network/proto_dhcpv6.lua b/protocols/luci-proto-ipv6/luasrc/model/cbi/admin_network/proto_dhcpv6.lua deleted file mode 100644 index 49281ee41d..0000000000 --- a/protocols/luci-proto-ipv6/luasrc/model/cbi/admin_network/proto_dhcpv6.lua +++ /dev/null @@ -1,58 +0,0 @@ --- Copyright 2013 Steven Barth <steven@midlink.org> --- Licensed to the public under the Apache License 2.0. - -local map, section, net = ... - - -local o = section:taboption("general", ListValue, "reqaddress", - translate("Request IPv6-address")) -o:value("try") -o:value("force") -o:value("none", "disabled") -o.default = "try" - - -o = section:taboption("general", Value, "reqprefix", - translate("Request IPv6-prefix of length")) -o:value("auto", translate("Automatic")) -o:value("no", translate("disabled")) -o:value("48") -o:value("52") -o:value("56") -o:value("60") -o:value("64") -o.default = "auto" - - -o = section:taboption("advanced", Flag, "defaultroute", - translate("Use default gateway"), - translate("If unchecked, no default route is configured")) -o.default = o.enabled - - -o = section:taboption("advanced", Flag, "peerdns", - translate("Use DNS servers advertised by peer"), - translate("If unchecked, the advertised DNS server addresses are ignored")) -o.default = o.enabled - - -o = section:taboption("advanced", Value, "ip6prefix", - translate("Custom delegated IPv6-prefix")) -o.dataype = "list(ip6addr)" - - -o = section:taboption("advanced", DynamicList, "dns", - translate("Use custom DNS servers")) -o:depends("peerdns", "") -o.datatype = "list(ip6addr)" -o.cast = "string" - - -o = section:taboption("advanced", Value, "clientid", - translate("Client ID to send when requesting DHCP")) - -luci.tools.proto.opt_macaddr(section, ifc, translate("Override MAC address")) - -o = section:taboption("advanced", Value, "mtu", translate("Override MTU")) -o.placeholder = "1500" -o.datatype = "max(9200)" diff --git a/protocols/luci-proto-ipv6/luasrc/model/cbi/admin_network/proto_dslite.lua b/protocols/luci-proto-ipv6/luasrc/model/cbi/admin_network/proto_dslite.lua deleted file mode 100644 index eca9750adb..0000000000 --- a/protocols/luci-proto-ipv6/luasrc/model/cbi/admin_network/proto_dslite.lua +++ /dev/null @@ -1,53 +0,0 @@ --- Copyright 2011 Jo-Philipp Wich <jow@openwrt.org> --- Copyright 2013 Steven Barth <steven@midlink.org> --- Licensed to the public under the Apache License 2.0. - -local map, section, net = ... - -local peeraddr, ip6addr -local tunlink, defaultroute, metric, ttl, mtu - - - - -peeraddr = section:taboption("general", Value, "peeraddr", - translate("DS-Lite AFTR address")) - -peeraddr.rmempty = false -peeraddr.datatype = "or(hostname,ip6addr)" - -ip6addr = section:taboption("general", Value, "ip6addr", - translate("Local IPv6 address"), - translate("Leave empty to use the current WAN address")) - -ip6addr.datatype = "ip6addr" - - -tunlink = section:taboption("advanced", DynamicList, "tunlink", translate("Tunnel Link")) -tunlink.template = "cbi/network_netlist" -tunlink.nocreate = true - - -defaultroute = section:taboption("advanced", Flag, "defaultroute", - translate("Default gateway"), - translate("If unchecked, no default route is configured")) - -defaultroute.default = defaultroute.enabled - - -metric = section:taboption("advanced", Value, "metric", - translate("Use gateway metric")) - -metric.placeholder = "0" -metric.datatype = "uinteger" -metric:depends("defaultroute", defaultroute.enabled) - - -ttl = section:taboption("advanced", Value, "ttl", translate("Use TTL on tunnel interface")) -ttl.placeholder = "64" -ttl.datatype = "range(1,255)" - - -mtu = section:taboption("advanced", Value, "mtu", translate("Use MTU on tunnel interface")) -mtu.placeholder = "1280" -mtu.datatype = "max(9200)" diff --git a/protocols/luci-proto-ipv6/luasrc/model/cbi/admin_network/proto_map.lua b/protocols/luci-proto-ipv6/luasrc/model/cbi/admin_network/proto_map.lua deleted file mode 100644 index 37d4ec901a..0000000000 --- a/protocols/luci-proto-ipv6/luasrc/model/cbi/admin_network/proto_map.lua +++ /dev/null @@ -1,88 +0,0 @@ --- Copyright 2011 Jo-Philipp Wich <jow@openwrt.org> --- Copyright 2013 Steven Barth <steven@midlink.org> --- Licensed to the public under the Apache License 2.0. - -local map, section, net = ... - -local peeraddr, ip6addr -local tunlink, defaultroute, metric, ttl, mtu - - -maptype = section:taboption("general", ListValue, "type", translate("Type")) -maptype:value("map-e", "MAP-E") -maptype:value("map-t", "MAP-T") -maptype:value("lw4o6", "LW4over6") - - -peeraddr = section:taboption("general", Value, "peeraddr", - translate("BR / DMR / AFTR")) - -peeraddr.rmempty = false -peeraddr.datatype = "ip6addr" - - -ipaddr = section:taboption("general", Value, "ipaddr", - translate("IPv4 prefix")) -ipaddr.datatype = "ip4addr" - - -ip4prefixlen = s:taboption("general", Value, "ip4prefixlen", - translate("IPv4 prefix length"), - translate("The length of the IPv4 prefix in bits, the remainder is used in the IPv6 addresses.")) - -ip4prefixlen.placeholder = "32" -ip4prefixlen.datatype = "range(0,32)" - -ip6addr = s:taboption("general", Value, "ip6prefix", - translate("IPv6 prefix"), - translate("The IPv6 prefix assigned to the provider, usually ends with <code>::</code>")) - -ip6addr.rmempty = false -ip6addr.datatype = "ip6addr" - - -ip6prefixlen = s:taboption("general", Value, "ip6prefixlen", - translate("IPv6 prefix length"), - translate("The length of the IPv6 prefix in bits")) - -ip6prefixlen.placeholder = "16" -ip6prefixlen.datatype = "range(0,64)" - - -s:taboption("general", Value, "ealen", - translate("EA-bits length")).datatype = "range(0,48)" - -s:taboption("general", Value, "psidlen", - translate("PSID-bits length")).datatype = "range(0,16)" - -s:taboption("general", Value, "offset", - translate("PSID offset")).datatype = "range(0,16)" - -tunlink = section:taboption("advanced", DynamicList, "tunlink", translate("Tunnel Link")) -tunlink.template = "cbi/network_netlist" -tunlink.nocreate = true - - -defaultroute = section:taboption("advanced", Flag, "defaultroute", - translate("Default gateway"), - translate("If unchecked, no default route is configured")) - -defaultroute.default = defaultroute.enabled - - -metric = section:taboption("advanced", Value, "metric", - translate("Use gateway metric")) - -metric.placeholder = "0" -metric.datatype = "uinteger" -metric:depends("defaultroute", defaultroute.enabled) - - -ttl = section:taboption("advanced", Value, "ttl", translate("Use TTL on tunnel interface")) -ttl.placeholder = "64" -ttl.datatype = "range(1,255)" - - -mtu = section:taboption("advanced", Value, "mtu", translate("Use MTU on tunnel interface")) -mtu.placeholder = "1280" -mtu.datatype = "max(9200)" diff --git a/protocols/luci-proto-ipv6/luasrc/model/network/proto_4x6.lua b/protocols/luci-proto-ipv6/luasrc/model/network/proto_4x6.lua index 7508e0d4b0..0b329d8a92 100644 --- a/protocols/luci-proto-ipv6/luasrc/model/network/proto_4x6.lua +++ b/protocols/luci-proto-ipv6/luasrc/model/network/proto_4x6.lua @@ -49,7 +49,7 @@ for _, p in ipairs({"dslite", "map", "464xlat"}) do return nil end - function proto.contains_interface(self, ifname) + function proto.contains_interface(self, ifc) return (netmod:ifnameof(ifc) == self:ifname()) end end diff --git a/protocols/luci-proto-ipv6/luasrc/model/network/proto_6x4.lua b/protocols/luci-proto-ipv6/luasrc/model/network/proto_6x4.lua index 9a4396c5be..2fd0b11957 100644 --- a/protocols/luci-proto-ipv6/luasrc/model/network/proto_6x4.lua +++ b/protocols/luci-proto-ipv6/luasrc/model/network/proto_6x4.lua @@ -42,7 +42,7 @@ for _, p in ipairs({"6in4", "6to4", "6rd"}) do return nil end - function proto.contains_interface(self, ifname) + function proto.contains_interface(self, ifc) return (netmod:ifnameof(ifc) == self:ifname()) end diff --git a/protocols/luci-proto-ncm/htdocs/luci-static/resources/protocol/ncm.js b/protocols/luci-proto-ncm/htdocs/luci-static/resources/protocol/ncm.js new file mode 100644 index 0000000000..3ab6c01d61 --- /dev/null +++ b/protocols/luci-proto-ncm/htdocs/luci-static/resources/protocol/ncm.js @@ -0,0 +1,123 @@ +'use strict'; +'require rpc'; +'require form'; +'require network'; + +var callFileList = rpc.declare({ + object: 'file', + method: 'list', + params: [ 'path' ], + expect: { entries: [] }, + filter: function(list, params) { + var rv = []; + for (var i = 0; i < list.length; i++) + if (list[i].name.match(/^ttyUSB/) || list[i].name.match(/^cdc-wdm/)) + rv.push(params.path + list[i].name); + return rv.sort(); + } +}); + +network.registerPatternVirtual(/^ncm-.+$/); +network.registerErrorCode('CONFIGURE_FAILED', _('Configuration failed')); +network.registerErrorCode('DISCONNECT_FAILED', _('Disconnection attempt failed')); +network.registerErrorCode('FINALIZE_FAILED', _('Finalizing failed')); +network.registerErrorCode('GETINFO_FAILED', _('Modem information query failed')); +network.registerErrorCode('INITIALIZE_FAILED', _('Initialization failure')); +network.registerErrorCode('SETMODE_FAILED', _('Setting operation mode failed')); +network.registerErrorCode('UNSUPPORTED_MODEM', _('Unsupported modem')); + +return network.registerProtocol('ncm', { + getI18n: function() { + return _('NCM'); + }, + + getIfname: function() { + return this._ubus('l3_device') || 'wan'; + }, + + getOpkgPackage: function() { + return 'comgt-ncm'; + }, + + isFloating: function() { + return true; + }, + + isVirtual: function() { + return true; + }, + + getDevices: function() { + return null; + }, + + containsDevice: function(ifname) { + return (network.getIfnameOf(ifname) == this.getIfname()); + }, + + renderFormOptions: function(s) { + var o; + + o = s.taboption('general', form.Value, 'device', _('Modem device')); + o.rmempty = false; + o.load = function(section_id) { + return callFileList('/dev/').then(L.bind(function(devices) { + for (var i = 0; i < devices.length; i++) + this.value(devices[i]); + return form.Value.prototype.load.apply(this, [section_id]); + }, this)); + }; + + o = s.taboption('general', form.Value, 'service', _('Service Type')); + o.value('', _('Modem default')); + o.value('preferlte', _('Prefer LTE')); + o.value('preferumts', _('Prefer UMTS')); + o.value('lte', 'LTE'); + o.value('umts', 'UMTS/GPRS'); + o.value('gsm', _('GPRS only')); + o.value('auto', _('auto')); + + o = s.taboption('general', form.ListValue, 'pdptype', _('IP Protocol')); + o.default = 'IP'; + o.value('IP', _('IPv4')); + o.value('IPV4V6', _('IPv4+IPv6')); + o.value('IPV6', _('IPv6')); + + s.taboption('general', form.Value, 'apn', _('APN')); + s.taboption('general', form.Value, 'pincode', _('PIN')); + s.taboption('general', form.Value, 'username', _('PAP/CHAP username')); + + o = s.taboption('general', form.Value, 'password', _('PAP/CHAP password')); + o.password = true; + + o = s.taboption('general', form.Value, 'dialnumber', _('Dial number')); + o.placeholder = '*99***1#'; + + if (L.hasSystemFeature('ipv6')) { + o = s.taboption('advanced', form.ListValue, 'ipv6', _('Obtain IPv6-Address')); + o.value('auto', _('Automatic')); + o.value('0', _('Disabled')); + o.value('1', _('Manual')); + o.default = 'auto'; + } + + o = s.taboption('advanced', form.Value, 'delay', _('Modem init timeout'), _('Maximum amount of seconds to wait for the modem to become ready')); + o.placeholder = '10'; + o.datatype = 'min(1)'; + + o = s.taboption('advanced', form.Flag, 'defaultroute', _('Default gateway'), _('If unchecked, no default route is configured')); + o.default = o.enabled; + + o = s.taboption('advanced', form.Value, 'metric', _('Use gateway metric')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + o.depends('defaultroute', '1'); + + o = s.taboption('advanced', form.Flag, 'peerdns', _('Use DNS servers advertised by peer'), _('If unchecked, the advertised DNS server addresses are ignored')); + o.default = o.enabled; + + o = s.taboption('advanced', form.DynamicList, 'dns', _('Use custom DNS servers')); + o.depends('peerdns', '0'); + o.datatype = 'ipaddr'; + } +}); diff --git a/protocols/luci-proto-ncm/luasrc/model/cbi/admin_network/proto_ncm.lua b/protocols/luci-proto-ncm/luasrc/model/cbi/admin_network/proto_ncm.lua deleted file mode 100644 index 3fe4ef33aa..0000000000 --- a/protocols/luci-proto-ncm/luasrc/model/cbi/admin_network/proto_ncm.lua +++ /dev/null @@ -1,110 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface - -Copyright 2015 Cezary Jackiewicz <cezary.jackiewicz@gmail.com> - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 -]]-- - -local map, section, net = ... - -local device, apn, service, pincode, username, password, dialnum -local ipv6, delay, defaultroute, metric, peerdns, dns - - -device = section:taboption("general", Value, "device", translate("Modem device")) -device.rmempty = false - -local dev -for dev in nixio.fs.glob("/dev/ttyUSB*") do - device:value(dev) -end -for dev in nixio.fs.glob("/dev/cdc-wdm*") do - device:value(dev) -end - -mode = section:taboption("general", Value, "mode", translate("Service Type")) -mode:value("", translate("Modem default")) -mode:value("preferlte", translate("Prefer LTE")) -mode:value("preferumts", translate("Prefer UMTS")) -mode:value("lte", "LTE") -mode:value("umts", "UMTS/GPRS") -mode:value("gsm", translate("GPRS only")) -mode:value("auto", translate("auto")) - - -mode = section:taboption("general", Value, "pdptype", translate("IP Protocol")) -mode.default = "IP" -mode:value("IP", translate("IPv4")) -mode:value("IPV4V6", translate("IPv4+IPv6")) -mode:value("IPV6", translate("IPv6")) - - -apn = section:taboption("general", Value, "apn", translate("APN")) - - -pincode = section:taboption("general", Value, "pincode", translate("PIN")) - - -username = section:taboption("general", Value, "username", translate("PAP/CHAP username")) - - -password = section:taboption("general", Value, "password", translate("PAP/CHAP password")) -password.password = true - - -dialnum = section:taboption("general", Value, "dialnum", translate("Dial number")) -dialnum.placeholder = "*99#" - - -if luci.model.network:has_ipv6() then - - ipv6 = section:taboption("advanced", ListValue, "ipv6") - ipv6:value("auto", translate("Automatic")) - ipv6:value("0", translate("Disabled")) - ipv6:value("1", translate("Manual")) - ipv6.default = "auto" - -end - - -delay = section:taboption("advanced", Value, "delay", - translate("Modem init timeout"), - translate("Maximum amount of seconds to wait for the modem to become ready")) - -delay.placeholder = "10" -delay.datatype = "min(1)" - - -defaultroute = section:taboption("advanced", Flag, "defaultroute", - translate("Use default gateway"), - translate("If unchecked, no default route is configured")) - -defaultroute.default = defaultroute.enabled - -metric = section:taboption("advanced", Value, "metric", - translate("Use gateway metric")) - -metric.placeholder = "0" -metric.datatype = "uinteger" -metric:depends("defaultroute", defaultroute.enabled) - - -peerdns = section:taboption("advanced", Flag, "peerdns", - translate("Use DNS servers advertised by peer"), - translate("If unchecked, the advertised DNS server addresses are ignored")) - -peerdns.default = peerdns.enabled - - -dns = section:taboption("advanced", DynamicList, "dns", - translate("Use custom DNS servers")) - -dns:depends("peerdns", "") -dns.datatype = "ipaddr" -dns.cast = "string" - diff --git a/protocols/luci-proto-openconnect/htdocs/luci-static/resources/protocol/openconnect.js b/protocols/luci-proto-openconnect/htdocs/luci-static/resources/protocol/openconnect.js new file mode 100644 index 0000000000..14fc8f6d35 --- /dev/null +++ b/protocols/luci-proto-openconnect/htdocs/luci-static/resources/protocol/openconnect.js @@ -0,0 +1,159 @@ +'use strict'; +'require rpc'; +'require form'; +'require network'; + +var callGetCertificateFiles = rpc.declare({ + object: 'luci.openconnect', + method: 'getCertificates', + params: [ 'interface' ], + expect: { '': {} } +}); + +var callSetCertificateFiles = rpc.declare({ + object: 'luci.openconnect', + method: 'setCertificates', + params: [ 'interface', 'user_certificate', 'user_privatekey', 'ca_certificate' ], + expect: { '': {} } +}); + +network.registerPatternVirtual(/^vpn-.+$/); + +function sanitizeCert(s) { + if (typeof(s) != 'string') + return null; + + s = s.trim(); + + if (s == '') + return null; + + s = s.replace(/\r\n?/g, '\n'); + + if (!s.match(/\n$/)) + s += '\n'; + + return s; +} + +function validateCert(priv, section_id, value) { + var beg = priv ? /^-----BEGIN RSA PRIVATE KEY-----$/ : /^-----BEGIN CERTIFICATE-----$/, + end = priv ? /^-----END RSA PRIVATE KEY-----$/ : /^-----END CERTIFICATE-----$/, + lines = value.trim().split(/[\r\n]/), + start = false, + i; + + for (i = 0; i < lines.length; i++) { + if (lines[i].match(beg)) + start = true; + else if (start && !lines[i].match(/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/)) + break; + } + + if (!start || i < lines.length - 1 || !lines[i].match(end)) + return _('This does not look like a valid PEM file'); + + return true; +} + +return network.registerProtocol('openconnect', { + getI18n: function() { + return _('OpenConnect (CISCO AnyConnect)'); + }, + + getIfname: function() { + return this._ubus('l3_device') || 'vpn-%s'.format(this.sid); + }, + + getOpkgPackage: function() { + return 'openconnect'; + }, + + isFloating: function() { + return true; + }, + + isVirtual: function() { + return true; + }, + + getDevices: function() { + return null; + }, + + containsDevice: function(ifname) { + return (network.getIfnameOf(ifname) == this.getIfname()); + }, + + renderFormOptions: function(s) { + var dev = this.getDevice().getName(), + certLoadPromise = null, + o; + + o = s.taboption('general', form.Value, 'server', _('VPN Server')); + o.datatype = 'host(0)'; + + o = s.taboption('general', form.Value, 'port', _('VPN Server port')); + o.placeholder = '443'; + o.datatype = 'port'; + + s.taboption('general', form.Value, 'serverhash', _("VPN Server's certificate SHA1 hash")); + s.taboption('general', form.Value, 'authgroup', _('Auth Group')); + s.taboption("general", form.Value, "username", _("Username")); + + o = s.taboption('general', form.Value, 'password', _('Password')); + o.password = true; + + o = s.taboption('general', form.Value, 'password2', _('Password2')); + o.password = true; + + o = s.taboption('general', form.TextValue, 'usercert', _('User certificate (PEM encoded)')); + o.rows = 10; + o.monospace = true; + o.validate = L.bind(validateCert, o, false); + o.load = function(section_id) { + certLoadPromise = certLoadPromise || callGetCertificateFiles(section_id); + return certLoadPromise.then(function(certs) { return certs.user_certificate }); + }; + o.write = function(section_id, value) { + return callSetCertificateFiles(section_id, sanitizeCert(value), null, null); + }; + + o = s.taboption('general', form.TextValue, 'userkey', _('User key (PEM encoded)')); + o.rows = 10; + o.monospace = true; + o.validate = L.bind(validateCert, o, true); + o.load = function(section_id) { + certLoadPromise = certLoadPromise || callGetCertificateFiles(section_id); + return certLoadPromise.then(function(certs) { return certs.user_privatekey }); + }; + o.write = function(section_id, value) { + return callSetCertificateFiles(section_id, null, sanitizeCert(value), null); + }; + + o = s.taboption('general', form.TextValue, 'ca', _('CA certificate; if empty it will be saved after the first connection.')); + o.rows = 10; + o.monospace = true; + o.validate = L.bind(validateCert, o, false); + o.load = function(section_id) { + certLoadPromise = certLoadPromise || callGetCertificateFiles(section_id); + return certLoadPromise.then(function(certs) { return certs.ca_certificate }); + }; + o.write = function(section_id, value) { + return callSetCertificateFiles(section_id, null, null, sanitizeCert(value)); + }; + + o = s.taboption('advanced', form.Flag, 'defaultroute', _('Default gateway'), _('If unchecked, no default route is configured')); + o.default = o.enabled; + + o = s.taboption('advanced', form.Value, 'metric', _('Use gateway metric')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + o.depends('defaultroute', '1'); + + o = s.taboption('advanced', form.Value, 'mtu', _('Override MTU')); + o.optional = true; + o.placeholder = 1406; + o.datatype = 'range(68, 9200)'; + } +}); diff --git a/protocols/luci-proto-openconnect/luasrc/model/cbi/admin_network/proto_openconnect.lua b/protocols/luci-proto-openconnect/luasrc/model/cbi/admin_network/proto_openconnect.lua deleted file mode 100644 index 5adfccae48..0000000000 --- a/protocols/luci-proto-openconnect/luasrc/model/cbi/admin_network/proto_openconnect.lua +++ /dev/null @@ -1,90 +0,0 @@ --- Copyright 2014 Nikos Mavrogiannopoulos <nmav@gnutls.org> --- Licensed to the public under the Apache License 2.0. - -local map, section, net = ... - -local server, username, password, cert, ca -local oc_cert_file, oc_key_file, oc_ca_file - -local ifc = net:get_interface():name() - -oc_cert_file = "/etc/openconnect/user-cert-" .. ifc .. ".pem" -oc_key_file = "/etc/openconnect/user-key-" .. ifc .. ".pem" -oc_ca_file = "/etc/openconnect/ca-" .. ifc .. ".pem" - -server = section:taboption("general", Value, "server", translate("VPN Server")) -server.datatype = "host(0)" - -port = section:taboption("general", Value, "port", translate("VPN Server port")) -port.placeholder = "443" -port.datatype = "port" - - -defaultroute = section:taboption("advanced", Flag, "defaultroute", - translate("Use default gateway"), - translate("If unchecked, no default route is configured")) - -defaultroute.default = defaultroute.enabled - - -metric = section:taboption("advanced", Value, "metric", - translate("Use gateway metric")) - -metric.placeholder = "0" -metric.datatype = "uinteger" -metric:depends("defaultroute", defaultroute.enabled) - -section:taboption("general", Value, "serverhash", translate("VPN Server's certificate SHA1 hash")) - -section:taboption("general", Value, "authgroup", translate("Auth Group")) - -username = section:taboption("general", Value, "username", translate("Username")) -password = section:taboption("general", Value, "password", translate("Password")) -password.password = true -password2 = section:taboption("general", Value, "password2", translate("Password2")) -password2.password = true - - -cert = section:taboption("advanced", Value, "usercert", translate("User certificate (PEM encoded)")) -cert.template = "cbi/tvalue" -cert.rows = 10 - -function cert.cfgvalue(self, section) - return nixio.fs.readfile(oc_cert_file) -end - -function cert.write(self, section, value) - value = value:gsub("\r\n?", "\n") - nixio.fs.writefile(oc_cert_file, value) -end - -cert = section:taboption("advanced", Value, "userkey", translate("User key (PEM encoded)")) -cert.template = "cbi/tvalue" -cert.rows = 10 - -function cert.cfgvalue(self, section) - return nixio.fs.readfile(oc_key_file) -end - -function cert.write(self, section, value) - value = value:gsub("\r\n?", "\n") - nixio.fs.writefile(oc_key_file, value) -end - - -ca = section:taboption("advanced", Value, "ca", translate("CA certificate; if empty it will be saved after the first connection.")) -ca.template = "cbi/tvalue" -ca.rows = 10 - -function ca.cfgvalue(self, section) - return nixio.fs.readfile(oc_ca_file) -end - -function ca.write(self, section, value) - value = value:gsub("\r\n?", "\n") - nixio.fs.writefile(oc_ca_file, value) -end - -mtu = section:taboption("advanced", Value, "mtu", translate("Override MTU")) -mtu.placeholder = "1406" -mtu.datatype = "max(9200)" diff --git a/protocols/luci-proto-openconnect/root/usr/libexec/rpcd/luci.openconnect b/protocols/luci-proto-openconnect/root/usr/libexec/rpcd/luci.openconnect new file mode 100755 index 0000000000..9378cc518b --- /dev/null +++ b/protocols/luci-proto-openconnect/root/usr/libexec/rpcd/luci.openconnect @@ -0,0 +1,78 @@ +#!/usr/bin/env lua + +local json = require "luci.jsonc" +local fs = require "nixio.fs" + +local function readfile(path) + local s = fs.readfile(path) + return s and (s:gsub("^%s+", ""):gsub("%s+$", "")) +end + +local function writefile(path, data) + local n = fs.writefile(path, data) + return (n == #data) +end + +local function parseInput() + local parse = json.new() + local done, err + + while true do + local chunk = io.read(4096) + if not chunk then + break + elseif not done and not err then + done, err = parse:parse(chunk) + end + end + + if not done then + print(json.stringify({ error = err or "Incomplete input" })) + os.exit(1) + end + + return parse:get() +end + +if arg[1] == "list" then + print(json.stringify({ + getCertificates = { + interface = "interface" + }, + setCertificates = { + interface = "interface", + user_certificate = "PEM file data", + user_privatekey = "PEM file data", + ca_certificate = "PEM file data" + } + })) +elseif arg[1] == "call" then + local args = parseInput() + + if not args.interface or + type(args.interface) ~= "string" or + not args.interface:match("^[a-zA-Z0-9_]+$") + then + print(json.stringify({ error = "Invalid interface name" })) + os.exit(1) + end + + if arg[2] == "getCertificates" then + print(json.stringify({ + user_certificate = readfile(string.format("/etc/openconnect/user-cert-%s.pem", args.interface)), + user_privatekey = readfile(string.format("/etc/openconnect/user-key-%s.pem", args.interface)), + ca_certificate = readfile(string.format("/etc/openconnect/ca-%s.pem", args.interface)) + })) + elseif arg[2] == "setCertificates" then + if args.user_certificate then + writefile(string.format("/etc/openconnect/user-cert-%s.pem", args.interface), args.user_certificate) + end + if args.user_privatekey then + writefile(string.format("/etc/openconnect/user-key-%s.pem", args.interface), args.user_privatekey) + end + if args.ca_certificate then + writefile(string.format("/etc/openconnect/ca-%s.pem", args.interface), args.ca_certificate) + end + print(json.stringify({ result = true })) + end +end diff --git a/protocols/luci-proto-openconnect/root/usr/share/rpcd/acl.d/luci-openconnect.json b/protocols/luci-proto-openconnect/root/usr/share/rpcd/acl.d/luci-openconnect.json new file mode 100644 index 0000000000..66bc5ac24f --- /dev/null +++ b/protocols/luci-proto-openconnect/root/usr/share/rpcd/acl.d/luci-openconnect.json @@ -0,0 +1,17 @@ +{ + "luci-proto-openconnect": { + "description": "Grant access to LuCI OpenConnect procedures", + "read": { + "ubus": { + "luci.openconnect": [ "getCertificates" ] + }, + "uci": [ "network" ] + }, + "write": { + "ubus": { + "luci.openconnect": [ "setCertificates" ] + }, + "uci": [ "network" ] + } + } +} diff --git a/protocols/luci-proto-ppp/htdocs/luci-static/resources/protocol/l2tp.js b/protocols/luci-proto-ppp/htdocs/luci-static/resources/protocol/l2tp.js new file mode 100644 index 0000000000..13bb3548a7 --- /dev/null +++ b/protocols/luci-proto-ppp/htdocs/luci-static/resources/protocol/l2tp.js @@ -0,0 +1,75 @@ +'use strict'; +'require uci'; +'require form'; +'require network'; + +network.registerPatternVirtual(/^l2tp-.+$/); + +return network.registerProtocol('l2tp', { + getI18n: function() { + return _('L2TP'); + }, + + getIfname: function() { + return this._ubus('l3_device') || 'l2tp-%s'.format(this.sid); + }, + + getOpkgPackage: function() { + return 'xl2tpd'; + }, + + isFloating: function() { + return true; + }, + + isVirtual: function() { + return true; + }, + + getDevices: function() { + return null; + }, + + containsDevice: function(ifname) { + return (network.getIfnameOf(ifname) == this.getIfname()); + }, + + renderFormOptions: function(s) { + var dev = this.getL3Device() || this.getDevice(), o; + + o = s.taboption('general', form.Value, 'server', _('L2TP Server')); + o.datatype = 'or(host(1), hostport(1))'; + + s.taboption('general', form.Value, 'username', _('PAP/CHAP username')); + + o = s.taboption('general', form.Value, 'password', _('PAP/CHAP password')); + o.password = true; + + if (L.hasSystemFeature('ipv6')) { + o = s.taboption('advanced', form.ListValue, 'ipv6', _('Obtain IPv6-Address'), _('Enable IPv6 negotiation on the PPP link')); + o.value('auto', _('Automatic')); + o.value('0', _('Disabled')); + o.value('1', _('Manual')); + o.default = 'auto'; + } + + o = s.taboption('advanced', form.Flag, 'defaultroute', _('Use default gateway'), _('If unchecked, no default route is configured')); + o.default = o.enabled; + + o = s.taboption('advanced', form.Flag, 'peerdns', _('Use DNS servers advertised by peer'), _('If unchecked, the advertised DNS server addresses are ignored')); + o.default = o.enabled; + + o = s.taboption('advanced', form.DynamicList, 'dns', _('Use custom DNS servers')); + o.depends('peerdns', '0'); + o.datatype = 'ipaddr'; + o.cast = 'string'; + + o = s.taboption('advanced', form.Value, 'metric', _('Use gateway metric')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + + o = s.taboption('advanced', form.Value, 'mtu', _('Override MTU')); + o.placeholder = dev ? (dev.getMTU() || '1500') : '1500'; + o.datatype = 'max(9200)'; + } +}); diff --git a/protocols/luci-proto-ppp/htdocs/luci-static/resources/protocol/ppp.js b/protocols/luci-proto-ppp/htdocs/luci-static/resources/protocol/ppp.js new file mode 100644 index 0000000000..57a7b6a0e1 --- /dev/null +++ b/protocols/luci-proto-ppp/htdocs/luci-static/resources/protocol/ppp.js @@ -0,0 +1,149 @@ +'use strict'; +'require rpc'; +'require uci'; +'require form'; +'require network'; + +var callFileList = rpc.declare({ + object: 'file', + method: 'list', + params: [ 'path' ], + expect: { entries: [] }, + filter: function(list, params) { + var rv = []; + for (var i = 0; i < list.length; i++) + if (list[i].name.match(/^tty[A-Z]/) || list[i].name.match(/^cdc-wdm/) || list[i].name.match(/^[0-9]+$/)) + rv.push(params.path + list[i].name); + return rv.sort(); + } +}); + +network.registerPatternVirtual(/^ppp-.+$/); + +function write_keepalive(section_id, value) { + var f_opt = this.map.lookupOption('_keepalive_failure', section_id), + i_opt = this.map.lookupOption('_keepalive_interval', section_id), + f = (f_opt != null) ? +f_opt[0].formvalue(section_id) : null, + i = (i_opt != null) ? +i_opt[0].formvalue(section_id) : null; + + if (f == null || f == '' || isNaN(f)) + f = 0; + + if (i == null || i == '' || isNaN(i) || i < 1) + i = 1; + + if (f > 0) + uci.set('network', section_id, 'keepalive', '%d %d'.format(f, i)); + else + uci.unset('network', section_id, 'keepalive'); +} + +return network.registerProtocol('ppp', { + getI18n: function() { + return _('PPP'); + }, + + getIfname: function() { + return this._ubus('l3_device') || 'ppp-%s'.format(this.sid); + }, + + getOpkgPackage: function() { + return 'ppp'; + }, + + isFloating: function() { + return true; + }, + + isVirtual: function() { + return true; + }, + + getDevices: function() { + return null; + }, + + containsDevice: function(ifname) { + return (network.getIfnameOf(ifname) == this.getIfname()); + }, + + renderFormOptions: function(s) { + var dev = this.getL3Device() || this.getDevice(), o; + + o = s.taboption('general', form.Value, 'device', _('Modem device')); + o.rmempty = false; + o.load = function(section_id) { + return callFileList('/dev/').then(L.bind(function(devices) { + for (var i = 0; i < devices.length; i++) + this.value(devices[i]); + return callFileList('/dev/tts/'); + }, this)).then(L.bind(function(devices) { + for (var i = 0; i < devices.length; i++) + this.value(devices[i]); + return form.Value.prototype.load.apply(this, [section_id]); + }, this)); + }; + + s.taboption('general', form.Value, 'username', _('PAP/CHAP username')); + + o = s.taboption('general', form.Value, 'password', _('PAP/CHAP password')); + o.password = true; + + if (L.hasSystemFeature('ipv6')) { + o = s.taboption('advanced', form.ListValue, 'ipv6', _('Obtain IPv6-Address'), _('Enable IPv6 negotiation on the PPP link')); + o.value('auto', _('Automatic')); + o.value('0', _('Disabled')); + o.value('1', _('Manual')); + o.default = 'auto'; + } + + o = s.taboption('advanced', form.Flag, 'defaultroute', _('Use default gateway'), _('If unchecked, no default route is configured')); + o.default = o.enabled; + + o = s.taboption('advanced', form.Flag, 'peerdns', _('Use DNS servers advertised by peer'), _('If unchecked, the advertised DNS server addresses are ignored')); + o.default = o.enabled; + + o = s.taboption('advanced', form.DynamicList, 'dns', _('Use custom DNS servers')); + o.depends('peerdns', '0'); + o.datatype = 'ipaddr'; + o.cast = 'string'; + + o = s.taboption('advanced', form.Value, 'metric', _('Use gateway metric')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + + o = s.taboption('advanced', form.Value, '_keepalive_failure', _('LCP echo failure threshold'), _('Presume peer to be dead after given amount of LCP echo failures, use 0 to ignore failures')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + o.write = write_keepalive; + o.remove = write_keepalive; + o.cfgvalue = function(section_id) { + var v = uci.get('network', section_id, 'keepalive'); + if (typeof(v) == 'string' && v != '') { + var m = v.match(/^(\d+)[ ,]\d+$/); + return m ? m[1] : v; + } + }; + + o = s.taboption('advanced', form.Value, '_keepalive_interval', _('LCP echo interval'), _('Send LCP echo requests at the given interval in seconds, only effective in conjunction with failure threshold')); + o.placeholder = '5'; + o.datatype = 'min(1)'; + o.write = write_keepalive; + o.remove = write_keepalive; + o.cfgvalue = function(section_id) { + var v = uci.get('network', section_id, 'keepalive'); + if (typeof(v) == 'string' && v != '') { + var m = v.match(/^\d+[ ,](\d+)$/); + return m ? m[1] : v; + } + }; + + o = s.taboption('advanced', form.Value, 'demand', _('Inactivity timeout'), _('Close inactive connection after the given amount of seconds, use 0 to persist connection')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + + o = s.taboption('advanced', form.Value, 'mtu', _('Override MTU')); + o.placeholder = dev ? (dev.getMTU() || '1500') : '1500'; + o.datatype = 'max(9200)'; + } +}); diff --git a/protocols/luci-proto-ppp/htdocs/luci-static/resources/protocol/pppoa.js b/protocols/luci-proto-ppp/htdocs/luci-static/resources/protocol/pppoa.js new file mode 100644 index 0000000000..483ac9e555 --- /dev/null +++ b/protocols/luci-proto-ppp/htdocs/luci-static/resources/protocol/pppoa.js @@ -0,0 +1,136 @@ +'use strict'; +'require uci'; +'require form'; +'require network'; + +network.registerPatternVirtual(/^pppoa-.+$/); + +function write_keepalive(section_id, value) { + var f_opt = this.map.lookupOption('_keepalive_failure', section_id), + i_opt = this.map.lookupOption('_keepalive_interval', section_id), + f = (f_opt != null) ? +f_opt[0].formvalue(section_id) : null, + i = (i_opt != null) ? +i_opt[0].formvalue(section_id) : null; + + if (f == null || f == '' || isNaN(f)) + f = 0; + + if (i == null || i == '' || isNaN(i) || i < 1) + i = 1; + + if (f > 0) + uci.set('network', section_id, 'keepalive', '%d %d'.format(f, i)); + else + uci.unset('network', section_id, 'keepalive'); +} + +return network.registerProtocol('pppoa', { + getI18n: function() { + return _('PPPoATM'); + }, + + getIfname: function() { + return this._ubus('l3_device') || 'pppoa-%s'.format(this.sid); + }, + + getOpkgPackage: function() { + return 'ppp-mod-pppoa'; + }, + + isFloating: function() { + return true; + }, + + isVirtual: function() { + return true; + }, + + getDevices: function() { + return null; + }, + + containsDevice: function(ifname) { + return (network.getIfnameOf(ifname) == this.getIfname()); + }, + + renderFormOptions: function(s) { + var dev = this.getL3Device() || this.getDevice(), o; + + o = s.taboption('general', form.ListValue, 'encaps', _('PPPoA Encapsulation')); + o.value('vc', 'VC-Mux'); + o.value('llc', 'LLC'); + + o = s.taboption('general', form.Value, 'atmdev', _('ATM device number')); + o.default = '0'; + o.datatype = 'uinteger'; + + o = s.taboption('general', form.Value, 'vci', _('ATM Virtual Channel Identifier (VCI)')); + o.default = '35'; + o.datatype = 'uinteger'; + + o = s.taboption('general', form.Value, 'vpi', _('ATM Virtual Path Identifier (VPI)')); + o.default = '8'; + o.datatype = 'uinteger'; + + s.taboption('general', form.Value, 'username', _('PAP/CHAP username')); + + o = s.taboption('general', form.Value, 'password', _('PAP/CHAP password')); + o.password = true; + + if (L.hasSystemFeature('ipv6')) { + o = s.taboption('advanced', form.ListValue, 'ipv6', _('Obtain IPv6-Address'), _('Enable IPv6 negotiation on the PPP link')); + o.value('auto', _('Automatic')); + o.value('0', _('Disabled')); + o.value('1', _('Manual')); + o.default = 'auto'; + } + + o = s.taboption('advanced', form.Flag, 'defaultroute', _('Use default gateway'), _('If unchecked, no default route is configured')); + o.default = o.enabled; + + o = s.taboption('advanced', form.Flag, 'peerdns', _('Use DNS servers advertised by peer'), _('If unchecked, the advertised DNS server addresses are ignored')); + o.default = o.enabled; + + o = s.taboption('advanced', form.DynamicList, 'dns', _('Use custom DNS servers')); + o.depends('peerdns', '0'); + o.datatype = 'ipaddr'; + o.cast = 'string'; + + o = s.taboption('advanced', form.Value, 'metric', _('Use gateway metric')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + + o = s.taboption('advanced', form.Value, '_keepalive_failure', _('LCP echo failure threshold'), _('Presume peer to be dead after given amount of LCP echo failures, use 0 to ignore failures')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + o.write = write_keepalive; + o.remove = write_keepalive; + o.cfgvalue = function(section_id) { + var v = uci.get('network', section_id, 'keepalive'); + if (typeof(v) == 'string' && v != '') { + var m = v.match(/^(\d+)[ ,]\d+$/); + return m ? m[1] : v; + } + }; + + o = s.taboption('advanced', form.Value, '_keepalive_interval', _('LCP echo interval'), _('Send LCP echo requests at the given interval in seconds, only effective in conjunction with failure threshold')); + o.placeholder = '5'; + o.datatype = 'min(1)'; + o.write = write_keepalive; + o.remove = write_keepalive; + o.cfgvalue = function(section_id) { + var v = uci.get('network', section_id, 'keepalive'); + if (typeof(v) == 'string' && v != '') { + var m = v.match(/^\d+[ ,](\d+)$/); + return m ? m[1] : v; + } + }; + + o = s.taboption('advanced', form.Value, 'demand', _('Inactivity timeout'), _('Close inactive connection after the given amount of seconds, use 0 to persist connection')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + + o = s.taboption('advanced', form.Value, 'mtu', _('Override MTU')); + o.placeholder = dev ? (dev.getMTU() || '1500') : '1500'; + o.datatype = 'max(9200)'; + } +}); diff --git a/protocols/luci-proto-ppp/htdocs/luci-static/resources/protocol/pppoe.js b/protocols/luci-proto-ppp/htdocs/luci-static/resources/protocol/pppoe.js new file mode 100644 index 0000000000..5d71c43376 --- /dev/null +++ b/protocols/luci-proto-ppp/htdocs/luci-static/resources/protocol/pppoe.js @@ -0,0 +1,114 @@ +'use strict'; +'require uci'; +'require form'; +'require network'; + +network.registerPatternVirtual(/^pppoe-.+$/); + +function write_keepalive(section_id, value) { + var f_opt = this.map.lookupOption('_keepalive_failure', section_id), + i_opt = this.map.lookupOption('_keepalive_interval', section_id), + f = (f_opt != null) ? +f_opt[0].formvalue(section_id) : null, + i = (i_opt != null) ? +i_opt[0].formvalue(section_id) : null; + + if (f == null || f == '' || isNaN(f)) + f = 0; + + if (i == null || i == '' || isNaN(i) || i < 1) + i = 1; + + if (f > 0) + uci.set('network', section_id, 'keepalive', '%d %d'.format(f, i)); + else + uci.unset('network', section_id, 'keepalive'); +} + +return network.registerProtocol('pppoe', { + getI18n: function() { + return _('PPPoE'); + }, + + getIfname: function() { + return this._ubus('l3_device') || 'pppoe-%s'.format(this.sid); + }, + + getOpkgPackage: function() { + return 'ppp-mod-pppoe'; + }, + + renderFormOptions: function(s) { + var dev = this.getL3Device() || this.getDevice(), o; + + s.taboption('general', form.Value, 'username', _('PAP/CHAP username')); + + o = s.taboption('general', form.Value, 'password', _('PAP/CHAP password')); + o.password = true; + + o = s.taboption('general', form.Value, 'ac', _('Access Concentrator'), _('Leave empty to autodetect')); + o.placeholder = _('auto'); + + o = s.taboption('general', form.Value, 'service', _('Service Name'), _('Leave empty to autodetect')); + o.placeholder = _('auto'); + + if (L.hasSystemFeature('ipv6')) { + o = s.taboption('advanced', form.ListValue, 'ipv6', _('Obtain IPv6-Address'), _('Enable IPv6 negotiation on the PPP link')); + o.value('auto', _('Automatic')); + o.value('0', _('Disabled')); + o.value('1', _('Manual')); + o.default = 'auto'; + } + + o = s.taboption('advanced', form.Flag, 'defaultroute', _('Use default gateway'), _('If unchecked, no default route is configured')); + o.default = o.enabled; + + o = s.taboption('advanced', form.Flag, 'peerdns', _('Use DNS servers advertised by peer'), _('If unchecked, the advertised DNS server addresses are ignored')); + o.default = o.enabled; + + o = s.taboption('advanced', form.DynamicList, 'dns', _('Use custom DNS servers')); + o.depends('peerdns', '0'); + o.datatype = 'ipaddr'; + o.cast = 'string'; + + o = s.taboption('advanced', form.Value, 'metric', _('Use gateway metric')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + + o = s.taboption('advanced', form.Value, '_keepalive_failure', _('LCP echo failure threshold'), _('Presume peer to be dead after given amount of LCP echo failures, use 0 to ignore failures')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + o.write = write_keepalive; + o.remove = write_keepalive; + o.cfgvalue = function(section_id) { + var v = uci.get('network', section_id, 'keepalive'); + if (typeof(v) == 'string' && v != '') { + var m = v.match(/^(\d+)[ ,]\d+$/); + return m ? m[1] : v; + } + }; + + o = s.taboption('advanced', form.Value, '_keepalive_interval', _('LCP echo interval'), _('Send LCP echo requests at the given interval in seconds, only effective in conjunction with failure threshold')); + o.placeholder = '5'; + o.datatype = 'min(1)'; + o.write = write_keepalive; + o.remove = write_keepalive; + o.cfgvalue = function(section_id) { + var v = uci.get('network', section_id, 'keepalive'); + if (typeof(v) == 'string' && v != '') { + var m = v.match(/^\d+[ ,](\d+)$/); + return m ? m[1] : v; + } + }; + + o = s.taboption('advanced', form.Value, 'host_uniq', _('Host-Uniq tag content'), _('Raw hex-encoded bytes. Leave empty unless your ISP require this')); + o.placeholder = _('auto'); + o.datatype = 'hexstring'; + + o = s.taboption('advanced', form.Value, 'demand', _('Inactivity timeout'), _('Close inactive connection after the given amount of seconds, use 0 to persist connection')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + + o = s.taboption('advanced', form.Value, 'mtu', _('Override MTU')); + o.placeholder = dev ? (dev.getMTU() || '1500') : '1500'; + o.datatype = 'max(9200)'; + } +}); diff --git a/protocols/luci-proto-ppp/htdocs/luci-static/resources/protocol/pptp.js b/protocols/luci-proto-ppp/htdocs/luci-static/resources/protocol/pptp.js new file mode 100644 index 0000000000..006adc1a1e --- /dev/null +++ b/protocols/luci-proto-ppp/htdocs/luci-static/resources/protocol/pptp.js @@ -0,0 +1,123 @@ +'use strict'; +'require uci'; +'require form'; +'require network'; + +network.registerPatternVirtual(/^pptp-.+$/); + +function write_keepalive(section_id, value) { + var f_opt = this.map.lookupOption('_keepalive_failure', section_id), + i_opt = this.map.lookupOption('_keepalive_interval', section_id), + f = (f_opt != null) ? +f_opt[0].formvalue(section_id) : null, + i = (i_opt != null) ? +i_opt[0].formvalue(section_id) : null; + + if (f == null || f == '' || isNaN(f)) + f = 0; + + if (i == null || i == '' || isNaN(i) || i < 1) + i = 1; + + if (f > 0) + uci.set('network', section_id, 'keepalive', '%d %d'.format(f, i)); + else + uci.unset('network', section_id, 'keepalive'); +} + +return network.registerProtocol('pptp', { + getI18n: function() { + return _('PPtP'); + }, + + getIfname: function() { + return this._ubus('l3_device') || 'pptp-%s'.format(this.sid); + }, + + getOpkgPackage: function() { + return 'ppp-mod-pptp'; + }, + + isFloating: function() { + return true; + }, + + isVirtual: function() { + return true; + }, + + getDevices: function() { + return null; + }, + + containsDevice: function(ifname) { + return (network.getIfnameOf(ifname) == this.getIfname()); + }, + + renderFormOptions: function(s) { + var dev = this.getL3Device() || this.getDevice(), o; + + o = s.taboption('general', form.Value, 'server', _('VPN Server')); + o.datatype = 'host(0)'; + + s.taboption('general', form.Value, 'username', _('PAP/CHAP username')); + + o = s.taboption('general', form.Value, 'password', _('PAP/CHAP password')); + o.password = true; + + if (L.hasSystemFeature('ipv6')) { + o = s.taboption('advanced', form.ListValue, 'ipv6', _('Obtain IPv6-Address'), _('Enable IPv6 negotiation on the PPP link')); + o.value('auto', _('Automatic')); + o.value('0', _('Disabled')); + o.value('1', _('Manual')); + o.default = 'auto'; + } + + o = s.taboption('advanced', form.Flag, 'defaultroute', _('Use default gateway'), _('If unchecked, no default route is configured')); + o.default = o.enabled; + + o = s.taboption('advanced', form.Flag, 'peerdns', _('Use DNS servers advertised by peer'), _('If unchecked, the advertised DNS server addresses are ignored')); + o.default = o.enabled; + + o = s.taboption('advanced', form.DynamicList, 'dns', _('Use custom DNS servers')); + o.depends('peerdns', '0'); + o.datatype = 'ipaddr'; + o.cast = 'string'; + + o = s.taboption('advanced', form.Value, 'metric', _('Use gateway metric')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + + o = s.taboption('advanced', form.Value, '_keepalive_failure', _('LCP echo failure threshold'), _('Presume peer to be dead after given amount of LCP echo failures, use 0 to ignore failures')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + o.write = write_keepalive; + o.remove = write_keepalive; + o.cfgvalue = function(section_id) { + var v = uci.get('network', section_id, 'keepalive'); + if (typeof(v) == 'string' && v != '') { + var m = v.match(/^(\d+)[ ,]\d+$/); + return m ? m[1] : v; + } + }; + + o = s.taboption('advanced', form.Value, '_keepalive_interval', _('LCP echo interval'), _('Send LCP echo requests at the given interval in seconds, only effective in conjunction with failure threshold')); + o.placeholder = '5'; + o.datatype = 'min(1)'; + o.write = write_keepalive; + o.remove = write_keepalive; + o.cfgvalue = function(section_id) { + var v = uci.get('network', section_id, 'keepalive'); + if (typeof(v) == 'string' && v != '') { + var m = v.match(/^\d+[ ,](\d+)$/); + return m ? m[1] : v; + } + }; + + o = s.taboption('advanced', form.Value, 'demand', _('Inactivity timeout'), _('Close inactive connection after the given amount of seconds, use 0 to persist connection')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + + o = s.taboption('advanced', form.Value, 'mtu', _('Override MTU')); + o.placeholder = dev ? (dev.getMTU() || '1500') : '1500'; + o.datatype = 'max(9200)'; + } +}); diff --git a/protocols/luci-proto-ppp/luasrc/model/cbi/admin_network/proto_l2tp.lua b/protocols/luci-proto-ppp/luasrc/model/cbi/admin_network/proto_l2tp.lua deleted file mode 100644 index 604f019ee6..0000000000 --- a/protocols/luci-proto-ppp/luasrc/model/cbi/admin_network/proto_l2tp.lua +++ /dev/null @@ -1,61 +0,0 @@ --- Copyright 2011 Jo-Philipp Wich <jow@openwrt.org> --- Licensed to the public under the Apache License 2.0. - -local map, section, net = ... - -local server, username, password -local ipv6, defaultroute, metric, peerdns, dns, mtu - - -server = section:taboption("general", Value, "server", translate("L2TP Server")) -server.datatype = "or(host(1), hostport(1))" - - -username = section:taboption("general", Value, "username", translate("PAP/CHAP username")) - - -password = section:taboption("general", Value, "password", translate("PAP/CHAP password")) -password.password = true - -if luci.model.network:has_ipv6() then - ipv6 = section:taboption("advanced", ListValue, "ipv6", - translate("Obtain IPv6-Address"), - translate("Enable IPv6 negotiation on the PPP link")) - ipv6:value("auto", translate("Automatic")) - ipv6:value("0", translate("Disabled")) - ipv6:value("1", translate("Manual")) - ipv6.default = "auto" -end - -defaultroute = section:taboption("advanced", Flag, "defaultroute", - translate("Use default gateway"), - translate("If unchecked, no default route is configured")) - -defaultroute.default = defaultroute.enabled - - -metric = section:taboption("advanced", Value, "metric", - translate("Use gateway metric")) - -metric.placeholder = "0" -metric.datatype = "uinteger" -metric:depends("defaultroute", defaultroute.enabled) - - -peerdns = section:taboption("advanced", Flag, "peerdns", - translate("Use DNS servers advertised by peer"), - translate("If unchecked, the advertised DNS server addresses are ignored")) - -peerdns.default = peerdns.enabled - - -dns = section:taboption("advanced", DynamicList, "dns", - translate("Use custom DNS servers")) - -dns:depends("peerdns", "") -dns.datatype = "ipaddr" -dns.cast = "string" - -mtu = section:taboption("advanced", Value, "mtu", translate("Override MTU")) -mtu.placeholder = "1500" -mtu.datatype = "max(9200)" diff --git a/protocols/luci-proto-ppp/luasrc/model/cbi/admin_network/proto_ppp.lua b/protocols/luci-proto-ppp/luasrc/model/cbi/admin_network/proto_ppp.lua deleted file mode 100644 index 5f468bc14c..0000000000 --- a/protocols/luci-proto-ppp/luasrc/model/cbi/admin_network/proto_ppp.lua +++ /dev/null @@ -1,127 +0,0 @@ --- Copyright 2011 Jo-Philipp Wich <jow@openwrt.org> --- Licensed to the public under the Apache License 2.0. - -local map, section, net = ... - -local device, username, password -local ipv6, defaultroute, metric, peerdns, dns, - keepalive_failure, keepalive_interval, demand, mtu - - -device = section:taboption("general", Value, "device", translate("Modem device")) -device.rmempty = false - -local device_suggestions = nixio.fs.glob("/dev/tty*S*") - or nixio.fs.glob("/dev/tts/*") - -if device_suggestions then - local node - for node in device_suggestions do - device:value(node) - end -end - - -username = section:taboption("general", Value, "username", translate("PAP/CHAP username")) - - -password = section:taboption("general", Value, "password", translate("PAP/CHAP password")) -password.password = true - - -if luci.model.network:has_ipv6() then - ipv6 = section:taboption("advanced", ListValue, "ipv6", - translate("Obtain IPv6-Address"), - translate("Enable IPv6 negotiation on the PPP link")) - ipv6:value("auto", translate("Automatic")) - ipv6:value("0", translate("Disabled")) - ipv6:value("1", translate("Manual")) - ipv6.default = "auto" -end - - -defaultroute = section:taboption("advanced", Flag, "defaultroute", - translate("Use default gateway"), - translate("If unchecked, no default route is configured")) - -defaultroute.default = defaultroute.enabled - - -metric = section:taboption("advanced", Value, "metric", - translate("Use gateway metric")) - -metric.placeholder = "0" -metric.datatype = "uinteger" -metric:depends("defaultroute", defaultroute.enabled) - - -peerdns = section:taboption("advanced", Flag, "peerdns", - translate("Use DNS servers advertised by peer"), - translate("If unchecked, the advertised DNS server addresses are ignored")) - -peerdns.default = peerdns.enabled - - -dns = section:taboption("advanced", DynamicList, "dns", - translate("Use custom DNS servers")) - -dns:depends("peerdns", "") -dns.datatype = "ipaddr" -dns.cast = "string" - - -keepalive_failure = section:taboption("advanced", Value, "_keepalive_failure", - translate("LCP echo failure threshold"), - translate("Presume peer to be dead after given amount of LCP echo failures, use 0 to ignore failures")) - -function keepalive_failure.cfgvalue(self, section) - local v = m:get(section, "keepalive") - if v and #v > 0 then - return tonumber(v:match("^(%d+)[ ,]+%d+") or v) - end -end - -keepalive_failure.placeholder = "0" -keepalive_failure.datatype = "uinteger" - - -keepalive_interval = section:taboption("advanced", Value, "_keepalive_interval", - translate("LCP echo interval"), - translate("Send LCP echo requests at the given interval in seconds, only effective in conjunction with failure threshold")) - -function keepalive_interval.cfgvalue(self, section) - local v = m:get(section, "keepalive") - if v and #v > 0 then - return tonumber(v:match("^%d+[ ,]+(%d+)")) - end -end - -function keepalive_interval.write(self, section, value) - local f = tonumber(keepalive_failure:formvalue(section)) or 0 - local i = tonumber(value) or 5 - if i < 1 then i = 1 end - if f > 0 then - m:set(section, "keepalive", "%d %d" %{ f, i }) - else - m:set(section, "keepalive", "0") - end -end - -keepalive_interval.remove = keepalive_interval.write -keepalive_failure.write = keepalive_interval.write -keepalive_failure.remove = keepalive_interval.write -keepalive_interval.placeholder = "5" -keepalive_interval.datatype = "min(1)" - - -demand = section:taboption("advanced", Value, "demand", - translate("Inactivity timeout"), - translate("Close inactive connection after the given amount of seconds, use 0 to persist connection")) - -demand.placeholder = "0" -demand.datatype = "uinteger" - - -mtu = section:taboption("advanced", Value, "mtu", translate("Override MTU")) -mtu.placeholder = "1500" -mtu.datatype = "max(9200)" diff --git a/protocols/luci-proto-ppp/luasrc/model/cbi/admin_network/proto_pppoa.lua b/protocols/luci-proto-ppp/luasrc/model/cbi/admin_network/proto_pppoa.lua deleted file mode 100644 index 004fd7ef67..0000000000 --- a/protocols/luci-proto-ppp/luasrc/model/cbi/admin_network/proto_pppoa.lua +++ /dev/null @@ -1,133 +0,0 @@ --- Copyright 2011 Jo-Philipp Wich <jow@openwrt.org> --- Licensed to the public under the Apache License 2.0. - -local map, section, net = ... - -local encaps, atmdev, vci, vpi, username, password -local ipv6, defaultroute, metric, peerdns, dns, - keepalive_failure, keepalive_interval, demand, mtu - - -encaps = section:taboption("general", ListValue, "encaps", translate("PPPoA Encapsulation")) -encaps:value("vc", "VC-Mux") -encaps:value("llc", "LLC") - - -atmdev = section:taboption("general", Value, "atmdev", translate("ATM device number")) -atmdev.default = "0" -atmdev.datatype = "uinteger" - - -vci = section:taboption("general", Value, "vci", translate("ATM Virtual Channel Identifier (VCI)")) -vci.default = "35" -vci.datatype = "uinteger" - - -vpi = section:taboption("general", Value, "vpi", translate("ATM Virtual Path Identifier (VPI)")) -vpi.default = "8" -vpi.datatype = "uinteger" - - -username = section:taboption("general", Value, "username", translate("PAP/CHAP username")) - - -password = section:taboption("general", Value, "password", translate("PAP/CHAP password")) -password.password = true - - -if luci.model.network:has_ipv6() then - ipv6 = section:taboption("advanced", ListValue, "ipv6", - translate("Obtain IPv6-Address"), - translate("Enable IPv6 negotiation on the PPP link")) - ipv6:value("auto", translate("Automatic")) - ipv6:value("0", translate("Disabled")) - ipv6:value("1", translate("Manual")) - ipv6.default = "auto" -end - - -defaultroute = section:taboption("advanced", Flag, "defaultroute", - translate("Use default gateway"), - translate("If unchecked, no default route is configured")) - -defaultroute.default = defaultroute.enabled - - -metric = section:taboption("advanced", Value, "metric", - translate("Use gateway metric")) - -metric.placeholder = "0" -metric.datatype = "uinteger" -metric:depends("defaultroute", defaultroute.enabled) - - -peerdns = section:taboption("advanced", Flag, "peerdns", - translate("Use DNS servers advertised by peer"), - translate("If unchecked, the advertised DNS server addresses are ignored")) - -peerdns.default = peerdns.enabled - - -dns = section:taboption("advanced", DynamicList, "dns", - translate("Use custom DNS servers")) - -dns:depends("peerdns", "") -dns.datatype = "ipaddr" -dns.cast = "string" - - -keepalive_failure = section:taboption("advanced", Value, "_keepalive_failure", - translate("LCP echo failure threshold"), - translate("Presume peer to be dead after given amount of LCP echo failures, use 0 to ignore failures")) - -function keepalive_failure.cfgvalue(self, section) - local v = m:get(section, "keepalive") - if v and #v > 0 then - return tonumber(v:match("^(%d+)[ ,]+%d+") or v) - end -end - -keepalive_failure.placeholder = "0" -keepalive_failure.datatype = "uinteger" - - -keepalive_interval = section:taboption("advanced", Value, "_keepalive_interval", - translate("LCP echo interval"), - translate("Send LCP echo requests at the given interval in seconds, only effective in conjunction with failure threshold")) - -function keepalive_interval.cfgvalue(self, section) - local v = m:get(section, "keepalive") - if v and #v > 0 then - return tonumber(v:match("^%d+[ ,]+(%d+)")) - end -end - -function keepalive_interval.write(self, section, value) - local f = tonumber(keepalive_failure:formvalue(section)) or 0 - local i = tonumber(value) or 5 - if i < 1 then i = 1 end - if f > 0 then - m:set(section, "keepalive", "%d %d" %{ f, i }) - else - m:set(section, "keepalive", "0") - end -end - -keepalive_interval.remove = keepalive_interval.write -keepalive_failure.write = keepalive_interval.write -keepalive_failure.remove = keepalive_interval.write -keepalive_interval.placeholder = "5" -keepalive_interval.datatype = "min(1)" - - -demand = section:taboption("advanced", Value, "demand", - translate("Inactivity timeout"), - translate("Close inactive connection after the given amount of seconds, use 0 to persist connection")) - -demand.placeholder = "0" -demand.datatype = "uinteger" - - -mtu = section:taboption("advanced", Value, "mtu", translate("Override MTU")) -mtu.placeholder = "1500" -mtu.datatype = "max(9200)" diff --git a/protocols/luci-proto-ppp/luasrc/model/cbi/admin_network/proto_pppoe.lua b/protocols/luci-proto-ppp/luasrc/model/cbi/admin_network/proto_pppoe.lua deleted file mode 100644 index 063d8c07eb..0000000000 --- a/protocols/luci-proto-ppp/luasrc/model/cbi/admin_network/proto_pppoe.lua +++ /dev/null @@ -1,135 +0,0 @@ --- Copyright 2011 Jo-Philipp Wich <jow@openwrt.org> --- Licensed to the public under the Apache License 2.0. - -local map, section, net = ... - -local username, password, ac, service -local ipv6, defaultroute, metric, peerdns, dns, - keepalive_failure, keepalive_interval, demand, mtu - - -username = section:taboption("general", Value, "username", translate("PAP/CHAP username")) - - -password = section:taboption("general", Value, "password", translate("PAP/CHAP password")) -password.password = true - - -ac = section:taboption("general", Value, "ac", - translate("Access Concentrator"), - translate("Leave empty to autodetect")) - -ac.placeholder = translate("auto") - - -service = section:taboption("general", Value, "service", - translate("Service Name"), - translate("Leave empty to autodetect")) - -service.placeholder = translate("auto") - - -if luci.model.network:has_ipv6() then - ipv6 = section:taboption("advanced", ListValue, "ipv6", - translate("Obtain IPv6-Address"), - translate("Enable IPv6 negotiation on the PPP link")) - ipv6:value("auto", translate("Automatic")) - ipv6:value("0", translate("Disabled")) - ipv6:value("1", translate("Manual")) - ipv6.default = "auto" -end - - -defaultroute = section:taboption("advanced", Flag, "defaultroute", - translate("Use default gateway"), - translate("If unchecked, no default route is configured")) - -defaultroute.default = defaultroute.enabled - - -metric = section:taboption("advanced", Value, "metric", - translate("Use gateway metric")) - -metric.placeholder = "0" -metric.datatype = "uinteger" -metric:depends("defaultroute", defaultroute.enabled) - - -peerdns = section:taboption("advanced", Flag, "peerdns", - translate("Use DNS servers advertised by peer"), - translate("If unchecked, the advertised DNS server addresses are ignored")) - -peerdns.default = peerdns.enabled - - -dns = section:taboption("advanced", DynamicList, "dns", - translate("Use custom DNS servers")) - -dns:depends("peerdns", "") -dns.datatype = "ipaddr" -dns.cast = "string" - - -keepalive_failure = section:taboption("advanced", Value, "_keepalive_failure", - translate("LCP echo failure threshold"), - translate("Presume peer to be dead after given amount of LCP echo failures, use 0 to ignore failures")) - -function keepalive_failure.cfgvalue(self, section) - local v = m:get(section, "keepalive") - if v and #v > 0 then - return tonumber(v:match("^(%d+)[ ,]+%d+") or v) - end -end - -keepalive_failure.placeholder = "0" -keepalive_failure.datatype = "uinteger" - - -keepalive_interval = section:taboption("advanced", Value, "_keepalive_interval", - translate("LCP echo interval"), - translate("Send LCP echo requests at the given interval in seconds, only effective in conjunction with failure threshold")) - -function keepalive_interval.cfgvalue(self, section) - local v = m:get(section, "keepalive") - if v and #v > 0 then - return tonumber(v:match("^%d+[ ,]+(%d+)")) - end -end - -function keepalive_interval.write(self, section, value) - local f = tonumber(keepalive_failure:formvalue(section)) or 0 - local i = tonumber(value) or 5 - if i < 1 then i = 1 end - if f > 0 then - m:set(section, "keepalive", "%d %d" %{ f, i }) - else - m:set(section, "keepalive", "0") - end -end - -keepalive_interval.remove = keepalive_interval.write -keepalive_failure.write = keepalive_interval.write -keepalive_failure.remove = keepalive_interval.write -keepalive_interval.placeholder = "5" -keepalive_interval.datatype = "min(1)" - - -host_uniq = section:taboption("advanced", Value, "host_uniq", - translate("Host-Uniq tag content"), - translate("Raw hex-encoded bytes. Leave empty unless your ISP require this")) - -host_uniq.placeholder = translate("auto") -host_uniq.datatype = "hexstring" - - -demand = section:taboption("advanced", Value, "demand", - translate("Inactivity timeout"), - translate("Close inactive connection after the given amount of seconds, use 0 to persist connection")) - -demand.placeholder = "0" -demand.datatype = "uinteger" - - -mtu = section:taboption("advanced", Value, "mtu", translate("Override MTU")) -mtu.placeholder = "1500" -mtu.datatype = "max(9200)" diff --git a/protocols/luci-proto-ppp/luasrc/model/cbi/admin_network/proto_pptp.lua b/protocols/luci-proto-ppp/luasrc/model/cbi/admin_network/proto_pptp.lua deleted file mode 100644 index 6a828efe96..0000000000 --- a/protocols/luci-proto-ppp/luasrc/model/cbi/admin_network/proto_pptp.lua +++ /dev/null @@ -1,106 +0,0 @@ --- Copyright 2011-2012 Jo-Philipp Wich <jow@openwrt.org> --- Licensed to the public under the Apache License 2.0. - -local map, section, net = ... - -local server, username, password -local defaultroute, metric, peerdns, dns, - keepalive_failure, keepalive_interval, demand, mtu - - -server = section:taboption("general", Value, "server", translate("VPN Server")) -server.datatype = "host(0)" - - -username = section:taboption("general", Value, "username", translate("PAP/CHAP username")) - - -password = section:taboption("general", Value, "password", translate("PAP/CHAP password")) -password.password = true - - -defaultroute = section:taboption("advanced", Flag, "defaultroute", - translate("Use default gateway"), - translate("If unchecked, no default route is configured")) - -defaultroute.default = defaultroute.enabled - - -metric = section:taboption("advanced", Value, "metric", - translate("Use gateway metric")) - -metric.placeholder = "0" -metric.datatype = "uinteger" -metric:depends("defaultroute", defaultroute.enabled) - - -peerdns = section:taboption("advanced", Flag, "peerdns", - translate("Use DNS servers advertised by peer"), - translate("If unchecked, the advertised DNS server addresses are ignored")) - -peerdns.default = peerdns.enabled - - -dns = section:taboption("advanced", DynamicList, "dns", - translate("Use custom DNS servers")) - -dns:depends("peerdns", "") -dns.datatype = "ipaddr" -dns.cast = "string" - - -keepalive_failure = section:taboption("advanced", Value, "_keepalive_failure", - translate("LCP echo failure threshold"), - translate("Presume peer to be dead after given amount of LCP echo failures, use 0 to ignore failures")) - -function keepalive_failure.cfgvalue(self, section) - local v = m:get(section, "keepalive") - if v and #v > 0 then - return tonumber(v:match("^(%d+)[ ,]+%d+") or v) - end -end - -keepalive_failure.placeholder = "0" -keepalive_failure.datatype = "uinteger" - - -keepalive_interval = section:taboption("advanced", Value, "_keepalive_interval", - translate("LCP echo interval"), - translate("Send LCP echo requests at the given interval in seconds, only effective in conjunction with failure threshold")) - -function keepalive_interval.cfgvalue(self, section) - local v = m:get(section, "keepalive") - if v and #v > 0 then - return tonumber(v:match("^%d+[ ,]+(%d+)")) - end -end - -function keepalive_interval.write(self, section, value) - local f = tonumber(keepalive_failure:formvalue(section)) or 0 - local i = tonumber(value) or 5 - if i < 1 then i = 1 end - if f > 0 then - m:set(section, "keepalive", "%d %d" %{ f, i }) - else - m:set(section, "keepalive", "0") - end -end - -keepalive_interval.remove = keepalive_interval.write -keepalive_failure.write = keepalive_interval.write -keepalive_failure.remove = keepalive_interval.write -keepalive_interval.placeholder = "5" -keepalive_interval.datatype = "min(1)" - - -demand = section:taboption("advanced", Value, "demand", - translate("Inactivity timeout"), - translate("Close inactive connection after the given amount of seconds, use 0 to persist connection")) - -demand.placeholder = "0" -demand.datatype = "uinteger" - - -mtu = section:taboption("advanced", Value, "mtu", translate("Override MTU")) -mtu.placeholder = "1500" -mtu.datatype = "max(9200)" diff --git a/protocols/luci-proto-pppossh/htdocs/luci-static/resources/protocol/pppossh.js b/protocols/luci-proto-pppossh/htdocs/luci-static/resources/protocol/pppossh.js new file mode 100644 index 0000000000..ec8e8a152e --- /dev/null +++ b/protocols/luci-proto-pppossh/htdocs/luci-static/resources/protocol/pppossh.js @@ -0,0 +1,142 @@ +'use strict'; +'require uci'; +'require form'; +'require network'; + +network.registerPatternVirtual(/^pppossh-.+$/); + +function write_keepalive(section_id, value) { + var f_opt = this.map.lookupOption('_keepalive_failure', section_id), + i_opt = this.map.lookupOption('_keepalive_interval', section_id), + f = (f_opt != null) ? +f_opt[0].formvalue(section_id) : null, + i = (i_opt != null) ? +i_opt[0].formvalue(section_id) : null; + + if (f == null || f == '' || isNaN(f)) + f = 0; + + if (i == null || i == '' || isNaN(i) || i < 1) + i = 1; + + if (f > 0) + uci.set('network', section_id, 'keepalive', '%d %d'.format(f, i)); + else + uci.unset('network', section_id, 'keepalive'); +} + +return network.registerProtocol('pppossh', { + getI18n: function() { + return _('PPPoSSH'); + }, + + getIfname: function() { + return this._ubus('l3_device') || 'pppossh-%s'.format(this.sid); + }, + + getOpkgPackage: function() { + return 'pppossh'; + }, + + isFloating: function() { + return true; + }, + + isVirtual: function() { + return true; + }, + + getDevices: function() { + return null; + }, + + containsDevice: function(ifname) { + return (network.getIfnameOf(ifname) == this.getIfname()); + }, + + renderFormOptions: function(s) { + var o; + + o = s.taboption('general', form.Value, 'sshuser', _('SSH username')); + o.rmempty = false; + o.validate = function(section_id, value) { + var id_opt = this.section.children.filter(function(o) { return o.option == 'identity' })[0]; + if (id_opt && value.length) { + var input = this.map.findElement('id', id_opt.cbid(section_id)).querySelector('input[type="text"]'); + if (input) + input.placeholder = (value == 'root' ? '/root' : '/home/' + value) + '/.ssh/id_rsa'; + } + return true; + }; + + o = s.taboption('general', form.Value, 'server', _('SSH server address')); + o.datatype = 'host(0)'; + o.rmempty = false; + + o = s.taboption('general', form.Value, 'port', _('SSH server port')); + o.datatype = 'port'; + o.optional = true; + o.placeholder = 22; + + o = s.taboption('general', form.Value, 'ssh_options', _('Extra SSH command options')); + o.optional = true; + + o = s.taboption('general', form.DynamicList, 'identity', _('List of SSH key files for auth')); + o.optional = true; + o.datatype = 'file'; + + o = s.taboption('general', form.Value, 'ipaddr', _('Local IP address to assign')); + o.datatype = 'ipaddr("nomask")'; + + o = s.taboption('general', form.Value, 'peeraddr', _('Peer IP address to assign')); + o.datatype = 'ipaddr("nomask")'; + + if (L.hasSystemFeature('ipv6')) { + o = s.taboption('advanced', form.Flag, 'ipv6', _('Obtain IPv6-Address'), _('Enable IPv6 negotiation on the PPP link')); + o.default = o.disabled; + } + + o = s.taboption('advanced', form.Flag, 'defaultroute', _('Use default gateway'), _('If unchecked, no default route is configured')); + o.default = o.enabled; + + o = s.taboption('advanced', form.Flag, 'peerdns', _('Use DNS servers advertised by peer'), _('If unchecked, the advertised DNS server addresses are ignored')); + o.default = o.enabled; + + o = s.taboption('advanced', form.DynamicList, 'dns', _('Use custom DNS servers')); + o.depends('peerdns', '0'); + o.datatype = 'ipaddr'; + o.cast = 'string'; + + o = s.taboption('advanced', form.Value, 'metric', _('Use gateway metric')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + + o = s.taboption('advanced', form.Value, '_keepalive_failure', _('LCP echo failure threshold'), _('Presume peer to be dead after given amount of LCP echo failures, use 0 to ignore failures')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + o.write = write_keepalive; + o.remove = write_keepalive; + o.cfgvalue = function(section_id) { + var v = uci.get('network', section_id, 'keepalive'); + if (typeof(v) == 'string' && v != '') { + var m = v.match(/^(\d+)[ ,]\d+$/); + return m ? m[1] : v; + } + }; + + o = s.taboption('advanced', form.Value, '_keepalive_interval', _('LCP echo interval'), _('Send LCP echo requests at the given interval in seconds, only effective in conjunction with failure threshold')); + o.placeholder = '5'; + o.datatype = 'min(1)'; + o.write = write_keepalive; + o.remove = write_keepalive; + o.cfgvalue = function(section_id) { + var v = uci.get('network', section_id, 'keepalive'); + if (typeof(v) == 'string' && v != '') { + var m = v.match(/^\d+[ ,](\d+)$/); + return m ? m[1] : v; + } + }; + + o = s.taboption('advanced', form.Value, 'demand', _('Inactivity timeout'), _('Close inactive connection after the given amount of seconds, use 0 to persist connection')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + } +}); diff --git a/protocols/luci-proto-pppossh/luasrc/model/cbi/admin_network/proto_pppossh.lua b/protocols/luci-proto-pppossh/luasrc/model/cbi/admin_network/proto_pppossh.lua deleted file mode 100644 index e53262b5dc..0000000000 --- a/protocols/luci-proto-pppossh/luasrc/model/cbi/admin_network/proto_pppossh.lua +++ /dev/null @@ -1,122 +0,0 @@ --- Copyright (C) 2015 Yousong Zhou <yszhou4tech@gmail.com> --- Licensed to the public under the Apache License 2.0. - -local map, section, net = ... - -local sshuser, server, port, ssh_options, identity, ipaddr, peeraddr - -sshuser = section:taboption("general", Value, "sshuser", translate("SSH username")) - -server = section:taboption("general", Value, "server", translate("SSH server address")) -server.datatype = "host(0)" - -port = section:taboption("general", Value, "port", translate("SSH server port")) -port.datatype = "port" -port.optional = true -port.default = 22 - -ssh_options = section:taboption("general", Value, "ssh_options", translate("Extra SSH command options")) -ssh_options.optional = true - -identity = section:taboption("general", DynamicList, "identity", translate("List of SSH key files for auth")) -identity.optional = true -identity.datatype = "file" - -ipaddr = section:taboption("general", Value, "ipaddr", translate("Local IP address to assign")) -ipaddr.datatype = "ipaddr" - -peeraddr = section:taboption("general", Value, "peeraddr", translate("Peer IP address to assign")) -peeraddr.datatype = "ipaddr" - - -local ipv6, defaultroute, metric, peerdns, dns, - keepalive_failure, keepalive_interval, demand - -if luci.model.network:has_ipv6() then - ipv6 = section:taboption("advanced", Flag, "ipv6", - translate("Enable IPv6 negotiation on the PPP link")) - ipv6.default = ipv6.disabled -end - - -defaultroute = section:taboption("advanced", Flag, "defaultroute", - translate("Use default gateway"), - translate("If unchecked, no default route is configured")) - -defaultroute.default = defaultroute.enabled - - -metric = section:taboption("advanced", Value, "metric", - translate("Use gateway metric")) - -metric.placeholder = "0" -metric.datatype = "uinteger" -metric:depends("defaultroute", defaultroute.enabled) - - -peerdns = section:taboption("advanced", Flag, "peerdns", - translate("Use DNS servers advertised by peer"), - translate("If unchecked, the advertised DNS server addresses are ignored")) - -peerdns.default = peerdns.enabled - - -dns = section:taboption("advanced", DynamicList, "dns", - translate("Use custom DNS servers")) - -dns:depends("peerdns", "") -dns.datatype = "ipaddr" -dns.cast = "string" - - -keepalive_failure = section:taboption("advanced", Value, "_keepalive_failure", - translate("LCP echo failure threshold"), - translate("Presume peer to be dead after given amount of LCP echo failures, use 0 to ignore failures")) - -function keepalive_failure.cfgvalue(self, section) - local v = m:get(section, "keepalive") - if v and #v > 0 then - return tonumber(v:match("^(%d+)[ ,]+%d+") or v) - end -end - -function keepalive_failure.write() end -function keepalive_failure.remove() end - -keepalive_failure.placeholder = "0" -keepalive_failure.datatype = "uinteger" - - -keepalive_interval = section:taboption("advanced", Value, "_keepalive_interval", - translate("LCP echo interval"), - translate("Send LCP echo requests at the given interval in seconds, only effective in conjunction with failure threshold")) - -function keepalive_interval.cfgvalue(self, section) - local v = m:get(section, "keepalive") - if v and #v > 0 then - return tonumber(v:match("^%d+[ ,]+(%d+)")) - end -end - -function keepalive_interval.write(self, section, value) - local f = tonumber(keepalive_failure:formvalue(section)) or 0 - local i = tonumber(value) or 5 - if i < 1 then i = 1 end - if f > 0 then - m:set(section, "keepalive", "%d %d" %{ f, i }) - else - m:set(section, "keepalive", "0") - end -end - -keepalive_interval.remove = keepalive_interval.write -keepalive_interval.placeholder = "5" -keepalive_interval.datatype = "min(1)" - - -demand = section:taboption("advanced", Value, "demand", - translate("Inactivity timeout"), - translate("Close inactive connection after the given amount of seconds, use 0 to persist connection")) - -demand.placeholder = "0" -demand.datatype = "uinteger" diff --git a/protocols/luci-proto-qmi/htdocs/luci-static/resources/protocol/qmi.js b/protocols/luci-proto-qmi/htdocs/luci-static/resources/protocol/qmi.js new file mode 100644 index 0000000000..eeda91f6e6 --- /dev/null +++ b/protocols/luci-proto-qmi/htdocs/luci-static/resources/protocol/qmi.js @@ -0,0 +1,101 @@ +'use strict'; +'require rpc'; +'require form'; +'require network'; + +var callFileList = rpc.declare({ + object: 'file', + method: 'list', + params: [ 'path' ], + expect: { entries: [] }, + filter: function(list, params) { + var rv = []; + for (var i = 0; i < list.length; i++) + if (list[i].name.match(/^cdc-wdm/)) + rv.push(params.path + list[i].name); + return rv.sort(); + } +}); + +network.registerPatternVirtual(/^qmi-.+$/); +network.registerErrorCode('CALL_FAILED', _('Call failed')); +network.registerErrorCode('NO_CID', _('Unable to obtain client ID')); +network.registerErrorCode('PLMN_FAILED', _('Setting PLMN failed')); + +return network.registerProtocol('qmi', { + getI18n: function() { + return _('QMI Cellular'); + }, + + getIfname: function() { + return this._ubus('l3_device') || 'qmi-%s'.format(this.sid); + }, + + getOpkgPackage: function() { + return 'uqmi'; + }, + + isFloating: function() { + return true; + }, + + isVirtual: function() { + return true; + }, + + getDevices: function() { + return null; + }, + + containsDevice: function(ifname) { + return (network.getIfnameOf(ifname) == this.getIfname()); + }, + + renderFormOptions: function(s) { + var dev = this.getL3Device() || this.getDevice(), o; + + o = s.taboption('general', form.Value, 'device', _('Modem device')); + o.rmempty = false; + o.load = function(section_id) { + return callFileList('/dev/').then(L.bind(function(devices) { + for (var i = 0; i < devices.length; i++) + this.value(devices[i]); + return form.Value.prototype.load.apply(this, [section_id]); + }, this)); + }; + + s.taboption('general', form.Value, 'apn', _('APN')); + s.taboption('general', form.Value, 'pincode', _('PIN')); + + o = s.taboption('general', form.ListValue, 'auth', _('Authentication Type')); + o.value('both', 'PAP/CHAP (both)'); + o.value('pap', 'PAP'); + o.value('chap', 'CHAP'); + o.value('none', 'NONE'); + o.default = 'none'; + + o = s.taboption('general', form.Value, 'username', _('PAP/CHAP username')); + o.depends('auth', 'pap'); + o.depends('auth', 'chap'); + o.depends('auth', 'both'); + + o = s.taboption('general', form.Value, 'password', _('PAP/CHAP password')); + o.depends('auth', 'pap'); + o.depends('auth', 'chap'); + o.depends('auth', 'both'); + o.password = true; + + if (L.hasSystemFeature('ipv6')) { + o = s.taboption('advanced', form.Flag, 'ipv6', _('Enable IPv6 negotiation')); + o.default = o.disabled; + } + + o = s.taboption('advanced', form.Value, 'delay', _('Modem init timeout'), _('Maximum amount of seconds to wait for the modem to become ready')); + o.placeholder = '10'; + o.datatype = 'min(1)'; + + o = s.taboption('advanced', form.Value, 'mtu', _('Override MTU')); + o.placeholder = dev ? (dev.getMTU() || '1500') : '1500'; + o.datatype = 'max(9200)'; + } +}); diff --git a/protocols/luci-proto-qmi/luasrc/model/cbi/admin_network/proto_qmi.lua b/protocols/luci-proto-qmi/luasrc/model/cbi/admin_network/proto_qmi.lua deleted file mode 100644 index 383bc4662f..0000000000 --- a/protocols/luci-proto-qmi/luasrc/model/cbi/admin_network/proto_qmi.lua +++ /dev/null @@ -1,63 +0,0 @@ --- Copyright 2016 David Thornley <david.thornley@touchstargroup.com> --- Licensed to the public under the Apache License 2.0. - -local map, section, net = ... - -local device, apn, pincode, username, password -local auth, ipv6, delay, mtu - - -device = section:taboption("general", Value, "device", translate("Modem device")) -device.rmempty = false - -local device_suggestions = nixio.fs.glob("/dev/cdc-wdm*") - -if device_suggestions then - local node - for node in device_suggestions do - device:value(node) - end -end - - -apn = section:taboption("general", Value, "apn", translate("APN")) - - -pincode = section:taboption("general", Value, "pincode", translate("PIN")) - - -auth = section:taboption("general", Value, "auth", translate("Authentication Type")) -auth:value("both", "PAP/CHAP (both)") -auth:value("pap", "PAP") -auth:value("chap", "CHAP") -auth:value("none", "NONE") -auth.default = "none" - - -username = section:taboption("general", Value, "username", translate("PAP/CHAP username")) -username:depends("auth", "pap") -username:depends("auth", "chap") -username:depends("auth", "both") - - -password = section:taboption("general", Value, "password", translate("PAP/CHAP password")) -password:depends("auth", "pap") -password:depends("auth", "chap") -password:depends("auth", "both") -password.password = true - - -if luci.model.network:has_ipv6() then - ipv6 = section:taboption("advanced", Flag, "ipv6", translate("Enable IPv6 negotiation")) - ipv6.default = ipv6.disabled -end - -delay = section:taboption("advanced", Value, "delay", - translate("Modem init timeout"), - translate("Maximum amount of seconds to wait for the modem to become ready")) -delay.placeholder = "10" -delay.datatype = "min(1)" - -mtu = section:taboption("advanced", Value, "mtu", translate("Override MTU")) -mtu.placeholder = "1500" -mtu.datatype = "max(9200)" diff --git a/protocols/luci-proto-relay/htdocs/luci-static/resources/protocol/relay.js b/protocols/luci-proto-relay/htdocs/luci-static/resources/protocol/relay.js new file mode 100644 index 0000000000..b3082276b1 --- /dev/null +++ b/protocols/luci-proto-relay/htdocs/luci-static/resources/protocol/relay.js @@ -0,0 +1,183 @@ +'use strict'; +'require uci'; +'require form'; +'require network'; +'require tools.widgets as widgets'; + +network.registerPatternVirtual(/^relay-.+$/); + +var RelayDevicePrototype = { + __init__: function(ifname, network) { + this.ifname = ifname; + this.network = network; + }, + + _aggregateDevices: function(fn, first) { + var devices = this.network ? this.network.getDevices() : [], + rv = 0; + + for (var i = 0; i < devices.length; i++) { + var v = devices[i][fn].apply(devices[i]); + + if (v != null) { + if (first) + return v; + + rv += v; + } + } + + return first ? null : [ rv, devices.length ]; + }, + + getPorts: function() { return this.network ? this.network.getDevices() : [] }, + + getType: function() { return 'tunnel' }, + getTypeI18n: function() { return _('Relay Bridge') }, + + getShortName: function() { + return '%s "%h"'.format(_('Relay'), this.ifname); + }, + + isUp: function() { + var res = this._aggregateDevices('isUp'); + return (res[1] > 0 && res[0] == res[1]); + }, + + getTXBytes: function() { return this._aggregateDevices('getTXBytes')[0] }, + getRXBytes: function() { return this._aggregateDevices('getRXBytes')[0] }, + getTXPackets: function() { return this._aggregateDevices('getTXPackets')[0] }, + getRXPackets: function() { return this._aggregateDevices('getRXPackets')[0] }, + + getMAC: function() { return this._aggregateDevices('getMAC', true) }, + + getIPAddrs: function() { + var ipaddr = this.network ? L.toArray(uci.get('network', this.network.getName(), 'ipaddr'))[0] : null; + return (ipaddr != null ? [ ipaddr ] : []); + }, + + getIP6Addrs: function() { return [] } +}; + +return network.registerProtocol('relay', { + getI18n: function() { + return _('Relay bridge'); + }, + + getIfname: function() { + return 'relay-%s'.format(this.sid); + }, + + getOpkgPackage: function() { + return 'relayd'; + }, + + isFloating: function() { + return true; + }, + + isVirtual: function() { + return true; + }, + + containsDevice: function(ifname) { + return (network.getIfnameOf(ifname) == this.getIfname()); + }, + + isUp: function() { + var dev = this.getDevice(); + return (dev ? dev.isUp() : false); + }, + + getDevice: function() { + return network.instantiateDevice(this.sid, this, RelayDevicePrototype); + }, + + getDevices: function() { + if (this.devices) + return this.devices; + + var networkNames = L.toArray(uci.get('network', this.sid, 'network')), + deviceNames = L.toArray(uci.get('network', this.sid, 'ifname')), + devices = {}, + rv = []; + + for (var i = 0; i < networkNames.length; i++) { + var net = network.instantiateNetwork(networkNames[i]), + dev = net ? net.getDevice() : null; + + if (dev) + devices[dev.getName()] = dev; + } + + for (var i = 0; i < deviceNames.length; i++) { + var dev = network.getDevice(deviceNames[i]); + + if (dev) + devices[dev.getName()] = dev; + } + + deviceNames = Object.keys(devices); + deviceNames.sort(); + + for (var i = 0; i < deviceNames.length; i++) + rv.push(devices[deviceNames[i]]); + + this.devices = rv; + + return rv; + }, + + getUptime: function() { + var networkNames = L.toArray(uci.get('network', this.sid, 'network')), + uptime = 0; + + for (var i = 0; i < networkNames.length; i++) { + var net = network.instantiateNetwork(networkNames[i]); + if (net) + uptime = Math.max(uptime, net.getUptime()); + } + + return uptime; + }, + + getErrors: function() { + return null; + }, + + renderFormOptions: function(s) { + var o; + + o = s.taboption('general', form.Value, 'ipaddr', _('Local IPv4 address'), _('Address to access local relay bridge')); + o.datatype = 'ip4addr("nomask")'; + + o = s.taboption('general', widgets.NetworkSelect, 'network', _('Relay between networks')); + o.exclude = s.section; + o.multiple = true; + o.nocreate = true; + o.nobridges = true; + o.novirtual = true; + + o = s.taboption('advanced', form.Flag, 'forward_bcast', _('Forward broadcast traffic')); + o.default = o.enabled; + + o = s.taboption('advanced', form.Flag, 'forward_dhcp', _('Forward DHCP traffic')); + o.default = o.enabled; + + o = s.taboption('advanced', form.Value, 'gateway', _('Use DHCP gateway'), _('Override the gateway in DHCP responses')); + o.datatype = 'ip4addr("nomask")'; + o.depends('forward_dhcp', '1'); + + o = s.taboption('advanced', form.Value, 'expiry', _('Host expiry timeout'), _('Specifies the maximum amount of seconds after which hosts are presumed to be dead')); + o.placeholder = '30'; + o.datatype = 'min(1)'; + + o = s.taboption('advanced', form.Value, 'retry', _('ARP retry threshold'), _('Specifies the maximum amount of failed ARP requests until hosts are presumed to be dead')); + o.placeholder = '5'; + o.datatype = 'min(1)'; + + o = s.taboption('advanced', form.Value, 'table', _('Use routing table'), _('Override the table used for internal routes')); + o.placeholder = '16800'; + o.datatype = 'range(0,65535)'; + } +}); diff --git a/protocols/luci-proto-relay/luasrc/model/cbi/admin_network/proto_relay.lua b/protocols/luci-proto-relay/luasrc/model/cbi/admin_network/proto_relay.lua deleted file mode 100644 index 3381d85e47..0000000000 --- a/protocols/luci-proto-relay/luasrc/model/cbi/admin_network/proto_relay.lua +++ /dev/null @@ -1,68 +0,0 @@ --- Copyright 2011 Jo-Philipp Wich <jow@openwrt.org> --- Licensed to the public under the Apache License 2.0. - -local map, section, net = ... - -local ipaddr, network -local forward_bcast, forward_dhcp, gateway, expiry, retry, table - - -ipaddr = section:taboption("general", Value, "ipaddr", - translate("Local IPv4 address"), - translate("Address to access local relay bridge")) - -ipaddr.datatype = "ip4addr" - - -network = s:taboption("general", DynamicList, "network", translate("Relay between networks")) -network.widget = "checkbox" -network.exclude = arg[1] -network.template = "cbi/network_netlist" -network.nocreate = true -network.nobridges = true -network.novirtual = true -network:depends("proto", "relay") - - -forward_bcast = section:taboption("advanced", Flag, "forward_bcast", - translate("Forward broadcast traffic")) - -forward_bcast.default = forward_bcast.enabled - - -forward_dhcp = section:taboption("advanced", Flag, "forward_dhcp", - translate("Forward DHCP traffic")) - -forward_dhcp.default = forward_dhcp.enabled - - -gateway = section:taboption("advanced", Value, "gateway", - translate("Use DHCP gateway"), - translate("Override the gateway in DHCP responses")) - -gateway.datatype = "ip4addr" -gateway:depends("forward_dhcp", forward_dhcp.enabled) - - -expiry = section:taboption("advanced", Value, "expiry", - translate("Host expiry timeout"), - translate("Specifies the maximum amount of seconds after which hosts are presumed to be dead")) - -expiry.placeholder = "30" -expiry.datatype = "min(1)" - - -retry = section:taboption("advanced", Value, "retry", - translate("ARP retry threshold"), - translate("Specifies the maximum amount of failed ARP requests until hosts are presumed to be dead")) - -retry.placeholder = "5" -retry.datatype = "min(1)" - - -table = section:taboption("advanced", Value, "table", - translate("Use routing table"), - translate("Override the table used for internal routes")) - -table.placeholder = "16800" -table.datatype = "range(0,65535)" diff --git a/protocols/luci-proto-vpnc/htdocs/luci-static/resources/protocol/vpnc.js b/protocols/luci-proto-vpnc/htdocs/luci-static/resources/protocol/vpnc.js new file mode 100644 index 0000000000..87ccc9df1c --- /dev/null +++ b/protocols/luci-proto-vpnc/htdocs/luci-static/resources/protocol/vpnc.js @@ -0,0 +1,111 @@ +'use strict'; +'require form'; +'require network'; + +network.registerPatternVirtual(/^vpn-.+$/); + +return network.registerProtocol('vpnc', { + getI18n: function() { + return _('VPNC (CISCO 3000 (and others) VPN)'); + }, + + getIfname: function() { + return this._ubus('l3_device') || 'vpn-%s'.format(this.sid); + }, + + getOpkgPackage: function() { + return 'vpnc'; + }, + + isFloating: function() { + return true; + }, + + isVirtual: function() { + return true; + }, + + getDevices: function() { + return null; + }, + + containsDevice: function(ifname) { + return (network.getIfnameOf(ifname) == this.getIfname()); + }, + + renderFormOptions: function(s) { + var o; + + o = s.taboption('general', form.Value, 'server', _('VPN Server')); + o.datatype = 'host(0)'; + + o = s.taboption('general', form.Value, 'local_addr', _('VPN Local address')); + o.placeholder = '0.0.0.0'; + o.datatype = 'ipaddr'; + + o = s.taboption('general', form.Value, 'local_port', _('VPN Local port')); + o.placeholder = '500'; + o.datatype = 'port'; + + o = s.taboption('general', form.Value, 'interface', _('Output Interface')); + o.template = 'cbi/network_netlist'; + + o = s.taboption('general', form.Value, 'mtu', _('MTU')); + o.datatype = 'uinteger'; + + s.taboption('general', form.Value, 'username', _('Username')); + + o = s.taboption('general', form.Value, 'password', _('Password')); + o.password = true; + + o = s.taboption('general', form.Value, 'hexpassword', _('Obfuscated Password')); + o.password = true; + + s.taboption('general', form.Value, 'authgroup', _('Auth Group')); + + o = s.taboption('general', form.Value, 'passgroup', _('Group Password')); + o.password = true; + + o = s.taboption('general', form.Value, 'hexpassgroup', _('Obfuscated Group Password')); + o.password= true; + + s.taboption('general', form.Value, 'domain', _('NT Domain')); + s.taboption('general', form.Value, 'vendor', _('Vendor')); + + o = s.taboption('general', form.ListValue, 'dh_group', _('IKE DH Group')); + o.value('dh2'); + o.value('dh1'); + o.value('dh5'); + + o = s.taboption('general', form.ListValue, 'pfs', _('Perfect Forward Secrecy')); + o.value('server'); + o.value('nopfs'); + o.value('dh1'); + o.value('dh2'); + o.value('dh5'); + + o = s.taboption('general', form.ListValue, 'natt_mode', _('NAT-T Mode')); + o.value('natt', _('RFC3947 NAT-T mode')); + o.value('none', _('No NAT-T')); + o.value('force-natt', _('Force use of NAT-T')); + o.value('cisco-udp', _('Cisco UDP encapsulation')); + + o = s.taboption('general', form.Flag, 'enable_no_enc', _('Disable Encryption'), _('If checked, encryption is disabled')); + o.default = o.disabled; + + o = s.taboption('general', form.Flag, 'enable_single_des', _('Enable Single DES'), _('If checked, 1DES is enabled')); + o.default = o.disabled; + + o = s.taboption('general', form.Value, 'dpd_idle', _('DPD Idle Timeout')); + o.datatype = 'uinteger'; + o.placeholder = '600'; + + o = s.taboption('general', form.Value, 'target_network', _('Target network')); + o.placeholder = '0.0.0.0/0'; + o.datatype = 'network'; + + o = s.taboption('general', form.ListValue, 'defaultroute', _('Default Route'), _('Set VPN as Default Route')); + o.value('0', _('No')); + o.value('1', _('Yes')); + } +}); diff --git a/protocols/luci-proto-vpnc/luasrc/model/cbi/admin_network/proto_vpnc.lua b/protocols/luci-proto-vpnc/luasrc/model/cbi/admin_network/proto_vpnc.lua deleted file mode 100644 index 3d85d02f40..0000000000 --- a/protocols/luci-proto-vpnc/luasrc/model/cbi/admin_network/proto_vpnc.lua +++ /dev/null @@ -1,85 +0,0 @@ --- Copyright 2015 Daniel Dickinson <openwrt@daniel.thecshore.com> --- Licensed to the public under the Apache License 2.0. - -local map, section, net = ... - -local server, username, password, hexpassword -local authgroup, interface, passgroup, hexpassgroup -local domain, vendor, natt_mode, dh_group -local pfs, enable_single_des, enable_no_enc -local mtu, local_addr, local_port, dpd_idle -local auth_mode, target_network, defaultroute - -local ifc = net:get_interface():name() - -server = section:taboption("general", Value, "server", translate("VPN Server")) -server.datatype = "host(0)" - -port = section:taboption("general", Value, "local_addr", translate("VPN Local address")) -port.placeholder = "0.0.0.0" -port.datatype = "ipaddr" - -port = section:taboption("general", Value, "local_port", translate("VPN Local port")) -port.placeholder = "500" -port.datatype = "port" - -ifname = section:taboption("general", Value, "interface", translate("Output Interface")) -ifname.template = "cbi/network_netlist" - -mtu = section:taboption("general", Value, "mtu", translate("MTU")) -mtu.datatype = "uinteger" - -username = section:taboption("general", Value, "username", translate("Username")) -password = section:taboption("general", Value, "password", translate("Password")) -password.password = true -hexpassword = section:taboption("general", Value, "hexpassword", translate("Obfuscated Password")) -hexpassword.password = true -authroup = section:taboption("general", Value, "authgroup", translate("Auth Group")) -passgroup = section:taboption("general", Value, "passgroup", translate("Group Password")) -passgroup.password = true -hexpassgroup = section:taboption("general", Value, "hexpassgroup", translate("Obfuscated Group Password")) -hexpassword.password= true - -domain = section:taboption("general", Value, "domain", translate("NT Domain")) -vendor = section:taboption("general", Value, "vendor", translate("Vendor")) -dh_group = section:taboption("general", ListValue, "dh_group", translate("IKE DH Group")) -dh_group:value("dh2") -dh_group:value("dh1") -dh_group:value("dh5") - -pfs = section:taboption("general", ListValue, "pfs", translate("Perfect Forward Secrecy")) -pfs:value("server") -pfs:value("nopfs") -pfs:value("dh1") -pfs:value("dh2") -pfs:value("dh5") - -natt_mode = section:taboption("general", ListValue, "natt_mode", translate("NAT-T Mode")) -natt_mode:value("natt", translate("RFC3947 NAT-T mode")) -natt_mode:value("none", translate("No NAT-T")) -natt_mode:value("force-natt", translate("Force use of NAT-T")) -natt_mode:value("cisco-udp", translate("Cisco UDP encapsulation")) - -enable_no_enc = section:taboption("general", Flag, "enable_no_enc", - translate("Disable Encryption"), - translate("If checked, encryption is disabled")) -enable_no_enc.default = enable_no_enc.disabled - -enable_single_des = section:taboption("general", Flag, "enable_single_des", - translate("Enable Single DES"), - translate("If checked, 1DES is enabled")) -enable_no_enc.default = enable_single_des.disabled - -dpd_idle = section:taboption("general", Value, "dpd_idle", translate("DPD Idle Timeout")) -dpd_idle.datatype = "uinteger" -dpd_idle.placeholder = "600" - -ifname = section:taboption("general", Value, "target_network", translate("Target network")) -port.placeholder = "0.0.0.0/0" -port.datatype = "network" - -defaultroute = section:taboption("general", ListValue, "defaultroute", - translate("Default Route"), - translate("Set VPN as Default Route")) -defaultroute:value("0", translate("No")) -defaultroute:value("1", translate("Yes")) diff --git a/protocols/luci-proto-wireguard/htdocs/luci-static/resources/protocol/wireguard.js b/protocols/luci-proto-wireguard/htdocs/luci-static/resources/protocol/wireguard.js new file mode 100644 index 0000000000..ab76326eee --- /dev/null +++ b/protocols/luci-proto-wireguard/htdocs/luci-static/resources/protocol/wireguard.js @@ -0,0 +1,140 @@ +'use strict'; +'require form'; +'require network'; + +function validateBase64(section_id, value) { + if (value.length == 0) + return true; + + if (value.length != 44 || !value.match(/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/)) + return _('Invalid Base64 key string'); + + return true; +} + +return network.registerProtocol('wireguard', { + getI18n: function() { + return _('WireGuard VPN'); + }, + + getIfname: function() { + return this._ubus('l3_device') || this.sid; + }, + + getOpkgPackage: function() { + return 'wireguard-tools'; + }, + + isFloating: function() { + return true; + }, + + isVirtual: function() { + return true; + }, + + getDevices: function() { + return null; + }, + + containsDevice: function(ifname) { + return (network.getIfnameOf(ifname) == this.getIfname()); + }, + + renderFormOptions: function(s) { + var o, ss; + + // -- general --------------------------------------------------------------------- + + o = s.taboption('general', form.Value, 'private_key', _('Private Key'), _('Required. Base64-encoded private key for this interface.')); + o.password = true; + o.validate = validateBase64; + o.rmempty = false; + + o = s.taboption('general', form.Value, 'listen_port', _('Listen Port'), _('Optional. UDP port used for outgoing and incoming packets.')); + o.datatype = 'port'; + o.placeholder = _('random'); + o.optional = true; + + o = s.taboption('general', form.DynamicList, 'addresses', _('IP Addresses'), _('Recommended. IP addresses of the WireGuard interface.')); + o.datatype = 'ipaddr'; + o.optional = true; + + + // -- advanced -------------------------------------------------------------------- + + o = s.taboption('advanced', form.Value, 'metric', _('Metric'), _('Optional')); + o.datatype = 'uinteger'; + o.placeholder = '0'; + o.optional = true; + + o = s.taboption('advanced', form.Value, 'mtu', _('MTU'), _('Optional. Maximum Transmission Unit of tunnel interface.')); + o.datatype = 'range(1280,1420)'; + o.placeholder = '1420'; + o.optional = true; + + o = s.taboption('advanced', form.Value, 'fwmark', _('Firewall Mark'), _('Optional. 32-bit mark for outgoing encrypted packets. Enter value in hex, starting with <code>0x</code>.')); + o.optional = true; + o.validate = function(section_id, value) { + if (value.length > 0 && !value.match(/^0x[a-fA-F0-9]{1,4}$/)) + return _('Invalid hexadecimal value'); + + return true; + }; + + + // -- peers ----------------------------------------------------------------------- + + try { + s.tab('peers', _('Peers'), _('Further information about WireGuard interfaces and peers at <a href=\'http://wireguard.com\'>wireguard.com</a>.')); + } + catch(e) {} + + o = s.taboption('peers', form.SectionValue, '_peers', form.TypedSection, 'wireguard_%s'.format(s.section)); + o.depends('proto', 'wireguard'); + + ss = o.subsection; + ss.anonymous = true; + ss.addremove = true; + ss.addbtntitle = _('Add peer'); + + ss.renderSectionPlaceholder = function() { + return E([], [ + E('br'), + E('em', _('No peers defined yet')) + ]); + }; + + o = ss.option(form.Value, 'description', _('Description'), _('Optional. Description of peer.')); + o.placeholder = 'My Peer'; + o.datatype = 'string'; + o.optional = true; + + o = ss.option(form.Value, 'public_key', _('Public Key'), _('Required. Base64-encoded public key of peer.')); + o.validate = validateBase64; + o.rmempty = false; + + o = ss.option(form.Value, 'preshared_key', _('Preshared Key'), _('Optional. Base64-encoded preshared key. Adds in an additional layer of symmetric-key cryptography for post-quantum resistance.')); + o.password = true; + o.validate = validateBase64; + o.optional = true; + + o = ss.option(form.DynamicList, 'allowed_ips', _('Allowed IPs'), _("Required. IP addresses and prefixes that this peer is allowed to use inside the tunnel. Usually the peer's tunnel IP addresses and the networks the peer routes through the tunnel.")); + o.datatype = 'ipaddr'; + o.rmempty = false; + + o = ss.option(form.Flag, 'route_allowed_ips', _('Route Allowed IPs'), _('Optional. Create routes for Allowed IPs for this peer.')); + + o = ss.option(form.Value, 'endpoint_host', _('Endpoint Host'), _('Optional. Host of peer. Names are resolved prior to bringing up the interface.')); + o.placeholder = 'vpn.example.com'; + o.datatype = 'host'; + + o = ss.option(form.Value, 'endpoint_port', _('Endpoint Port'), _('Optional. Port of peer.')); + o.placeholder = '51820'; + o.datatype = 'port'; + + o = ss.option(form.Value, 'persistent_keepalive', _('Persistent Keep Alive'), _('Optional. Seconds between keep alive messages. Default is 0 (disabled). Recommended value if this device is behind a NAT is 25.')); + o.datatype = 'range(0,65535)'; + o.placeholder = '0'; + } +}); diff --git a/protocols/luci-proto-wireguard/luasrc/model/cbi/admin_network/proto_wireguard.lua b/protocols/luci-proto-wireguard/luasrc/model/cbi/admin_network/proto_wireguard.lua deleted file mode 100644 index 64e256a517..0000000000 --- a/protocols/luci-proto-wireguard/luasrc/model/cbi/admin_network/proto_wireguard.lua +++ /dev/null @@ -1,179 +0,0 @@ --- Copyright 2016-2017 Dan Luedtke <mail@danrl.com> --- Licensed to the public under the Apache License 2.0. - - -local map, section, net = ... -local ifname = net:get_interface():name() -local private_key, listen_port -local metric, mtu, preshared_key, description -local peers, public_key, allowed_ips, endpoint, persistent_keepalive - - --- general --------------------------------------------------------------------- - -private_key = section:taboption( - "general", - Value, - "private_key", - translate("Private Key"), - translate("Required. Base64-encoded private key for this interface.") -) -private_key.password = true -private_key.datatype = "and(base64,rangelength(44,44))" -private_key.optional = false - - -listen_port = section:taboption( - "general", - Value, - "listen_port", - translate("Listen Port"), - translate("Optional. UDP port used for outgoing and incoming packets.") -) -listen_port.datatype = "port" -listen_port.placeholder = translate("random") -listen_port.optional = true - -addresses = section:taboption( - "general", - DynamicList, - "addresses", - translate("IP Addresses"), - translate("Recommended. IP addresses of the WireGuard interface.") -) -addresses.datatype = "ipaddr" -addresses.optional = true - - --- advanced -------------------------------------------------------------------- - -metric = section:taboption( - "advanced", - Value, - "metric", - translate("Metric"), - translate("Optional") -) -metric.datatype = "uinteger" -metric.placeholder = "0" -metric.optional = true - - -mtu = section:taboption( - "advanced", - Value, - "mtu", - translate("MTU"), - translate("Optional. Maximum Transmission Unit of tunnel interface.") -) -mtu.datatype = "range(1280,1420)" -mtu.placeholder = "1420" -mtu.optional = true - -fwmark = section:taboption( - "advanced", - Value, - "fwmark", - translate("Firewall Mark"), - translate("Optional. 32-bit mark for outgoing encrypted packets. " .. - "Enter value in hex, starting with <code>0x</code>.") -) -fwmark.datatype = "hex(4)" -fwmark.optional = true - - --- peers ----------------------------------------------------------------------- - -peers = map:section( - TypedSection, - "wireguard_" .. ifname, - translate("Peers"), - translate("Further information about WireGuard interfaces and peers " .. - "at <a href=\"http://wireguard.com\">wireguard.com</a>.") -) -peers.template = "cbi/tsection" -peers.anonymous = true -peers.addremove = true - - -description = peers:option( - Value, - "description", - translate("Description"), - translate("Optional. Description of peer.")) -description.placeholder = "My Peer" -description.datatype = "string" -description.optional = true - - -public_key = peers:option( - Value, - "public_key", - translate("Public Key"), - translate("Required. Base64-encoded public key of peer.") -) -public_key.datatype = "and(base64,rangelength(44,44))" -public_key.optional = false - - -preshared_key = peers:option( - Value, - "preshared_key", - translate("Preshared Key"), - translate("Optional. Base64-encoded preshared key. " .. - "Adds in an additional layer of symmetric-key " .. - "cryptography for post-quantum resistance.") -) -preshared_key.password = true -preshared_key.datatype = "and(base64,rangelength(44,44))" -preshared_key.optional = true - - -allowed_ips = peers:option( - DynamicList, - "allowed_ips", - translate("Allowed IPs"), - translate("Required. IP addresses and prefixes that this peer is allowed " .. - "to use inside the tunnel. Usually the peer's tunnel IP " .. - "addresses and the networks the peer routes through the tunnel.") -) -allowed_ips.datatype = "ipaddr" -allowed_ips.optional = false - - -route_allowed_ips = peers:option( - Flag, - "route_allowed_ips", - translate("Route Allowed IPs"), - translate("Optional. Create routes for Allowed IPs for this peer.") -) - - -endpoint_host = peers:option( - Value, - "endpoint_host", - translate("Endpoint Host"), - translate("Optional. Host of peer. Names are resolved " .. - "prior to bringing up the interface.")) -endpoint_host.placeholder = "vpn.example.com" -endpoint_host.datatype = "host" - - -endpoint_port = peers:option( - Value, - "endpoint_port", - translate("Endpoint Port"), - translate("Optional. Port of peer.")) -endpoint_port.placeholder = "51820" -endpoint_port.datatype = "port" - - -persistent_keepalive = peers:option( - Value, - "persistent_keepalive", - translate("Persistent Keep Alive"), - translate("Optional. Seconds between keep alive messages. " .. - "Default is 0 (disabled). Recommended value if " .. - "this device is behind a NAT is 25.")) -persistent_keepalive.datatype = "range(0,65535)" -persistent_keepalive.placeholder = "0" |