cosmetics changes in GUI
[tomato.git] / release / src / router / www / basic-network.asp
blobc9c6ff1c0fde274d40ad49f94469ff5799794fb5
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_port,dnscrypt_cmd,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"); %>
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');
379 var ghz = [];
380 var bands = [];
381 var nm_loaded = [], ch_loaded = [], max_channel = [];
383 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
384 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
385 if (wl_sunit(uidx)<0) {
386 var b;
387 b = [];
388 for (var i = 0; i < wl_bands[uidx].length; ++i) {
389 b.push([wl_bands[uidx][i] + '', (wl_bands[uidx][i] == '1') ? '5 GHz' : '2.4 GHz']);
391 bands.push(b);
393 b = [];
394 ghz.push(b);
396 nm_loaded.push(0);
397 ch_loaded.push(0);
398 max_channel.push(0);
399 refresher.push(null);
403 function selectedBand(uidx)
405 if (bands[uidx].length > 1) {
406 var e = E('_f_wl'+u+'_nband');
407 return (e.value + '' == '' ? eval('nvram.wl'+u+'_nband') : e.value);
408 } else if (bands[uidx].length > 0) {
409 return bands[uidx][0][0] || '0';
410 } else {
411 return '0';
415 function refreshNetModes(uidx)
417 var e, i, buf, val;
419 if (uidx >= wl_ifaces.length) return;
420 var u = wl_unit(uidx);
422 var m = [['mixed','Auto']];
423 if (selectedBand(uidx) == '1') {
424 m.push(['a-only','A Only']);
425 if (nphy) {
426 m.push(['n-only','N Only']);
429 else {
430 m.push(['b-only','B Only']);
431 m.push(['g-only','G Only']);
432 if (nphy) {
433 m.push(['bg-mixed','B/G Mixed']);
434 m.push(['n-only','N Only']);
438 e = E('_wl'+u+'_net_mode');
439 buf = '';
440 val = (!nm_loaded[uidx] || (e.value + '' == '')) ? eval('nvram.wl'+u+'_net_mode') : e.value;
441 if (val == 'disabled') val = 'mixed';
442 for (i = 0; i < m.length; ++i)
443 buf += '<option value="' + m[i][0] + '"' + ((m[i][0] == val) ? ' selected' : '') + '>' + m[i][1] + '</option>';
445 e = E('__wl'+u+'_net_mode');
446 buf = '<select name="wl'+u+'_net_mode" onchange="verifyFields(this, 1)" id = "_wl'+u+'_net_mode">' + buf + '</select>';
447 elem.setInnerHTML(e, buf);
448 nm_loaded[uidx] = 1;
451 function refreshChannels(uidx)
453 if (refresher[uidx] != null) return;
454 if (u >= wl_ifaces.length) return;
455 var u = wl_unit(uidx);
457 refresher[uidx] = new XmlHttp();
458 refresher[uidx].onCompleted = function(text, xml) {
459 try {
460 var e, i, buf, val;
462 var wl_channels = [];
463 eval(text);
465 ghz[uidx] = [];
466 max_channel[uidx] = 0;
467 for (i = 0; i < wl_channels.length; ++i) {
468 ghz[uidx].push([wl_channels[i][0] + '',
469 (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']);
470 max_channel[uidx] = wl_channels[i][0] * 1;
473 e = E('_wl'+u+'_channel');
474 buf = '';
475 val = (!ch_loaded[uidx] || (e.value + '' == '')) ? eval('nvram.wl'+u+'_channel') : e.value;
476 for (i = 0; i < ghz[uidx].length; ++i)
477 buf += '<option value="' + ghz[uidx][i][0] + '"' + ((ghz[uidx][i][0] == val) ? ' selected' : '') + '>' + ghz[uidx][i][1] + '</option>';
479 e = E('__wl'+u+'_channel');
480 buf = '<select name="wl'+u+'_channel" onchange="verifyFields(this, 1)" id = "_wl'+u+'_channel">' + buf + '</select>';
481 elem.setInnerHTML(e, buf);
482 ch_loaded[uidx] = 1;
484 refresher[uidx] = null;
485 verifyFields(null, 1);
487 catch (x) {
489 refresher[uidx] = null;
492 var bw, sb, e;
494 e = E('_f_wl'+u+'_nctrlsb');
495 sb = (e.value + '' == '' ? eval('nvram.wl'+u+'_nctrlsb') : e.value);
496 e = E('_wl'+u+'_nbw_cap');
497 bw = (e.value + '' == '' ? eval('nvram.wl'+u+'_nbw_cap') : e.value) == '0' ? '20' : '40';
499 refresher[uidx].onError = function(ex) { alert(ex); refresher[uidx] = null; reloadPage(); }
500 refresher[uidx].post('update.cgi', 'exec=wlchannels&arg0=' + u + '&arg1=' + (nphy ? '1' : '0') +
501 '&arg2=' + bw + '&arg3=' + selectedBand(uidx) + '&arg4=' + sb);
504 function spin(x, unit)
506 for (var u = 0; u < wl_ifaces.length; ++u) {
507 E('_f_wl'+wl_unit(u)+'_scan').disabled = x;
509 var e = E('_f_wl'+unit+'_scan');
510 if (x) e.value = 'Scan ' + (wscan.tries + 1);
511 else e.value = 'Scan';
512 E('spin'+unit).style.visibility = x ? 'visible' : 'hidden';
515 function scan()
517 if (xob) return;
519 var unit = wscan.unit;
520 var uidx = wl_uidx(unit);
522 xob = new XmlHttp();
523 xob.onCompleted = function(text, xml) {
524 try {
525 var i;
527 wlscandata = [];
528 eval(text);
530 for (i = 0; i < wlscandata.length; ++i) {
531 var data = wlscandata[i];
532 var ch = data[2];
533 var mac = data[0];
535 if (!wscan.inuse[ch]) {
536 wscan.inuse[ch] = {
537 count: 0,
538 rssi: -999,
539 ssid: ''
543 if (!wscan.seen[mac]) {
544 wscan.seen[mac] = 1;
545 ++wscan.inuse[ch].count;
548 if (data[4] > wscan.inuse[ch].rssi) {
549 wscan.inuse[ch].rssi = data[4];
550 wscan.inuse[ch].ssid = data[1];
553 var e = E('_wl'+unit+'_channel');
554 for (i = 1; i < ghz[uidx].length; ++i) {
555 var s = ghz[uidx][i][1];
556 var u = wscan.inuse[ghz[uidx][i][0]];
557 if (u) s += ' (' + u.count + ' AP' + (u.count == 1 ? '' : 's') + ' / strongest: "' + escapeHTML(ellipsis(u.ssid, 15)) + '" ' + u.rssi + ' dBm)';
558 e.options[i].innerHTML = s;
560 e.style.width = '400px';
562 xob = null;
564 if (wscan.tries < 4) {
565 ++wscan.tries;
566 setTimeout(scan, 1000);
567 return;
570 catch (x) {
572 spin(0, unit);
574 xob.onError = function(x) {
575 alert('error: ' + x);
576 spin(0, unit);
577 xob = null;
580 spin(1, unit);
581 xob.post('update.cgi', 'exec=wlscan&arg0='+unit);
584 function scanButton(u)
586 if (xob) return;
588 wscan = {
589 unit: u,
590 seen: [],
591 inuse: [],
592 tries: 0
595 scan();
598 function joinAddr(a) {
599 var r, i, s;
601 r = [];
602 for (i = 0; i < a.length; ++i) {
603 s = a[i];
604 if ((s != '00:00:00:00:00:00') && (s != '0.0.0.0')) r.push(s);
606 return r.join(' ');
609 function random_x(max)
611 var c = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
612 var s = '';
613 while (max-- > 0) s += c.substr(Math.floor(c.length * Math.random()), 1);
614 return s;
617 function random_psk(id)
619 var e = E(id);
620 e.value = random_x(63);
621 verifyFields(null, 1);
624 function random_wep(u)
626 E('_wl'+u+'_passphrase').value = random_x(16);
627 generate_wep(u);
630 function v_wep(e, quiet)
632 var s = e.value;
634 if (((s.length == 5) || (s.length == 13)) && (s.length == (e.maxLength >> 1))) {
635 // no checking
637 else {
638 s = s.toUpperCase().replace(/[^0-9A-F]/g, '');
639 if (s.length != e.maxLength) {
640 ferror.set(e, 'Invalid WEP key. Expecting ' + e.maxLength + ' hex or ' + (e.maxLength >> 1) + ' ASCII characters.', quiet);
641 return 0;
645 e.value = s;
646 ferror.clear(e);
647 return 1;
650 // compatible w/ Linksys' and Netgear's (key 1) method for 128-bits
651 function generate_wep(u)
653 function _wepgen(pass, i)
655 while (pass.length < 64) pass += pass;
656 return hex_md5(pass.substr(0, 64)).substr(i, (E('_wl'+u+'_wep_bit').value == 128) ? 26 : 10);
659 var e = E('_wl'+u+'_passphrase');
660 var pass = e.value;
661 if (!v_length(e, false, 3)) return;
662 E('_wl'+u+'_key1').value = _wepgen(pass, 0);
663 pass += '#$%';
664 E('_wl'+u+'_key2').value = _wepgen(pass, 2);
665 pass += '!@#';
666 E('_wl'+u+'_key3').value = _wepgen(pass, 4);
667 pass += '%&^';
668 E('_wl'+u+'_key4').value = _wepgen(pass, 6);
669 verifyFields(null, 1);
672 function verifyFields(focused, quiet)
674 var i;
675 var ok = 1;
676 var a, b, c, d, e;
677 var u, uidx;
678 var wmode, sm2;
680 var n = E('_f_lan_state').checked;
681 E('_f_lan_desc').disabled = !n;
682 E('_f_lan_invert').disabled = !n;
684 /* DNSCRYPT-BEGIN */
685 var p = E('_f_dnscrypt_proxy').checked;
686 E('_dnscrypt_port').disabled = !p;
687 E('_dnscrypt_cmd').disabled = !p;
688 /* DNSCRYPT-END */
690 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
691 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
692 if (wl_sunit(uidx)<0) {
693 u = wl_unit(uidx);
694 if (focused == E('_f_wl'+u+'_nband')) {
695 refreshNetModes(uidx);
696 refreshChannels(uidx);
698 else if (focused == E('_f_wl'+u+'_nctrlsb') || focused == E('_wl'+u+'_nbw_cap')) {
699 refreshChannels(uidx);
704 // --- visibility ---
706 var vis = {
707 _wan_proto: 1,
708 _ppp_username: 1,
709 _ppp_passwd: 1,
710 _ppp_service: 1,
711 _ppp_custom: 1,
712 _l2tp_server_ip: 1,
713 _wan_ipaddr: 1,
714 _wan_netmask: 1,
715 _wan_gateway: 1,
716 _pptp_server_ip: 1,
717 _f_pptp_dhcp: 1,
718 _ppp_demand: 1,
719 _ppp_idletime: 1,
720 _ppp_redialperiod: 1,
721 _pppoe_lei: 1,
722 _pppoe_lef: 1,
723 _mtu_enable: 1,
724 _f_wan_mtu: 1,
725 _f_wan_islan: 0,
726 _f_ppp_mlppp: 1,
727 _modem_ipaddr: 1,
729 _f_dns_1: 1,
730 _f_dns_2: 1,
731 _f_dns_3: 1,
732 _lan_gateway: 1,
733 _wan_wins: 1,
734 _modem_pin: 1,
735 _modem_dev: 1,
736 _modem_init: 1,
737 _modem_apn: 1
740 var wl_vis = [];
741 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
742 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
743 if (wl_sunit(uidx)<0) {
744 a = {
745 _f_wl_radio: 1,
746 _f_wl_mode: 1,
747 _f_wl_nband: (bands[uidx].length > 1) ? 1 : 0,
748 _wl_net_mode: 1,
749 _wl_ssid: 1,
750 _f_wl_bcast: 1,
751 _wl_channel: 1,
752 _wl_nbw_cap: nphy ? 1 : 0,
753 _f_wl_nctrlsb: nphy ? 1 : 0,
754 _f_wl_scan: 1,
756 _wl_security_mode: 1,
757 _wl_crypto: 1,
758 _wl_wpa_psk: 1,
759 _f_wl_psk_random1: 1,
760 _f_wl_psk_random2: 1,
761 _wl_wpa_gtk_rekey: 1,
762 _wl_radius_key: 1,
763 _wl_radius_ipaddr: 1,
764 _wl_radius_port: 1,
765 _wl_wep_bit: 1,
766 _wl_passphrase: 1,
767 _f_wl_wep_gen: 1,
768 _f_wl_wep_random: 1,
769 _wl_key1: 1,
770 _wl_key2: 1,
771 _wl_key3: 1,
772 _wl_key4: 1,
774 _f_wl_lazywds: 1,
775 _f_wl_wds_0: 1
777 wl_vis.push(a);
781 var wan = E('_wan_proto').value;
783 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
784 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
785 if (wl_sunit(uidx)<0) {
786 wmode = E('_f_wl'+wl_unit(uidx)+'_mode').value;
788 if (wmode == 'wet') {
789 wan = 'disabled';
790 vis._wan_proto = 0;
793 if ((wan == 'disabled') || (wmode == 'sta') || (wmode == 'wet')) {
794 vis._f_wan_islan = 1;
799 switch (wan) {
800 case 'disabled':
801 vis._ppp_username = 0;
802 vis._ppp_service = 0;
803 vis._ppp_custom = 0;
804 vis._l2tp_server_ip = 0;
805 vis._wan_ipaddr = 0;
806 vis._wan_netmask = 0;
807 vis._wan_gateway = 0;
808 vis._pptp_server_ip = 0;
809 vis._f_pptp_dhcp = 0;
810 vis._ppp_demand = 0;
811 vis._mtu_enable = 0;
812 vis._f_wan_mtu = 0;
813 vis._f_ppp_mlppp = 0;
814 vis._modem_ipaddr = 0;
815 vis._modem_pin = 0;
816 vis._modem_dev = 0;
817 vis._modem_init = 0;
818 vis._modem_apn = 0;
819 vis._pppoe_lei = 0;
820 vis._pppoe_lef = 0;
821 break;
822 case 'dhcp':
823 vis._l2tp_server_ip = 0;
824 vis._pppoe_lei = 0;
825 vis._pppoe_lef = 0;
826 vis._ppp_demand = 0;
827 vis._ppp_service = 0;
828 vis._ppp_username = 0;
829 vis._ppp_custom = 0;
830 vis._pptp_server_ip = 0;
831 vis._f_pptp_dhcp = 0;
832 vis._wan_gateway = 0;
833 vis._wan_ipaddr = 0;
834 vis._wan_netmask = 0;
835 vis._f_ppp_mlppp = 0;
836 vis._modem_ipaddr = 1;
838 vis._lan_gateway = 0;
839 vis._modem_pin = 0;
840 vis._modem_dev = 0;
841 vis._modem_init = 0;
842 vis._modem_apn = 0;
843 break;
844 case 'pppoe':
845 vis._l2tp_server_ip = 0;
846 vis._pptp_server_ip = 0;
847 vis._f_pptp_dhcp = 0;
848 vis._wan_gateway = 0;
849 vis._wan_ipaddr = 0;
850 vis._wan_netmask = 0;
851 vis._modem_ipaddr = 1;
853 vis._lan_gateway = 0;
854 vis._modem_pin = 0;
855 vis._modem_dev = 0;
856 vis._modem_init = 0;
857 vis._modem_apn = 0;
858 break;
859 case 'ppp3g':
860 vis._pppoe_lei = 0;
861 vis._pppoe_lef = 0;
862 vis._ppp_service = 0;
863 vis._l2tp_server_ip = 0;
864 vis._pptp_server_ip = 0;
865 vis._f_pptp_dhcp = 0;
866 vis._wan_gateway = 0;
867 vis._wan_ipaddr = 0;
868 vis._wan_netmask = 0;
869 vis._lan_gateway = 0;
870 vis._modem_ipaddr = 0;
871 vis._f_ppp_mlppp = 0;
872 break;
873 case 'static':
874 vis._pppoe_lei = 0;
875 vis._pppoe_lef = 0;
876 vis._l2tp_server_ip = 0;
877 vis._ppp_demand = 0;
878 vis._ppp_service = 0;
879 vis._ppp_username = 0;
880 vis._ppp_custom = 0;
881 vis._pptp_server_ip = 0;
882 vis._f_pptp_dhcp = 0;
883 vis._f_ppp_mlppp = 0;
884 vis._modem_ipaddr = 1;
886 vis._lan_gateway = 0;
887 vis._modem_pin = 0;
888 vis._modem_dev = 0;
889 vis._modem_init = 0;
890 vis._modem_apn = 0;
891 break;
892 case 'pptp':
893 vis._pppoe_lei = 0;
894 vis._pppoe_lef = 0;
895 vis._l2tp_server_ip = 0;
896 vis._ppp_service = 0;
897 vis._wan_gateway = (!E('_f_pptp_dhcp').checked);
898 vis._wan_ipaddr = (!E('_f_pptp_dhcp').checked);
899 vis._modem_ipaddr = 0;
901 vis._lan_gateway = 0;
902 vis._modem_pin = 0;
903 vis._modem_dev = 0;
904 vis._modem_init = 0;
905 vis._modem_apn = 0;
906 break;
907 case 'l2tp':
908 vis._pppoe_lei = 0;
909 vis._pppoe_lef = 0;
910 vis._pptp_server_ip = 0;
911 vis._ppp_service = 0;
912 vis._wan_gateway = (!E('_f_pptp_dhcp').checked);
913 vis._wan_ipaddr = (!E('_f_pptp_dhcp').checked);
914 vis._modem_ipaddr = 0;
916 vis._lan_gateway = 0;
917 vis._modem_pin = 0;
918 vis._modem_dev = 0;
919 vis._modem_init = 0;
920 vis._modem_apn = 0;
921 break;
924 vis._ppp_idletime = (E('_ppp_demand').value == 1) && vis._ppp_demand
925 vis._ppp_redialperiod = !vis._ppp_idletime && vis._ppp_demand;
927 if (vis._mtu_enable) {
928 if (E('_mtu_enable').value == 0) {
929 vis._f_wan_mtu = 2;
930 a = E('_f_wan_mtu');
931 switch (E('_wan_proto').value) {
932 case 'pppoe':
933 a.value = 1492;
934 break;
935 case 'pptp':
936 case 'l2tp':
937 a.value = 1460;
938 break;
939 default:
940 a.value = 1500;
941 break;
946 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
947 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
948 if (wl_sunit(uidx)<0) {
949 u = wl_unit(uidx);
950 wmode = E('_f_wl'+u+'_mode').value;
952 if (!E('_f_wl'+u+'_radio').checked) {
953 for (a in wl_vis[uidx]) {
954 wl_vis[uidx][a] = 2;
956 wl_vis[uidx]._f_wl_radio = 1;
957 wl_vis[uidx]._wl_nbw_cap = nphy ? 2 : 0;
958 wl_vis[uidx]._f_wl_nband = (bands[uidx].length > 1) ? 2 : 0;
961 switch (wmode) {
962 case 'apwds':
963 case 'wds':
964 break;
965 case 'wet':
966 case 'sta':
967 wl_vis[uidx]._f_wl_bcast = 0;
968 wl_vis[uidx]._wl_channel = 0;
969 wl_vis[uidx]._wl_nbw_cap = 0;
970 vis._modem_ipaddr = 0;
971 default:
972 wl_vis[uidx]._f_wl_lazywds = 0;
973 wl_vis[uidx]._f_wl_wds_0 = 0;
974 break;
977 sm2 = E('_wl'+u+'_security_mode').value;
978 switch (sm2) {
979 case 'disabled':
980 wl_vis[uidx]._wl_crypto = 0;
981 wl_vis[uidx]._wl_wep_bit = 0;
982 wl_vis[uidx]._wl_wpa_psk = 0;
983 wl_vis[uidx]._wl_radius_key = 0;
984 wl_vis[uidx]._wl_radius_ipaddr = 0;
985 wl_vis[uidx]._wl_wpa_gtk_rekey = 0;
986 break;
987 case 'wep':
988 wl_vis[uidx]._wl_crypto = 0;
989 wl_vis[uidx]._wl_wpa_psk = 0;
990 wl_vis[uidx]._wl_radius_key = 0;
991 wl_vis[uidx]._wl_radius_ipaddr = 0;
992 wl_vis[uidx]._wl_wpa_gtk_rekey = 0;
993 break;
994 case 'radius':
995 wl_vis[uidx]._wl_crypto = 0;
996 wl_vis[uidx]._wl_wpa_psk = 0;
997 break;
998 default: // wpa*
999 wl_vis[uidx]._wl_wep_bit = 0;
1000 if (sm2.indexOf('personal') != -1) {
1001 wl_vis[uidx]._wl_radius_key = 0;
1002 wl_vis[uidx]._wl_radius_ipaddr = 0;
1004 else {
1005 wl_vis[uidx]._wl_wpa_psk = 0;
1007 break;
1010 if ((E('_f_wl'+u+'_lazywds').value == 1) && (wl_vis[uidx]._f_wl_wds_0 == 1)) {
1011 wl_vis[uidx]._f_wl_wds_0 = 2;
1014 if (wl_vis[uidx]._wl_nbw_cap != 0) {
1015 switch (E('_wl'+u+'_net_mode').value) {
1016 case 'b-only':
1017 case 'g-only':
1018 case 'a-only':
1019 case 'bg-mixed':
1020 wl_vis[uidx]._wl_nbw_cap = 2;
1021 if (E('_wl'+u+'_nbw_cap').value != '0') {
1022 E('_wl'+u+'_nbw_cap').value = 0;
1023 refreshChannels(uidx);
1025 break;
1027 // avoid Enterprise-TKIP with 40MHz
1028 if ((sm2 == 'wpa_enterprise') && (E('_wl'+u+'_crypto').value == 'tkip')) {
1029 wl_vis[uidx]._wl_nbw_cap = 2;
1030 if (E('_wl'+u+'_nbw_cap').value != '0') {
1031 E('_wl'+u+'_nbw_cap').value = 0;
1032 refreshChannels(uidx);
1037 wl_vis[uidx]._f_wl_nctrlsb = (E('_wl'+u+'_nbw_cap').value == 0) ? 0 : wl_vis[uidx]._wl_nbw_cap;
1039 /* REMOVE-BEGIN
1040 This is ugly...
1041 Special case - 2.4GHz band, currently running in B/G-only mode,
1042 with N/Auto and 40MHz selected in the GUI.
1043 Channel list is not filtered in this case by the wl driver,
1044 and includes all channels available with 20MHz channel width.
1045 REMOVE-END */
1046 b = selectedBand(uidx);
1047 if (wl_vis[uidx]._wl_channel == 1 && wl_vis[uidx]._f_wl_nctrlsb != 0 &&
1048 ((b == '2') || (wl_vis[uidx]._f_wl_nband == 0 && b == '0'))) {
1049 switch (eval('nvram.wl'+u+'_net_mode')) {
1050 case 'b-only':
1051 case 'g-only':
1052 case 'bg-mixed':
1053 i = E('_wl'+u+'_channel').value * 1;
1054 if (i > 0 && i < 5) {
1055 E('_f_wl'+u+'_nctrlsb').value = 'lower';
1056 wl_vis[uidx]._f_wl_nctrlsb = 2;
1058 else if (i > max_channel[uidx] - 4) {
1059 E('_f_wl'+u+'_nctrlsb').value = 'upper';
1060 wl_vis[uidx]._f_wl_nctrlsb = 2;
1062 break;
1066 wl_vis[uidx]._f_wl_scan = wl_vis[uidx]._wl_channel;
1067 wl_vis[uidx]._f_wl_psk_random1 = wl_vis[uidx]._wl_wpa_psk;
1068 wl_vis[uidx]._f_wl_psk_random2 = wl_vis[uidx]._wl_radius_key;
1069 wl_vis[uidx]._wl_radius_port = wl_vis[uidx]._wl_radius_ipaddr;
1070 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;
1072 for (i = 1; i < 10; ++i) {
1073 wl_vis[uidx]['_f_wl_wds_' + i] = wl_vis[uidx]._f_wl_wds_0;
1076 } // for each wl_iface
1078 vis._ppp_passwd = vis._ppp_username;
1080 for (a in vis) {
1081 b = E(a);
1082 c = vis[a];
1083 /* REMOVE-BEGIN
1084 // if (b != null)
1085 REMOVE-END */
1086 b.disabled = (c != 1);
1087 PR(b).style.display = c ? '' : 'none';
1090 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1091 if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1092 for (a in wl_vis[uidx]) {
1093 i = 3;
1094 if (a.substr(0, 6) == '_f_wl_') i = 5;
1095 b = E(a.substr(0, i) + wl_unit(uidx) + a.substr(i, a.length));
1096 c = wl_vis[uidx][a];
1097 b.disabled = (c != 1);
1098 PR(b).style.display = c ? '' : 'none';
1103 // --- verify ---
1105 ferror.clear('_wan_proto');
1107 var wlclnt = 0;
1108 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1109 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1110 if (wl_sunit(uidx)<0) {
1111 u = wl_unit(uidx);
1112 wmode = E('_f_wl'+u+'_mode').value;
1113 sm2 = E('_wl'+u+'_security_mode').value;
1115 /* REMOVE-BEGIN
1116 if ((wl_vis[uidx]._f_wl_mode == 1) && (wmode != 'ap') && (sm2.substr(0, 4) == 'wpa2')) {
1117 ferror.set('_wl'+u+'_security_mode', 'WPA2 is supported only in AP mode.', quiet || !ok);
1118 ok = 0;
1120 else ferror.clear('_wl'+u+'_security_mode');
1121 REMOVE-END */
1123 // --- N standard does not support WPA+TKIP ---
1124 a = E('_wl'+u+'_crypto');
1125 switch (E('_wl'+u+'_net_mode').value) {
1126 case 'mixed':
1127 case 'n-only':
1128 if (nphy && (a.value == 'tkip') && (sm2.indexOf('wpa') != -1)) {
1129 ferror.set(a, 'TKIP encryption is not supported with WPA / WPA2 in N mode.', quiet || !ok);
1130 ok = 0;
1132 else ferror.clear(a);
1133 break;
1136 a = E('_wl'+u+'_net_mode');
1137 ferror.clear(a);
1138 b = E('_f_wl'+u+'_mode');
1139 ferror.clear(b);
1140 if ((wmode == 'sta') || (wmode == 'wet')) {
1141 ++wlclnt;
1142 if (wlclnt > 1) {
1143 ferror.set(b, 'Only one wireless interface can be configured in client mode.', quiet || !ok);
1144 ok = 0;
1146 else if (a.value == 'n-only') {
1147 ferror.set(a, 'N-only is not supported in wireless client modes, use Auto.', quiet || !ok);
1148 ok = 0;
1152 a = E('_wl'+u+'_wpa_psk');
1153 ferror.clear(a);
1154 if (wl_vis[uidx]._wl_wpa_psk == 1) {
1155 if ((a.value.length < 8) || ((a.value.length == 64) && (a.value.search(/[^0-9A-Fa-f]/) != -1))) {
1156 ferror.set('_wl'+u+'_wpa_psk', 'Invalid pre-shared key. Please enter at least 8 characters or 64 hexadecimal digits.', quiet || !ok);
1157 ok = 0;
1161 // wl channel
1162 if (((wmode == 'wds') || (wmode == 'apwds')) && (wl_vis[uidx]._wl_channel == 1) && (E('_wl'+u+'_channel').value == '0')) {
1163 ferror.set('_wl'+u+'_channel', 'Fixed wireless channel required in WDS mode.', quiet || !ok);
1164 ok = 0;
1166 else ferror.clear('_wl'+u+'_channel');
1168 if (E('_f_wl'+u+'_mode').value == 'sta') {
1169 if ((wan == 'disabled') && (E('_f_wl'+u+'_radio').checked)) {
1170 ferror.set('_wan_proto', 'Wireless Client mode requires a valid WAN setting (usually DHCP).', quiet || !ok);
1171 ok = 0;
1177 // domain name or IP address
1178 a = ['_l2tp_server_ip', '_pptp_server_ip'];
1179 for (i = a.length - 1; i >= 0; --i)
1180 if ((vis[a[i]]) && ((!v_length(a[i], 1, 1)) || ((!v_ip(a[i], 1)) && (!v_domain(a[i], 1))))) {
1181 if (!quiet && ok) ferror.show(a[i]);
1182 ok = 0;
1185 // IP address
1186 a = ['_wan_gateway','_wan_ipaddr'];
1187 for (i = a.length - 1; i >= 0; --i)
1188 if ((vis[a[i]]) && (!v_ip(a[i], quiet || !ok))) ok = 0;
1190 // IP address, blank -> 0.0.0.0
1191 a = ['_f_dns_1', '_f_dns_2', '_f_dns_3','_wan_wins','_lan_gateway', '_modem_ipaddr'];
1192 for (i = a.length - 1; i >= 0; --i)
1193 if ((vis[a[i]]) && (!v_dns(a[i], quiet || !ok))) ok = 0;
1195 // netmask
1196 a = ['_wan_netmask'];
1197 for (i = a.length - 1; i >= 0; --i)
1198 if ((vis[a[i]]) && (!v_netmask(a[i], quiet || !ok))) ok = 0;
1200 // range
1201 a = [['_ppp_idletime', 3, 1440],['_ppp_redialperiod', 1, 86400],['_f_wan_mtu', 576, 1500],
1202 ['_pppoe_lei', 1, 60],['_pppoe_lef', 1, 10]];
1203 for (i = a.length - 1; i >= 0; --i) {
1204 v = a[i];
1205 if ((vis[v[0]]) && (!v_range(v[0], quiet || !ok, v[1], v[2]))) ok = 0;
1208 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1209 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1210 if (wl_sunit(uidx)<0) {
1211 u = wl_unit(uidx);
1213 // IP address
1214 a = ['_radius_ipaddr'];
1215 for (i = a.length - 1; i >= 0; --i) {
1216 if ((wl_vis[uidx]['_wl'+a[i]]) && (!v_ip('_wl'+u+a[i], quiet || !ok))) ok = 0;
1219 // range
1220 a = [['_wpa_gtk_rekey', 60, 7200], ['_radius_port', 1, 65535]];
1221 for (i = a.length - 1; i >= 0; --i) {
1222 v = a[i];
1223 if ((wl_vis[uidx]['_wl'+v[0]]) && (!v_range('_wl'+u+v[0], quiet || !ok, v[1], v[2]))) ok = 0;
1226 // length
1227 a = [['_ssid', 1], ['_radius_key', 1]];
1228 for (i = a.length - 1; i >= 0; --i) {
1229 v = a[i];
1230 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;
1233 if (wl_vis[uidx]._wl_key1) {
1234 a = (E('_wl'+u+'_wep_bit').value == 128) ? 26 : 10;
1235 for (i = 1; i <= 4; ++i) {
1236 b = E('_wl'+u+'_key' + i);
1237 b.maxLength = a;
1238 if ((b.value.length > 0) || (E('_f_wl'+u+'_wepidx_' + i).checked)) {
1239 if (!v_wep(b, quiet || !ok)) ok = 0;
1241 else ferror.clear(b);
1245 ferror.clear('_f_wl'+u+'_wds_0');
1246 if (wl_vis[uidx]._f_wl_wds_0 == 1) {
1247 b = 0;
1248 for (i = 0; i < 10; ++i) {
1249 a = E('_f_wl'+u+'_wds_' + i);
1250 if (!v_macz(a, quiet || !ok)) ok = 0;
1251 else if (!isMAC0(a.value)) b = 1;
1253 if (!b) {
1254 ferror.set('_f_wl'+u+'_wds_0', 'WDS MAC address required.', quiet || !ok);
1255 ok = 0;
1261 return ok;
1264 function earlyInit()
1266 verifyFields(null, 1);
1269 function save()
1271 if (lg.isEditing()) return;
1272 lg.resetNewEditor();
1274 var a, b, c;
1275 var i;
1276 var u, uidx, wmode, sm2, wradio;
1278 if (!verifyFields(null, false)) return;
1280 var fom = E('_fom');
1282 fom.wan_mtu.value = fom.f_wan_mtu.value;
1283 fom.wan_mtu.disabled = fom.f_wan_mtu.disabled;
1285 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1286 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1287 if (wl_sunit(uidx)<0) {
1288 u = wl_unit(uidx);
1289 wmode = E('_f_wl'+u+'_mode').value;
1290 sm2 = E('_wl'+u+'_security_mode').value;
1291 wradio = E('_f_wl'+u+'_radio').checked;
1293 E('_wl'+u+'_nband').value = selectedBand(uidx);
1295 if (wmode == 'apwds') E('_wl'+u+'_mode').value = 'ap';
1296 else E('_wl'+u+'_mode').value = wmode;
1298 if (wmode == 'wet') {
1299 fom.wan_proto.value = 'disabled';
1300 fom.wan_proto.disabled = 0;
1301 /* REMOVE-BEGIN */
1302 // TODO - what's required ? integrate with tomatogrid?
1303 /* REMOVE-END */
1306 a = [];
1307 for (i = 0; i < 10; ++i) a.push(E('_f_wl'+u+'_wds_' + i).value);
1308 E('_wl'+u+'_wds').value = joinAddr(a);
1310 if (wmode.indexOf('wds') != -1) {
1311 E('_wl'+u+'_wds_enable').value = 1;
1312 E('_wl'+u+'_lazywds').value = E('_f_wl'+u+'_lazywds').value;
1313 if (E('_wl'+u+'_lazywds').value == 1) E('_wl'+u+'_wds').value = '';
1315 else {
1316 E('_wl'+u+'_wds_enable').value = 0;
1317 E('_wl'+u+'_wds').value = '';
1318 E('_wl'+u+'_lazywds').value = 0;
1321 E('_wl'+u+'_radio').value = wradio ? 1 : 0;
1322 E('_wl'+u+'_auth').value = eval('nvram.wl'+u+'_auth');
1324 e = E('_wl'+u+'_akm');
1325 switch (sm2) {
1326 case 'disabled':
1327 case 'radius':
1328 case 'wep':
1329 e.value = '';
1330 break;
1331 default:
1332 c = [];
1334 if (sm2.indexOf('personal') != -1) {
1335 if (sm2.indexOf('wpa2_') == -1) c.push('psk');
1336 if (sm2.indexOf('wpa_') == -1) c.push('psk2');
1338 else {
1339 if (sm2.indexOf('wpa2_') == -1) c.push('wpa');
1340 if (sm2.indexOf('wpa_') == -1) c.push('wpa2');
1342 c = c.join(' ');
1343 e.value = c;
1344 break;
1346 E('_wl'+u+'_auth_mode').value = (sm2 == 'radius') ? 'radius' : 'none';
1347 E('_wl'+u+'_wep').value = ((sm2 == 'radius') || (sm2 == 'wep')) ? 'enabled': 'disabled';
1349 if (sm2.indexOf('wpa') != -1) E('_wl'+u+'_auth').value = 0;
1351 E('_wl'+u+'_nreqd').value = 0;
1352 E('_wl'+u+'_gmode').value = 1;
1353 E('_wl'+u+'_nmode').value = 0;
1354 E('_wl'+u+'_nmcsidx').value = -2; // Legacy Rate
1355 E('_wl'+u+'_nbw').value = 0;
1356 switch (E('_wl'+u+'_net_mode').value) {
1357 case 'b-only':
1358 E('_wl'+u+'_gmode').value = 0;
1359 break;
1360 case 'g-only':
1361 E('_wl'+u+'_gmode').value = 4;
1362 break;
1363 case 'bg-mixed':
1364 break;
1365 case 'a-only':
1366 E('_wl'+u+'_nmcsidx').value = -1; // Auto
1367 break;
1368 case 'n-only':
1369 if (selectedBand(uidx) == '1') { // 5 GHz
1370 E('_wl'+u+'_nmode').value = -1;
1371 E('_wl'+u+'_nmcsidx').value = -1;
1372 } else {
1373 E('_wl'+u+'_nmode').value = 1;
1374 E('_wl'+u+'_nmcsidx').value = 32;
1376 E('_wl'+u+'_nreqd').value = 1;
1377 break;
1378 default: // Auto
1379 E('_wl'+u+'_nmode').value = -1;
1380 E('_wl'+u+'_nmcsidx').value = -1;
1381 break;
1384 E('_wl'+u+'_nctrlsb').value = eval('nvram.wl'+u+'_nctrlsb');
1385 if (E('_wl'+u+'_nmode').value != 0) {
1386 E('_wl'+u+'_nctrlsb').value = E('_f_wl'+u+'_nctrlsb').value;
1387 E('_wl'+u+'_nbw').value = (E('_wl'+u+'_nbw_cap').value == 0) ? 20 : 40;
1390 E('_wl'+u+'_closed').value = E('_f_wl'+u+'_bcast').checked ? 0 : 1;
1392 a = fields.radio.selected(eval('fom.f_wl'+u+'_wepidx'));
1393 if (a) E('_wl'+u+'_key').value = a.value;
1397 fom.wan_islan.value = fom.f_wan_islan.checked ? 1 : 0;
1398 fom.pptp_dhcp.value = fom.f_pptp_dhcp.checked ? 1 : 0;
1400 fom.wan_dns.value = joinAddr([fom.f_dns_1.value, fom.f_dns_2.value, fom.f_dns_3.value]);
1402 /* DNSCRYPT-BEGIN */
1403 fom.dnscrypt_proxy.value = fom.f_dnscrypt_proxy.checked ? 1 : 0;
1404 /* DNSCRYPT-END */
1406 fom.lan_state.value = fom.f_lan_state.checked ? 1 : 0;
1407 fom.lan_desc.value = fom.f_lan_desc.checked ? 1 : 0;
1408 fom.lan_invert.value = fom.f_lan_invert.checked ? 1 : 0;
1410 // initialize/wipe out relevant fields
1411 for (var i = 0 ; i <= MAX_BRIDGE_ID ; i++) {
1412 var j = (i == 0) ? '' : i.toString();
1413 fom['lan' + j + '_ifname'].value = '';
1414 fom['lan' + j + '_ipaddr'].value = '';
1415 fom['lan' + j + '_netmask'].value = '';
1416 fom['lan' + j + '_proto'].value = '';
1417 fom['lan' + j + '_stp'].value = '';
1418 fom['dhcp' + j + '_start'].value = '';
1419 fom['dhcp' + j + '_num'].value = '';
1420 fom['dhcp' + j + '_lease'].value = '';
1421 fom['dhcpd' + j + '_startip'].value = '';
1422 fom['dhcpd' + j + '_endip'].value = '';
1425 var d = lg.getAllData();
1426 for (var i = 0; i < d.length; ++i) {
1428 if (lg.countOverlappingNetworks(d[i][2]) > 1) {
1429 var s = 'Cannot proceed: two or more LAN bridges have conflicting IP addresses or overlapping subnets';
1430 alert(s);
1431 var e = E('footer-msg');
1432 e.innerHTML = s;
1433 e.style.visibility = 'visible';
1434 setTimeout(
1435 function() {
1436 e.innerHTML = '';
1437 e.style.visibility = 'hidden';
1438 }, 5000);
1439 return;
1442 var j = (parseInt(d[i][0]) == 0) ? '' : d[i][0].toString();
1443 fom['lan' + j + '_ifname'].value = 'br' + d[i][0];
1444 fom['lan' + j + '_stp'].value = d[i][1];
1445 fom['lan' + j + '_ipaddr'].value = d[i][2];
1446 fom['lan' + j + '_netmask'].value = d[i][3];
1447 fom['lan' + j + '_proto'].value = (d[i][4] != '0') ? 'dhcp' : 'static';
1448 fom['dhcp' + j + '_start'].value = (d[i][4] != '0') ? (d[i][5]).split('.').splice(3, 1) : '';
1449 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)
1450 fom['dhcp' + j + '_lease'].value = (d[i][4] != '0') ? d[i][7] : '';
1451 fom['dhcpd' + j + '_startip'].value = (d[i][4] != '0') ? d[i][5] : '';
1452 fom['dhcpd' + j + '_endip'].value = (d[i][4] != '0') ? d[i][6] : '';
1454 /* REMOVE-BEGIN */
1455 alert('lan' + j + '_ifname=' + fom['lan' + j + '_ifname'].value + '\n' +
1456 'lan' + j + '_stp=' + fom['lan' + j + '_stp'].value + '\n' +
1457 'lan' + j + '_ipaddr=' + fom['lan' + j + '_ipaddr'].value + '\n' +
1458 'lan' + j + '_netmask=' + fom['lan' + j + '_netmask'].value + '\n' +
1459 'lan' + j + '_proto=' + fom['lan' + j + '_proto'].value + '\n' +
1460 'dhcp' + j + '_start=' + fom['dhcp' + j + '_start'].value + '\n' +
1461 'dhcp' + j + '_num=' + fom['dhcp' + j + '_num'].value + '\n' +
1462 'dhcp' + j + '_lease=' + fom['dhcp' + j + '_lease'].value + '\n' +
1463 'dhcpd' + j + '_startip=' + fom['dhcpd' + j + '_startip'].value + '\n' +
1464 'dhcpd' + j + '_endip=' + fom['dhcpd' + j + '_endip'].value);
1465 /* REMOVE-END */
1468 var e = E('footer-msg');
1469 var t = fixIP(fom['lan_ipaddr'].value);
1470 if ((fom['lan_ifname'].value != 'br0') || (fom['lan_ipaddr'].value == '0.0.0.0') || (!t)) {
1471 e.innerHTML = 'Bridge br0 must be always defined and have a valid IP address set.';
1472 e.style.visibility = 'visible';
1473 setTimeout(
1474 function() {
1475 e.innerHTML = '';
1476 e.style.visibility = 'hidden';
1477 }, 5000);
1478 return;
1481 /* REMOVE-BEGIN
1482 // if ((nvram.lan_ipaddr != fom.lan_ipaddr.value) || (nvram.lan1_ipaddr != fom.lan1_ipaddr.value) ||
1483 // (nvram.lan2_ipaddr != fom.lan2_ipaddr.value) || (nvram.lan3_ipaddr != fom.lan3_ipaddr.value)){
1484 REMOVE-END */
1486 fom.ppp_mlppp.value = fom.f_ppp_mlppp.checked ? 1 : 0;
1488 if (nvram.lan_ipaddr != fom.lan_ipaddr.value) {
1489 fom._moveip.value = 1;
1490 form.submit(fom);
1492 else {
1493 form.submit(fom, 1);
1497 function init()
1499 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1500 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1501 if (wl_sunit(uidx)<0) {
1502 refreshNetModes(uidx);
1503 refreshChannels(uidx);
1507 </script>
1509 </head>
1510 <body onload='init()'>
1511 <form id='_fom' method='post' action='tomato.cgi'>
1512 <table id='container' cellspacing=0>
1513 <tr><td colspan=2 id='header'>
1514 <div class='title'>Tomato</div>
1515 <div class='version'>Version <% version(); %></div>
1516 </td></tr>
1517 <tr id='body'><td id='navi'><script type='text/javascript'>navi()</script></td>
1518 <td id='content'>
1519 <div id='ident'><% ident(); %></div>
1521 <!-- / / / -->
1523 <input type='hidden' name='_nextpage' value='basic-network.asp'>
1524 <input type='hidden' name='_nextwait' value='10'>
1525 <input type='hidden' name='_service' value='*'>
1526 <input type='hidden' name='_moveip' value='0'>
1528 <input type='hidden' name='wan_mtu'>
1529 <input type='hidden' name='wan_islan'>
1530 <input type='hidden' name='pptp_dhcp'>
1531 <input type='hidden' name='wan_dns'>
1532 <input type='hidden' name='ppp_mlppp'>
1533 /* DNSCRYPT-BEGIN */
1534 <input type='hidden' name='dnscrypt_proxy'>
1535 /* DNSCRYPT-END */
1536 <input type='hidden' name='lan_state'>
1537 <input type='hidden' name='lan_desc'>
1538 <input type='hidden' name='lan_invert'>
1540 <script type='text/javascript'>
1542 for (var i = 0 ; i <= MAX_BRIDGE_ID ; i++) {
1543 var j = (i == 0) ? '' : i.toString();
1544 W('<input type=\'hidden\' id=\'lan' + j + '_ifname\' name=\'lan' + j + '_ifname\'>');
1545 W('<input type=\'hidden\' id=\'lan' + j + '_ipaddr\' name=\'lan' + j + '_ipaddr\'>');
1546 W('<input type=\'hidden\' id=\'lan' + j + '_netmask\' name=\'lan' + j + '_netmask\'>');
1547 W('<input type=\'hidden\' id=\'lan' + j + '_proto\' name=\'lan' + j + '_proto\'>');
1548 W('<input type=\'hidden\' id=\'lan' + j + '_stp\' name=\'lan' + j + '_stp\'>');
1549 W('<input type=\'hidden\' id=\'dhcp' + j + '_start\' name=\'dhcp' + j + '_start\'>');
1550 W('<input type=\'hidden\' id=\'dhcp' + j + '_num\' name=\'dhcp' + j + '_num\'>');
1551 W('<input type=\'hidden\' id=\'dhcp' + j + '_lease\' name=\'dhcp' + j + '_lease\'>');
1552 W('<input type=\'hidden\' id=\'dhcpd' + j + '_startip\' name=\'dhcpd' + j + '_startip\'>');
1553 W('<input type=\'hidden\' id=\'dhcpd' + j + '_endip\' name=\'dhcpd' + j + '_endip\'>');
1555 </script>
1557 <div class='section-title'>WAN / Internet</div>
1558 <div class='section'>
1559 <script type='text/javascript'>
1560 createFieldTable('', [
1561 { title: 'Type', name: 'wan_proto', type: 'select', options: [['dhcp','DHCP'],['pppoe','PPPoE'],['static','Static'],['pptp','PPTP'],['l2tp','L2TP'],
1562 /* LINUX26-BEGIN */
1563 /* USB-BEGIN */
1564 ['ppp3g','3G Modem'],
1565 /* USB-END */
1566 /* LINUX26-END */
1567 ['disabled','Disabled']],
1568 value: nvram.wan_proto },
1569 { 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 },
1570 { 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>' },
1571 { title: 'Modem init string', name: 'modem_init', type: 'text', maxlen: 25, size: 32, value: nvram.modem_init },
1572 { title: 'APN', name: 'modem_apn', type: 'text', maxlen: 25, size: 32, value: nvram.modem_apn },
1573 { title: 'Username', name: 'ppp_username', type: 'text', maxlen: 60, size: 64, value: nvram.ppp_username },
1574 { title: 'Password', name: 'ppp_passwd', type: 'password', maxlen: 60, size: 64, peekaboo: 1, value: nvram.ppp_passwd },
1575 { title: 'Service Name', name: 'ppp_service', type: 'text', maxlen: 50, size: 64, value: nvram.ppp_service },
1576 { title: 'L2TP Server', name: 'l2tp_server_ip', type: 'text', maxlen: 128, size: 64, value: nvram.l2tp_server_ip },
1577 { title: 'Use DHCP', name: 'f_pptp_dhcp', type: 'checkbox', value: (nvram.pptp_dhcp == 1) },
1578 { title: 'IP Address', name: 'wan_ipaddr', type: 'text', maxlen: 15, size: 17, value: nvram.wan_ipaddr },
1579 { title: 'Subnet Mask', name: 'wan_netmask', type: 'text', maxlen: 15, size: 17, value: nvram.wan_netmask },
1580 { title: 'Gateway', name: 'wan_gateway', type: 'text', maxlen: 15, size: 17, value: nvram.wan_gateway },
1581 { title: 'PPTP Gateway', name: 'pptp_server_ip', type: 'text', maxlen: 128, size: 64, value: nvram.pptp_server_ip },
1582 { title: 'Options', name: 'ppp_custom', type: 'text', maxlen: 256, size: 64, value: nvram.ppp_custom },
1583 { title: 'Connect Mode', name: 'ppp_demand', type: 'select', options: [['1', 'Connect On Demand'],['0', 'Keep Alive']],
1584 value: nvram.ppp_demand },
1585 { title: 'Max Idle Time', indent: 2, name: 'ppp_idletime', type: 'text', maxlen: 5, size: 7, suffix: ' <i>(minutes)</i>',
1586 value: nvram.ppp_idletime },
1587 { title: 'Redial Interval', indent: 2, name: 'ppp_redialperiod', type: 'text', maxlen: 5, size: 7, suffix: ' <i>(seconds)</i>',
1588 value: nvram.ppp_redialperiod },
1589 { title: 'LCP Echo Interval', indent: 2, name: 'pppoe_lei', type: 'text', maxlen: 5, size: 7, suffix: ' <i>seconds (range: 1 - 60; default: 10)</i>',
1590 value: nvram.pppoe_lei },
1591 { 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>',
1592 value: nvram.pppoe_lef },
1593 { title: 'MTU', multi: [
1594 { name: 'mtu_enable', type: 'select', options: [['0', 'Default'],['1','Manual']], value: nvram.mtu_enable },
1595 { name: 'f_wan_mtu', type: 'text', maxlen: 4, size: 6, value: nvram.wan_mtu } ] },
1596 { title: 'Single Line MLPPP', name: 'f_ppp_mlppp', type: 'checkbox', value: (nvram.ppp_mlppp == 1) },
1598 { 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 },
1600 { title: 'Bridge WAN port to primary LAN (br0)', name: 'f_wan_islan', type: 'checkbox', value: (nvram.wan_islan == 1) }
1603 </script>
1604 </div>
1606 <div class='section-title'>LAN</div>
1607 <div class='section'>
1608 <table class='tomato-grid' cellspacing=1 id='lan-grid'></table>
1610 <script type='text/javascript'>lg.setup();</script>
1612 <script type='text/javascript'>
1613 dns = nvram.wan_dns.split(/\s+/);
1614 /* REMOVE-BEGIN
1615 //ipp = nvram.lan_ipaddr.split('.').splice(0, 3).join('.');
1616 REMOVE-END */
1617 createFieldTable('', [
1618 { title: 'Default Gateway', name: 'lan_gateway', type: 'text', maxlen: 15, size: 17, value: nvram.lan_gateway },
1619 { 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' },
1620 { title: '', name: 'f_dns_2', type: 'text', maxlen: 21, size: 25, value: dns[1] || '0.0.0.0' },
1621 { title: '', name: 'f_dns_3', type: 'text', maxlen: 21, size: 25, value: dns[2] || '0.0.0.0' },
1622 /* DNSCRYPT-BEGIN */
1623 { title: 'Use dnscrypt-proxy', name: 'f_dnscrypt_proxy', type: 'checkbox', value: (nvram.dnscrypt_proxy == 1) },
1624 { title: 'Local Port', indent: 2, name: 'dnscrypt_port', type: 'text', maxlen: 5, size: 7, value: nvram.dnscrypt_port },
1625 { title: 'Startup Parameters', indent: 2, name: 'dnscrypt_cmd', type: 'text', maxlen: 256, size: 64, value: nvram.dnscrypt_cmd, suffix: ' <i>(optional)</i>' },
1626 /* DNSCRYPT-END */
1627 { title: 'WINS <i>(for DHCP)</i>', name: 'wan_wins', type: 'text', maxlen: 15, size: 17, value: nvram.wan_wins }
1629 </script>
1630 </div>
1632 <div class='section-title'>Ethernet Ports State - Configuration</div>
1633 <div class='section'>
1634 <script type='text/javascript'>
1635 createFieldTable('', [
1636 { title: 'Enable Ports State', name: 'f_lan_state', type: 'checkbox', value: (nvram.lan_state == 1) },
1637 { title: 'Show Speed Info', indent: 2, name: 'f_lan_desc', type: 'checkbox', value: (nvram.lan_desc == 1) },
1638 { title: 'Invert Ports Order', indent: 2, name: 'f_lan_invert', type: 'checkbox', value: (nvram.lan_invert == 1) }
1640 </script>
1641 </div>
1643 <script type='text/javascript'>
1645 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1646 //if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1647 if (wl_sunit(uidx)<0) {
1648 var u = wl_unit(uidx);
1650 W('<input type=\'hidden\' id=\'_wl'+u+'_mode\' name=\'wl'+u+'_mode\'>');
1651 W('<input type=\'hidden\' id=\'_wl'+u+'_nband\' name=\'wl'+u+'_nband\'>');
1652 W('<input type=\'hidden\' id=\'_wl'+u+'_wds_enable\' name=\'wl'+u+'_wds_enable\'>');
1653 W('<input type=\'hidden\' id=\'_wl'+u+'_wds\' name=\'wl'+u+'_wds\'>');
1654 W('<input type=\'hidden\' id=\'_wl'+u+'_radio\' name=\'wl'+u+'_radio\'>');
1655 W('<input type=\'hidden\' id=\'_wl'+u+'_closed\' name=\'wl'+u+'_closed\'>');
1656 W('<input type=\'hidden\' id=\'_wl'+u+'_key\' name=\'wl'+u+'_key\'>');
1657 W('<input type=\'hidden\' id=\'_wl'+u+'_gmode\' name=\'wl'+u+'_gmode\'>');
1658 W('<input type=\'hidden\' id=\'_wl'+u+'_akm\' name=\'wl'+u+'_akm\'>');
1659 W('<input type=\'hidden\' id=\'_wl'+u+'_auth\' name=\'wl'+u+'_auth\'>');
1660 W('<input type=\'hidden\' id=\'_wl'+u+'_auth_mode\' name=\'wl'+u+'_auth_mode\'>');
1661 W('<input type=\'hidden\' id=\'_wl'+u+'_wep\' name=\'wl'+u+'_wep\'>');
1662 W('<input type=\'hidden\' id=\'_wl'+u+'_lazywds\' name=\'wl'+u+'_lazywds\'>');
1663 W('<input type=\'hidden\' id=\'_wl'+u+'_nmode\' name=\'wl'+u+'_nmode\'>');
1664 W('<input type=\'hidden\' id=\'_wl'+u+'_nmcsidx\' name=\'wl'+u+'_nmcsidx\'>');
1665 W('<input type=\'hidden\' id=\'_wl'+u+'_nreqd\' name=\'wl'+u+'_nreqd\'>');
1666 W('<input type=\'hidden\' id=\'_wl'+u+'_nctrlsb\' name=\'wl'+u+'_nctrlsb\'>');
1667 W('<input type=\'hidden\' id=\'_wl'+u+'_nbw\' name=\'wl'+u+'_nbw\'>');
1669 W('<div class=\'section-title\'>Wireless');
1670 // if (wl_ifaces.length > 1)
1671 W(' (' + wl_display_ifname(uidx) + ')');
1672 W('</div>');
1674 W('<div class=\'section\'>');
1676 f = [
1677 { title: 'Enable Wireless', name: 'f_wl'+u+'_radio', type: 'checkbox',
1678 value: (eval('nvram.wl'+u+'_radio') == '1') && (eval('nvram.wl'+u+'_net_mode') != 'disabled') },
1679 { title: 'MAC Address', text: '<a href="advanced-mac.asp">' + eval('nvram.wl'+u+'_hwaddr') + '</a>' },
1680 { title: 'Wireless Mode', name: 'f_wl'+u+'_mode', type: 'select',
1681 options: [['ap', 'Access Point'],['apwds', 'Access Point + WDS'],['sta', 'Wireless Client'],['wet', 'Wireless Ethernet Bridge'],['wds', 'WDS']],
1682 value: ((eval('nvram.wl'+u+'_mode') == 'ap') && (eval('nvram.wl'+u+'_wds_enable') == '1')) ? 'apwds' : eval('nvram.wl'+u+'_mode') },
1683 { title: 'Radio Band', name: 'f_wl'+u+'_nband', type: 'select', options: bands[uidx],
1684 value: eval('nvram.wl'+u+'_nband') || '0' == '0' ? bands[uidx][0][0] : eval('nvram.wl'+u+'_nband') },
1685 { title: 'Wireless Network Mode', name: 'wl'+u+'_net_mode', type: 'select',
1686 value: (eval('nvram.wl'+u+'_net_mode') == 'disabled') ? 'mixed' : eval('nvram.wl'+u+'_net_mode'),
1687 options: [], prefix: '<span id="__wl'+u+'_net_mode">', suffix: '</span>' },
1688 { title: 'SSID', name: 'wl'+u+'_ssid', type: 'text', maxlen: 32, size: 34, value: eval('nvram.wl'+u+'_ssid') },
1689 { title: 'Broadcast', indent: 2, name: 'f_wl'+u+'_bcast', type: 'checkbox', value: (eval('nvram.wl'+u+'_closed') == '0') },
1690 { 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+'">',
1691 value: eval('nvram.wl'+u+'_channel') },
1692 { title: 'Channel Width', name: 'wl'+u+'_nbw_cap', type: 'select', options: [['0','20 MHz'],['1','40 MHz']],
1693 value: eval('nvram.wl'+u+'_nbw_cap') },
1694 { title: 'Control Sideband', name: 'f_wl'+u+'_nctrlsb', type: 'select', options: [['lower','Lower'],['upper','Upper']],
1695 value: eval('nvram.wl'+u+'_nctrlsb') == 'none' ? 'lower' : eval('nvram.wl'+u+'_nctrlsb') },
1696 null,
1697 { title: 'Security', name: 'wl'+u+'_security_mode', type: 'select',
1698 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']],
1699 value: eval('nvram.wl'+u+'_security_mode') },
1700 { title: 'Encryption', indent: 2, name: 'wl'+u+'_crypto', type: 'select',
1701 options: [['tkip','TKIP'],['aes','AES'],['tkip+aes','TKIP / AES']], value: eval('nvram.wl'+u+'_crypto') },
1702 { title: 'Shared Key', indent: 2, name: 'wl'+u+'_wpa_psk', type: 'password', maxlen: 64, size: 66, peekaboo: 1,
1703 suffix: ' <input type="button" id="_f_wl'+u+'_psk_random1" value="Random" onclick="random_psk(\'_wl'+u+'_wpa_psk\')">',
1704 value: eval('nvram.wl'+u+'_wpa_psk') },
1705 { title: 'Shared Key', indent: 2, name: 'wl'+u+'_radius_key', type: 'password', maxlen: 80, size: 32, peekaboo: 1,
1706 suffix: ' <input type="button" id="_f_wl'+u+'_psk_random2" value="Random" onclick="random_psk(\'_wl'+u+'_radius_key\')">',
1707 value: eval('nvram.wl'+u+'_radius_key') },
1708 { title: 'Group Key Renewal', indent: 2, name: 'wl'+u+'_wpa_gtk_rekey', type: 'text', maxlen: 4, size: 6, suffix: ' <i>(seconds)</i>',
1709 value: eval('nvram.wl'+u+'_wpa_gtk_rekey') },
1710 { title: 'Radius Server', indent: 2, multi: [
1711 { name: 'wl'+u+'_radius_ipaddr', type: 'text', maxlen: 15, size: 17, value: eval('nvram.wl'+u+'_radius_ipaddr') },
1712 { name: 'wl'+u+'_radius_port', type: 'text', maxlen: 5, size: 7, prefix: ' : ', value: eval('nvram.wl'+u+'_radius_port') } ] },
1713 { title: 'Encryption', indent: 2, name: 'wl'+u+'_wep_bit', type: 'select', options: [['128','128-bits'],['64','64-bits']],
1714 value: eval('nvram.wl'+u+'_wep_bit') },
1715 { title: 'Passphrase', indent: 2, name: 'wl'+u+'_passphrase', type: 'text', maxlen: 16, size: 20,
1716 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+')">',
1717 value: eval('nvram.wl'+u+'_passphrase') }
1720 for (i = 1; i <= 4; ++i) {
1721 f.push(
1722 { title: ('Key ' + i), indent: 2, name: ('wl'+u+'_key' + i), type: 'text', maxlen: 26, size: 34,
1723 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>' : '>'),
1724 value: nvram['wl'+u+'_key' + i] });
1727 f.push(null,
1728 { title: 'WDS', name: 'f_wl'+u+'_lazywds', type: 'select',
1729 options: [['0','Link With...'],['1','Automatic']], value: nvram['wl'+u+'_lazywds'] } );
1730 wds = eval('nvram.wl'+u+'_wds').split(/\s+/);
1731 for (i = 0; i < 10; i += 2) {
1732 f.push({ title: (i ? '' : 'MAC Address'), indent: 2, multi: [
1733 { name: 'f_wl'+u+'_wds_' + i, type: 'text', maxlen: 17, size: 20, value: wds[i] || '00:00:00:00:00:00' },
1734 { name: 'f_wl'+u+'_wds_' + (i + 1), type: 'text', maxlen: 17, size: 20, value: wds[i + 1] || '00:00:00:00:00:00' } ] } );
1737 createFieldTable('', f);
1738 W('</div>');
1741 // for each wlif
1742 </script>
1744 <!-- / / / -->
1746 </td></tr>
1747 <tr><td id='footer' colspan=2>
1748 <span id='footer-msg'></span>
1749 <input type='button' value='Save' id='save-button' onclick='save()'>
1750 <input type='button' value='Cancel' id='cancel-button' onclick='reloadPage();'>
1751 </td></tr>
1752 </table>
1753 </form>
1754 <script type='text/javascript'>earlyInit()</script>
1755 <div style='height:100px'></div>
1756 </body>
1757 </html>