Migrate UI cleanup phase 4 from MIPS into ARM
[tomato.git] / release / src-rt-6.x.4708 / router / www / basic-network.asp
blobd7513c6dc3b4618852bec53bd00eb4bd72655c13
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 <meta name="viewport" content="width=device-width">
15 <title>[<% ident(); %>] Basic: Network</title>
16 <link rel='stylesheet' type='text/css' href='tomato.css'>
17 <% css(); %>
18 <script type='text/javascript' src='tomato.js'></script>
20 <!-- / / / -->
22 <style type='text/css'>
23 #lan-grid .co1,
24 #lan-grid .co2,
25 #lan-grid .co3,
26 #lan-grid .co4,
27 #lan-grid .co5,
28 #lan-grid .co6,
29 #lan-grid .co7 {
30 text-align: center;
33 #lan-grid .centered {
34 text-align: center;
37 #spin {
38 visibility: hidden;
39 vertical-align: middle;
41 </style>
43 <script type='text/javascript' src='debug.js'></script>
45 <script type='text/javascript' src='md5.js'></script>
46 <script type='text/javascript' src='wireless.jsx?_http_id=<% nv(http_id); %>'></script>
47 <script type='text/javascript' src='interfaces.js'></script>
48 <script type='text/javascript'>
49 // <% 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"); %>
51 var lg = new TomatoGrid();
52 lg.setup = function() {
53 this.init('lan-grid', '', 4, [
54 { type: 'select', options: [[0, '0'],[1, '1'],[2, '2'],[3, '3']], prefix: '<div class="centered">', suffix: '</div>' },
55 { type: 'checkbox', prefix: '<div class="centered">', suffix: '</div>' },
56 { type: 'text', maxlen: 15, size: 17 },
57 { type: 'text', maxlen: 15, size: 17 },
58 { type: 'checkbox', prefix: '<div class="centered">', suffix: '</div>' },
59 { multi: [ { type: 'text', maxlen: 15, size: 17}, { type: 'text', maxlen: 15, size: 17 } ] },
60 { type: 'text', maxlen: 6, size: 8 }] );
61 this.headerSet(['Bridge', 'STP', 'IP Address', 'Netmask', 'DHCP', 'IP&nbsp;Range&nbsp;<i>(first/last)</i>', 'Lease&nbsp;Time&nbsp;<i>(mins)</i>']);
63 var numBridges = 0;
64 for (var i = 0 ; i <= MAX_BRIDGE_ID ; i++) {
65 var j = (i == 0) ? '' : i.toString();
66 if (nvram['lan' + j + '_ifname'].length > 0) {
67 if ((!fixIP(nvram['dhcpd' + j + '_startip'])) || (!fixIP(nvram['dhcpd' + j + '_endip']))) {
68 if ((fixIP(nvram['lan' + j + '_ipaddr'])) && (fixIP(nvram['lan' + j + '_netmask'])) && (nvram['dhcp' + j + '_start'] != '')) {
69 var n = getNetworkAddress(nvram['lan' + j + '_ipaddr'], nvram['lan' + j + '_netmask']);
70 nvram['dhcpd' + j + '_startip'] = getAddress(('0.0.0.' + nvram['dhcp' + j + '_start'] * 1), n);
71 nvram['dhcpd' + j + '_endip'] = getAddress(('0.0.0.' + ((nvram['dhcp' + j + '_start'] * 1) + (nvram['dhcp' + j + '_num'] *1) - 1)), n);
74 lg.insertData(-1, [
75 i.toString(),
76 nvram['lan' + j + '_stp'],
77 nvram['lan' + j + '_ipaddr'],
78 nvram['lan' + j + '_netmask'],
79 (nvram['lan' + j + '_proto'] == 'dhcp') ? '1' : '0',
80 nvram['dhcpd' + j + '_startip'],
81 nvram['dhcpd' + j + '_endip'],
82 (nvram['lan' + j + '_proto'] == 'dhcp') ? (((nvram['dhcp' + j + '_lease'])*1 == 0) ? '1440' : (nvram['dhcp' + j + '_lease']).toString()) : ''
83 ] ) ;
84 numBridges++;
87 lg.canDelete = false;
88 lg.sort(0);
89 elem.removeClass(lg.header.cells[lg.sortColumn], 'sortasc', 'sortdes');
90 lg.showNewEditor();
91 lg.resetNewEditor();
94 lg.dataToView = function(data) {
95 return ['br' + data[0],
96 (data[1].toString() == '1') ? '<small><i>Enabled</i></small>' : '<small><i>Disabled</i></small>',
97 data[2],
98 data[3],
99 (data[4].toString() == '1') ? '<small><i>Enabled</i></small>' : '<small><i>Disabled</i></small>',
100 (data[5].toString() + ((numberOfBitsOnNetMask(data[3])>=24) ? (' - ' + data[6].split('.').splice(3, 1).toString()) : ('<br>' + data[6].toString()) )),
101 (((data[7] != null) && (data[7] != '')) ? data[7] : '') ];
104 lg.dataToFieldValues = function (data) {
105 return [data[0],
106 (data[1] != 0) ? 'checked' : '',
107 data[2].toString(),
108 data[3].toString(),
109 (data[4].toString() == '1') ? 'checked' : '',
110 data[5].toString(),
111 data[6].toString(),
112 data[7].toString() ];
115 lg.fieldValuesToData = function(row) {
116 var f = fields.getAll(row);
117 return [f[0].value,
118 f[1].checked ? 1 : 0,
119 f[2].value,
120 f[3].value,
121 f[4].checked ? 1 : 0,
122 f[5].value,
123 f[6].value,
124 f[7].value ];
127 lg.resetNewEditor = function() {
128 var f = fields.getAll(this.newEditor);
129 f[0].selectedIndex=0;
130 var t = MAX_BRIDGE_ID;
131 while((this.countBridge(f[0].selectedIndex) > 0) && (t > 0)) {
132 f[0].selectedIndex = (f[0].selectedIndex%(MAX_BRIDGE_ID))+1;
133 t--;
135 for(var j=0; j<= MAX_BRIDGE_ID ; j++) {
136 f[0].options[j].disabled = (this.countBridge(j) > 0);
138 f[1].checked = 0;
139 f[2].value = '';
140 f[3].value = '';
141 f[5].value = '';
142 f[6].value = '';
143 f[7].value = '';
144 f[4].checked = 0;
145 f[4].disabled = 1;
146 f[5].disabled = 1;
147 f[6].disabled = 1;
148 f[7].disabled = 1;
149 ferror.clearAll(fields.getAll(this.newEditor));
152 lg.onCancel = function() {
153 this.removeEditor();
154 this.showSource();
155 this.disableNewEditor(false);
157 this.resetNewEditor();
160 lg.onAdd = function() {
161 var data;
163 this.moving = null;
164 this.rpHide();
166 if (!this.verifyFields(this.newEditor, false)) return;
168 data = this.fieldValuesToData(this.newEditor);
169 this.insertData(-1, data);
171 this.disableNewEditor(false);
172 this.resetNewEditor();
174 this.resort();
177 lg.onOK = function() {
178 var i, data, view;
180 if (!this.verifyFields(this.editor, false)) return;
182 data = this.fieldValuesToData(this.editor);
183 view = this.dataToView(data);
185 this.source.setRowData(data);
186 for (i = 0; i < this.source.cells.length; ++i) {
187 this.source.cells[i].innerHTML = view[i];
190 this.removeEditor();
191 this.showSource();
192 this.disableNewEditor(false);
194 this.resort();
195 this.resetNewEditor();
198 lg.onDelete = function() {
199 this.removeEditor();
200 elem.remove(this.source);
201 this.source = null;
202 this.disableNewEditor(false);
204 this.resetNewEditor();
207 lg.countElem = function(f, v) {
208 var data = this.getAllData();
209 var total = 0;
210 for (var i = 0; i < data.length; ++i) {
211 total += (data[i][f] == v) ? 1 : 0;
213 return total;
216 lg.countBridge = function (v) {
217 return this.countElem(0,v);
220 lg.countOverlappingNetworks = function (ip) {
221 var data = this.getAllData();
222 var total = 0;
223 for (var i = 0; i < data.length; ++i) {
224 var net = getNetworkAddress(data[i][2], data[i][3]);
225 var brd = getBroadcastAddress(net, data[i][3]);
226 total += ((aton(ip) <= aton(brd)) && (aton(ip) >= aton(net))) ? 1 : 0;
228 return total;
231 lg.verifyFields = function(row, quiet) {
232 var ok=1;
233 var f;
235 f = fields.getAll(row);
237 for(var j=0; j<= MAX_BRIDGE_ID ; j++) {
238 f[0].options[j].disabled = (this.countBridge(j) > 0);
241 if(this.countBridge(f[0].selectedIndex) > 0) {
242 ferror.set(f[0], 'Cannot add another entry for bridge br' + f[0].selectedIndex, quiet);
243 ok = 0;
244 } else {
245 ferror.clear(f[0]);
247 // valid IP address?
248 if(!v_ip(f[2], quiet || !ok))
249 ok = 0;
250 // if we have a properly defined IP address - 0.0.0.0 is NOT a valid IP address for our intents/purposes!
251 if ((f[2].value != '') && (f[2].value != '0.0.0.0')) {
252 // allow DHCP to be enabled
253 f[4].disabled = 0;
254 // validate netmask
255 if(!v_netmask(f[3], quiet || !ok)) {
256 return 0;
257 } else {
258 // should be 22 bits or smaller network
259 if ((numberOfBitsOnNetMask(f[3].value) < 22) && (nvram.cstats_enable == '1' )) {
260 if (!confirm("Netmask should have at least 22 bits (255.255.252.0). You may continue anyway but remember - you was warned")) return;
261 } else {
262 ferror.clear(f[3]);
265 if(f[2].value == getNetworkAddress(f[2].value, f[3].value)) {
266 var s = 'Invalid IP address or subnet mask (the address of the network cannot be used)';
267 ferror.set(f[2], s, quiet);
268 ferror.set(f[3], s, quiet);
269 return 0;
270 } else
271 if(f[2].value == getBroadcastAddress(getNetworkAddress(f[2].value, f[3].value), f[3].value)) {
272 var s = 'Invalid IP address or subnet mask (the broadcast address cannot be used)';
273 ferror.set(f[2], s, quiet);
274 ferror.set(f[3], s, quiet);
275 return 0;
276 } else
277 if (this.countOverlappingNetworks(f[2].value) > 0) {
278 var s = 'Invalid IP address or subnet mask (conflicts/overlaps with another LAN bridge)';
279 ferror.set(f[2], s, quiet);
280 ferror.set(f[3], s, quiet);
281 return 0;
282 } else {
283 ferror.clear(f[2]);
284 ferror.clear(f[3]);
286 } else {
287 f[4].checked = 0;
288 f[4].disabled = 1;
290 // dhcp enabled?
291 if( (f[4].checked) && (v_ip(f[2], 1)) && (v_netmask(f[3],1)) ) {
292 f[5].disabled = 0;
293 f[6].disabled = 0;
294 f[7].disabled = 0;
295 // first/last IP still unset?
296 if (f[5].value == '') {
297 var l;
298 var m = aton(f[2].value) & aton(f[3].value);
299 var o = (m) ^ (~ aton(f[3].value))
300 var n = o - m;
301 do {
302 if (--n < 0) {
303 f[5].value = '';
304 return;
306 m++;
307 } while (((l = fixIP(ntoa(m), 1)) == null) || (l == f[2].value) );
308 f[5].value = l;
310 if (f[6].value == '') {
311 var l;
312 var m = aton(f[2].value) & aton(f[3].value);
313 var o = (m) ^ (~ aton(f[3].value));
314 var n = o - m;
315 do {
316 if (--n < 0) {
317 f[6].value = '';
318 return;
320 o--;
321 } while (((l = fixIP(ntoa(o), 1)) == null) || (l == f[2].value) );
322 f[6].value = l;
324 // first IP valid?
325 if ((getNetworkAddress(f[5].value, f[3].value) != getNetworkAddress(f[2].value, f[3].value)) ||
326 (f[5].value == getBroadcastAddress(getNetworkAddress(f[2].value, f[3].value), f[3].value)) ||
327 (f[5].value == getNetworkAddress(f[2].value, f[3].value)) ||
328 (f[2].value == f[5].value)) {
329 ferror.set(f[5], 'Invalid first IP address or subnet mask', quiet || !ok);
330 return 0;
331 } else {
332 ferror.clear(f[5]);
334 // last IP valid?
335 if ((getNetworkAddress(f[6].value, f[3].value) != getNetworkAddress(f[2].value, f[3].value)) ||
336 (f[6].value == getBroadcastAddress(getNetworkAddress(f[2].value, f[3].value), f[3].value)) ||
337 (f[6].value == getNetworkAddress(f[2].value, f[3].value)) ||
338 (f[2].value == f[6].value)) {
339 ferror.set(f[6], 'Invalid last IP address or subnet mask', quiet || !ok);
340 return 0;
341 } else {
342 ferror.clear(f[6]);
344 // validate range, swap first/last IP if needed
345 if (aton(f[6].value) < aton(f[5].value)) {
346 var t = f[5].value;
347 f[5].value = f[6].value;
348 f[6].value = t;
350 // lease time
351 if (parseInt(f[7].value*1) == 0)
352 f[7].value = 1440; // from nvram/defaults.c
353 if(!v_mins(f[7], quiet || !ok, 1, 10080))
354 ok = 0;
355 } else {
356 f[5].disabled = 1;
357 f[6].disabled = 1;
358 f[7].disabled = 1;
359 ferror.clear(f[5]);
360 ferror.clear(f[6]);
361 ferror.clear(f[7]);
363 return ok;
366 W('<style type=\'text/css\'>');
367 for (var u = 0; u < wl_ifaces.length; ++u) {
368 W('#spin'+wl_unit(u)+', ');
370 W('#spin {');
371 W(' visibility: hidden;');
372 W(' vertical-align: middle;');
373 W('}');
374 W('</style>');
376 var xob = null;
377 var refresher = [];
378 var nphy = features('11n');
379 var acphy = features('11ac');
381 var ghz = [];
382 var bands = [];
383 var nm_loaded = [], ch_loaded = [], max_channel = [];
385 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
386 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
387 if (wl_sunit(uidx)<0) {
388 var b;
389 b = [];
390 for (var i = 0; i < wl_bands[uidx].length; ++i) {
391 b.push([wl_bands[uidx][i] + '', (wl_bands[uidx][i] == '1') ? '5 GHz' : '2.4 GHz']);
393 bands.push(b);
395 b = [];
396 ghz.push(b);
398 nm_loaded.push(0);
399 ch_loaded.push(0);
400 max_channel.push(0);
401 refresher.push(null);
405 function selectedBand(uidx)
407 if (bands[uidx].length > 1) {
408 var e = E('_f_wl'+u+'_nband');
409 return (e.value + '' == '' ? eval('nvram.wl'+u+'_nband') : e.value);
410 } else if (bands[uidx].length > 0) {
411 return bands[uidx][0][0] || '0';
412 } else {
413 return '0';
417 function refreshNetModes(uidx)
419 var e, i, buf, val;
421 if (uidx >= wl_ifaces.length) return;
422 var u = wl_unit(uidx);
424 var m = [['mixed','Auto']];
425 if (selectedBand(uidx) == '1') {
426 m.push(['a-only','A Only']);
427 if (nphy) {
428 m.push(['n-only','N Only']);
431 else {
432 m.push(['b-only','B Only']);
433 m.push(['g-only','G Only']);
434 if (nphy) {
435 m.push(['bg-mixed','B/G Mixed']);
436 m.push(['n-only','N Only']);
440 e = E('_wl'+u+'_net_mode');
441 buf = '';
442 val = (!nm_loaded[uidx] || (e.value + '' == '')) ? eval('nvram.wl'+u+'_net_mode') : e.value;
443 if (val == 'disabled') val = 'mixed';
444 for (i = 0; i < m.length; ++i)
445 buf += '<option value="' + m[i][0] + '"' + ((m[i][0] == val) ? ' selected' : '') + '>' + m[i][1] + '</option>';
447 e = E('__wl'+u+'_net_mode');
448 buf = '<select name="wl'+u+'_net_mode" onchange="verifyFields(this, 1)" id = "_wl'+u+'_net_mode">' + buf + '</select>';
449 elem.setInnerHTML(e, buf);
450 nm_loaded[uidx] = 1;
453 function refreshBandWidth(uidx)
455 var e, i, buf, val;
457 if (uidx >= wl_ifaces.length) return;
458 var u = wl_unit(uidx);
460 var m = [['0','20 MHz']];
461 if(nphy || acphy){
462 m.push(['1','40 MHz']);
464 if(acphy && selectedBand(uidx) == '1') {
465 m.push(['3','80 MHz']);
468 e = E('_wl'+u+'_nbw_cap');
469 buf = '';
470 val = (!nm_loaded[uidx] || (e.value + '' == '')) ? eval('nvram.wl'+u+'_nbw_cap') : e.value;
471 for (i = 0; i < m.length; ++i)
472 buf += '<option value="' + m[i][0] + '"' + ((m[i][0] == val) ? ' selected' : '') + '>' + m[i][1] + '</option>';
474 e = E('__wl'+u+'_nbw_cap');
475 buf = '<select name="wl'+u+'_nbw_cap" onchange="verifyFields(this, 1)" id = "_wl'+u+'_nbw_cap">' + buf + '</select>';
476 elem.setInnerHTML(e, buf);
477 nm_loaded[uidx] = 1;
480 function refreshChannels(uidx)
482 if (refresher[uidx] != null) return;
483 if (u >= wl_ifaces.length) return;
484 var u = wl_unit(uidx);
486 refresher[uidx] = new XmlHttp();
487 refresher[uidx].onCompleted = function(text, xml) {
488 try {
489 var e, i, buf, val;
491 var wl_channels = [];
492 eval(text);
494 ghz[uidx] = [];
495 max_channel[uidx] = 0;
496 for (i = 0; i < wl_channels.length; ++i) {
497 ghz[uidx].push([wl_channels[i][0] + '',
498 (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 (deprecated)']);
499 max_channel[uidx] = wl_channels[i][0] * 1;
502 e = E('_wl'+u+'_channel');
503 buf = '';
504 val = (!ch_loaded[uidx] || (e.value + '' == '')) ? eval('nvram.wl'+u+'_channel') : e.value;
505 for (i = 0; i < ghz[uidx].length; ++i)
506 buf += '<option value="' + ghz[uidx][i][0] + '"' + ((ghz[uidx][i][0] == val) ? ' selected' : '') + '>' + ghz[uidx][i][1] + '</option>';
508 e = E('__wl'+u+'_channel');
509 buf = '<select name="wl'+u+'_channel" onchange="verifyFields(this, 1)" id = "_wl'+u+'_channel">' + buf + '</select>';
510 elem.setInnerHTML(e, buf);
511 ch_loaded[uidx] = 1;
513 refresher[uidx] = null;
514 verifyFields(null, 1);
516 catch (x) {
518 refresher[uidx] = null;
521 var bw, sb, e;
523 e = E('_f_wl'+u+'_nctrlsb');
524 sb = (e.value + '' == '' ? eval('nvram.wl'+u+'_nctrlsb') : e.value);
525 e = E('_wl'+u+'_nbw_cap');
526 switch(e.value + '' == '' ? eval('nvram.wl'+u+'_nbw_cap') : e.value) {
527 case '0':
528 bw = '20';
529 break;
530 case '1':
531 bw = '40';
532 break;
533 case '3':
534 bw = '80';
535 break;
536 default:
537 alert("Wrong nbw_cap.");
540 refresher[uidx].onError = function(ex) { alert(ex); refresher[uidx] = null; reloadPage(); }
541 refresher[uidx].post('update.cgi', 'exec=wlchannels&arg0=' + u + '&arg1=' + (nphy || acphy ? '1' : '0') +
542 '&arg2=' + bw + '&arg3=' + selectedBand(uidx) + '&arg4=' + sb);
545 function spin(x, unit)
547 for (var u = 0; u < wl_ifaces.length; ++u) {
548 E('_f_wl'+wl_unit(u)+'_scan').disabled = x;
550 var e = E('_f_wl'+unit+'_scan');
551 if (x) e.value = 'Scan ' + (wscan.tries + 1);
552 else e.value = 'Scan';
553 E('spin'+unit).style.visibility = x ? 'visible' : 'hidden';
556 function scan()
558 if (xob) return;
560 var unit = wscan.unit;
561 var uidx = wl_uidx(unit);
563 xob = new XmlHttp();
564 xob.onCompleted = function(text, xml) {
565 try {
566 var i;
568 wlscandata = [];
569 eval(text);
571 for (i = 0; i < wlscandata.length; ++i) {
572 var data = wlscandata[i];
573 var ch = data[2];
574 var mac = data[0];
576 if (!wscan.inuse[ch]) {
577 wscan.inuse[ch] = {
578 count: 0,
579 rssi: -999,
580 ssid: ''
584 if (!wscan.seen[mac]) {
585 wscan.seen[mac] = 1;
586 ++wscan.inuse[ch].count;
589 if (data[4] > wscan.inuse[ch].rssi) {
590 wscan.inuse[ch].rssi = data[4];
591 wscan.inuse[ch].ssid = data[1];
594 var e = E('_wl'+unit+'_channel');
595 for (i = 1; i < ghz[uidx].length; ++i) {
596 var s = ghz[uidx][i][1];
597 var u = wscan.inuse[ghz[uidx][i][0]];
598 if (u) s += ' (' + u.count + ' AP' + (u.count == 1 ? '' : 's') + ' / strongest: "' + escapeHTML(ellipsis(u.ssid, 15)) + '" ' + u.rssi + ' dBm)';
599 e.options[i].innerHTML = s;
601 e.style.width = '400px';
603 xob = null;
605 if (wscan.tries < 4) {
606 ++wscan.tries;
607 setTimeout(scan, 1000);
608 return;
611 catch (x) {
613 spin(0, unit);
615 xob.onError = function(x) {
616 alert('error: ' + x);
617 spin(0, unit);
618 xob = null;
621 spin(1, unit);
622 xob.post('update.cgi', 'exec=wlscan&arg0='+unit);
625 function scanButton(u)
627 if (xob) return;
629 wscan = {
630 unit: u,
631 seen: [],
632 inuse: [],
633 tries: 0
636 scan();
639 function joinAddr(a) {
640 var r, i, s;
642 r = [];
643 for (i = 0; i < a.length; ++i) {
644 s = a[i];
645 if ((s != '00:00:00:00:00:00') && (s != '0.0.0.0')) r.push(s);
647 return r.join(' ');
650 function random_x(max)
652 var c = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
653 var s = '';
654 while (max-- > 0) s += c.substr(Math.floor(c.length * Math.random()), 1);
655 return s;
658 function random_psk(id)
660 var e = E(id);
661 e.value = random_x(63);
662 verifyFields(null, 1);
665 function random_wep(u)
667 E('_wl'+u+'_passphrase').value = random_x(16);
668 generate_wep(u);
671 function v_wep(e, quiet)
673 var s = e.value;
675 if (((s.length == 5) || (s.length == 13)) && (s.length == (e.maxLength >> 1))) {
676 // no checking
678 else {
679 s = s.toUpperCase().replace(/[^0-9A-F]/g, '');
680 if (s.length != e.maxLength) {
681 ferror.set(e, 'Invalid WEP key. Expecting ' + e.maxLength + ' hex or ' + (e.maxLength >> 1) + ' ASCII characters.', quiet);
682 return 0;
686 e.value = s;
687 ferror.clear(e);
688 return 1;
691 // compatible w/ Linksys' and Netgear's (key 1) method for 128-bits
692 function generate_wep(u)
694 function _wepgen(pass, i)
696 while (pass.length < 64) pass += pass;
697 return hex_md5(pass.substr(0, 64)).substr(i, (E('_wl'+u+'_wep_bit').value == 128) ? 26 : 10);
700 var e = E('_wl'+u+'_passphrase');
701 var pass = e.value;
702 if (!v_length(e, false, 3)) return;
703 E('_wl'+u+'_key1').value = _wepgen(pass, 0);
704 pass += '#$%';
705 E('_wl'+u+'_key2').value = _wepgen(pass, 2);
706 pass += '!@#';
707 E('_wl'+u+'_key3').value = _wepgen(pass, 4);
708 pass += '%&^';
709 E('_wl'+u+'_key4').value = _wepgen(pass, 6);
710 verifyFields(null, 1);
713 function verifyFields(focused, quiet)
715 var i;
716 var ok = 1;
717 var a, b, c, d, e;
718 var u, uidx;
719 var wmode, sm2;
721 var n = E('_f_lan_state').checked;
722 E('_f_lan_desc').disabled = !n;
723 E('_f_lan_invert').disabled = !n;
725 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
726 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
727 if (wl_sunit(uidx)<0) {
728 u = wl_unit(uidx);
729 if (focused == E('_f_wl'+u+'_nband')) {
730 refreshNetModes(uidx);
731 refreshChannels(uidx);
732 refreshBandWidth(uidx);
734 else if (focused == E('_f_wl'+u+'_nctrlsb') || focused == E('_wl'+u+'_nbw_cap')) {
735 refreshChannels(uidx);
740 // --- visibility ---
742 var vis = {
743 _wan_proto: 1,
744 _ppp_username: 1,
745 _ppp_passwd: 1,
746 _ppp_service: 1,
747 _ppp_custom: 1,
748 _l2tp_server_ip: 1,
749 _wan_ipaddr: 1,
750 _wan_netmask: 1,
751 _wan_gateway: 1,
752 _pptp_server_ip: 1,
753 _f_pptp_dhcp: 1,
754 _ppp_demand: 1,
755 _ppp_idletime: 1,
756 _ppp_redialperiod: 1,
757 _pppoe_lei: 1,
758 _pppoe_lef: 1,
759 _mtu_enable: 1,
760 _f_wan_mtu: 1,
761 _f_wan_islan: 0,
762 _f_ppp_mlppp: 1,
763 _modem_ipaddr: 1,
765 _f_dns_1: 1,
766 _f_dns_2: 1,
767 _f_dns_3: 1,
768 /* DNSSEC-BEGIN */
769 _f_dnssec_enable: 1,
770 /* DNSSEC-END */
771 _lan_gateway: 1,
772 _wan_wins: 1,
773 _modem_pin: 1,
774 _modem_dev: 1,
775 _modem_init: 1,
776 _modem_apn: 1
779 var wl_vis = [];
780 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
781 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
782 if (wl_sunit(uidx)<0) {
783 a = {
784 _f_wl_radio: 1,
785 _f_wl_mode: 1,
786 _f_wl_nband: (bands[uidx].length > 1) ? 1 : 0,
787 _wl_net_mode: 1,
788 _wl_ssid: 1,
789 _f_wl_bcast: 1,
790 _wl_channel: 1,
791 _wl_nbw_cap: nphy || acphy ? 1 : 0,
792 _f_wl_nctrlsb: nphy || acphy ? 1 : 0,
793 _f_wl_scan: 1,
795 _wl_security_mode: 1,
796 _wl_crypto: 1,
797 _wl_wpa_psk: 1,
798 _f_wl_psk_random1: 1,
799 _f_wl_psk_random2: 1,
800 _wl_wpa_gtk_rekey: 1,
801 _wl_radius_key: 1,
802 _wl_radius_ipaddr: 1,
803 _wl_radius_port: 1,
804 _wl_wep_bit: 1,
805 _wl_passphrase: 1,
806 _f_wl_wep_gen: 1,
807 _f_wl_wep_random: 1,
808 _wl_key1: 1,
809 _wl_key2: 1,
810 _wl_key3: 1,
811 _wl_key4: 1,
813 _f_wl_lazywds: 1,
814 _f_wl_wds_0: 1
816 wl_vis.push(a);
820 var wan = E('_wan_proto').value;
822 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
823 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
824 if (wl_sunit(uidx)<0) {
825 wmode = E('_f_wl'+wl_unit(uidx)+'_mode').value;
827 if (wmode == 'wet') {
828 wan = 'disabled';
829 vis._wan_proto = 0;
832 if ((wan == 'disabled') || (wmode == 'sta') || (wmode == 'wet')) {
833 vis._f_wan_islan = 1;
838 switch (wan) {
839 case 'disabled':
840 vis._ppp_username = 0;
841 vis._ppp_service = 0;
842 vis._ppp_custom = 0;
843 vis._l2tp_server_ip = 0;
844 vis._wan_ipaddr = 0;
845 vis._wan_netmask = 0;
846 vis._wan_gateway = 0;
847 vis._pptp_server_ip = 0;
848 vis._f_pptp_dhcp = 0;
849 vis._ppp_demand = 0;
850 vis._mtu_enable = 0;
851 vis._f_wan_mtu = 0;
852 vis._f_ppp_mlppp = 0;
853 vis._modem_ipaddr = 0;
854 vis._modem_pin = 0;
855 vis._modem_dev = 0;
856 vis._modem_init = 0;
857 vis._modem_apn = 0;
858 vis._pppoe_lei = 0;
859 vis._pppoe_lef = 0;
860 break;
861 case 'dhcp':
862 vis._l2tp_server_ip = 0;
863 vis._pppoe_lei = 0;
864 vis._pppoe_lef = 0;
865 vis._ppp_demand = 0;
866 vis._ppp_service = 0;
867 vis._ppp_username = 0;
868 vis._ppp_custom = 0;
869 vis._pptp_server_ip = 0;
870 vis._f_pptp_dhcp = 0;
871 vis._wan_gateway = 0;
872 vis._wan_ipaddr = 0;
873 vis._wan_netmask = 0;
874 vis._f_ppp_mlppp = 0;
875 vis._modem_ipaddr = 1;
877 vis._lan_gateway = 0;
878 vis._modem_pin = 0;
879 vis._modem_dev = 0;
880 vis._modem_init = 0;
881 vis._modem_apn = 0;
882 break;
883 case 'pppoe':
884 vis._l2tp_server_ip = 0;
885 vis._pptp_server_ip = 0;
886 vis._f_pptp_dhcp = 0;
887 vis._wan_gateway = 0;
888 vis._wan_ipaddr = 0;
889 vis._wan_netmask = 0;
890 vis._modem_ipaddr = 1;
892 vis._lan_gateway = 0;
893 vis._modem_pin = 0;
894 vis._modem_dev = 0;
895 vis._modem_init = 0;
896 vis._modem_apn = 0;
897 break;
898 case 'ppp3g':
899 vis._pppoe_lei = 0;
900 vis._pppoe_lef = 0;
901 vis._ppp_service = 0;
902 vis._l2tp_server_ip = 0;
903 vis._pptp_server_ip = 0;
904 vis._f_pptp_dhcp = 0;
905 vis._wan_gateway = 0;
906 vis._wan_ipaddr = 0;
907 vis._wan_netmask = 0;
908 vis._lan_gateway = 0;
909 vis._modem_ipaddr = 0;
910 vis._f_ppp_mlppp = 0;
911 break;
912 case 'lte':
913 vis._pppoe_lei = 0;
914 vis._pppoe_lef = 0;
915 vis._ppp_service = 0;
916 vis._ppp_demand = 0;
917 vis._ppp_service = 0;
918 vis._ppp_username = 0;
919 vis._ppp_custom = 0;
920 vis._l2tp_server_ip = 0;
921 vis._pptp_server_ip = 0;
922 vis._f_pptp_dhcp = 0;
923 vis._wan_gateway = 0;
924 vis._wan_ipaddr = 0;
925 vis._wan_netmask = 0;
926 vis._lan_gateway = 0;
927 vis._modem_ipaddr = 0;
928 vis._modem_dev = 0;
929 vis._modem_init = 0;
930 vis._f_ppp_mlppp = 0;
931 break;
932 case 'static':
933 vis._pppoe_lei = 0;
934 vis._pppoe_lef = 0;
935 vis._l2tp_server_ip = 0;
936 vis._ppp_demand = 0;
937 vis._ppp_service = 0;
938 vis._ppp_username = 0;
939 vis._ppp_custom = 0;
940 vis._pptp_server_ip = 0;
941 vis._f_pptp_dhcp = 0;
942 vis._f_ppp_mlppp = 0;
943 vis._modem_ipaddr = 1;
945 vis._lan_gateway = 0;
946 vis._modem_pin = 0;
947 vis._modem_dev = 0;
948 vis._modem_init = 0;
949 vis._modem_apn = 0;
950 break;
951 case 'pptp':
952 vis._pppoe_lei = 0;
953 vis._pppoe_lef = 0;
954 vis._l2tp_server_ip = 0;
955 vis._ppp_service = 0;
956 vis._wan_gateway = (!E('_f_pptp_dhcp').checked);
957 vis._wan_ipaddr = (!E('_f_pptp_dhcp').checked);
958 vis._modem_ipaddr = 0;
960 vis._lan_gateway = 0;
961 vis._modem_pin = 0;
962 vis._modem_dev = 0;
963 vis._modem_init = 0;
964 vis._modem_apn = 0;
965 break;
966 case 'l2tp':
967 vis._pppoe_lei = 0;
968 vis._pppoe_lef = 0;
969 vis._pptp_server_ip = 0;
970 vis._ppp_service = 0;
971 vis._wan_gateway = (!E('_f_pptp_dhcp').checked);
972 vis._wan_ipaddr = (!E('_f_pptp_dhcp').checked);
973 vis._modem_ipaddr = 0;
975 vis._lan_gateway = 0;
976 vis._modem_pin = 0;
977 vis._modem_dev = 0;
978 vis._modem_init = 0;
979 vis._modem_apn = 0;
980 break;
983 vis._ppp_idletime = (E('_ppp_demand').value == 1) && vis._ppp_demand
984 vis._ppp_redialperiod = !vis._ppp_idletime && vis._ppp_demand;
986 if (vis._mtu_enable) {
987 if (E('_mtu_enable').value == 0) {
988 vis._f_wan_mtu = 2;
989 a = E('_f_wan_mtu');
990 switch (E('_wan_proto').value) {
991 case 'pppoe':
992 a.value = 1492;
993 break;
994 case 'pptp':
995 case 'l2tp':
996 a.value = 1460;
997 break;
998 default:
999 a.value = 1500;
1000 break;
1005 /* DNSCRYPT-BEGIN */
1006 var p = E('_f_dnscrypt_proxy').checked;
1007 vis._dnscrypt_priority = p;
1008 vis._dnscrypt_port = p;
1009 vis._dnscrypt_log = p;
1010 vis._f_dnscrypt_manual = p;
1011 var q = E('_f_dnscrypt_proxy').checked && E('_f_dnscrypt_manual').checked;
1012 vis._dnscrypt_provider_name = q;
1013 vis._dnscrypt_provider_key = q;
1014 vis._dnscrypt_resolver_address = q;
1015 var r = E('_f_dnscrypt_proxy').checked && !E('_f_dnscrypt_manual').checked;
1016 vis._dnscrypt_resolver = r;
1017 /* DNSCRYPT-END */
1019 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1020 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1021 if (wl_sunit(uidx)<0) {
1022 u = wl_unit(uidx);
1023 wmode = E('_f_wl'+u+'_mode').value;
1025 if (!E('_f_wl'+u+'_radio').checked) {
1026 for (a in wl_vis[uidx]) {
1027 wl_vis[uidx][a] = 2;
1029 wl_vis[uidx]._f_wl_radio = 1;
1030 wl_vis[uidx]._wl_nbw_cap = nphy || acphy ? 2 : 0;
1031 wl_vis[uidx]._f_wl_nband = (bands[uidx].length > 1) ? 2 : 0;
1034 switch (wmode) {
1035 case 'apwds':
1036 case 'wds':
1037 break;
1038 case 'wet':
1039 case 'sta':
1040 wl_vis[uidx]._f_wl_bcast = 0;
1041 wl_vis[uidx]._wl_channel = 0;
1042 wl_vis[uidx]._wl_nbw_cap = 0;
1043 vis._modem_ipaddr = 0;
1044 default:
1045 wl_vis[uidx]._f_wl_lazywds = 0;
1046 wl_vis[uidx]._f_wl_wds_0 = 0;
1047 break;
1050 sm2 = E('_wl'+u+'_security_mode').value;
1051 switch (sm2) {
1052 case 'disabled':
1053 wl_vis[uidx]._wl_crypto = 0;
1054 wl_vis[uidx]._wl_wep_bit = 0;
1055 wl_vis[uidx]._wl_wpa_psk = 0;
1056 wl_vis[uidx]._wl_radius_key = 0;
1057 wl_vis[uidx]._wl_radius_ipaddr = 0;
1058 wl_vis[uidx]._wl_wpa_gtk_rekey = 0;
1059 break;
1060 case 'wep':
1061 wl_vis[uidx]._wl_crypto = 0;
1062 wl_vis[uidx]._wl_wpa_psk = 0;
1063 wl_vis[uidx]._wl_radius_key = 0;
1064 wl_vis[uidx]._wl_radius_ipaddr = 0;
1065 wl_vis[uidx]._wl_wpa_gtk_rekey = 0;
1066 break;
1067 case 'radius':
1068 wl_vis[uidx]._wl_crypto = 0;
1069 wl_vis[uidx]._wl_wpa_psk = 0;
1070 break;
1071 default: // wpa*
1072 wl_vis[uidx]._wl_wep_bit = 0;
1073 if (sm2.indexOf('personal') != -1) {
1074 wl_vis[uidx]._wl_radius_key = 0;
1075 wl_vis[uidx]._wl_radius_ipaddr = 0;
1077 else {
1078 wl_vis[uidx]._wl_wpa_psk = 0;
1080 break;
1083 if ((E('_f_wl'+u+'_lazywds').value == 1) && (wl_vis[uidx]._f_wl_wds_0 == 1)) {
1084 wl_vis[uidx]._f_wl_wds_0 = 2;
1087 if (wl_vis[uidx]._wl_nbw_cap != 0) {
1088 switch (E('_wl'+u+'_net_mode').value) {
1089 case 'b-only':
1090 case 'g-only':
1091 case 'a-only':
1092 case 'bg-mixed':
1093 wl_vis[uidx]._wl_nbw_cap = 2;
1094 if (E('_wl'+u+'_nbw_cap').value != '0') {
1095 E('_wl'+u+'_nbw_cap').value = 0;
1096 refreshChannels(uidx);
1098 break;
1100 // avoid Enterprise-TKIP with 40MHz
1101 if ((sm2 == 'wpa_enterprise') && (E('_wl'+u+'_crypto').value == 'tkip')) {
1102 wl_vis[uidx]._wl_nbw_cap = 2;
1103 if (E('_wl'+u+'_nbw_cap').value != '0') {
1104 E('_wl'+u+'_nbw_cap').value = 0;
1105 refreshChannels(uidx);
1110 wl_vis[uidx]._f_wl_nctrlsb = (E('_wl'+u+'_nbw_cap').value == 0) ? 0 : wl_vis[uidx]._wl_nbw_cap;
1112 /* REMOVE-BEGIN
1113 This is ugly...
1114 Special case - 2.4GHz band, currently running in B/G-only mode,
1115 with N/Auto and 40MHz selected in the GUI.
1116 Channel list is not filtered in this case by the wl driver,
1117 and includes all channels available with 20MHz channel width.
1118 REMOVE-END */
1119 b = selectedBand(uidx);
1120 if (wl_vis[uidx]._wl_channel == 1 && wl_vis[uidx]._f_wl_nctrlsb != 0 &&
1121 ((b == '2') || (wl_vis[uidx]._f_wl_nband == 0 && b == '0'))) {
1122 switch (eval('nvram.wl'+u+'_net_mode')) {
1123 case 'b-only':
1124 case 'g-only':
1125 case 'bg-mixed':
1126 i = E('_wl'+u+'_channel').value * 1;
1127 if (i > 0 && i < 5) {
1128 E('_f_wl'+u+'_nctrlsb').value = 'lower';
1129 wl_vis[uidx]._f_wl_nctrlsb = 2;
1131 else if (i > max_channel[uidx] - 4) {
1132 E('_f_wl'+u+'_nctrlsb').value = 'upper';
1133 wl_vis[uidx]._f_wl_nctrlsb = 2;
1135 break;
1139 wl_vis[uidx]._f_wl_scan = wl_vis[uidx]._wl_channel;
1140 wl_vis[uidx]._f_wl_psk_random1 = wl_vis[uidx]._wl_wpa_psk;
1141 wl_vis[uidx]._f_wl_psk_random2 = wl_vis[uidx]._wl_radius_key;
1142 wl_vis[uidx]._wl_radius_port = wl_vis[uidx]._wl_radius_ipaddr;
1143 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;
1145 for (i = 1; i < 10; ++i) {
1146 wl_vis[uidx]['_f_wl_wds_' + i] = wl_vis[uidx]._f_wl_wds_0;
1149 } // for each wl_iface
1151 vis._ppp_passwd = vis._ppp_username;
1153 for (a in vis) {
1154 b = E(a);
1155 c = vis[a];
1156 /* REMOVE-BEGIN
1157 // if (b != null)
1158 REMOVE-END */
1159 b.disabled = (c != 1);
1160 PR(b).style.display = c ? '' : 'none';
1163 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1164 if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1165 for (a in wl_vis[uidx]) {
1166 i = 3;
1167 if (a.substr(0, 6) == '_f_wl_') i = 5;
1168 b = E(a.substr(0, i) + wl_unit(uidx) + a.substr(i, a.length));
1169 c = wl_vis[uidx][a];
1170 b.disabled = (c != 1);
1171 PR(b).style.display = c ? '' : 'none';
1176 // --- verify ---
1178 ferror.clear('_wan_proto');
1180 var wlclnt = 0;
1181 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1182 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1183 if (wl_sunit(uidx)<0) {
1184 u = wl_unit(uidx);
1185 wmode = E('_f_wl'+u+'_mode').value;
1186 sm2 = E('_wl'+u+'_security_mode').value;
1188 /* REMOVE-BEGIN
1189 if ((wl_vis[uidx]._f_wl_mode == 1) && (wmode != 'ap') && (sm2.substr(0, 4) == 'wpa2')) {
1190 ferror.set('_wl'+u+'_security_mode', 'WPA2 is supported only in AP mode.', quiet || !ok);
1191 ok = 0;
1193 else ferror.clear('_wl'+u+'_security_mode');
1194 REMOVE-END */
1196 // --- N standard does not support WPA+TKIP ---
1197 a = E('_wl'+u+'_crypto');
1198 switch (E('_wl'+u+'_net_mode').value) {
1199 case 'mixed':
1200 case 'n-only':
1201 if ((nphy || acphy) && (a.value == 'tkip') && (sm2.indexOf('wpa') != -1)) {
1202 ferror.set(a, 'TKIP encryption is not supported with WPA / WPA2 in N and AC mode.', quiet || !ok);
1203 ok = 0;
1205 else ferror.clear(a);
1206 break;
1209 a = E('_wl'+u+'_net_mode');
1210 ferror.clear(a);
1211 b = E('_f_wl'+u+'_mode');
1212 ferror.clear(b);
1213 if ((wmode == 'sta') || (wmode == 'wet')) {
1214 ++wlclnt;
1215 if (wlclnt > 1) {
1216 ferror.set(b, 'Only one wireless interface can be configured in client mode.', quiet || !ok);
1217 ok = 0;
1219 else if (a.value == 'n-only') {
1220 ferror.set(a, 'N-only is not supported in wireless client modes, use Auto.', quiet || !ok);
1221 ok = 0;
1225 a = E('_wl'+u+'_wpa_psk');
1226 ferror.clear(a);
1227 if (wl_vis[uidx]._wl_wpa_psk == 1) {
1228 if ((a.value.length < 8) || ((a.value.length == 64) && (a.value.search(/[^0-9A-Fa-f]/) != -1))) {
1229 ferror.set('_wl'+u+'_wpa_psk', 'Invalid pre-shared key. Please enter at least 8 characters or 64 hexadecimal digits.', quiet || !ok);
1230 ok = 0;
1234 // wl channel
1235 if (((wmode == 'wds') || (wmode == 'apwds')) && (wl_vis[uidx]._wl_channel == 1) && (E('_wl'+u+'_channel').value == '0')) {
1236 ferror.set('_wl'+u+'_channel', 'Fixed wireless channel required in WDS mode.', quiet || !ok);
1237 ok = 0;
1239 else ferror.clear('_wl'+u+'_channel');
1241 if (E('_f_wl'+u+'_mode').value == 'sta') {
1242 if ((wan == 'disabled') && (E('_f_wl'+u+'_radio').checked)) {
1243 ferror.set('_wan_proto', 'Wireless Client mode requires a valid WAN setting (usually DHCP).', quiet || !ok);
1244 ok = 0;
1250 // domain name or IP address
1251 a = ['_l2tp_server_ip', '_pptp_server_ip'];
1252 for (i = a.length - 1; i >= 0; --i)
1253 if ((vis[a[i]]) && ((!v_length(a[i], 1, 1)) || ((!v_ip(a[i], 1)) && (!v_domain(a[i], 1))))) {
1254 if (!quiet && ok) ferror.show(a[i]);
1255 ok = 0;
1258 // IP address
1259 a = ['_wan_gateway','_wan_ipaddr'];
1260 for (i = a.length - 1; i >= 0; --i)
1261 if ((vis[a[i]]) && (!v_ip(a[i], quiet || !ok))) ok = 0;
1263 // IP address, blank -> 0.0.0.0
1264 a = ['_f_dns_1', '_f_dns_2', '_f_dns_3','_wan_wins','_lan_gateway', '_modem_ipaddr'];
1265 for (i = a.length - 1; i >= 0; --i)
1266 if ((vis[a[i]]) && (!v_dns(a[i], quiet || !ok))) ok = 0;
1268 // netmask
1269 a = ['_wan_netmask'];
1270 for (i = a.length - 1; i >= 0; --i)
1271 if ((vis[a[i]]) && (!v_netmask(a[i], quiet || !ok))) ok = 0;
1273 // range
1274 a = [['_ppp_idletime', 3, 1440],['_ppp_redialperiod', 1, 86400],['_f_wan_mtu', 576, 1500],
1275 ['_pppoe_lei', 1, 60],['_pppoe_lef', 1, 10]];
1276 for (i = a.length - 1; i >= 0; --i) {
1277 v = a[i];
1278 if ((vis[v[0]]) && (!v_range(v[0], quiet || !ok, v[1], v[2]))) ok = 0;
1281 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1282 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1283 if (wl_sunit(uidx)<0) {
1284 u = wl_unit(uidx);
1286 // IP address
1287 a = ['_radius_ipaddr'];
1288 for (i = a.length - 1; i >= 0; --i) {
1289 if ((wl_vis[uidx]['_wl'+a[i]]) && (!v_ip('_wl'+u+a[i], quiet || !ok))) ok = 0;
1292 // range
1293 a = [['_wpa_gtk_rekey', 60, 7200], ['_radius_port', 1, 65535]];
1294 for (i = a.length - 1; i >= 0; --i) {
1295 v = a[i];
1296 if ((wl_vis[uidx]['_wl'+v[0]]) && (!v_range('_wl'+u+v[0], quiet || !ok, v[1], v[2]))) ok = 0;
1299 // length
1300 a = [['_ssid', 1], ['_radius_key', 1]];
1301 for (i = a.length - 1; i >= 0; --i) {
1302 v = a[i];
1303 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;
1306 if (wl_vis[uidx]._wl_key1) {
1307 a = (E('_wl'+u+'_wep_bit').value == 128) ? 26 : 10;
1308 for (i = 1; i <= 4; ++i) {
1309 b = E('_wl'+u+'_key' + i);
1310 b.maxLength = a;
1311 if ((b.value.length > 0) || (E('_f_wl'+u+'_wepidx_' + i).checked)) {
1312 if (!v_wep(b, quiet || !ok)) ok = 0;
1314 else ferror.clear(b);
1318 ferror.clear('_f_wl'+u+'_wds_0');
1319 if (wl_vis[uidx]._f_wl_wds_0 == 1) {
1320 b = 0;
1321 for (i = 0; i < 10; ++i) {
1322 a = E('_f_wl'+u+'_wds_' + i);
1323 if (!v_macz(a, quiet || !ok)) ok = 0;
1324 else if (!isMAC0(a.value)) b = 1;
1326 if (!b) {
1327 ferror.set('_f_wl'+u+'_wds_0', 'WDS MAC address required.', quiet || !ok);
1328 ok = 0;
1334 return ok;
1337 function earlyInit()
1339 verifyFields(null, 1);
1342 function save()
1344 if (lg.isEditing()) return;
1345 lg.resetNewEditor();
1347 var a, b, c;
1348 var i;
1349 var u, uidx, wmode, sm2, wradio;
1351 if (!verifyFields(null, false)) return;
1353 var fom = E('_fom');
1355 fom.wan_mtu.value = fom.f_wan_mtu.value;
1356 fom.wan_mtu.disabled = fom.f_wan_mtu.disabled;
1358 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1359 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1360 if (wl_sunit(uidx)<0) {
1361 u = wl_unit(uidx);
1362 wmode = E('_f_wl'+u+'_mode').value;
1363 sm2 = E('_wl'+u+'_security_mode').value;
1364 wradio = E('_f_wl'+u+'_radio').checked;
1366 E('_wl'+u+'_nband').value = selectedBand(uidx);
1368 if (wmode == 'apwds') E('_wl'+u+'_mode').value = 'ap';
1369 else E('_wl'+u+'_mode').value = wmode;
1371 if (wmode == 'wet') {
1372 fom.wan_proto.value = 'disabled';
1373 fom.wan_proto.disabled = 0;
1374 /* REMOVE-BEGIN */
1375 // TODO - what's required ? integrate with tomatogrid?
1376 /* REMOVE-END */
1379 a = [];
1380 for (i = 0; i < 10; ++i) a.push(E('_f_wl'+u+'_wds_' + i).value);
1381 E('_wl'+u+'_wds').value = joinAddr(a);
1383 if (wmode.indexOf('wds') != -1) {
1384 E('_wl'+u+'_wds_enable').value = 1;
1385 E('_wl'+u+'_lazywds').value = E('_f_wl'+u+'_lazywds').value;
1386 if (E('_wl'+u+'_lazywds').value == 1) E('_wl'+u+'_wds').value = '';
1388 else {
1389 E('_wl'+u+'_wds_enable').value = 0;
1390 E('_wl'+u+'_wds').value = '';
1391 E('_wl'+u+'_lazywds').value = 0;
1394 E('_wl'+u+'_radio').value = wradio ? 1 : 0;
1395 E('_wl'+u+'_auth').value = eval('nvram.wl'+u+'_auth');
1397 e = E('_wl'+u+'_akm');
1398 switch (sm2) {
1399 case 'disabled':
1400 case 'radius':
1401 case 'wep':
1402 e.value = '';
1403 break;
1404 default:
1405 c = [];
1407 if (sm2.indexOf('personal') != -1) {
1408 if (sm2.indexOf('wpa2_') == -1) c.push('psk');
1409 if (sm2.indexOf('wpa_') == -1) c.push('psk2');
1411 else {
1412 if (sm2.indexOf('wpa2_') == -1) c.push('wpa');
1413 if (sm2.indexOf('wpa_') == -1) c.push('wpa2');
1415 c = c.join(' ');
1416 e.value = c;
1417 break;
1419 E('_wl'+u+'_auth_mode').value = (sm2 == 'radius') ? 'radius' : 'none';
1420 E('_wl'+u+'_wep').value = ((sm2 == 'radius') || (sm2 == 'wep')) ? 'enabled': 'disabled';
1422 if (sm2.indexOf('wpa') != -1) E('_wl'+u+'_auth').value = 0;
1424 E('_wl'+u+'_nreqd').value = 0;
1425 E('_wl'+u+'_gmode').value = 1;
1426 E('_wl'+u+'_nmode').value = 0;
1427 E('_wl'+u+'_nmcsidx').value = -2; // Legacy Rate
1428 E('_wl'+u+'_nbw').value = 0;
1429 switch (E('_wl'+u+'_net_mode').value) {
1430 case 'b-only':
1431 E('_wl'+u+'_gmode').value = 0;
1432 break;
1433 case 'g-only':
1434 E('_wl'+u+'_gmode').value = 4;
1435 break;
1436 case 'bg-mixed':
1437 break;
1438 case 'a-only':
1439 E('_wl'+u+'_nmcsidx').value = -1; // Auto
1440 break;
1441 case 'n-only':
1442 if (selectedBand(uidx) == '1') { // 5 GHz
1443 E('_wl'+u+'_nmode').value = -1;
1444 E('_wl'+u+'_nmcsidx').value = -1;
1445 } else {
1446 E('_wl'+u+'_nmode').value = 1;
1447 E('_wl'+u+'_nmcsidx').value = 32;
1449 E('_wl'+u+'_nreqd').value = 1;
1450 break;
1451 default: // Auto
1452 E('_wl'+u+'_nmode').value = -1;
1453 E('_wl'+u+'_nmcsidx').value = -1;
1454 break;
1457 E('_wl'+u+'_nctrlsb').value = eval('nvram.wl'+u+'_nctrlsb');
1458 if (E('_wl'+u+'_nmode').value != 0) {
1459 E('_wl'+u+'_nctrlsb').value = E('_f_wl'+u+'_nctrlsb').value;
1460 E('_wl'+u+'_nbw').value = (E('_wl'+u+'_nbw_cap').value == 0) ? 20 : ((E('_wl'+u+'_nbw_cap').value== 3) ? 80:40);
1463 E('_wl'+u+'_closed').value = E('_f_wl'+u+'_bcast').checked ? 0 : 1;
1465 a = fields.radio.selected(eval('fom.f_wl'+u+'_wepidx'));
1466 if (a) E('_wl'+u+'_key').value = a.value;
1470 fom.wan_islan.value = fom.f_wan_islan.checked ? 1 : 0;
1471 fom.pptp_dhcp.value = fom.f_pptp_dhcp.checked ? 1 : 0;
1473 fom.wan_dns.value = joinAddr([fom.f_dns_1.value, fom.f_dns_2.value, fom.f_dns_3.value]);
1475 /* DNSSEC-BEGIN */
1476 fom.dnssec_enable.value = fom.f_dnssec_enable.checked ? 1 : 0;
1477 /* DNSSEC-END */
1479 /* DNSCRYPT-BEGIN */
1480 fom.dnscrypt_proxy.value = fom.f_dnscrypt_proxy.checked ? 1 : 0;
1481 fom.dnscrypt_manual.value = fom.f_dnscrypt_manual.checked ? 1 : 0;
1482 /* DNSCRYPT-END */
1484 fom.lan_state.value = fom.f_lan_state.checked ? 1 : 0;
1485 fom.lan_desc.value = fom.f_lan_desc.checked ? 1 : 0;
1486 fom.lan_invert.value = fom.f_lan_invert.checked ? 1 : 0;
1488 // initialize/wipe out relevant fields
1489 for (var i = 0 ; i <= MAX_BRIDGE_ID ; i++) {
1490 var j = (i == 0) ? '' : i.toString();
1491 fom['lan' + j + '_ifname'].value = '';
1492 fom['lan' + j + '_ipaddr'].value = '';
1493 fom['lan' + j + '_netmask'].value = '';
1494 fom['lan' + j + '_proto'].value = '';
1495 fom['lan' + j + '_stp'].value = '';
1496 fom['dhcp' + j + '_start'].value = '';
1497 fom['dhcp' + j + '_num'].value = '';
1498 fom['dhcp' + j + '_lease'].value = '';
1499 fom['dhcpd' + j + '_startip'].value = '';
1500 fom['dhcpd' + j + '_endip'].value = '';
1503 var d = lg.getAllData();
1504 for (var i = 0; i < d.length; ++i) {
1506 if (lg.countOverlappingNetworks(d[i][2]) > 1) {
1507 var s = 'Cannot proceed: two or more LAN bridges have conflicting IP addresses or overlapping subnets';
1508 alert(s);
1509 var e = E('footer-msg');
1510 e.innerHTML = s;
1511 e.style.visibility = 'visible';
1512 setTimeout(
1513 function() {
1514 e.innerHTML = '';
1515 e.style.visibility = 'hidden';
1516 }, 5000);
1517 return;
1520 var j = (parseInt(d[i][0]) == 0) ? '' : d[i][0].toString();
1521 fom['lan' + j + '_ifname'].value = 'br' + d[i][0];
1522 fom['lan' + j + '_stp'].value = d[i][1];
1523 fom['lan' + j + '_ipaddr'].value = d[i][2];
1524 fom['lan' + j + '_netmask'].value = d[i][3];
1525 fom['lan' + j + '_proto'].value = (d[i][4] != '0') ? 'dhcp' : 'static';
1526 fom['dhcp' + j + '_start'].value = (d[i][4] != '0') ? (d[i][5]).split('.').splice(3, 1) : '';
1527 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)
1528 fom['dhcp' + j + '_lease'].value = (d[i][4] != '0') ? d[i][7] : '';
1529 fom['dhcpd' + j + '_startip'].value = (d[i][4] != '0') ? d[i][5] : '';
1530 fom['dhcpd' + j + '_endip'].value = (d[i][4] != '0') ? d[i][6] : '';
1532 /* REMOVE-BEGIN */
1533 alert('lan' + j + '_ifname=' + fom['lan' + j + '_ifname'].value + '\n' +
1534 'lan' + j + '_stp=' + fom['lan' + j + '_stp'].value + '\n' +
1535 'lan' + j + '_ipaddr=' + fom['lan' + j + '_ipaddr'].value + '\n' +
1536 'lan' + j + '_netmask=' + fom['lan' + j + '_netmask'].value + '\n' +
1537 'lan' + j + '_proto=' + fom['lan' + j + '_proto'].value + '\n' +
1538 'dhcp' + j + '_start=' + fom['dhcp' + j + '_start'].value + '\n' +
1539 'dhcp' + j + '_num=' + fom['dhcp' + j + '_num'].value + '\n' +
1540 'dhcp' + j + '_lease=' + fom['dhcp' + j + '_lease'].value + '\n' +
1541 'dhcpd' + j + '_startip=' + fom['dhcpd' + j + '_startip'].value + '\n' +
1542 'dhcpd' + j + '_endip=' + fom['dhcpd' + j + '_endip'].value);
1543 /* REMOVE-END */
1546 var e = E('footer-msg');
1547 var t = fixIP(fom['lan_ipaddr'].value);
1548 if ((fom['lan_ifname'].value != 'br0') || (fom['lan_ipaddr'].value == '0.0.0.0') || (!t)) {
1549 e.innerHTML = 'Bridge br0 must be always defined and have a valid IP address set.';
1550 e.style.visibility = 'visible';
1551 setTimeout(
1552 function() {
1553 e.innerHTML = '';
1554 e.style.visibility = 'hidden';
1555 }, 5000);
1556 return;
1559 /* REMOVE-BEGIN
1560 // if ((nvram.lan_ipaddr != fom.lan_ipaddr.value) || (nvram.lan1_ipaddr != fom.lan1_ipaddr.value) ||
1561 // (nvram.lan2_ipaddr != fom.lan2_ipaddr.value) || (nvram.lan3_ipaddr != fom.lan3_ipaddr.value)){
1562 REMOVE-END */
1564 fom.ppp_mlppp.value = fom.f_ppp_mlppp.checked ? 1 : 0;
1566 if (nvram.lan_ipaddr != fom.lan_ipaddr.value) {
1567 fom._moveip.value = 1;
1568 form.submit(fom);
1570 else {
1571 form.submit(fom, 1);
1575 function init()
1577 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1578 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1579 if (wl_sunit(uidx)<0) {
1580 refreshNetModes(uidx);
1581 refreshChannels(uidx);
1582 refreshBandWidth(uidx);
1586 </script>
1588 </head>
1589 <body onload='init()'>
1590 <form id='_fom' method='post' action='tomato.cgi'>
1591 <table id='container' cellspacing=0>
1592 <tr><td colspan=2 id='header'>
1593 <div class='title'>Tomato</div>
1594 <div class='version'>Version <% version(); %></div>
1595 </td></tr>
1596 <tr id='body'><td id='navi'><script type='text/javascript'>navi()</script></td>
1597 <td id='content'>
1598 <div id='ident'><% ident(); %></div>
1600 <!-- / / / -->
1602 <input type='hidden' name='_nextpage' value='basic-network.asp'>
1603 <input type='hidden' name='_nextwait' value='10'>
1604 <input type='hidden' name='_service' value='*'>
1605 <input type='hidden' name='_moveip' value='0'>
1607 <input type='hidden' name='wan_mtu'>
1608 <input type='hidden' name='wan_islan'>
1609 <input type='hidden' name='pptp_dhcp'>
1610 <input type='hidden' name='wan_dns'>
1611 <input type='hidden' name='ppp_mlppp'>
1612 <!-- DNSSEC-BEGIN -->
1613 <input type='hidden' name='dnssec_enable'>
1614 <!-- DNSSEC-END -->
1615 /* DNSCRYPT-BEGIN */
1616 <input type='hidden' name='dnscrypt_proxy'>
1617 <input type='hidden' name='dnscrypt_manual'>
1618 /* DNSCRYPT-END */
1619 <input type='hidden' name='lan_state'>
1620 <input type='hidden' name='lan_desc'>
1621 <input type='hidden' name='lan_invert'>
1623 <script type='text/javascript'>
1625 for (var i = 0 ; i <= MAX_BRIDGE_ID ; i++) {
1626 var j = (i == 0) ? '' : i.toString();
1627 W('<input type=\'hidden\' id=\'lan' + j + '_ifname\' name=\'lan' + j + '_ifname\'>');
1628 W('<input type=\'hidden\' id=\'lan' + j + '_ipaddr\' name=\'lan' + j + '_ipaddr\'>');
1629 W('<input type=\'hidden\' id=\'lan' + j + '_netmask\' name=\'lan' + j + '_netmask\'>');
1630 W('<input type=\'hidden\' id=\'lan' + j + '_proto\' name=\'lan' + j + '_proto\'>');
1631 W('<input type=\'hidden\' id=\'lan' + j + '_stp\' name=\'lan' + j + '_stp\'>');
1632 W('<input type=\'hidden\' id=\'dhcp' + j + '_start\' name=\'dhcp' + j + '_start\'>');
1633 W('<input type=\'hidden\' id=\'dhcp' + j + '_num\' name=\'dhcp' + j + '_num\'>');
1634 W('<input type=\'hidden\' id=\'dhcp' + j + '_lease\' name=\'dhcp' + j + '_lease\'>');
1635 W('<input type=\'hidden\' id=\'dhcpd' + j + '_startip\' name=\'dhcpd' + j + '_startip\'>');
1636 W('<input type=\'hidden\' id=\'dhcpd' + j + '_endip\' name=\'dhcpd' + j + '_endip\'>');
1638 </script>
1640 <div class='section-title'>WAN / Internet</div>
1641 <div class='section'>
1642 <script type='text/javascript'>
1643 createFieldTable('', [
1644 { title: 'Type', name: 'wan_proto', type: 'select', options: [['dhcp','DHCP'],['pppoe','PPPoE'],['static','Static'],['pptp','PPTP'],['l2tp','L2TP'],
1645 /* LINUX26-BEGIN */
1646 /* USB-BEGIN */
1647 ['ppp3g','3G Modem'],
1648 ['lte','4G/LTE'],
1649 /* USB-END */
1650 /* LINUX26-END */
1651 ['disabled','Disabled']],
1652 value: nvram.wan_proto },
1653 { 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 },
1654 { title: 'PIN Code', name: 'modem_pin', type: 'text', maxlen: 6, size: 8, value: nvram.modem_pin, suffix: ' <small>(advised to turn off PIN Code)</small>' },
1655 { title: 'Modem init string', name: 'modem_init', type: 'text', maxlen: 25, size: 32, value: nvram.modem_init },
1656 { title: 'APN', name: 'modem_apn', type: 'text', maxlen: 25, size: 32, suffix: ' <small>(if empty, AT+CGDCONT will not be sent)</small>', value: nvram.modem_apn },
1657 { title: 'Username', name: 'ppp_username', type: 'text', maxlen: 60, size: 64, value: nvram.ppp_username },
1658 { title: 'Password', name: 'ppp_passwd', type: 'password', maxlen: 60, size: 64, peekaboo: 1, value: nvram.ppp_passwd },
1659 { title: 'Service Name', name: 'ppp_service', type: 'text', maxlen: 50, size: 64, value: nvram.ppp_service },
1660 { title: 'L2TP Server', name: 'l2tp_server_ip', type: 'text', maxlen: 128, size: 64, value: nvram.l2tp_server_ip },
1661 { title: 'Use DHCP', name: 'f_pptp_dhcp', type: 'checkbox', value: (nvram.pptp_dhcp == 1) },
1662 { title: 'IP Address', name: 'wan_ipaddr', type: 'text', maxlen: 15, size: 17, value: nvram.wan_ipaddr },
1663 { title: 'Subnet Mask', name: 'wan_netmask', type: 'text', maxlen: 15, size: 17, value: nvram.wan_netmask },
1664 { title: 'Gateway', name: 'wan_gateway', type: 'text', maxlen: 15, size: 17, value: nvram.wan_gateway },
1665 { title: 'PPTP Gateway', name: 'pptp_server_ip', type: 'text', maxlen: 128, size: 64, value: nvram.pptp_server_ip },
1666 { title: 'Options', name: 'ppp_custom', type: 'text', maxlen: 256, size: 64, value: nvram.ppp_custom },
1667 { title: 'Connect Mode', name: 'ppp_demand', type: 'select', options: [['1', 'Connect On Demand'],['0', 'Keep Alive']],
1668 value: nvram.ppp_demand },
1669 { title: 'Max Idle Time', indent: 2, name: 'ppp_idletime', type: 'text', maxlen: 5, size: 7, suffix: ' <small>minutes</small>',
1670 value: nvram.ppp_idletime },
1671 { title: 'Redial Interval', indent: 2, name: 'ppp_redialperiod', type: 'text', maxlen: 5, size: 7, suffix: ' <small>seconds</small>',
1672 value: nvram.ppp_redialperiod },
1673 { title: 'LCP Echo Interval', indent: 2, name: 'pppoe_lei', type: 'text', maxlen: 5, size: 7, suffix: ' <small>seconds (range: 1 - 60; default: 10)</small>',
1674 value: nvram.pppoe_lei },
1675 { title: 'LCP Echo Link fail limit', indent: 2, name: 'pppoe_lef', type: 'text', maxlen: 5, size: 7, suffix: ' <small>(range: 1 - 10; default: 5)</small>',
1676 value: nvram.pppoe_lef },
1677 { title: 'MTU', multi: [
1678 { name: 'mtu_enable', type: 'select', options: [['0', 'Default'],['1','Manual']], value: nvram.mtu_enable },
1679 { name: 'f_wan_mtu', type: 'text', maxlen: 4, size: 6, value: nvram.wan_mtu } ] },
1680 { title: 'Single Line MLPPP', name: 'f_ppp_mlppp', type: 'checkbox', value: (nvram.ppp_mlppp == 1) },
1682 { title: 'Route Modem IP', name: 'modem_ipaddr', type: 'text', maxlen: 15, size: 17, suffix: ' <small>(must be in different subnet to router, 0.0.0.0 to disable)</small>', value: nvram.modem_ipaddr },
1684 { title: 'Bridge WAN port to primary LAN (br0)', name: 'f_wan_islan', type: 'checkbox', value: (nvram.wan_islan == 1) }
1687 </script>
1688 </div>
1690 <div class='section-title'>LAN</div>
1691 <div class='section'>
1692 <table class='tomato-grid' cellspacing=1 id='lan-grid'></table>
1694 <script type='text/javascript'>lg.setup();</script>
1696 <script type='text/javascript'>
1697 dns = nvram.wan_dns.split(/\s+/);
1698 /* REMOVE-BEGIN
1699 //ipp = nvram.lan_ipaddr.split('.').splice(0, 3).join('.');
1700 REMOVE-END */
1701 createFieldTable('', [
1702 { title: 'Default Gateway', name: 'lan_gateway', type: 'text', maxlen: 15, size: 17, value: nvram.lan_gateway },
1703 { title: 'Static DNS', suffix: ' <small>(IP or IP:port)</small>', name: 'f_dns_1', type: 'text', maxlen: 21, size: 25, value: dns[0] || '0.0.0.0' },
1704 { title: '', name: 'f_dns_2', type: 'text', maxlen: 21, size: 25, value: dns[1] || '0.0.0.0' },
1705 { title: '', name: 'f_dns_3', type: 'text', maxlen: 21, size: 25, value: dns[2] || '0.0.0.0' },
1706 /* DNSSEC-BEGIN */
1707 { title: 'Enable DNSSEC', name: 'f_dnssec_enable', type: 'checkbox', suffix: ' <small>(must be supported by upstream nameservers)</small>', value: (nvram.dnssec_enable == 1) },
1708 /* DNSSEC-END */
1709 /* DNSCRYPT-BEGIN */
1710 { title: 'Use dnscrypt-proxy', name: 'f_dnscrypt_proxy', type: 'checkbox', value: (nvram.dnscrypt_proxy == 1) },
1711 { title: 'Manual Entry', indent: 2, name: 'f_dnscrypt_manual', type: 'checkbox', value: (nvram.dnscrypt_manual == 1) },
1712 { 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>' },
1713 { 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>' },
1714 { title: 'Provider Name', indent: 2, name: 'dnscrypt_provider_name', type: 'text', maxlen: 60, size: 25, value: nvram.dnscrypt_provider_name },
1715 { title: 'Provider Public Key', indent: 2, name: 'dnscrypt_provider_key', type: 'text', maxlen: 80, size: 25, value: nvram.dnscrypt_provider_key },
1716 { title: 'Priority', indent: 2, name: 'dnscrypt_priority', type: 'select', options: [['1','Strict-Order'],['2','No-Resolv'],['0','None']], value: nvram.dnscrypt_priority },
1717 { title: 'Local Port', indent: 2, name: 'dnscrypt_port', type: 'text', maxlen: 5, size: 7, value: nvram.dnscrypt_port },
1718 { title: 'Log Level', indent: 2, name: 'dnscrypt_log', type: 'text', maxlen: 2, size: 5, value: nvram.dnscrypt_log },
1719 /* DNSCRYPT-END */
1720 { title: 'WINS <i>(for DHCP)</i>', name: 'wan_wins', type: 'text', maxlen: 15, size: 17, value: nvram.wan_wins }
1722 </script>
1723 </div>
1725 <div class='section-title'>Ethernet Ports State - Configuration</div>
1726 <div class='section'>
1727 <script type='text/javascript'>
1728 createFieldTable('', [
1729 { title: 'Enable Ports State', name: 'f_lan_state', type: 'checkbox', value: (nvram.lan_state == 1) },
1730 { title: 'Show Speed Info', indent: 2, name: 'f_lan_desc', type: 'checkbox', value: (nvram.lan_desc == 1) },
1731 { title: 'Invert Ports Order', indent: 2, name: 'f_lan_invert', type: 'checkbox', value: (nvram.lan_invert == 1) }
1733 </script>
1734 </div>
1736 <script type='text/javascript'>
1738 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1739 //if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1740 if (wl_sunit(uidx)<0) {
1741 var u = wl_unit(uidx);
1743 W('<input type=\'hidden\' id=\'_wl'+u+'_mode\' name=\'wl'+u+'_mode\'>');
1744 W('<input type=\'hidden\' id=\'_wl'+u+'_nband\' name=\'wl'+u+'_nband\'>');
1745 W('<input type=\'hidden\' id=\'_wl'+u+'_wds_enable\' name=\'wl'+u+'_wds_enable\'>');
1746 W('<input type=\'hidden\' id=\'_wl'+u+'_wds\' name=\'wl'+u+'_wds\'>');
1747 W('<input type=\'hidden\' id=\'_wl'+u+'_radio\' name=\'wl'+u+'_radio\'>');
1748 W('<input type=\'hidden\' id=\'_wl'+u+'_closed\' name=\'wl'+u+'_closed\'>');
1749 W('<input type=\'hidden\' id=\'_wl'+u+'_key\' name=\'wl'+u+'_key\'>');
1750 W('<input type=\'hidden\' id=\'_wl'+u+'_gmode\' name=\'wl'+u+'_gmode\'>');
1751 W('<input type=\'hidden\' id=\'_wl'+u+'_akm\' name=\'wl'+u+'_akm\'>');
1752 W('<input type=\'hidden\' id=\'_wl'+u+'_auth\' name=\'wl'+u+'_auth\'>');
1753 W('<input type=\'hidden\' id=\'_wl'+u+'_auth_mode\' name=\'wl'+u+'_auth_mode\'>');
1754 W('<input type=\'hidden\' id=\'_wl'+u+'_wep\' name=\'wl'+u+'_wep\'>');
1755 W('<input type=\'hidden\' id=\'_wl'+u+'_lazywds\' name=\'wl'+u+'_lazywds\'>');
1756 W('<input type=\'hidden\' id=\'_wl'+u+'_nmode\' name=\'wl'+u+'_nmode\'>');
1757 W('<input type=\'hidden\' id=\'_wl'+u+'_nmcsidx\' name=\'wl'+u+'_nmcsidx\'>');
1758 W('<input type=\'hidden\' id=\'_wl'+u+'_nreqd\' name=\'wl'+u+'_nreqd\'>');
1759 W('<input type=\'hidden\' id=\'_wl'+u+'_nctrlsb\' name=\'wl'+u+'_nctrlsb\'>');
1760 W('<input type=\'hidden\' id=\'_wl'+u+'_nbw\' name=\'wl'+u+'_nbw\'>');
1762 W('<div class=\'section-title\'>Wireless');
1763 // if (wl_ifaces.length > 1)
1764 W(' (' + wl_display_ifname(uidx) + ')');
1765 W('</div>');
1767 W('<div class=\'section\'>');
1769 f = [
1770 { title: 'Enable Wireless', name: 'f_wl'+u+'_radio', type: 'checkbox',
1771 value: (eval('nvram.wl'+u+'_radio') == '1') && (eval('nvram.wl'+u+'_net_mode') != 'disabled') },
1772 { title: 'MAC Address', text: '<a href="advanced-mac.asp">' + eval('nvram.wl'+u+'_hwaddr') + '</a>' },
1773 { title: 'Wireless Mode', name: 'f_wl'+u+'_mode', type: 'select',
1774 options: [['ap', 'Access Point'],['apwds', 'Access Point + WDS'],['sta', 'Wireless Client'],['wet', 'Wireless Ethernet Bridge'],['wds', 'WDS']],
1775 value: ((eval('nvram.wl'+u+'_mode') == 'ap') && (eval('nvram.wl'+u+'_wds_enable') == '1')) ? 'apwds' : eval('nvram.wl'+u+'_mode') },
1776 { title: 'Radio Band', name: 'f_wl'+u+'_nband', type: 'select', options: bands[uidx],
1777 value: eval('nvram.wl'+u+'_nband') || '0' == '0' ? bands[uidx][0][0] : eval('nvram.wl'+u+'_nband') },
1778 { title: 'Wireless Network Mode', name: 'wl'+u+'_net_mode', type: 'select',
1779 value: (eval('nvram.wl'+u+'_net_mode') == 'disabled') ? 'mixed' : eval('nvram.wl'+u+'_net_mode'),
1780 options: [], prefix: '<span id="__wl'+u+'_net_mode">', suffix: '</span>' },
1781 { title: 'SSID', name: 'wl'+u+'_ssid', type: 'text', maxlen: 32, size: 34, value: eval('nvram.wl'+u+'_ssid') },
1782 { title: 'Broadcast', indent: 2, name: 'f_wl'+u+'_bcast', type: 'checkbox', value: (eval('nvram.wl'+u+'_closed') == '0') },
1783 { 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+'">',
1784 value: eval('nvram.wl'+u+'_channel') },
1785 { title: 'Channel Width', name: 'wl'+u+'_nbw_cap', type: 'select', options: [],
1786 value: eval('nvram.wl'+u+'_nbw_cap'), prefix: '<span id="__wl'+u+'_nbw_cap">', suffix: '</span>' },
1787 { title: 'Control Sideband', name: 'f_wl'+u+'_nctrlsb', type: 'select', options: [['lower','Lower'],['upper','Upper']],
1788 value: eval('nvram.wl'+u+'_nctrlsb') == 'none' ? 'lower' : eval('nvram.wl'+u+'_nctrlsb') },
1789 null,
1790 { title: 'Security', name: 'wl'+u+'_security_mode', type: 'select',
1791 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']],
1792 value: eval('nvram.wl'+u+'_security_mode') },
1793 { title: 'Encryption', indent: 2, name: 'wl'+u+'_crypto', type: 'select',
1794 options: [['tkip','TKIP'],['aes','AES'],['tkip+aes','TKIP / AES']], value: eval('nvram.wl'+u+'_crypto') },
1795 { title: 'Shared Key', indent: 2, name: 'wl'+u+'_wpa_psk', type: 'password', maxlen: 64, size: 66, peekaboo: 1,
1796 suffix: ' <input type="button" id="_f_wl'+u+'_psk_random1" value="Random" onclick="random_psk(\'_wl'+u+'_wpa_psk\')">',
1797 value: eval('nvram.wl'+u+'_wpa_psk') },
1798 { title: 'Shared Key', indent: 2, name: 'wl'+u+'_radius_key', type: 'password', maxlen: 80, size: 32, peekaboo: 1,
1799 suffix: ' <input type="button" id="_f_wl'+u+'_psk_random2" value="Random" onclick="random_psk(\'_wl'+u+'_radius_key\')">',
1800 value: eval('nvram.wl'+u+'_radius_key') },
1801 { title: 'Group Key Renewal', indent: 2, name: 'wl'+u+'_wpa_gtk_rekey', type: 'text', maxlen: 4, size: 6, suffix: ' <small>seconds</small>',
1802 value: eval('nvram.wl'+u+'_wpa_gtk_rekey') },
1803 { title: 'Radius Server', indent: 2, multi: [
1804 { name: 'wl'+u+'_radius_ipaddr', type: 'text', maxlen: 15, size: 17, value: eval('nvram.wl'+u+'_radius_ipaddr') },
1805 { name: 'wl'+u+'_radius_port', type: 'text', maxlen: 5, size: 7, prefix: ' : ', value: eval('nvram.wl'+u+'_radius_port') } ] },
1806 { title: 'Encryption', indent: 2, name: 'wl'+u+'_wep_bit', type: 'select', options: [['128','128-bits'],['64','64-bits']],
1807 value: eval('nvram.wl'+u+'_wep_bit') },
1808 { title: 'Passphrase', indent: 2, name: 'wl'+u+'_passphrase', type: 'text', maxlen: 16, size: 20,
1809 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+')">',
1810 value: eval('nvram.wl'+u+'_passphrase') }
1813 for (i = 1; i <= 4; ++i) {
1814 f.push(
1815 { title: ('Key ' + i), indent: 2, name: ('wl'+u+'_key' + i), type: 'text', maxlen: 26, size: 34,
1816 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>' : '>'),
1817 value: nvram['wl'+u+'_key' + i] });
1820 f.push(null,
1821 { title: 'WDS', name: 'f_wl'+u+'_lazywds', type: 'select',
1822 options: [['0','Link With...'],['1','Automatic']], value: nvram['wl'+u+'_lazywds'] } );
1823 wds = eval('nvram.wl'+u+'_wds').split(/\s+/);
1824 for (i = 0; i < 10; i += 2) {
1825 f.push({ title: (i ? '' : 'MAC Address'), indent: 2, multi: [
1826 { name: 'f_wl'+u+'_wds_' + i, type: 'text', maxlen: 17, size: 20, value: wds[i] || '00:00:00:00:00:00' },
1827 { name: 'f_wl'+u+'_wds_' + (i + 1), type: 'text', maxlen: 17, size: 20, value: wds[i + 1] || '00:00:00:00:00:00' } ] } );
1830 createFieldTable('', f);
1831 W('</div>');
1834 // for each wlif
1835 </script>
1837 <!-- / / / -->
1839 </td></tr>
1840 <tr><td id='footer' colspan=2>
1841 <span id='footer-msg'></span>
1842 <input type='button' value='Save' id='save-button' onclick='save()'>
1843 <input type='button' value='Cancel' id='cancel-button' onclick='reloadPage();'>
1844 </td></tr>
1845 </table>
1846 </form>
1847 <script type='text/javascript'>earlyInit()</script>
1848 <div style='height:100px'></div>
1849 </body>
1850 </html>