fix "The field 'wl_radio' is invalid. Please report this problem." when 2.4G network...
[tomato.git] / release / src-rt-6.x.4708 / router / www / basic-network.asp
blob55c9eb159295181633b8d7d631d579fcf4129c2f
1 <!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0//EN'>
2 <!--
3 Tomato GUI
4 Copyright (C) 2006-2010 Jonathan Zarate
5 http://www.polarcloud.com/tomato/
7 For use with Tomato Firmware only.
8 No part of this file may be used without permission.
9 -->
10 <html>
11 <head>
12 <meta http-equiv='content-type' content='text/html;charset=utf-8'>
13 <meta name='robots' content='noindex,nofollow'>
14 <title>[<% ident(); %>] Basic: Network</title>
15 <link rel='stylesheet' type='text/css' href='tomato.css'>
16 <% css(); %>
17 <script type='text/javascript' src='tomato.js'></script>
19 <!-- / / / -->
21 <style type='text/css'>
22 #lan-grid .co1,
23 #lan-grid .co2,
24 #lan-grid .co3,
25 #lan-grid .co4,
26 #lan-grid .co5,
27 #lan-grid .co6,
28 #lan-grid .co7 {
29 text-align: center;
32 #lan-grid .centered {
33 text-align: center;
36 #spin {
37 visibility: hidden;
38 vertical-align: middle;
40 </style>
42 <script type='text/javascript' src='debug.js'></script>
44 <script type='text/javascript' src='md5.js'></script>
45 <script type='text/javascript' src='wireless.jsx?_http_id=<% nv(http_id); %>'></script>
46 <script type='text/javascript' src='interfaces.js'></script>
47 <script type='text/javascript'>
48 // <% nvram("dhcp_lease,dhcp_num,dhcp_start,dhcpd_startip,dhcpd_endip,l2tp_server_ip,lan_gateway,lan_ipaddr,lan_netmask,lan_proto,lan_state,lan_desc,lan_invert,mtu_enable,ppp_demand,ppp_idletime,pppoe_lei,pppoe_lef,ppp_passwd,ppp_redialperiod,ppp_service,ppp_username,ppp_custom,pptp_server_ip,pptp_dhcp,wl_security_mode,wan_dns,dnscrypt_proxy,dnscrypt_priority,dnscrypt_port,dnscrypt_resolver,dnscrypt_log,dnscrypt_manual,dnscrypt_provider_name,dnscrypt_provider_key,dnscrypt_resolver_address,wan_gateway,wan_ipaddr,wan_mtu,wan_netmask,wan_proto,wan_wins,wl_wds_enable,wl_channel,wl_closed,wl_crypto,wl_key,wl_key1,wl_key2,wl_key3,wl_key4,wl_lazywds,wl_mode,wl_net_mode,wl_passphrase,wl_radio,wl_radius_ipaddr,wl_radius_port,wl_ssid,wl_wds,wl_wep_bit,wl_wpa_gtk_rekey,wl_wpa_psk,wl_radius_key,wl_auth,wl_hwaddr,wan_islan,t_features,wl_nbw_cap,wl_nctrlsb,wl_nband,wl_phytype,lan_ifname,lan_stp,lan1_ifname,lan1_ipaddr,lan1_netmask,lan1_proto,lan1_stp,dhcp1_start,dhcp1_num,dhcp1_lease,dhcpd1_startip,dhcpd1_endip,lan2_ifname,lan2_ipaddr,lan2_netmask,lan2_proto,lan2_stp,dhcp2_start,dhcp2_num,dhcp2_lease,dhcpd2_startip,dhcpd2_endip,lan3_ifname,lan3_ipaddr,lan3_netmask,lan3_proto,lan3_stp,dhcp3_start,dhcp3_num,dhcp3_lease,dhcpd3_startip,dhcpd3_endip,ppp_mlppp,modem_ipaddr,modem_pin,modem_dev,modem_init,modem_apn,cstats_enable,dnssec_enable"); %>
50 var lg = new TomatoGrid();
51 lg.setup = function() {
52 this.init('lan-grid', '', 4, [
53 { type: 'select', options: [[0, '0'],[1, '1'],[2, '2'],[3, '3']], prefix: '<div class="centered">', suffix: '</div>' },
54 { type: 'checkbox', prefix: '<div class="centered">', suffix: '</div>' },
55 { type: 'text', maxlen: 15, size: 17 },
56 { type: 'text', maxlen: 15, size: 17 },
57 { type: 'checkbox', prefix: '<div class="centered">', suffix: '</div>' },
58 { multi: [ { type: 'text', maxlen: 15, size: 17}, { type: 'text', maxlen: 15, size: 17 } ] },
59 { type: 'text', maxlen: 6, size: 8 }] );
60 this.headerSet(['Bridge', 'STP', 'IP Address', 'Netmask', 'DHCP', 'IP&nbsp;Range&nbsp;<i>(first/last)</i>', 'Lease&nbsp;Time&nbsp;<i>(mins)</i>']);
62 var numBridges = 0;
63 for (var i = 0 ; i <= MAX_BRIDGE_ID ; i++) {
64 var j = (i == 0) ? '' : i.toString();
65 if (nvram['lan' + j + '_ifname'].length > 0) {
66 if ((!fixIP(nvram['dhcpd' + j + '_startip'])) || (!fixIP(nvram['dhcpd' + j + '_endip']))) {
67 if ((fixIP(nvram['lan' + j + '_ipaddr'])) && (fixIP(nvram['lan' + j + '_netmask'])) && (nvram['dhcp' + j + '_start'] != '')) {
68 var n = getNetworkAddress(nvram['lan' + j + '_ipaddr'], nvram['lan' + j + '_netmask']);
69 nvram['dhcpd' + j + '_startip'] = getAddress(('0.0.0.' + nvram['dhcp' + j + '_start'] * 1), n);
70 nvram['dhcpd' + j + '_endip'] = getAddress(('0.0.0.' + ((nvram['dhcp' + j + '_start'] * 1) + (nvram['dhcp' + j + '_num'] *1) - 1)), n);
73 lg.insertData(-1, [
74 i.toString(),
75 nvram['lan' + j + '_stp'],
76 nvram['lan' + j + '_ipaddr'],
77 nvram['lan' + j + '_netmask'],
78 (nvram['lan' + j + '_proto'] == 'dhcp') ? '1' : '0',
79 nvram['dhcpd' + j + '_startip'],
80 nvram['dhcpd' + j + '_endip'],
81 (nvram['lan' + j + '_proto'] == 'dhcp') ? (((nvram['dhcp' + j + '_lease'])*1 == 0) ? '1440' : (nvram['dhcp' + j + '_lease']).toString()) : ''
82 ] ) ;
83 numBridges++;
86 lg.canDelete = false;
87 lg.sort(0);
88 elem.removeClass(lg.header.cells[lg.sortColumn], 'sortasc', 'sortdes');
89 lg.showNewEditor();
90 lg.resetNewEditor();
93 lg.dataToView = function(data) {
94 return ['br' + data[0],
95 (data[1].toString() == '1') ? '<small><i>Enabled</i></small>' : '<small><i>Disabled</i></small>',
96 data[2],
97 data[3],
98 (data[4].toString() == '1') ? '<small><i>Enabled</i></small>' : '<small><i>Disabled</i></small>',
99 (data[5].toString() + ((numberOfBitsOnNetMask(data[3])>=24) ? (' - ' + data[6].split('.').splice(3, 1).toString()) : ('<br>' + data[6].toString()) )),
100 (((data[7] != null) && (data[7] != '')) ? data[7] : '') ];
103 lg.dataToFieldValues = function (data) {
104 return [data[0],
105 (data[1] != 0) ? 'checked' : '',
106 data[2].toString(),
107 data[3].toString(),
108 (data[4].toString() == '1') ? 'checked' : '',
109 data[5].toString(),
110 data[6].toString(),
111 data[7].toString() ];
114 lg.fieldValuesToData = function(row) {
115 var f = fields.getAll(row);
116 return [f[0].value,
117 f[1].checked ? 1 : 0,
118 f[2].value,
119 f[3].value,
120 f[4].checked ? 1 : 0,
121 f[5].value,
122 f[6].value,
123 f[7].value ];
126 lg.resetNewEditor = function() {
127 var f = fields.getAll(this.newEditor);
128 f[0].selectedIndex=0;
129 var t = MAX_BRIDGE_ID;
130 while((this.countBridge(f[0].selectedIndex) > 0) && (t > 0)) {
131 f[0].selectedIndex = (f[0].selectedIndex%(MAX_BRIDGE_ID))+1;
132 t--;
134 for(var j=0; j<= MAX_BRIDGE_ID ; j++) {
135 f[0].options[j].disabled = (this.countBridge(j) > 0);
137 f[1].checked = 0;
138 f[2].value = '';
139 f[3].value = '';
140 f[5].value = '';
141 f[6].value = '';
142 f[7].value = '';
143 f[4].checked = 0;
144 f[4].disabled = 1;
145 f[5].disabled = 1;
146 f[6].disabled = 1;
147 f[7].disabled = 1;
148 ferror.clearAll(fields.getAll(this.newEditor));
151 lg.onCancel = function() {
152 this.removeEditor();
153 this.showSource();
154 this.disableNewEditor(false);
156 this.resetNewEditor();
159 lg.onAdd = function() {
160 var data;
162 this.moving = null;
163 this.rpHide();
165 if (!this.verifyFields(this.newEditor, false)) return;
167 data = this.fieldValuesToData(this.newEditor);
168 this.insertData(-1, data);
170 this.disableNewEditor(false);
171 this.resetNewEditor();
173 this.resort();
176 lg.onOK = function() {
177 var i, data, view;
179 if (!this.verifyFields(this.editor, false)) return;
181 data = this.fieldValuesToData(this.editor);
182 view = this.dataToView(data);
184 this.source.setRowData(data);
185 for (i = 0; i < this.source.cells.length; ++i) {
186 this.source.cells[i].innerHTML = view[i];
189 this.removeEditor();
190 this.showSource();
191 this.disableNewEditor(false);
193 this.resort();
194 this.resetNewEditor();
197 lg.onDelete = function() {
198 this.removeEditor();
199 elem.remove(this.source);
200 this.source = null;
201 this.disableNewEditor(false);
203 this.resetNewEditor();
206 lg.countElem = function(f, v) {
207 var data = this.getAllData();
208 var total = 0;
209 for (var i = 0; i < data.length; ++i) {
210 total += (data[i][f] == v) ? 1 : 0;
212 return total;
215 lg.countBridge = function (v) {
216 return this.countElem(0,v);
219 lg.countOverlappingNetworks = function (ip) {
220 var data = this.getAllData();
221 var total = 0;
222 for (var i = 0; i < data.length; ++i) {
223 var net = getNetworkAddress(data[i][2], data[i][3]);
224 var brd = getBroadcastAddress(net, data[i][3]);
225 total += ((aton(ip) <= aton(brd)) && (aton(ip) >= aton(net))) ? 1 : 0;
227 return total;
230 lg.verifyFields = function(row, quiet) {
231 var ok=1;
232 var f;
234 f = fields.getAll(row);
236 for(var j=0; j<= MAX_BRIDGE_ID ; j++) {
237 f[0].options[j].disabled = (this.countBridge(j) > 0);
240 if(this.countBridge(f[0].selectedIndex) > 0) {
241 ferror.set(f[0], 'Cannot add another entry for bridge br' + f[0].selectedIndex, quiet);
242 ok = 0;
243 } else {
244 ferror.clear(f[0]);
246 // valid IP address?
247 if(!v_ip(f[2], quiet || !ok))
248 ok = 0;
249 // if we have a properly defined IP address - 0.0.0.0 is NOT a valid IP address for our intents/purposes!
250 if ((f[2].value != '') && (f[2].value != '0.0.0.0')) {
251 // allow DHCP to be enabled
252 f[4].disabled = 0;
253 // validate netmask
254 if(!v_netmask(f[3], quiet || !ok)) {
255 return 0;
256 } else {
257 // should be 22 bits or smaller network
258 if ((numberOfBitsOnNetMask(f[3].value) < 22) && (nvram.cstats_enable == '1' )) {
259 if (!confirm("Netmask should have at least 22 bits (255.255.252.0). You may continue anyway but remember - you was warned")) return;
260 } else {
261 ferror.clear(f[3]);
264 if(f[2].value == getNetworkAddress(f[2].value, f[3].value)) {
265 var s = 'Invalid IP address or subnet mask (the address of the network cannot be used)';
266 ferror.set(f[2], s, quiet);
267 ferror.set(f[3], s, quiet);
268 return 0;
269 } else
270 if(f[2].value == getBroadcastAddress(getNetworkAddress(f[2].value, f[3].value), f[3].value)) {
271 var s = 'Invalid IP address or subnet mask (the broadcast address cannot be used)';
272 ferror.set(f[2], s, quiet);
273 ferror.set(f[3], s, quiet);
274 return 0;
275 } else
276 if (this.countOverlappingNetworks(f[2].value) > 0) {
277 var s = 'Invalid IP address or subnet mask (conflicts/overlaps with another LAN bridge)';
278 ferror.set(f[2], s, quiet);
279 ferror.set(f[3], s, quiet);
280 return 0;
281 } else {
282 ferror.clear(f[2]);
283 ferror.clear(f[3]);
285 } else {
286 f[4].checked = 0;
287 f[4].disabled = 1;
289 // dhcp enabled?
290 if( (f[4].checked) && (v_ip(f[2], 1)) && (v_netmask(f[3],1)) ) {
291 f[5].disabled = 0;
292 f[6].disabled = 0;
293 f[7].disabled = 0;
294 // first/last IP still unset?
295 if (f[5].value == '') {
296 var l;
297 var m = aton(f[2].value) & aton(f[3].value);
298 var o = (m) ^ (~ aton(f[3].value))
299 var n = o - m;
300 do {
301 if (--n < 0) {
302 f[5].value = '';
303 return;
305 m++;
306 } while (((l = fixIP(ntoa(m), 1)) == null) || (l == f[2].value) );
307 f[5].value = l;
309 if (f[6].value == '') {
310 var l;
311 var m = aton(f[2].value) & aton(f[3].value);
312 var o = (m) ^ (~ aton(f[3].value));
313 var n = o - m;
314 do {
315 if (--n < 0) {
316 f[6].value = '';
317 return;
319 o--;
320 } while (((l = fixIP(ntoa(o), 1)) == null) || (l == f[2].value) );
321 f[6].value = l;
323 // first IP valid?
324 if ((getNetworkAddress(f[5].value, f[3].value) != getNetworkAddress(f[2].value, f[3].value)) ||
325 (f[5].value == getBroadcastAddress(getNetworkAddress(f[2].value, f[3].value), f[3].value)) ||
326 (f[5].value == getNetworkAddress(f[2].value, f[3].value)) ||
327 (f[2].value == f[5].value)) {
328 ferror.set(f[5], 'Invalid first IP address or subnet mask', quiet || !ok);
329 return 0;
330 } else {
331 ferror.clear(f[5]);
333 // last IP valid?
334 if ((getNetworkAddress(f[6].value, f[3].value) != getNetworkAddress(f[2].value, f[3].value)) ||
335 (f[6].value == getBroadcastAddress(getNetworkAddress(f[2].value, f[3].value), f[3].value)) ||
336 (f[6].value == getNetworkAddress(f[2].value, f[3].value)) ||
337 (f[2].value == f[6].value)) {
338 ferror.set(f[6], 'Invalid last IP address or subnet mask', quiet || !ok);
339 return 0;
340 } else {
341 ferror.clear(f[6]);
343 // validate range, swap first/last IP if needed
344 if (aton(f[6].value) < aton(f[5].value)) {
345 var t = f[5].value;
346 f[5].value = f[6].value;
347 f[6].value = t;
349 // lease time
350 if (parseInt(f[7].value*1) == 0)
351 f[7].value = 1440; // from nvram/defaults.c
352 if(!v_mins(f[7], quiet || !ok, 1, 10080))
353 ok = 0;
354 } else {
355 f[5].disabled = 1;
356 f[6].disabled = 1;
357 f[7].disabled = 1;
358 ferror.clear(f[5]);
359 ferror.clear(f[6]);
360 ferror.clear(f[7]);
362 return ok;
365 W('<style type=\'text/css\'>');
366 for (var u = 0; u < wl_ifaces.length; ++u) {
367 W('#spin'+wl_unit(u)+', ');
369 W('#spin {');
370 W(' visibility: hidden;');
371 W(' vertical-align: middle;');
372 W('}');
373 W('</style>');
375 var xob = null;
376 var refresher = [];
377 var nphy = features('11n');
378 var acphy = features('11ac');
380 var ghz = [];
381 var bands = [];
382 var nm_loaded = [], ch_loaded = [], max_channel = [];
384 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
385 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
386 if (wl_sunit(uidx)<0) {
387 var b;
388 b = [];
389 for (var i = 0; i < wl_bands[uidx].length; ++i) {
390 b.push([wl_bands[uidx][i] + '', (wl_bands[uidx][i] == '1') ? '5 GHz' : '2.4 GHz']);
392 bands.push(b);
394 b = [];
395 ghz.push(b);
397 nm_loaded.push(0);
398 ch_loaded.push(0);
399 max_channel.push(0);
400 refresher.push(null);
404 function selectedBand(uidx)
406 if (bands[uidx].length > 1) {
407 var e = E('_f_wl'+u+'_nband');
408 return (e.value + '' == '' ? eval('nvram.wl'+u+'_nband') : e.value);
409 } else if (bands[uidx].length > 0) {
410 return bands[uidx][0][0] || '0';
411 } else {
412 return '0';
416 function refreshNetModes(uidx)
418 var e, i, buf, val;
420 if (uidx >= wl_ifaces.length) return;
421 var u = wl_unit(uidx);
423 var m = [['mixed','Auto']];
424 if (selectedBand(uidx) == '1') {
425 m.push(['a-only','A Only']);
426 if (nphy) {
427 m.push(['n-only','N Only']);
430 else {
431 m.push(['b-only','B Only']);
432 m.push(['g-only','G Only']);
433 if (nphy) {
434 m.push(['bg-mixed','B/G Mixed']);
435 m.push(['n-only','N Only']);
439 e = E('_wl'+u+'_net_mode');
440 buf = '';
441 val = (!nm_loaded[uidx] || (e.value + '' == '')) ? eval('nvram.wl'+u+'_net_mode') : e.value;
442 if (val == 'disabled') val = 'mixed';
443 for (i = 0; i < m.length; ++i)
444 buf += '<option value="' + m[i][0] + '"' + ((m[i][0] == val) ? ' selected' : '') + '>' + m[i][1] + '</option>';
446 e = E('__wl'+u+'_net_mode');
447 buf = '<select name="wl'+u+'_net_mode" onchange="verifyFields(this, 1)" id = "_wl'+u+'_net_mode">' + buf + '</select>';
448 elem.setInnerHTML(e, buf);
449 nm_loaded[uidx] = 1;
452 function refreshBandWidth(uidx)
454 var e, i, buf, val;
456 if (uidx >= wl_ifaces.length) return;
457 var u = wl_unit(uidx);
459 var m = [['0','20 MHz']];
460 if(nphy || acphy){
461 m.push(['1','40 MHz']);
463 if(acphy && selectedBand(uidx) == '1') {
464 m.push(['3','80 MHz']);
467 e = E('_wl'+u+'_nbw_cap');
468 buf = '';
469 val = (!nm_loaded[uidx] || (e.value + '' == '')) ? eval('nvram.wl'+u+'_nbw_cap') : e.value;
470 for (i = 0; i < m.length; ++i)
471 buf += '<option value="' + m[i][0] + '"' + ((m[i][0] == val) ? ' selected' : '') + '>' + m[i][1] + '</option>';
473 e = E('__wl'+u+'_nbw_cap');
474 buf = '<select name="wl'+u+'_nbw_cap" onchange="verifyFields(this, 1)" id = "_wl'+u+'_nbw_cap">' + buf + '</select>';
475 elem.setInnerHTML(e, buf);
476 nm_loaded[uidx] = 1;
479 function refreshChannels(uidx)
481 if (refresher[uidx] != null) return;
482 if (u >= wl_ifaces.length) return;
483 var u = wl_unit(uidx);
485 refresher[uidx] = new XmlHttp();
486 refresher[uidx].onCompleted = function(text, xml) {
487 try {
488 var e, i, buf, val;
490 var wl_channels = [];
491 eval(text);
493 ghz[uidx] = [];
494 max_channel[uidx] = 0;
495 for (i = 0; i < wl_channels.length; ++i) {
496 ghz[uidx].push([wl_channels[i][0] + '',
497 (wl_channels[i][0]) ? ((wl_channels[i][1]) ? wl_channels[i][0] + ' - ' + (wl_channels[i][1] / 1000.0).toFixed(3) + ' GHz' : wl_channels[i][0] + '') : 'Auto']);
498 max_channel[uidx] = wl_channels[i][0] * 1;
501 e = E('_wl'+u+'_channel');
502 buf = '';
503 val = (!ch_loaded[uidx] || (e.value + '' == '')) ? eval('nvram.wl'+u+'_channel') : e.value;
504 for (i = 0; i < ghz[uidx].length; ++i)
505 buf += '<option value="' + ghz[uidx][i][0] + '"' + ((ghz[uidx][i][0] == val) ? ' selected' : '') + '>' + ghz[uidx][i][1] + '</option>';
507 e = E('__wl'+u+'_channel');
508 buf = '<select name="wl'+u+'_channel" onchange="verifyFields(this, 1)" id = "_wl'+u+'_channel">' + buf + '</select>';
509 elem.setInnerHTML(e, buf);
510 ch_loaded[uidx] = 1;
512 refresher[uidx] = null;
513 verifyFields(null, 1);
515 catch (x) {
517 refresher[uidx] = null;
520 var bw, sb, e;
522 e = E('_f_wl'+u+'_nctrlsb');
523 sb = (e.value + '' == '' ? eval('nvram.wl'+u+'_nctrlsb') : e.value);
524 e = E('_wl'+u+'_nbw_cap');
525 switch(e.value + '' == '' ? eval('nvram.wl'+u+'_nbw_cap') : e.value) {
526 case '0':
527 bw = '20';
528 break;
529 case '1':
530 bw = '40';
531 break;
532 case '3':
533 bw = '80';
534 break;
535 default:
536 alert("Wrong nbw_cap.");
539 refresher[uidx].onError = function(ex) { alert(ex); refresher[uidx] = null; reloadPage(); }
540 refresher[uidx].post('update.cgi', 'exec=wlchannels&arg0=' + u + '&arg1=' + (nphy || acphy ? '1' : '0') +
541 '&arg2=' + bw + '&arg3=' + selectedBand(uidx) + '&arg4=' + sb);
544 function spin(x, unit)
546 for (var u = 0; u < wl_ifaces.length; ++u) {
547 E('_f_wl'+wl_unit(u)+'_scan').disabled = x;
549 var e = E('_f_wl'+unit+'_scan');
550 if (x) e.value = 'Scan ' + (wscan.tries + 1);
551 else e.value = 'Scan';
552 E('spin'+unit).style.visibility = x ? 'visible' : 'hidden';
555 function scan()
557 if (xob) return;
559 var unit = wscan.unit;
560 var uidx = wl_uidx(unit);
562 xob = new XmlHttp();
563 xob.onCompleted = function(text, xml) {
564 try {
565 var i;
567 wlscandata = [];
568 eval(text);
570 for (i = 0; i < wlscandata.length; ++i) {
571 var data = wlscandata[i];
572 var ch = data[2];
573 var mac = data[0];
575 if (!wscan.inuse[ch]) {
576 wscan.inuse[ch] = {
577 count: 0,
578 rssi: -999,
579 ssid: ''
583 if (!wscan.seen[mac]) {
584 wscan.seen[mac] = 1;
585 ++wscan.inuse[ch].count;
588 if (data[4] > wscan.inuse[ch].rssi) {
589 wscan.inuse[ch].rssi = data[4];
590 wscan.inuse[ch].ssid = data[1];
593 var e = E('_wl'+unit+'_channel');
594 for (i = 1; i < ghz[uidx].length; ++i) {
595 var s = ghz[uidx][i][1];
596 var u = wscan.inuse[ghz[uidx][i][0]];
597 if (u) s += ' (' + u.count + ' AP' + (u.count == 1 ? '' : 's') + ' / strongest: "' + escapeHTML(ellipsis(u.ssid, 15)) + '" ' + u.rssi + ' dBm)';
598 e.options[i].innerHTML = s;
600 e.style.width = '400px';
602 xob = null;
604 if (wscan.tries < 4) {
605 ++wscan.tries;
606 setTimeout(scan, 1000);
607 return;
610 catch (x) {
612 spin(0, unit);
614 xob.onError = function(x) {
615 alert('error: ' + x);
616 spin(0, unit);
617 xob = null;
620 spin(1, unit);
621 xob.post('update.cgi', 'exec=wlscan&arg0='+unit);
624 function scanButton(u)
626 if (xob) return;
628 wscan = {
629 unit: u,
630 seen: [],
631 inuse: [],
632 tries: 0
635 scan();
638 function joinAddr(a) {
639 var r, i, s;
641 r = [];
642 for (i = 0; i < a.length; ++i) {
643 s = a[i];
644 if ((s != '00:00:00:00:00:00') && (s != '0.0.0.0')) r.push(s);
646 return r.join(' ');
649 function random_x(max)
651 var c = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
652 var s = '';
653 while (max-- > 0) s += c.substr(Math.floor(c.length * Math.random()), 1);
654 return s;
657 function random_psk(id)
659 var e = E(id);
660 e.value = random_x(63);
661 verifyFields(null, 1);
664 function random_wep(u)
666 E('_wl'+u+'_passphrase').value = random_x(16);
667 generate_wep(u);
670 function v_wep(e, quiet)
672 var s = e.value;
674 if (((s.length == 5) || (s.length == 13)) && (s.length == (e.maxLength >> 1))) {
675 // no checking
677 else {
678 s = s.toUpperCase().replace(/[^0-9A-F]/g, '');
679 if (s.length != e.maxLength) {
680 ferror.set(e, 'Invalid WEP key. Expecting ' + e.maxLength + ' hex or ' + (e.maxLength >> 1) + ' ASCII characters.', quiet);
681 return 0;
685 e.value = s;
686 ferror.clear(e);
687 return 1;
690 // compatible w/ Linksys' and Netgear's (key 1) method for 128-bits
691 function generate_wep(u)
693 function _wepgen(pass, i)
695 while (pass.length < 64) pass += pass;
696 return hex_md5(pass.substr(0, 64)).substr(i, (E('_wl'+u+'_wep_bit').value == 128) ? 26 : 10);
699 var e = E('_wl'+u+'_passphrase');
700 var pass = e.value;
701 if (!v_length(e, false, 3)) return;
702 E('_wl'+u+'_key1').value = _wepgen(pass, 0);
703 pass += '#$%';
704 E('_wl'+u+'_key2').value = _wepgen(pass, 2);
705 pass += '!@#';
706 E('_wl'+u+'_key3').value = _wepgen(pass, 4);
707 pass += '%&^';
708 E('_wl'+u+'_key4').value = _wepgen(pass, 6);
709 verifyFields(null, 1);
712 function verifyFields(focused, quiet)
714 var i;
715 var ok = 1;
716 var a, b, c, d, e;
717 var u, uidx;
718 var wmode, sm2;
720 var n = E('_f_lan_state').checked;
721 E('_f_lan_desc').disabled = !n;
722 E('_f_lan_invert').disabled = !n;
724 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
725 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
726 if (wl_sunit(uidx)<0) {
727 u = wl_unit(uidx);
728 if (focused == E('_f_wl'+u+'_nband')) {
729 refreshNetModes(uidx);
730 refreshChannels(uidx);
731 refreshBandWidth(uidx);
733 else if (focused == E('_f_wl'+u+'_nctrlsb') || focused == E('_wl'+u+'_nbw_cap')) {
734 refreshChannels(uidx);
739 // --- visibility ---
741 var vis = {
742 _wan_proto: 1,
743 _ppp_username: 1,
744 _ppp_passwd: 1,
745 _ppp_service: 1,
746 _ppp_custom: 1,
747 _l2tp_server_ip: 1,
748 _wan_ipaddr: 1,
749 _wan_netmask: 1,
750 _wan_gateway: 1,
751 _pptp_server_ip: 1,
752 _f_pptp_dhcp: 1,
753 _ppp_demand: 1,
754 _ppp_idletime: 1,
755 _ppp_redialperiod: 1,
756 _pppoe_lei: 1,
757 _pppoe_lef: 1,
758 _mtu_enable: 1,
759 _f_wan_mtu: 1,
760 _f_wan_islan: 0,
761 _f_ppp_mlppp: 1,
762 _modem_ipaddr: 1,
764 _f_dns_1: 1,
765 _f_dns_2: 1,
766 _f_dns_3: 1,
767 /* DNSSEC-BEGIN */
768 _f_dnssec_enable: 1,
769 /* DNSSEC-END */
770 _lan_gateway: 1,
771 _wan_wins: 1,
772 _modem_pin: 1,
773 _modem_dev: 1,
774 _modem_init: 1,
775 _modem_apn: 1
778 var wl_vis = [];
779 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
780 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
781 if (wl_sunit(uidx)<0) {
782 a = {
783 _f_wl_radio: 1,
784 _f_wl_mode: 1,
785 _f_wl_nband: (bands[uidx].length > 1) ? 1 : 0,
786 _wl_net_mode: 1,
787 _wl_ssid: 1,
788 _f_wl_bcast: 1,
789 _wl_channel: 1,
790 _wl_nbw_cap: nphy || acphy ? 1 : 0,
791 _f_wl_nctrlsb: nphy || acphy ? 1 : 0,
792 _f_wl_scan: 1,
794 _wl_security_mode: 1,
795 _wl_crypto: 1,
796 _wl_wpa_psk: 1,
797 _f_wl_psk_random1: 1,
798 _f_wl_psk_random2: 1,
799 _wl_wpa_gtk_rekey: 1,
800 _wl_radius_key: 1,
801 _wl_radius_ipaddr: 1,
802 _wl_radius_port: 1,
803 _wl_wep_bit: 1,
804 _wl_passphrase: 1,
805 _f_wl_wep_gen: 1,
806 _f_wl_wep_random: 1,
807 _wl_key1: 1,
808 _wl_key2: 1,
809 _wl_key3: 1,
810 _wl_key4: 1,
812 _f_wl_lazywds: 1,
813 _f_wl_wds_0: 1
815 wl_vis.push(a);
819 var wan = E('_wan_proto').value;
821 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
822 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
823 if (wl_sunit(uidx)<0) {
824 wmode = E('_f_wl'+wl_unit(uidx)+'_mode').value;
826 if (wmode == 'wet') {
827 wan = 'disabled';
828 vis._wan_proto = 0;
831 if ((wan == 'disabled') || (wmode == 'sta') || (wmode == 'wet')) {
832 vis._f_wan_islan = 1;
837 switch (wan) {
838 case 'disabled':
839 vis._ppp_username = 0;
840 vis._ppp_service = 0;
841 vis._ppp_custom = 0;
842 vis._l2tp_server_ip = 0;
843 vis._wan_ipaddr = 0;
844 vis._wan_netmask = 0;
845 vis._wan_gateway = 0;
846 vis._pptp_server_ip = 0;
847 vis._f_pptp_dhcp = 0;
848 vis._ppp_demand = 0;
849 vis._mtu_enable = 0;
850 vis._f_wan_mtu = 0;
851 vis._f_ppp_mlppp = 0;
852 vis._modem_ipaddr = 0;
853 vis._modem_pin = 0;
854 vis._modem_dev = 0;
855 vis._modem_init = 0;
856 vis._modem_apn = 0;
857 vis._pppoe_lei = 0;
858 vis._pppoe_lef = 0;
859 break;
860 case 'dhcp':
861 vis._l2tp_server_ip = 0;
862 vis._pppoe_lei = 0;
863 vis._pppoe_lef = 0;
864 vis._ppp_demand = 0;
865 vis._ppp_service = 0;
866 vis._ppp_username = 0;
867 vis._ppp_custom = 0;
868 vis._pptp_server_ip = 0;
869 vis._f_pptp_dhcp = 0;
870 vis._wan_gateway = 0;
871 vis._wan_ipaddr = 0;
872 vis._wan_netmask = 0;
873 vis._f_ppp_mlppp = 0;
874 vis._modem_ipaddr = 1;
876 vis._lan_gateway = 0;
877 vis._modem_pin = 0;
878 vis._modem_dev = 0;
879 vis._modem_init = 0;
880 vis._modem_apn = 0;
881 break;
882 case 'pppoe':
883 vis._l2tp_server_ip = 0;
884 vis._pptp_server_ip = 0;
885 vis._f_pptp_dhcp = 0;
886 vis._wan_gateway = 0;
887 vis._wan_ipaddr = 0;
888 vis._wan_netmask = 0;
889 vis._modem_ipaddr = 1;
891 vis._lan_gateway = 0;
892 vis._modem_pin = 0;
893 vis._modem_dev = 0;
894 vis._modem_init = 0;
895 vis._modem_apn = 0;
896 break;
897 case 'ppp3g':
898 vis._pppoe_lei = 0;
899 vis._pppoe_lef = 0;
900 vis._ppp_service = 0;
901 vis._l2tp_server_ip = 0;
902 vis._pptp_server_ip = 0;
903 vis._f_pptp_dhcp = 0;
904 vis._wan_gateway = 0;
905 vis._wan_ipaddr = 0;
906 vis._wan_netmask = 0;
907 vis._lan_gateway = 0;
908 vis._modem_ipaddr = 0;
909 vis._f_ppp_mlppp = 0;
910 break;
911 case 'lte':
912 vis._pppoe_lei = 0;
913 vis._pppoe_lef = 0;
914 vis._ppp_service = 0;
915 vis._ppp_demand = 0;
916 vis._ppp_service = 0;
917 vis._ppp_username = 0;
918 vis._ppp_custom = 0;
919 vis._l2tp_server_ip = 0;
920 vis._pptp_server_ip = 0;
921 vis._f_pptp_dhcp = 0;
922 vis._wan_gateway = 0;
923 vis._wan_ipaddr = 0;
924 vis._wan_netmask = 0;
925 vis._lan_gateway = 0;
926 vis._modem_ipaddr = 0;
927 vis._modem_dev = 0;
928 vis._modem_init = 0;
929 vis._f_ppp_mlppp = 0;
930 break;
931 case 'static':
932 vis._pppoe_lei = 0;
933 vis._pppoe_lef = 0;
934 vis._l2tp_server_ip = 0;
935 vis._ppp_demand = 0;
936 vis._ppp_service = 0;
937 vis._ppp_username = 0;
938 vis._ppp_custom = 0;
939 vis._pptp_server_ip = 0;
940 vis._f_pptp_dhcp = 0;
941 vis._f_ppp_mlppp = 0;
942 vis._modem_ipaddr = 1;
944 vis._lan_gateway = 0;
945 vis._modem_pin = 0;
946 vis._modem_dev = 0;
947 vis._modem_init = 0;
948 vis._modem_apn = 0;
949 break;
950 case 'pptp':
951 vis._pppoe_lei = 0;
952 vis._pppoe_lef = 0;
953 vis._l2tp_server_ip = 0;
954 vis._ppp_service = 0;
955 vis._wan_gateway = (!E('_f_pptp_dhcp').checked);
956 vis._wan_ipaddr = (!E('_f_pptp_dhcp').checked);
957 vis._modem_ipaddr = 0;
959 vis._lan_gateway = 0;
960 vis._modem_pin = 0;
961 vis._modem_dev = 0;
962 vis._modem_init = 0;
963 vis._modem_apn = 0;
964 break;
965 case 'l2tp':
966 vis._pppoe_lei = 0;
967 vis._pppoe_lef = 0;
968 vis._pptp_server_ip = 0;
969 vis._ppp_service = 0;
970 vis._wan_gateway = (!E('_f_pptp_dhcp').checked);
971 vis._wan_ipaddr = (!E('_f_pptp_dhcp').checked);
972 vis._modem_ipaddr = 0;
974 vis._lan_gateway = 0;
975 vis._modem_pin = 0;
976 vis._modem_dev = 0;
977 vis._modem_init = 0;
978 vis._modem_apn = 0;
979 break;
982 vis._ppp_idletime = (E('_ppp_demand').value == 1) && vis._ppp_demand
983 vis._ppp_redialperiod = !vis._ppp_idletime && vis._ppp_demand;
985 if (vis._mtu_enable) {
986 if (E('_mtu_enable').value == 0) {
987 vis._f_wan_mtu = 2;
988 a = E('_f_wan_mtu');
989 switch (E('_wan_proto').value) {
990 case 'pppoe':
991 a.value = 1492;
992 break;
993 case 'pptp':
994 case 'l2tp':
995 a.value = 1460;
996 break;
997 default:
998 a.value = 1500;
999 break;
1004 /* DNSCRYPT-BEGIN */
1005 var p = E('_f_dnscrypt_proxy').checked;
1006 vis._dnscrypt_priority = p;
1007 vis._dnscrypt_port = p;
1008 vis._dnscrypt_log = p;
1009 vis._f_dnscrypt_manual = p;
1010 var q = E('_f_dnscrypt_proxy').checked && E('_f_dnscrypt_manual').checked;
1011 vis._dnscrypt_provider_name = q;
1012 vis._dnscrypt_provider_key = q;
1013 vis._dnscrypt_resolver_address = q;
1014 var r = E('_f_dnscrypt_proxy').checked && !E('_f_dnscrypt_manual').checked;
1015 vis._dnscrypt_resolver = r;
1016 /* DNSCRYPT-END */
1018 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1019 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1020 if (wl_sunit(uidx)<0) {
1021 u = wl_unit(uidx);
1022 wmode = E('_f_wl'+u+'_mode').value;
1024 if (!E('_f_wl'+u+'_radio').checked) {
1025 for (a in wl_vis[uidx]) {
1026 wl_vis[uidx][a] = 2;
1028 wl_vis[uidx]._f_wl_radio = 1;
1029 wl_vis[uidx]._wl_nbw_cap = nphy || acphy ? 2 : 0;
1030 wl_vis[uidx]._f_wl_nband = (bands[uidx].length > 1) ? 2 : 0;
1033 switch (wmode) {
1034 case 'apwds':
1035 case 'wds':
1036 break;
1037 case 'wet':
1038 case 'sta':
1039 wl_vis[uidx]._f_wl_bcast = 0;
1040 wl_vis[uidx]._wl_channel = 0;
1041 wl_vis[uidx]._wl_nbw_cap = 0;
1042 vis._modem_ipaddr = 0;
1043 default:
1044 wl_vis[uidx]._f_wl_lazywds = 0;
1045 wl_vis[uidx]._f_wl_wds_0 = 0;
1046 break;
1049 sm2 = E('_wl'+u+'_security_mode').value;
1050 switch (sm2) {
1051 case 'disabled':
1052 wl_vis[uidx]._wl_crypto = 0;
1053 wl_vis[uidx]._wl_wep_bit = 0;
1054 wl_vis[uidx]._wl_wpa_psk = 0;
1055 wl_vis[uidx]._wl_radius_key = 0;
1056 wl_vis[uidx]._wl_radius_ipaddr = 0;
1057 wl_vis[uidx]._wl_wpa_gtk_rekey = 0;
1058 break;
1059 case 'wep':
1060 wl_vis[uidx]._wl_crypto = 0;
1061 wl_vis[uidx]._wl_wpa_psk = 0;
1062 wl_vis[uidx]._wl_radius_key = 0;
1063 wl_vis[uidx]._wl_radius_ipaddr = 0;
1064 wl_vis[uidx]._wl_wpa_gtk_rekey = 0;
1065 break;
1066 case 'radius':
1067 wl_vis[uidx]._wl_crypto = 0;
1068 wl_vis[uidx]._wl_wpa_psk = 0;
1069 break;
1070 default: // wpa*
1071 wl_vis[uidx]._wl_wep_bit = 0;
1072 if (sm2.indexOf('personal') != -1) {
1073 wl_vis[uidx]._wl_radius_key = 0;
1074 wl_vis[uidx]._wl_radius_ipaddr = 0;
1076 else {
1077 wl_vis[uidx]._wl_wpa_psk = 0;
1079 break;
1082 if ((E('_f_wl'+u+'_lazywds').value == 1) && (wl_vis[uidx]._f_wl_wds_0 == 1)) {
1083 wl_vis[uidx]._f_wl_wds_0 = 2;
1086 if (wl_vis[uidx]._wl_nbw_cap != 0) {
1087 switch (E('_wl'+u+'_net_mode').value) {
1088 case 'b-only':
1089 case 'g-only':
1090 case 'a-only':
1091 case 'bg-mixed':
1092 wl_vis[uidx]._wl_nbw_cap = 2;
1093 if (E('_wl'+u+'_nbw_cap').value != '0') {
1094 E('_wl'+u+'_nbw_cap').value = 0;
1095 refreshChannels(uidx);
1097 break;
1099 // avoid Enterprise-TKIP with 40MHz
1100 if ((sm2 == 'wpa_enterprise') && (E('_wl'+u+'_crypto').value == 'tkip')) {
1101 wl_vis[uidx]._wl_nbw_cap = 2;
1102 if (E('_wl'+u+'_nbw_cap').value != '0') {
1103 E('_wl'+u+'_nbw_cap').value = 0;
1104 refreshChannels(uidx);
1109 wl_vis[uidx]._f_wl_nctrlsb = (E('_wl'+u+'_nbw_cap').value == 0) ? 0 : wl_vis[uidx]._wl_nbw_cap;
1111 /* REMOVE-BEGIN
1112 This is ugly...
1113 Special case - 2.4GHz band, currently running in B/G-only mode,
1114 with N/Auto and 40MHz selected in the GUI.
1115 Channel list is not filtered in this case by the wl driver,
1116 and includes all channels available with 20MHz channel width.
1117 REMOVE-END */
1118 b = selectedBand(uidx);
1119 if (wl_vis[uidx]._wl_channel == 1 && wl_vis[uidx]._f_wl_nctrlsb != 0 &&
1120 ((b == '2') || (wl_vis[uidx]._f_wl_nband == 0 && b == '0'))) {
1121 switch (eval('nvram.wl'+u+'_net_mode')) {
1122 case 'b-only':
1123 case 'g-only':
1124 case 'bg-mixed':
1125 i = E('_wl'+u+'_channel').value * 1;
1126 if (i > 0 && i < 5) {
1127 E('_f_wl'+u+'_nctrlsb').value = 'lower';
1128 wl_vis[uidx]._f_wl_nctrlsb = 2;
1130 else if (i > max_channel[uidx] - 4) {
1131 E('_f_wl'+u+'_nctrlsb').value = 'upper';
1132 wl_vis[uidx]._f_wl_nctrlsb = 2;
1134 break;
1138 wl_vis[uidx]._f_wl_scan = wl_vis[uidx]._wl_channel;
1139 wl_vis[uidx]._f_wl_psk_random1 = wl_vis[uidx]._wl_wpa_psk;
1140 wl_vis[uidx]._f_wl_psk_random2 = wl_vis[uidx]._wl_radius_key;
1141 wl_vis[uidx]._wl_radius_port = wl_vis[uidx]._wl_radius_ipaddr;
1142 wl_vis[uidx]._wl_key1 = wl_vis[uidx]._wl_key2 = wl_vis[uidx]._wl_key3 = wl_vis[uidx]._wl_key4 = wl_vis[uidx]._f_wl_wep_gen = wl_vis[uidx]._f_wl_wep_random = wl_vis[uidx]._wl_passphrase = wl_vis[uidx]._wl_wep_bit;
1144 for (i = 1; i < 10; ++i) {
1145 wl_vis[uidx]['_f_wl_wds_' + i] = wl_vis[uidx]._f_wl_wds_0;
1148 } // for each wl_iface
1150 vis._ppp_passwd = vis._ppp_username;
1152 for (a in vis) {
1153 b = E(a);
1154 c = vis[a];
1155 /* REMOVE-BEGIN
1156 // if (b != null)
1157 REMOVE-END */
1158 b.disabled = (c != 1);
1159 PR(b).style.display = c ? '' : 'none';
1162 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1163 if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1164 for (a in wl_vis[uidx]) {
1165 i = 3;
1166 if (a.substr(0, 6) == '_f_wl_') i = 5;
1167 b = E(a.substr(0, i) + wl_unit(uidx) + a.substr(i, a.length));
1168 c = wl_vis[uidx][a];
1169 b.disabled = (c != 1);
1170 PR(b).style.display = c ? '' : 'none';
1175 // --- verify ---
1177 ferror.clear('_wan_proto');
1179 var wlclnt = 0;
1180 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1181 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1182 if (wl_sunit(uidx)<0) {
1183 u = wl_unit(uidx);
1184 wmode = E('_f_wl'+u+'_mode').value;
1185 sm2 = E('_wl'+u+'_security_mode').value;
1187 /* REMOVE-BEGIN
1188 if ((wl_vis[uidx]._f_wl_mode == 1) && (wmode != 'ap') && (sm2.substr(0, 4) == 'wpa2')) {
1189 ferror.set('_wl'+u+'_security_mode', 'WPA2 is supported only in AP mode.', quiet || !ok);
1190 ok = 0;
1192 else ferror.clear('_wl'+u+'_security_mode');
1193 REMOVE-END */
1195 // --- N standard does not support WPA+TKIP ---
1196 a = E('_wl'+u+'_crypto');
1197 switch (E('_wl'+u+'_net_mode').value) {
1198 case 'mixed':
1199 case 'n-only':
1200 if ((nphy || acphy) && (a.value == 'tkip') && (sm2.indexOf('wpa') != -1)) {
1201 ferror.set(a, 'TKIP encryption is not supported with WPA / WPA2 in N and AC mode.', quiet || !ok);
1202 ok = 0;
1204 else ferror.clear(a);
1205 break;
1208 a = E('_wl'+u+'_net_mode');
1209 ferror.clear(a);
1210 b = E('_f_wl'+u+'_mode');
1211 ferror.clear(b);
1212 if ((wmode == 'sta') || (wmode == 'wet')) {
1213 ++wlclnt;
1214 if (wlclnt > 1) {
1215 ferror.set(b, 'Only one wireless interface can be configured in client mode.', quiet || !ok);
1216 ok = 0;
1218 else if (a.value == 'n-only') {
1219 ferror.set(a, 'N-only is not supported in wireless client modes, use Auto.', quiet || !ok);
1220 ok = 0;
1224 a = E('_wl'+u+'_wpa_psk');
1225 ferror.clear(a);
1226 if (wl_vis[uidx]._wl_wpa_psk == 1) {
1227 if ((a.value.length < 8) || ((a.value.length == 64) && (a.value.search(/[^0-9A-Fa-f]/) != -1))) {
1228 ferror.set('_wl'+u+'_wpa_psk', 'Invalid pre-shared key. Please enter at least 8 characters or 64 hexadecimal digits.', quiet || !ok);
1229 ok = 0;
1233 // wl channel
1234 if (((wmode == 'wds') || (wmode == 'apwds')) && (wl_vis[uidx]._wl_channel == 1) && (E('_wl'+u+'_channel').value == '0')) {
1235 ferror.set('_wl'+u+'_channel', 'Fixed wireless channel required in WDS mode.', quiet || !ok);
1236 ok = 0;
1238 else ferror.clear('_wl'+u+'_channel');
1240 if (E('_f_wl'+u+'_mode').value == 'sta') {
1241 if ((wan == 'disabled') && (E('_f_wl'+u+'_radio').checked)) {
1242 ferror.set('_wan_proto', 'Wireless Client mode requires a valid WAN setting (usually DHCP).', quiet || !ok);
1243 ok = 0;
1249 // domain name or IP address
1250 a = ['_l2tp_server_ip', '_pptp_server_ip'];
1251 for (i = a.length - 1; i >= 0; --i)
1252 if ((vis[a[i]]) && ((!v_length(a[i], 1, 1)) || ((!v_ip(a[i], 1)) && (!v_domain(a[i], 1))))) {
1253 if (!quiet && ok) ferror.show(a[i]);
1254 ok = 0;
1257 // IP address
1258 a = ['_wan_gateway','_wan_ipaddr'];
1259 for (i = a.length - 1; i >= 0; --i)
1260 if ((vis[a[i]]) && (!v_ip(a[i], quiet || !ok))) ok = 0;
1262 // IP address, blank -> 0.0.0.0
1263 a = ['_f_dns_1', '_f_dns_2', '_f_dns_3','_wan_wins','_lan_gateway', '_modem_ipaddr'];
1264 for (i = a.length - 1; i >= 0; --i)
1265 if ((vis[a[i]]) && (!v_dns(a[i], quiet || !ok))) ok = 0;
1267 // netmask
1268 a = ['_wan_netmask'];
1269 for (i = a.length - 1; i >= 0; --i)
1270 if ((vis[a[i]]) && (!v_netmask(a[i], quiet || !ok))) ok = 0;
1272 // range
1273 a = [['_ppp_idletime', 3, 1440],['_ppp_redialperiod', 1, 86400],['_f_wan_mtu', 576, 1500],
1274 ['_pppoe_lei', 1, 60],['_pppoe_lef', 1, 10]];
1275 for (i = a.length - 1; i >= 0; --i) {
1276 v = a[i];
1277 if ((vis[v[0]]) && (!v_range(v[0], quiet || !ok, v[1], v[2]))) ok = 0;
1280 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1281 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1282 if (wl_sunit(uidx)<0) {
1283 u = wl_unit(uidx);
1285 // IP address
1286 a = ['_radius_ipaddr'];
1287 for (i = a.length - 1; i >= 0; --i) {
1288 if ((wl_vis[uidx]['_wl'+a[i]]) && (!v_ip('_wl'+u+a[i], quiet || !ok))) ok = 0;
1291 // range
1292 a = [['_wpa_gtk_rekey', 60, 7200], ['_radius_port', 1, 65535]];
1293 for (i = a.length - 1; i >= 0; --i) {
1294 v = a[i];
1295 if ((wl_vis[uidx]['_wl'+v[0]]) && (!v_range('_wl'+u+v[0], quiet || !ok, v[1], v[2]))) ok = 0;
1298 // length
1299 a = [['_ssid', 1], ['_radius_key', 1]];
1300 for (i = a.length - 1; i >= 0; --i) {
1301 v = a[i];
1302 if ((wl_vis[uidx]['_wl'+v[0]]) && (!v_length('_wl'+u+v[0], quiet || !ok, v[1], E('_wl'+u+v[0]).maxlength))) ok = 0;
1305 if (wl_vis[uidx]._wl_key1) {
1306 a = (E('_wl'+u+'_wep_bit').value == 128) ? 26 : 10;
1307 for (i = 1; i <= 4; ++i) {
1308 b = E('_wl'+u+'_key' + i);
1309 b.maxLength = a;
1310 if ((b.value.length > 0) || (E('_f_wl'+u+'_wepidx_' + i).checked)) {
1311 if (!v_wep(b, quiet || !ok)) ok = 0;
1313 else ferror.clear(b);
1317 ferror.clear('_f_wl'+u+'_wds_0');
1318 if (wl_vis[uidx]._f_wl_wds_0 == 1) {
1319 b = 0;
1320 for (i = 0; i < 10; ++i) {
1321 a = E('_f_wl'+u+'_wds_' + i);
1322 if (!v_macz(a, quiet || !ok)) ok = 0;
1323 else if (!isMAC0(a.value)) b = 1;
1325 if (!b) {
1326 ferror.set('_f_wl'+u+'_wds_0', 'WDS MAC address required.', quiet || !ok);
1327 ok = 0;
1333 return ok;
1336 function earlyInit()
1338 verifyFields(null, 1);
1341 function save()
1343 if (lg.isEditing()) return;
1344 lg.resetNewEditor();
1346 var a, b, c;
1347 var i;
1348 var u, uidx, wmode, sm2, wradio;
1350 if (!verifyFields(null, false)) return;
1352 var fom = E('_fom');
1354 fom.wan_mtu.value = fom.f_wan_mtu.value;
1355 fom.wan_mtu.disabled = fom.f_wan_mtu.disabled;
1357 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1358 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1359 if (wl_sunit(uidx)<0) {
1360 u = wl_unit(uidx);
1361 wmode = E('_f_wl'+u+'_mode').value;
1362 sm2 = E('_wl'+u+'_security_mode').value;
1363 wradio = E('_f_wl'+u+'_radio').checked;
1365 E('_wl'+u+'_nband').value = selectedBand(uidx);
1367 if (wmode == 'apwds') E('_wl'+u+'_mode').value = 'ap';
1368 else E('_wl'+u+'_mode').value = wmode;
1370 if (wmode == 'wet') {
1371 for (wan_uidx = 1; wan_uidx <= maxwan_num; ++wan_uidx) {
1372 var v = (wan_uidx>1) ? wan_uidx : '';
1373 E('_wan'+v+'_proto').value = 'disabled';
1375 /* REMOVE-BEGIN */
1376 // TODO - what's required ? integrate with tomatogrid?
1377 /* REMOVE-END */
1380 a = [];
1381 for (i = 0; i < 10; ++i) a.push(E('_f_wl'+u+'_wds_' + i).value);
1382 E('_wl'+u+'_wds').value = joinAddr(a);
1384 if (wmode.indexOf('wds') != -1) {
1385 E('_wl'+u+'_wds_enable').value = 1;
1386 E('_wl'+u+'_lazywds').value = E('_f_wl'+u+'_lazywds').value;
1387 if (E('_wl'+u+'_lazywds').value == 1) E('_wl'+u+'_wds').value = '';
1389 else {
1390 E('_wl'+u+'_wds_enable').value = 0;
1391 E('_wl'+u+'_wds').value = '';
1392 E('_wl'+u+'_lazywds').value = 0;
1395 E('_wl'+u+'_radio').value = wradio ? 1 : 0;
1396 E('_wl'+u+'_auth').value = eval('nvram.wl'+u+'_auth');
1398 e = E('_wl'+u+'_akm');
1399 switch (sm2) {
1400 case 'disabled':
1401 case 'radius':
1402 case 'wep':
1403 e.value = '';
1404 break;
1405 default:
1406 c = [];
1408 if (sm2.indexOf('personal') != -1) {
1409 if (sm2.indexOf('wpa2_') == -1) c.push('psk');
1410 if (sm2.indexOf('wpa_') == -1) c.push('psk2');
1412 else {
1413 if (sm2.indexOf('wpa2_') == -1) c.push('wpa');
1414 if (sm2.indexOf('wpa_') == -1) c.push('wpa2');
1416 c = c.join(' ');
1417 e.value = c;
1418 break;
1420 E('_wl'+u+'_auth_mode').value = (sm2 == 'radius') ? 'radius' : 'none';
1421 E('_wl'+u+'_wep').value = ((sm2 == 'radius') || (sm2 == 'wep')) ? 'enabled': 'disabled';
1423 if (sm2.indexOf('wpa') != -1) E('_wl'+u+'_auth').value = 0;
1425 E('_wl'+u+'_nreqd').value = 0;
1426 E('_wl'+u+'_gmode').value = 1;
1427 E('_wl'+u+'_nmode').value = 0;
1428 E('_wl'+u+'_nmcsidx').value = -2; // Legacy Rate
1429 E('_wl'+u+'_nbw').value = 0;
1430 switch (E('_wl'+u+'_net_mode').value) {
1431 case 'b-only':
1432 E('_wl'+u+'_gmode').value = 0;
1433 break;
1434 case 'g-only':
1435 E('_wl'+u+'_gmode').value = 4;
1436 break;
1437 case 'bg-mixed':
1438 break;
1439 case 'a-only':
1440 E('_wl'+u+'_nmcsidx').value = -1; // Auto
1441 break;
1442 case 'n-only':
1443 if (selectedBand(uidx) == '1') { // 5 GHz
1444 E('_wl'+u+'_nmode').value = -1;
1445 E('_wl'+u+'_nmcsidx').value = -1;
1446 } else {
1447 E('_wl'+u+'_nmode').value = 1;
1448 E('_wl'+u+'_nmcsidx').value = 32;
1450 E('_wl'+u+'_nreqd').value = 1;
1451 break;
1452 default: // Auto
1453 E('_wl'+u+'_nmode').value = -1;
1454 E('_wl'+u+'_nmcsidx').value = -1;
1455 break;
1458 E('_wl'+u+'_nctrlsb').value = eval('nvram.wl'+u+'_nctrlsb');
1459 if (E('_wl'+u+'_nmode').value != 0) {
1460 E('_wl'+u+'_nctrlsb').value = E('_f_wl'+u+'_nctrlsb').value;
1461 E('_wl'+u+'_nbw').value = (E('_wl'+u+'_nbw_cap').value == 0) ? 20 : ((E('_wl'+u+'_nbw_cap').value== 3) ? 80:40);
1464 E('_wl'+u+'_closed').value = E('_f_wl'+u+'_bcast').checked ? 0 : 1;
1466 a = fields.radio.selected(eval('fom.f_wl'+u+'_wepidx'));
1467 if (a) E('_wl'+u+'_key').value = a.value;
1471 fom.wan_islan.value = fom.f_wan_islan.checked ? 1 : 0;
1472 fom.pptp_dhcp.value = fom.f_pptp_dhcp.checked ? 1 : 0;
1474 fom.wan_dns.value = joinAddr([fom.f_dns_1.value, fom.f_dns_2.value, fom.f_dns_3.value]);
1476 /* DNSSEC-BEGIN */
1477 fom.dnssec_enable.value = fom.f_dnssec_enable.checked ? 1 : 0;
1478 /* DNSSEC-END */
1480 /* DNSCRYPT-BEGIN */
1481 fom.dnscrypt_proxy.value = fom.f_dnscrypt_proxy.checked ? 1 : 0;
1482 fom.dnscrypt_manual.value = fom.f_dnscrypt_manual.checked ? 1 : 0;
1483 /* DNSCRYPT-END */
1485 fom.lan_state.value = fom.f_lan_state.checked ? 1 : 0;
1486 fom.lan_desc.value = fom.f_lan_desc.checked ? 1 : 0;
1487 fom.lan_invert.value = fom.f_lan_invert.checked ? 1 : 0;
1489 // initialize/wipe out relevant fields
1490 for (var i = 0 ; i <= MAX_BRIDGE_ID ; i++) {
1491 var j = (i == 0) ? '' : i.toString();
1492 fom['lan' + j + '_ifname'].value = '';
1493 fom['lan' + j + '_ipaddr'].value = '';
1494 fom['lan' + j + '_netmask'].value = '';
1495 fom['lan' + j + '_proto'].value = '';
1496 fom['lan' + j + '_stp'].value = '';
1497 fom['dhcp' + j + '_start'].value = '';
1498 fom['dhcp' + j + '_num'].value = '';
1499 fom['dhcp' + j + '_lease'].value = '';
1500 fom['dhcpd' + j + '_startip'].value = '';
1501 fom['dhcpd' + j + '_endip'].value = '';
1504 var d = lg.getAllData();
1505 for (var i = 0; i < d.length; ++i) {
1507 if (lg.countOverlappingNetworks(d[i][2]) > 1) {
1508 var s = 'Cannot proceed: two or more LAN bridges have conflicting IP addresses or overlapping subnets';
1509 alert(s);
1510 var e = E('footer-msg');
1511 e.innerHTML = s;
1512 e.style.visibility = 'visible';
1513 setTimeout(
1514 function() {
1515 e.innerHTML = '';
1516 e.style.visibility = 'hidden';
1517 }, 5000);
1518 return;
1521 var j = (parseInt(d[i][0]) == 0) ? '' : d[i][0].toString();
1522 fom['lan' + j + '_ifname'].value = 'br' + d[i][0];
1523 fom['lan' + j + '_stp'].value = d[i][1];
1524 fom['lan' + j + '_ipaddr'].value = d[i][2];
1525 fom['lan' + j + '_netmask'].value = d[i][3];
1526 fom['lan' + j + '_proto'].value = (d[i][4] != '0') ? 'dhcp' : 'static';
1527 fom['dhcp' + j + '_start'].value = (d[i][4] != '0') ? (d[i][5]).split('.').splice(3, 1) : '';
1528 fom['dhcp' + j + '_num'].value = (d[i][4] != '0') ? d[i][6].split('.').splice(3, 1) - (d[i][5]).split('.').splice(3, 1) + 1 : ''; // presuming /24 subnet (legacy)
1529 fom['dhcp' + j + '_lease'].value = (d[i][4] != '0') ? d[i][7] : '';
1530 fom['dhcpd' + j + '_startip'].value = (d[i][4] != '0') ? d[i][5] : '';
1531 fom['dhcpd' + j + '_endip'].value = (d[i][4] != '0') ? d[i][6] : '';
1533 /* REMOVE-BEGIN */
1534 alert('lan' + j + '_ifname=' + fom['lan' + j + '_ifname'].value + '\n' +
1535 'lan' + j + '_stp=' + fom['lan' + j + '_stp'].value + '\n' +
1536 'lan' + j + '_ipaddr=' + fom['lan' + j + '_ipaddr'].value + '\n' +
1537 'lan' + j + '_netmask=' + fom['lan' + j + '_netmask'].value + '\n' +
1538 'lan' + j + '_proto=' + fom['lan' + j + '_proto'].value + '\n' +
1539 'dhcp' + j + '_start=' + fom['dhcp' + j + '_start'].value + '\n' +
1540 'dhcp' + j + '_num=' + fom['dhcp' + j + '_num'].value + '\n' +
1541 'dhcp' + j + '_lease=' + fom['dhcp' + j + '_lease'].value + '\n' +
1542 'dhcpd' + j + '_startip=' + fom['dhcpd' + j + '_startip'].value + '\n' +
1543 'dhcpd' + j + '_endip=' + fom['dhcpd' + j + '_endip'].value);
1544 /* REMOVE-END */
1547 var e = E('footer-msg');
1548 var t = fixIP(fom['lan_ipaddr'].value);
1549 if ((fom['lan_ifname'].value != 'br0') || (fom['lan_ipaddr'].value == '0.0.0.0') || (!t)) {
1550 e.innerHTML = 'Bridge br0 must be always defined and have a valid IP address set.';
1551 e.style.visibility = 'visible';
1552 setTimeout(
1553 function() {
1554 e.innerHTML = '';
1555 e.style.visibility = 'hidden';
1556 }, 5000);
1557 return;
1560 /* REMOVE-BEGIN
1561 // if ((nvram.lan_ipaddr != fom.lan_ipaddr.value) || (nvram.lan1_ipaddr != fom.lan1_ipaddr.value) ||
1562 // (nvram.lan2_ipaddr != fom.lan2_ipaddr.value) || (nvram.lan3_ipaddr != fom.lan3_ipaddr.value)){
1563 REMOVE-END */
1565 fom.ppp_mlppp.value = fom.f_ppp_mlppp.checked ? 1 : 0;
1567 if (nvram.lan_ipaddr != fom.lan_ipaddr.value) {
1568 fom._moveip.value = 1;
1569 form.submit(fom);
1571 else {
1572 form.submit(fom, 1);
1576 function init()
1578 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1579 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1580 if (wl_sunit(uidx)<0) {
1581 refreshNetModes(uidx);
1582 refreshChannels(uidx);
1583 refreshBandWidth(uidx);
1587 </script>
1589 </head>
1590 <body onload='init()'>
1591 <form id='_fom' method='post' action='tomato.cgi'>
1592 <table id='container' cellspacing=0>
1593 <tr><td colspan=2 id='header'>
1594 <div class='title'>Tomato</div>
1595 <div class='version'>Version <% version(); %></div>
1596 </td></tr>
1597 <tr id='body'><td id='navi'><script type='text/javascript'>navi()</script></td>
1598 <td id='content'>
1599 <div id='ident'><% ident(); %></div>
1601 <!-- / / / -->
1603 <input type='hidden' name='_nextpage' value='basic-network.asp'>
1604 <input type='hidden' name='_nextwait' value='10'>
1605 <input type='hidden' name='_service' value='*'>
1606 <input type='hidden' name='_moveip' value='0'>
1608 <input type='hidden' name='wan_mtu'>
1609 <input type='hidden' name='wan_islan'>
1610 <input type='hidden' name='pptp_dhcp'>
1611 <input type='hidden' name='wan_dns'>
1612 <input type='hidden' name='ppp_mlppp'>
1613 <!-- DNSSEC-BEGIN -->
1614 <input type='hidden' name='dnssec_enable'>
1615 <!-- DNSSEC-END -->
1616 /* DNSCRYPT-BEGIN */
1617 <input type='hidden' name='dnscrypt_proxy'>
1618 <input type='hidden' name='dnscrypt_manual'>
1619 /* DNSCRYPT-END */
1620 <input type='hidden' name='lan_state'>
1621 <input type='hidden' name='lan_desc'>
1622 <input type='hidden' name='lan_invert'>
1624 <script type='text/javascript'>
1626 for (var i = 0 ; i <= MAX_BRIDGE_ID ; i++) {
1627 var j = (i == 0) ? '' : i.toString();
1628 W('<input type=\'hidden\' id=\'lan' + j + '_ifname\' name=\'lan' + j + '_ifname\'>');
1629 W('<input type=\'hidden\' id=\'lan' + j + '_ipaddr\' name=\'lan' + j + '_ipaddr\'>');
1630 W('<input type=\'hidden\' id=\'lan' + j + '_netmask\' name=\'lan' + j + '_netmask\'>');
1631 W('<input type=\'hidden\' id=\'lan' + j + '_proto\' name=\'lan' + j + '_proto\'>');
1632 W('<input type=\'hidden\' id=\'lan' + j + '_stp\' name=\'lan' + j + '_stp\'>');
1633 W('<input type=\'hidden\' id=\'dhcp' + j + '_start\' name=\'dhcp' + j + '_start\'>');
1634 W('<input type=\'hidden\' id=\'dhcp' + j + '_num\' name=\'dhcp' + j + '_num\'>');
1635 W('<input type=\'hidden\' id=\'dhcp' + j + '_lease\' name=\'dhcp' + j + '_lease\'>');
1636 W('<input type=\'hidden\' id=\'dhcpd' + j + '_startip\' name=\'dhcpd' + j + '_startip\'>');
1637 W('<input type=\'hidden\' id=\'dhcpd' + j + '_endip\' name=\'dhcpd' + j + '_endip\'>');
1639 </script>
1641 <div class='section-title'>WAN / Internet</div>
1642 <div class='section'>
1643 <script type='text/javascript'>
1644 createFieldTable('', [
1645 { title: 'Type', name: 'wan_proto', type: 'select', options: [['dhcp','DHCP'],['pppoe','PPPoE'],['static','Static'],['pptp','PPTP'],['l2tp','L2TP'],
1646 /* LINUX26-BEGIN */
1647 /* USB-BEGIN */
1648 ['ppp3g','3G Modem'],
1649 ['lte','4G/LTE'],
1650 /* USB-END */
1651 /* LINUX26-END */
1652 ['disabled','Disabled']],
1653 value: nvram.wan_proto },
1654 { title: 'Modem device', name: 'modem_dev', type: 'select', options: [['ttyUSB0', '/dev/ttyUSB0'],['ttyUSB1', '/dev/ttyUSB1'],['ttyUSB2', '/dev/ttyUSB2'],['ttyUSB3', '/dev/ttyUSB3'],['ttyUSB4', '/dev/ttyUSB4'],['ttyUSB5', '/dev/ttyUSB5'],['ttyUSB6', '/dev/ttyUSB6'],['ttyACM0', '/dev/ttyACM0']], value: nvram.modem_dev },
1655 { title: 'PIN Code', name: 'modem_pin', type: 'text', maxlen: 6, size: 8, value: nvram.modem_pin, suffix: ' <i>Advised to turn off PIN Code</i>' },
1656 { title: 'Modem init string', name: 'modem_init', type: 'text', maxlen: 25, size: 32, value: nvram.modem_init },
1657 { title: 'APN', name: 'modem_apn', type: 'text', maxlen: 25, size: 32, value: nvram.modem_apn },
1658 { title: 'Username', name: 'ppp_username', type: 'text', maxlen: 60, size: 64, value: nvram.ppp_username },
1659 { title: 'Password', name: 'ppp_passwd', type: 'password', maxlen: 60, size: 64, peekaboo: 1, value: nvram.ppp_passwd },
1660 { title: 'Service Name', name: 'ppp_service', type: 'text', maxlen: 50, size: 64, value: nvram.ppp_service },
1661 { title: 'L2TP Server', name: 'l2tp_server_ip', type: 'text', maxlen: 128, size: 64, value: nvram.l2tp_server_ip },
1662 { title: 'Use DHCP', name: 'f_pptp_dhcp', type: 'checkbox', value: (nvram.pptp_dhcp == 1) },
1663 { title: 'IP Address', name: 'wan_ipaddr', type: 'text', maxlen: 15, size: 17, value: nvram.wan_ipaddr },
1664 { title: 'Subnet Mask', name: 'wan_netmask', type: 'text', maxlen: 15, size: 17, value: nvram.wan_netmask },
1665 { title: 'Gateway', name: 'wan_gateway', type: 'text', maxlen: 15, size: 17, value: nvram.wan_gateway },
1666 { title: 'PPTP Gateway', name: 'pptp_server_ip', type: 'text', maxlen: 128, size: 64, value: nvram.pptp_server_ip },
1667 { title: 'Options', name: 'ppp_custom', type: 'text', maxlen: 256, size: 64, value: nvram.ppp_custom },
1668 { title: 'Connect Mode', name: 'ppp_demand', type: 'select', options: [['1', 'Connect On Demand'],['0', 'Keep Alive']],
1669 value: nvram.ppp_demand },
1670 { title: 'Max Idle Time', indent: 2, name: 'ppp_idletime', type: 'text', maxlen: 5, size: 7, suffix: ' <i>(minutes)</i>',
1671 value: nvram.ppp_idletime },
1672 { title: 'Redial Interval', indent: 2, name: 'ppp_redialperiod', type: 'text', maxlen: 5, size: 7, suffix: ' <i>(seconds)</i>',
1673 value: nvram.ppp_redialperiod },
1674 { title: 'LCP Echo Interval', indent: 2, name: 'pppoe_lei', type: 'text', maxlen: 5, size: 7, suffix: ' <i>seconds (range: 1 - 60; default: 10)</i>',
1675 value: nvram.pppoe_lei },
1676 { title: 'LCP Echo Link fail limit', indent: 2, name: 'pppoe_lef', type: 'text', maxlen: 5, size: 7, suffix: ' <i>(range: 1 - 10; default: 5)</i>',
1677 value: nvram.pppoe_lef },
1678 { title: 'MTU', multi: [
1679 { name: 'mtu_enable', type: 'select', options: [['0', 'Default'],['1','Manual']], value: nvram.mtu_enable },
1680 { name: 'f_wan_mtu', type: 'text', maxlen: 4, size: 6, value: nvram.wan_mtu } ] },
1681 { title: 'Single Line MLPPP', name: 'f_ppp_mlppp', type: 'checkbox', value: (nvram.ppp_mlppp == 1) },
1683 { title: 'Route Modem IP', name: 'modem_ipaddr', type: 'text', maxlen: 15, size: 17, suffix: ' <i>(must be in different subnet to router, 0.0.0.0 to disable)</i>', value: nvram.modem_ipaddr },
1685 { title: 'Bridge WAN port to primary LAN (br0)', name: 'f_wan_islan', type: 'checkbox', value: (nvram.wan_islan == 1) }
1688 </script>
1689 </div>
1691 <div class='section-title'>LAN</div>
1692 <div class='section'>
1693 <table class='tomato-grid' cellspacing=1 id='lan-grid'></table>
1695 <script type='text/javascript'>lg.setup();</script>
1697 <script type='text/javascript'>
1698 dns = nvram.wan_dns.split(/\s+/);
1699 /* REMOVE-BEGIN
1700 //ipp = nvram.lan_ipaddr.split('.').splice(0, 3).join('.');
1701 REMOVE-END */
1702 createFieldTable('', [
1703 { title: 'Default Gateway', name: 'lan_gateway', type: 'text', maxlen: 15, size: 17, value: nvram.lan_gateway },
1704 { title: 'Static DNS', suffix: '&nbsp; <i>(IP:port)</i>', name: 'f_dns_1', type: 'text', maxlen: 21, size: 25, value: dns[0] || '0.0.0.0' },
1705 { title: '', name: 'f_dns_2', type: 'text', maxlen: 21, size: 25, value: dns[1] || '0.0.0.0' },
1706 { title: '', name: 'f_dns_3', type: 'text', maxlen: 21, size: 25, value: dns[2] || '0.0.0.0' },
1707 /* DNSSEC-BEGIN */
1708 { title: 'Enable DNSSEC', name: 'f_dnssec_enable', type: 'checkbox', suffix: ' <i>(must be supported by the upstream nameservers)</i>', value: (nvram.dnssec_enable == 1) },
1709 /* DNSSEC-END */
1710 /* DNSCRYPT-BEGIN */
1711 { title: 'Use dnscrypt-proxy', name: 'f_dnscrypt_proxy', type: 'checkbox', value: (nvram.dnscrypt_proxy == 1) },
1712 { title: 'Manual Entry', indent: 2, name: 'f_dnscrypt_manual', type: 'checkbox', value: (nvram.dnscrypt_manual == 1) },
1713 { title: 'Resolver', indent: 2, name: 'dnscrypt_resolver', type: 'select', options: _dnscrypt_resolvers_, value: nvram.dnscrypt_resolver, suffix: ' <a href=\'https://github.com/jedisct1/dnscrypt-proxy/blob/master/dnscrypt-resolvers.csv\' target=\'_new\'>Resolver Details</a>' },
1714 { title: 'Resolver Address', indent: 2, name: 'dnscrypt_resolver_address', type: 'text', maxlen: 50, size: 25, value: nvram.dnscrypt_resolver_address, suffix: ' <a href=\'https://github.com/jedisct1/dnscrypt-proxy/blob/master/dnscrypt-resolvers.csv\' target=\'_new\'>Resolver Details</a>' },
1715 { title: 'Provider Name', indent: 2, name: 'dnscrypt_provider_name', type: 'text', maxlen: 60, size: 25, value: nvram.dnscrypt_provider_name },
1716 { title: 'Provider Public Key', indent: 2, name: 'dnscrypt_provider_key', type: 'text', maxlen: 80, size: 25, value: nvram.dnscrypt_provider_key },
1717 { title: 'Priority', indent: 2, name: 'dnscrypt_priority', type: 'select', options: [['1','Strict-Order'],['2','No-Resolv'],['0','None']], value: nvram.dnscrypt_priority },
1718 { title: 'Local Port', indent: 2, name: 'dnscrypt_port', type: 'text', maxlen: 5, size: 7, value: nvram.dnscrypt_port },
1719 { title: 'Log Level', indent: 2, name: 'dnscrypt_log', type: 'text', maxlen: 2, size: 5, value: nvram.dnscrypt_log },
1720 /* DNSCRYPT-END */
1721 { title: 'WINS <i>(for DHCP)</i>', name: 'wan_wins', type: 'text', maxlen: 15, size: 17, value: nvram.wan_wins }
1723 </script>
1724 </div>
1726 <div class='section-title'>Ethernet Ports State - Configuration</div>
1727 <div class='section'>
1728 <script type='text/javascript'>
1729 createFieldTable('', [
1730 { title: 'Enable Ports State', name: 'f_lan_state', type: 'checkbox', value: (nvram.lan_state == 1) },
1731 { title: 'Show Speed Info', indent: 2, name: 'f_lan_desc', type: 'checkbox', value: (nvram.lan_desc == 1) },
1732 { title: 'Invert Ports Order', indent: 2, name: 'f_lan_invert', type: 'checkbox', value: (nvram.lan_invert == 1) }
1734 </script>
1735 </div>
1737 <script type='text/javascript'>
1739 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1740 //if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1741 if (wl_sunit(uidx)<0) {
1742 var u = wl_unit(uidx);
1744 W('<input type=\'hidden\' id=\'_wl'+u+'_mode\' name=\'wl'+u+'_mode\'>');
1745 W('<input type=\'hidden\' id=\'_wl'+u+'_nband\' name=\'wl'+u+'_nband\'>');
1746 W('<input type=\'hidden\' id=\'_wl'+u+'_wds_enable\' name=\'wl'+u+'_wds_enable\'>');
1747 W('<input type=\'hidden\' id=\'_wl'+u+'_wds\' name=\'wl'+u+'_wds\'>');
1748 W('<input type=\'hidden\' id=\'_wl'+u+'_radio\' name=\'wl'+u+'_radio\'>');
1749 W('<input type=\'hidden\' id=\'_wl'+u+'_closed\' name=\'wl'+u+'_closed\'>');
1750 W('<input type=\'hidden\' id=\'_wl'+u+'_key\' name=\'wl'+u+'_key\'>');
1751 W('<input type=\'hidden\' id=\'_wl'+u+'_gmode\' name=\'wl'+u+'_gmode\'>');
1752 W('<input type=\'hidden\' id=\'_wl'+u+'_akm\' name=\'wl'+u+'_akm\'>');
1753 W('<input type=\'hidden\' id=\'_wl'+u+'_auth\' name=\'wl'+u+'_auth\'>');
1754 W('<input type=\'hidden\' id=\'_wl'+u+'_auth_mode\' name=\'wl'+u+'_auth_mode\'>');
1755 W('<input type=\'hidden\' id=\'_wl'+u+'_wep\' name=\'wl'+u+'_wep\'>');
1756 W('<input type=\'hidden\' id=\'_wl'+u+'_lazywds\' name=\'wl'+u+'_lazywds\'>');
1757 W('<input type=\'hidden\' id=\'_wl'+u+'_nmode\' name=\'wl'+u+'_nmode\'>');
1758 W('<input type=\'hidden\' id=\'_wl'+u+'_nmcsidx\' name=\'wl'+u+'_nmcsidx\'>');
1759 W('<input type=\'hidden\' id=\'_wl'+u+'_nreqd\' name=\'wl'+u+'_nreqd\'>');
1760 W('<input type=\'hidden\' id=\'_wl'+u+'_nctrlsb\' name=\'wl'+u+'_nctrlsb\'>');
1761 W('<input type=\'hidden\' id=\'_wl'+u+'_nbw\' name=\'wl'+u+'_nbw\'>');
1763 W('<div class=\'section-title\'>Wireless');
1764 // if (wl_ifaces.length > 1)
1765 W(' (' + wl_display_ifname(uidx) + ')');
1766 W('</div>');
1768 W('<div class=\'section\'>');
1770 f = [
1771 { title: 'Enable Wireless', name: 'f_wl'+u+'_radio', type: 'checkbox',
1772 value: (eval('nvram.wl'+u+'_radio') == '1') && (eval('nvram.wl'+u+'_net_mode') != 'disabled') },
1773 { title: 'MAC Address', text: '<a href="advanced-mac.asp">' + eval('nvram.wl'+u+'_hwaddr') + '</a>' },
1774 { title: 'Wireless Mode', name: 'f_wl'+u+'_mode', type: 'select',
1775 options: [['ap', 'Access Point'],['apwds', 'Access Point + WDS'],['sta', 'Wireless Client'],['wet', 'Wireless Ethernet Bridge'],['wds', 'WDS']],
1776 value: ((eval('nvram.wl'+u+'_mode') == 'ap') && (eval('nvram.wl'+u+'_wds_enable') == '1')) ? 'apwds' : eval('nvram.wl'+u+'_mode') },
1777 { title: 'Radio Band', name: 'f_wl'+u+'_nband', type: 'select', options: bands[uidx],
1778 value: eval('nvram.wl'+u+'_nband') || '0' == '0' ? bands[uidx][0][0] : eval('nvram.wl'+u+'_nband') },
1779 { title: 'Wireless Network Mode', name: 'wl'+u+'_net_mode', type: 'select',
1780 value: (eval('nvram.wl'+u+'_net_mode') == 'disabled') ? 'mixed' : eval('nvram.wl'+u+'_net_mode'),
1781 options: [], prefix: '<span id="__wl'+u+'_net_mode">', suffix: '</span>' },
1782 { title: 'SSID', name: 'wl'+u+'_ssid', type: 'text', maxlen: 32, size: 34, value: eval('nvram.wl'+u+'_ssid') },
1783 { title: 'Broadcast', indent: 2, name: 'f_wl'+u+'_bcast', type: 'checkbox', value: (eval('nvram.wl'+u+'_closed') == '0') },
1784 { title: 'Channel', name: 'wl'+u+'_channel', type: 'select', options: ghz[uidx], prefix: '<span id="__wl'+u+'_channel">', suffix: '</span> <input type="button" id="_f_wl'+u+'_scan" value="Scan" onclick="scanButton('+u+')"> <img src="spin.gif" id="spin'+u+'">',
1785 value: eval('nvram.wl'+u+'_channel') },
1786 { title: 'Channel Width', name: 'wl'+u+'_nbw_cap', type: 'select', options: [],
1787 value: eval('nvram.wl'+u+'_nbw_cap'), prefix: '<span id="__wl'+u+'_nbw_cap">', suffix: '</span>' },
1788 { title: 'Control Sideband', name: 'f_wl'+u+'_nctrlsb', type: 'select', options: [['lower','Lower'],['upper','Upper']],
1789 value: eval('nvram.wl'+u+'_nctrlsb') == 'none' ? 'lower' : eval('nvram.wl'+u+'_nctrlsb') },
1790 null,
1791 { title: 'Security', name: 'wl'+u+'_security_mode', type: 'select',
1792 options: [['disabled','Disabled'],['wep','WEP'],['wpa_personal','WPA Personal'],['wpa_enterprise','WPA Enterprise'],['wpa2_personal','WPA2 Personal'],['wpa2_enterprise','WPA2 Enterprise'],['wpaX_personal','WPA / WPA2 Personal'],['wpaX_enterprise','WPA / WPA2 Enterprise'],['radius','Radius']],
1793 value: eval('nvram.wl'+u+'_security_mode') },
1794 { title: 'Encryption', indent: 2, name: 'wl'+u+'_crypto', type: 'select',
1795 options: [['tkip','TKIP'],['aes','AES'],['tkip+aes','TKIP / AES']], value: eval('nvram.wl'+u+'_crypto') },
1796 { title: 'Shared Key', indent: 2, name: 'wl'+u+'_wpa_psk', type: 'password', maxlen: 64, size: 66, peekaboo: 1,
1797 suffix: ' <input type="button" id="_f_wl'+u+'_psk_random1" value="Random" onclick="random_psk(\'_wl'+u+'_wpa_psk\')">',
1798 value: eval('nvram.wl'+u+'_wpa_psk') },
1799 { title: 'Shared Key', indent: 2, name: 'wl'+u+'_radius_key', type: 'password', maxlen: 80, size: 32, peekaboo: 1,
1800 suffix: ' <input type="button" id="_f_wl'+u+'_psk_random2" value="Random" onclick="random_psk(\'_wl'+u+'_radius_key\')">',
1801 value: eval('nvram.wl'+u+'_radius_key') },
1802 { title: 'Group Key Renewal', indent: 2, name: 'wl'+u+'_wpa_gtk_rekey', type: 'text', maxlen: 4, size: 6, suffix: ' <i>(seconds)</i>',
1803 value: eval('nvram.wl'+u+'_wpa_gtk_rekey') },
1804 { title: 'Radius Server', indent: 2, multi: [
1805 { name: 'wl'+u+'_radius_ipaddr', type: 'text', maxlen: 15, size: 17, value: eval('nvram.wl'+u+'_radius_ipaddr') },
1806 { name: 'wl'+u+'_radius_port', type: 'text', maxlen: 5, size: 7, prefix: ' : ', value: eval('nvram.wl'+u+'_radius_port') } ] },
1807 { title: 'Encryption', indent: 2, name: 'wl'+u+'_wep_bit', type: 'select', options: [['128','128-bits'],['64','64-bits']],
1808 value: eval('nvram.wl'+u+'_wep_bit') },
1809 { title: 'Passphrase', indent: 2, name: 'wl'+u+'_passphrase', type: 'text', maxlen: 16, size: 20,
1810 suffix: ' <input type="button" id="_f_wl'+u+'_wep_gen" value="Generate" onclick="generate_wep('+u+')"> <input type="button" id="_f_wl'+u+'_wep_random" value="Random" onclick="random_wep('+u+')">',
1811 value: eval('nvram.wl'+u+'_passphrase') }
1814 for (i = 1; i <= 4; ++i) {
1815 f.push(
1816 { title: ('Key ' + i), indent: 2, name: ('wl'+u+'_key' + i), type: 'text', maxlen: 26, size: 34,
1817 suffix: '<input type="radio" onchange="verifyFields(this,1)" onclick="verifyFields(this,1)" name="f_wl'+u+'_wepidx" id="_f_wl'+u+'_wepidx_' + i + '" value="' + i + '"' + ((eval('nvram.wl'+u+'_key') == i) ? ' checked>' : '>'),
1818 value: nvram['wl'+u+'_key' + i] });
1821 f.push(null,
1822 { title: 'WDS', name: 'f_wl'+u+'_lazywds', type: 'select',
1823 options: [['0','Link With...'],['1','Automatic']], value: nvram['wl'+u+'_lazywds'] } );
1824 wds = eval('nvram.wl'+u+'_wds').split(/\s+/);
1825 for (i = 0; i < 10; i += 2) {
1826 f.push({ title: (i ? '' : 'MAC Address'), indent: 2, multi: [
1827 { name: 'f_wl'+u+'_wds_' + i, type: 'text', maxlen: 17, size: 20, value: wds[i] || '00:00:00:00:00:00' },
1828 { name: 'f_wl'+u+'_wds_' + (i + 1), type: 'text', maxlen: 17, size: 20, value: wds[i + 1] || '00:00:00:00:00:00' } ] } );
1831 createFieldTable('', f);
1832 W('</div>');
1835 // for each wlif
1836 </script>
1838 <!-- / / / -->
1840 </td></tr>
1841 <tr><td id='footer' colspan=2>
1842 <span id='footer-msg'></span>
1843 <input type='button' value='Save' id='save-button' onclick='save()'>
1844 <input type='button' value='Cancel' id='cancel-button' onclick='reloadPage();'>
1845 </td></tr>
1846 </table>
1847 </form>
1848 <script type='text/javascript'>earlyInit()</script>
1849 <div style='height:100px'></div>
1850 </body>
1851 </html>