f8a6d9486e75c9ba8880e01fea92cf70aa6accfa
6 function isCIDR(value
) {
7 return Array
.isArray(value
) || /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/(\d{1,2}|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/.test(value
);
10 function calculateBroadcast(s
, use_cfgvalue
) {
11 var readfn
= use_cfgvalue
? 'cfgvalue' : 'formvalue',
12 addropt
= s
.children
.filter(function(o
) { return o
.option
== 'ipaddr'})[0],
13 addrvals
= addropt
? L
.toArray(addropt
[readfn
](s
.section
)) : [],
14 maskopt
= s
.children
.filter(function(o
) { return o
.option
== 'netmask'})[0],
15 maskval
= maskopt
? maskopt
[readfn
](s
.section
) : null,
16 firstsubnet
= maskval
? addrvals
[0] + '/' + maskval
: addrvals
.filter(function(a
) { return a
.indexOf('/') > 0 })[0];
18 if (firstsubnet
== null)
21 var addr_mask
= firstsubnet
.split('/'),
22 addr
= validation
.parseIPv4(addr_mask
[0]),
26 mask
= validation
.parseIPv4(network
.prefixToMask(+mask
));
28 mask
= validation
.parseIPv4(mask
);
31 addr
[0] | (~mask
[0] >>> 0 & 255),
32 addr
[1] | (~mask
[1] >>> 0 & 255),
33 addr
[2] | (~mask
[2] >>> 0 & 255),
34 addr
[3] | (~mask
[3] >>> 0 & 255)
40 function validateBroadcast(section_id
, value
) {
41 var opt
= this.map
.lookupOption('broadcast', section_id
),
42 node
= opt
? this.map
.findElement('id', opt
[0].cbid(section_id
)) : null,
43 addr
= node
? calculateBroadcast(this.section
, false) : null;
47 node
.querySelector('input').setAttribute('placeholder', addr
);
49 node
.querySelector('input').removeAttribute('placeholder');
55 return network
.registerProtocol('static', {
56 CBIIPValue
: form
.Value
.extend({
57 handleSwitch: function(section_id
, option_index
, ev
) {
58 var maskopt
= this.map
.lookupOption('netmask', section_id
);
60 if (maskopt
== null || !this.isValid(section_id
))
63 var maskval
= maskopt
[0].formvalue(section_id
),
64 addrval
= this.formvalue(section_id
),
65 prefix
= maskval
? network
.maskToPrefix(maskval
) : 32;
70 this.datatype
= 'or(cidr4,ipmask4)';
72 var parent
= L
.dom
.parent(ev
.target
, '.cbi-value-field');
73 L
.dom
.content(parent
, form
.DynamicList
.prototype.renderWidget
.apply(this, [
76 addrval
? '%s/%d'.format(addrval
, prefix
) : ''
79 var masknode
= this.map
.findElement('id', maskopt
[0].cbid(section_id
));
81 parent
= L
.dom
.parent(masknode
, '.cbi-value');
82 parent
.parentNode
.removeChild(parent
);
86 renderWidget: function(section_id
, option_index
, cfgvalue
) {
87 var maskopt
= this.map
.lookupOption('netmask', section_id
),
88 widget
= isCIDR(cfgvalue
) ? 'DynamicList' : 'Value';
90 if (widget
== 'DynamicList') {
91 this.datatype
= 'or(cidr4,ipmask4)';
92 this.placeholder
= _('Add IPv4 address…');
95 this.datatype
= 'ip4addr("nomask")';
98 var node
= form
[widget
].prototype.renderWidget
.apply(this, [ section_id
, option_index
, cfgvalue
]);
100 if (widget
== 'Value')
101 L
.dom
.append(node
, E('button', {
102 'class': 'cbi-button cbi-button-neutral',
103 'title': _('Switch to CIDR list notation'),
104 'aria-label': _('Switch to CIDR list notation'),
105 'click': L
.bind(this.handleSwitch
, this, section_id
, option_index
)
111 validate
: validateBroadcast
114 CBINetmaskValue
: form
.Value
.extend({
115 render: function(option_index
, section_id
, in_table
) {
116 var addropt
= this.section
.children
.filter(function(o
) { return o
.option
== 'ipaddr' })[0],
117 addrval
= addropt
? addropt
.cfgvalue(section_id
) : null;
119 if (addrval
!= null && isCIDR(addrval
))
122 this.value('255.255.255.0');
123 this.value('255.255.0.0');
124 this.value('255.0.0.0');
126 return form
.Value
.prototype.render
.apply(this, [ option_index
, section_id
, in_table
]);
129 validate
: validateBroadcast
132 CBIGatewayValue
: form
.Value
.extend({
133 datatype
: 'ip4addr("nomask")',
135 render: function(option_index
, section_id
, in_table
) {
136 return network
.getWANNetworks().then(L
.bind(function(wans
) {
137 if (wans
.length
== 1) {
138 var gwaddr
= wans
[0].getGatewayAddr();
139 this.placeholder
= gwaddr
? '%s (%s)'.format(gwaddr
, wans
[0].getName()) : '';
142 return form
.Value
.prototype.render
.apply(this, [ option_index
, section_id
, in_table
]);
146 validate: function(section_id
, value
) {
147 var addropt
= this.section
.children
.filter(function(o
) { return o
.option
== 'ipaddr' })[0],
148 addrval
= addropt
? L
.toArray(addropt
.cfgvalue(section_id
)) : null;
150 if (addrval
!= null) {
151 for (var i
= 0; i
< addrval
.length
; i
++) {
152 var addr
= addrval
[i
].split('/')[0];
154 return _('The gateway address must not be a local IP address');
162 CBIBroadcastValue
: form
.Value
.extend({
163 datatype
: 'ip4addr("nomask")',
165 render: function(option_index
, section_id
, in_table
) {
166 this.placeholder
= calculateBroadcast(this.section
, true);
167 return form
.Value
.prototype.render
.apply(this, [ option_index
, section_id
, in_table
]);
171 getI18n: function() {
172 return _('Static address');
175 renderFormOptions: function(s
) {
176 var dev
= this.getL2Device() || this.getDevice(), o
;
178 s
.taboption('general', this.CBIIPValue
, 'ipaddr', _('IPv4 address'));
179 s
.taboption('general', this.CBINetmaskValue
, 'netmask', _('IPv4 netmask'));
180 s
.taboption('general', this.CBIGatewayValue
, 'gateway', _('IPv4 gateway'));
181 s
.taboption('general', this.CBIBroadcastValue
, 'broadcast', _('IPv4 broadcast'));
182 s
.taboption('general', form
.DynamicList
, 'dns', _('Use custom DNS servers'));
184 o
= s
.taboption('general', form
.Value
, 'ip6assign', _('IPv6 assignment length'), _('Assign a part of given length of every public IPv6-prefix to this interface'));
185 o
.value('', _('disabled'));
187 o
.datatype
= 'max(64)';
189 o
= s
.taboption('general', form
.Value
, 'ip6hint', _('IPv6 assignment hint'), _('Assign prefix parts using this hexadecimal subprefix ID for this interface.'));
190 for (var i
= 33; i
<= 64; i
++)
191 o
.depends('ip6assign', i
);
193 o
= s
.taboption('general', form
.DynamicList
, 'ip6addr', _('IPv6 address'));
194 o
.datatype
= 'ip6addr';
195 o
.placeholder
= _('Add IPv6 address…');
196 o
.depends('ip6assign', '');
198 o
= s
.taboption('general', form
.Value
, 'ip6gw', _('IPv6 gateway'));
199 o
.datatype
= 'ip6addr("nomask")';
200 o
.depends('ip6assign', '');
202 o
= s
.taboption('general', form
.Value
, 'ip6prefix', _('IPv6 routed prefix'), _('Public prefix routed to this device for distribution to clients.'));
203 o
.datatype
= 'ip6addr';
204 o
.depends('ip6assign', '');
206 o
= s
.taboption('general', form
.Value
, 'ip6ifaceid', _('IPv6 suffix'), _("Optional. Allowed values: 'eui64', 'random', fixed value like '::1' or '::1:2'. When IPv6 prefix (like 'a:b:c:d::') is received from a delegating server, use the suffix (like '::1') to form the IPv6 address ('a:b:c:d::1') for the interface."));
207 o
.datatype
= 'ip6hostid';
208 o
.placeholder
= '::1';
210 o
= s
.taboption('advanced', form
.Value
, 'macaddr', _('Override MAC address'));
211 o
.datatype
= 'macaddr';
212 o
.placeholder
= dev
? (dev
.getMAC() || '') : '';
214 o
= s
.taboption('advanced', form
.Value
, 'mtu', _('Override MTU'));
215 o
.datatype
= 'max(9200)';
216 o
.placeholder
= dev
? (dev
.getMTU() || '1500') : '1500';
218 o
= s
.taboption('advanced', form
.Value
, 'metric', _('Use gateway metric'));
219 o
.placeholder
= this.getMetric() || '0';
220 o
.datatype
= 'uinteger';