From e6523658e2e2aa60d85b88cd4634bb2917d030cc Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Sat, 1 Feb 2014 18:35:42 +0000 Subject: [PATCH] luci2: add network protocol support extensions --- luci2/htdocs/luci2/proto/6in4.js | 89 +++++++++++++++++++++++++++++ luci2/htdocs/luci2/proto/6rd.js | 63 +++++++++++++++++++++ luci2/htdocs/luci2/proto/6to4.js | 35 ++++++++++++ luci2/htdocs/luci2/proto/dhcp.js | 60 ++++++++++++++++++++ luci2/htdocs/luci2/proto/dhcpv6.js | 59 +++++++++++++++++++ luci2/htdocs/luci2/proto/dslite.js | 46 +++++++++++++++ luci2/htdocs/luci2/proto/none.js | 6 ++ luci2/htdocs/luci2/proto/static.js | 113 +++++++++++++++++++++++++++++++++++++ 8 files changed, 471 insertions(+) create mode 100644 luci2/htdocs/luci2/proto/6in4.js create mode 100644 luci2/htdocs/luci2/proto/6rd.js create mode 100644 luci2/htdocs/luci2/proto/6to4.js create mode 100644 luci2/htdocs/luci2/proto/dhcp.js create mode 100644 luci2/htdocs/luci2/proto/dhcpv6.js create mode 100644 luci2/htdocs/luci2/proto/dslite.js create mode 100644 luci2/htdocs/luci2/proto/none.js create mode 100644 luci2/htdocs/luci2/proto/static.js diff --git a/luci2/htdocs/luci2/proto/6in4.js b/luci2/htdocs/luci2/proto/6in4.js new file mode 100644 index 0000000..4e5d24f --- /dev/null +++ b/luci2/htdocs/luci2/proto/6in4.js @@ -0,0 +1,89 @@ +L.NetworkModel.Protocol.extend({ + protocol: '6in4', + description: L.tr('IPv6-in-IPv4 (RFC4213)'), + tunnel: true, + virtual: true, + + populateForm: function(section, iface) + { + var wan = L.NetworkModel.findWAN(); + + section.taboption('general', L.cbi.InputValue, 'ipaddr', { + caption: L.tr('Local IPv4 address'), + description: L.tr('Leave empty to use the current WAN address'), + datatype: 'ip4addr', + placeholder: wan ? wan.getIPv4Addrs()[0] : undefined, + optional: true + }); + + section.taboption('general', L.cbi.InputValue, 'peeraddr', { + caption: L.tr('Remote IPv4 address'), + description: L.tr('This is usually the address of the nearest PoP optional by the tunnel broker'), + datatype: 'ip4addr', + optional: false + }); + + section.taboption('general', L.cbi.InputValue, 'ip6addr', { + caption: L.tr('Local IPv6 address'), + description: L.tr('This is the local endpoint address assigned by the tunnel broker, it usually ends with :2'), + datatype: 'ip6addr', + optional: false + }); + + section.taboption('general', L.cbi.InputValue, 'ip6prefix', { + caption: L.tr('IPv6 routed prefix'), + description: L.tr('This is the prefix routed to you by the tunnel broker for use by clients'), + datatype: 'ip6addr', + optional: true + }); + + var update = section.taboption('general', L.cbi.CheckboxValue, '_update', { + caption: L.tr('Dynamic tunnel'), + description: L.tr('Enable HE.net dynamic endpoint update'), + enabled: '1', + disabled: '0' + }); + + update.save = function(sid) { }; + update.ucivalue = function(sid) { + var n = parseInt(this.map.get('network', sid, 'tunnelid')); + return !isNaN(n); + }; + + section.taboption('general', L.cbi.InputValue, 'tunnelid', { + caption: L.tr('Tunnel ID'), + datatype: 'uinteger', + optional: false, + keep: false + }).depends('_update', true); + + section.taboption('general', L.cbi.InputValue, 'username', { + caption: L.tr('HE.net user ID'), + description: L.tr('This is the 32 byte hex encoded user ID, not the login name'), + datatype: 'rangelength(32, 32)', + optional: false, + keep: false + }).depends('_update', true); + + section.taboption('general', L.cbi.PasswordValue, 'password', { + caption: L.tr('HE.net password'), + optional: false, + keep: false + }).depends('_update', true); + + section.taboption('advanced', L.cbi.CheckboxValue, 'defaultroute', { + caption: L.tr('Default route'), + description: L.tr('Create IPv6 default route via tunnel'), + optional: true, + initial: true + }); + + section.taboption('advanced', L.cbi.InputValue, 'ttl', { + caption: L.tr('Override TTL'), + description: L.tr('Specifies the Time-to-Live on the tunnel interface'), + datatype: 'range(1,255)', + placeholder: 64, + optional: true + }); + } +}); diff --git a/luci2/htdocs/luci2/proto/6rd.js b/luci2/htdocs/luci2/proto/6rd.js new file mode 100644 index 0000000..47f6d29 --- /dev/null +++ b/luci2/htdocs/luci2/proto/6rd.js @@ -0,0 +1,63 @@ +L.NetworkModel.Protocol.extend({ + protocol: '6rd', + description: L.tr('IPv6-over-IPv4 (6rd)'), + tunnel: true, + virtual: true, + + populateForm: function(section, iface) + { + var wan = L.NetworkModel.findWAN(); + + section.taboption('general', L.cbi.InputValue, 'peeraddr', { + caption: L.tr('6RD Gateway'), + datatype: 'ip4addr', + optional: false + }); + + section.taboption('general', L.cbi.InputValue, 'ipaddr', { + caption: L.tr('Local IPv4 address'), + description: L.tr('Leave empty to use the current WAN address'), + datatype: 'ip4addr', + placeholder: wan ? wan.getIPv4Addrs()[0] : undefined, + optional: true + }); + + section.taboption('general', L.cbi.InputValue, 'ip4prefixlen', { + caption: L.tr('IPv4 prefix length'), + description: L.tr('The length of the IPv4 prefix in bits, the remainder is used in the IPv6 addresses'), + datatype: 'range(0, 32)', + placeholder: 0, + optional: true + }); + + section.taboption('general', L.cbi.InputValue, 'ip6prefix', { + caption: L.tr('IPv6 prefix'), + description: L.tr('The IPv6 prefix assigned to the provider, usually ends with "::"'), + datatype: 'ip6addr', + optional: false + }); + + section.taboption('general', L.cbi.InputValue, 'ip6prefixlen', { + caption: L.tr('IPv6 prefix length'), + description: L.tr('The length of the IPv6 prefix in bits'), + datatype: 'range(0, 128)', + placeholder: 16, + optional: true + }); + + section.taboption('advanced', L.cbi.CheckboxValue, 'defaultroute', { + caption: L.tr('Default route'), + description: L.tr('Create IPv6 default route via tunnel'), + optional: true, + initial: true + }); + + section.taboption('advanced', L.cbi.InputValue, 'ttl', { + caption: L.tr('Override TTL'), + description: L.tr('Specifies the Time-to-Live on the tunnel interface'), + datatype: 'range(1,255)', + placeholder: 64, + optional: true + }); + } +}); diff --git a/luci2/htdocs/luci2/proto/6to4.js b/luci2/htdocs/luci2/proto/6to4.js new file mode 100644 index 0000000..4ec81b0 --- /dev/null +++ b/luci2/htdocs/luci2/proto/6to4.js @@ -0,0 +1,35 @@ +L.NetworkModel.Protocol.extend({ + protocol: '6to4', + description: L.tr('IPv6-over-IPv4 (6to4)'), + tunnel: true, + virtual: true, + + populateForm: function(section, iface) + { + section.taboption('general', L.cbi.InputValue, 'ipaddr', { + caption: L.tr('Local IPv4 address'), + description: L.tr('Leave empty to use the current WAN address'), + datatype: 'ip4addr', + optional: true + }).load = function() { + var wan = L.NetworkModel.findWAN(); + if (wan) + this.options.placeholder = wan.getIPv4Addrs()[0]; + }; + + section.taboption('advanced', L.cbi.CheckboxValue, 'defaultroute', { + caption: L.tr('Default route'), + description: L.tr('Create IPv6 default route via tunnel'), + optional: true, + initial: true + }); + + section.taboption('advanced', L.cbi.InputValue, 'ttl', { + caption: L.tr('Override TTL'), + description: L.tr('Specifies the Time-to-Live on the tunnel interface'), + datatype: 'range(1,255)', + placeholder: 64, + optional: true + }); + } +}); diff --git a/luci2/htdocs/luci2/proto/dhcp.js b/luci2/htdocs/luci2/proto/dhcp.js new file mode 100644 index 0000000..4f0ae46 --- /dev/null +++ b/luci2/htdocs/luci2/proto/dhcp.js @@ -0,0 +1,60 @@ +L.NetworkModel.Protocol.extend({ + protocol: 'dhcp', + description: L.tr('DHCP client'), + tunnel: false, + virtual: false, + + populateForm: function(section, iface) + { + section.taboption('general', L.cbi.InputValue, 'hostname', { + caption: L.tr('Hostname'), + description: L.tr('Hostname to send when requesting DHCP'), + datatype: 'hostname', + optional: true + }).load = function() { + var self = this; + return L.system.getBoardInfo().then(function(info) { + self.options.placeholder = info.hostname; + }); + }; + + section.taboption('advanced', L.cbi.CheckboxValue, 'broadcast', { + caption: L.tr('Use broadcast'), + description: L.tr('Required for certain ISPs, e.g. Charter with DOCSIS3'), + optional: true + }); + + section.taboption('advanced', L.cbi.CheckboxValue, 'defaultroute', { + caption: L.tr('Use gateway'), + description: L.tr('Create default route via DHCP gateway'), + optional: true, + initial: true + }); + + section.taboption('advanced', L.cbi.CheckboxValue, 'peerdns', { + caption: L.tr('Use DNS'), + description: L.tr('Use DNS servers advertised by DHCP'), + optional: true, + initial: true + }); + + section.taboption('advanced', L.cbi.DynamicList, 'dns', { + caption: L.tr('Custom DNS'), + description: L.tr('Use custom DNS servers instead of DHCP ones'), + datatype: 'ipaddr', + optional: true + }).depends('peerdns', false); + + section.taboption('advanced', L.cbi.InputValue, 'clientid', { + caption: L.tr('Client ID'), + description: L.tr('Client ID to send when requesting DHCP'), + optional: true + }); + + section.taboption('advanced', L.cbi.InputValue, 'vendorid', { + caption: L.tr('Vendor Class'), + description: L.tr('Vendor Class to send when requesting DHCP'), + optional: true + }); + } +}); diff --git a/luci2/htdocs/luci2/proto/dhcpv6.js b/luci2/htdocs/luci2/proto/dhcpv6.js new file mode 100644 index 0000000..48c858a --- /dev/null +++ b/luci2/htdocs/luci2/proto/dhcpv6.js @@ -0,0 +1,59 @@ +L.NetworkModel.Protocol.extend({ + protocol: 'dhcpv6', + description: L.tr('DHCPv6 client / IPv6 autoconfig'), + tunnel: false, + virtual: false, + + populateForm: function(section, iface) + { + section.taboption('general', L.cbi.ListValue, 'reqaddress', { + caption: L.tr('Request IPv6 address'), + initial: 'try' + }).value('try', L.tr('Attempt DHCPv6, fallback to RA')) + .value('force', L.tr('Force DHCPv6')) + .value('none', L.tr('RA only')); + + section.taboption('general', L.cbi.ComboBox, 'reqprefix', { + caption: L.tr('Request IPv6 prefix'), + description: L.tr('Specifies the requested prefix length'), + initial: 'auto', + datatype: 'or("auto", "no", range(32, 64))' + }).value('auto', L.tr('automatic')) + .value('no', L.tr('disabled')) + .value('48').value('52').value('56').value('60').value('64'); + + section.taboption('general', L.cbi.InputValue, 'ip6prefix', { + caption: L.tr('Custom prefix'), + description: L.tr('Specifies an additional custom IPv6 prefix for distribution to clients'), + datatype: 'ip6addr', + optional: true + }); + + section.taboption('advanced', L.cbi.CheckboxValue, 'defaultroute', { + caption: L.tr('Default route'), + description: L.tr('Create IPv6 default route via tunnel'), + optional: true, + initial: true + }); + + section.taboption('advanced', L.cbi.CheckboxValue, 'peerdns', { + caption: L.tr('Use DNS'), + description: L.tr('Use DNS servers advertised by DHCPv6'), + optional: true, + initial: true + }); + + section.taboption('advanced', L.cbi.DynamicList, 'dns', { + caption: L.tr('Custom DNS'), + description: L.tr('Use custom DNS servers instead of DHCPv6 ones'), + datatype: 'ipaddr', + optional: true + }).depends('peerdns', false); + + section.taboption('advanced', L.cbi.InputValue, 'clientid', { + caption: L.tr('Client ID'), + description: L.tr('Client ID to send when requesting DHCPv6'), + optional: true + }); + } +}); diff --git a/luci2/htdocs/luci2/proto/dslite.js b/luci2/htdocs/luci2/proto/dslite.js new file mode 100644 index 0000000..26a92b5 --- /dev/null +++ b/luci2/htdocs/luci2/proto/dslite.js @@ -0,0 +1,46 @@ +L.NetworkModel.Protocol.extend({ + protocol: 'dslite', + description: L.tr('Dual-Stack Lite (RFC6333)'), + tunnel: true, + virtual: true, + + populateForm: function(section, iface) + { + var wan6 = L.NetworkModel.findWAN6(); + + section.taboption('general', L.cbi.InputValue, 'peeraddr', { + caption: L.tr('DS-Lite AFTR address'), + datatype: 'ip6addr', + optional: false + }); + + section.taboption('general', L.cbi.InputValue, 'ip6addr', { + caption: L.tr('Local IPv6 address'), + description: L.tr('Leave empty to use the current WAN address'), + datatype: 'ip6addr', + placeholder: wan6 ? wan6.getIPv6Addrs()[0] : undefined, + optional: true + }); + + section.taboption('advanced', L.cbi.NetworkList, 'tunlink', { + caption: L.tr('Tunnel Link'), + initial: wan6 ? wan6.name() : undefined, + optional: true + }); + + section.taboption('advanced', L.cbi.CheckboxValue, 'defaultroute', { + caption: L.tr('Default route'), + description: L.tr('Create IPv4 default route via tunnel'), + optional: true, + initial: true + }); + + section.taboption('advanced', L.cbi.InputValue, 'ttl', { + caption: L.tr('Override TTL'), + description: L.tr('Specifies the Time-to-Live on the tunnel interface'), + datatype: 'range(1,255)', + placeholder: 64, + optional: true + }); + } +}); diff --git a/luci2/htdocs/luci2/proto/none.js b/luci2/htdocs/luci2/proto/none.js new file mode 100644 index 0000000..0b7a648 --- /dev/null +++ b/luci2/htdocs/luci2/proto/none.js @@ -0,0 +1,6 @@ +L.NetworkModel.Protocol.extend({ + protocol: 'none', + description: L.tr('Unmanaged'), + tunnel: false, + virtual: false +}); diff --git a/luci2/htdocs/luci2/proto/static.js b/luci2/htdocs/luci2/proto/static.js new file mode 100644 index 0000000..afa2d6c --- /dev/null +++ b/luci2/htdocs/luci2/proto/static.js @@ -0,0 +1,113 @@ +L.NetworkModel.Protocol.extend({ + protocol: 'static', + description: L.tr('Static address'), + tunnel: false, + virtual: false, + + _ev_broadcast: function(ev) + { + var self = ev.data.self; + var sid = ev.data.sid; + + var i = ($('#' + self.section.id('field', sid, 'ipaddr')).val() || '').split(/\./); + var m = ($('#' + self.section.id('field', sid, 'netmask') + ' select').val() || '').split(/\./); + + var I = 0; + var M = 0; + + for (var n = 0; n < 4; n++) + { + i[n] = parseInt(i[n]); + m[n] = parseInt(m[n]); + + if (isNaN(i[n]) || i[n] < 0 || i[n] > 255 || + isNaN(m[n]) || m[n] < 0 || m[n] > 255) + return; + + I |= (i[n] << ((3 - n) * 8)); + M |= (m[n] << ((3 - n) * 8)); + } + + var B = I | ~M; + + $('#' + self.section.id('field', sid, 'broadcast')) + .attr('placeholder', '%d.%d.%d.%d'.format( + (B >> 24) & 0xFF, (B >> 16) & 0xFF, + (B >> 8) & 0xFF, (B >> 0) & 0xFF + )); + }, + + populateForm: function(section, iface) + { + var device = L.NetworkModel.getDeviceByInterface(iface); + + section.taboption('general', L.cbi.InputValue, 'ipaddr', { + caption: L.tr('IPv4 address'), + datatype: 'ip4addr', + optional: true + }).on('blur validate', this._ev_broadcast); + + section.taboption('general', L.cbi.ComboBox, 'netmask', { + caption: L.tr('IPv4 netmask'), + datatype: 'ip4addr', + optional: true + }).on('blur validate', this._ev_broadcast) + .value('255.255.255.0') + .value('255.255.0.0') + .value('255.0.0.0'); + + section.taboption('general', L.cbi.InputValue, 'broadcast', { + caption: L.tr('IPv4 broadcast'), + datatype: 'ip4addr', + optional: true + }); + + section.taboption('general', L.cbi.InputValue, 'gateway', { + caption: L.tr('IPv4 gateway'), + datatype: 'ip4addr', + optional: true + }); + + section.taboption('general', L.cbi.DynamicList, 'dns', { + caption: L.tr('DNS servers'), + datatype: 'ipaddr', + optional: true + }); + + + section.taboption('ipv6', L.cbi.ComboBox, 'ip6assign', { + caption: L.tr('IPv6 assignment length'), + description: L.tr('Assign a part of given length of every public IPv6-prefix to this interface'), + datatype: 'max(64)', + optional: true + }).value('', L.tr('disabled')).value('64'); + + var ip6hint = section.taboption('ipv6', L.cbi.InputValue, 'ip6hint', { + caption: L.tr('IPv6 assignment hint'), + description: L.tr('Assign prefix parts using this hexadecimal subprefix ID for this interface'), + optional: true + }); + + for (var i = 33; i <= 64; i++) + ip6hint.depends('ip6assign', i); + + section.taboption('ipv6', L.cbi.InputValue, 'ip6addr', { + caption: L.tr('IPv6 address'), + datatype: 'ip6addr', + optional: true + }).depends('ip6assign', false); + + section.taboption('ipv6', L.cbi.InputValue, 'ip6gw', { + caption: L.tr('IPv6 gateway'), + datatype: 'ip6addr', + optional: true + }).depends('ip6assign', false); + + section.taboption('ipv6', L.cbi.InputValue, 'ip6prefix', { + caption: L.tr('IPv6 routed prefix'), + description: L.tr('Public prefix routed to this device for distribution to clients'), + datatype: 'ip6addr', + optional: true + }).depends('ip6assign', false); + } +}); -- 2.11.0