Merge branch 'VLAN-GUI' into Toastman-VLAN
[tomato.git] / release / src / router / www / basic-network.asp
blob0522d2d5436f0f6812fb967ef7fbc1476ce64211
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: Networks</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;
35 </style>
37 <script type='text/javascript' src='debug.js'></script>
39 <script type='text/javascript' src='md5.js'></script>
40 <script type='text/javascript' src='wireless.jsx?_http_id=<% nv(http_id); %>'></script>
41 <script type='text/javascript' src='interfaces.js'></script>
42 <script type='text/javascript'>
43 // <% nvram("dhcp_lease,dhcp_num,dhcp_start,dhcpd_startip,dhcpd_endip,l2tp_server_ip,lan_gateway,lan_ipaddr,lan_netmask,lan_proto,mtu_enable,ppp_demand,ppp_idletime,ppp_passwd,ppp_redialperiod,ppp_service,ppp_username,ppp_custom,pptp_server_ip,pptp_dhcp,ppp_defgw,wl_security_mode,wan_dns,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"); %>
45 var lg = new TomatoGrid();
46 lg.setup = function() {
47 this.init('lan-grid', '', 4, [
48 { type: 'select', options: [[0, '0'],[1, '1'],[2, '2'],[3, '3']], prefix: '<div class="centered">', suffix: '</div>' },
49 { type: 'checkbox', prefix: '<div class="centered">', suffix: '</div>' },
50 { type: 'text', maxlen: 15, size: 17 },
51 { type: 'text', maxlen: 15, size: 17 },
52 { type: 'checkbox', prefix: '<div class="centered">', suffix: '</div>' },
53 { multi: [ { type: 'text', maxlen: 15, size: 17}, { type: 'text', maxlen: 15, size: 17 } ] },
54 { type: 'text', maxlen: 6, size: 8 }] );
55 this.headerSet(['Bridge', 'STP', 'IP Address', 'Netmask', 'DHCP', 'IP&nbsp;Range&nbsp;<i>(first/last)</i>', 'Lease&nbsp;Time&nbsp;<i>(mins)</i>']);
57 var numBridges = 0;
58 for (var i = 0 ; i <= MAX_BRIDGE_ID ; i++) {
59 var j = (i == 0) ? '' : i.toString();
60 if (nvram['lan' + j + '_ifname'].length > 0) {
61 if ((!fixIP(nvram['dhcpd' + j + '_startip'])) || (!fixIP(nvram['dhcpd' + j + '_endip']))) {
62 var x = nvram['lan' + j + '_ipaddr'].split('.').splice(0, 3).join('.') + '.';
63 nvram['dhcpd' + j + '_startip'] = x + nvram['dhcp' + j + '_start'];
64 nvram['dhcpd' + j + '_endip'] = x + ((nvram['dhcp' + j + '_start'] * 1) + (nvram['dhcp' + j + '_num'] * 1) - 1);
66 lg.insertData(-1, [
67 i.toString(),
68 nvram['lan' + j + '_stp'],
69 nvram['lan' + j + '_ipaddr'],
70 nvram['lan' + j + '_netmask'],
71 (nvram['lan' + j + '_proto'] == 'dhcp') ? '1' : '0',
72 (nvram['dhcp' + j + '_start'] != '') ? fixIP(getNetworkAddress(nvram['lan' + j + '_ipaddr'], nvram['lan' + j + '_netmask']).split('.').splice(0, 3).join('.') + '.' + nvram['dhcp' + j + '_start']) : '',
73 (nvram['dhcp' + j + '_start'] != '') ? parseInt(nvram['dhcp' + j + '_start']) + parseInt(nvram['dhcp' + j + '_num']) - 1 : '',
74 (nvram['dhcp' + j + '_start'] != '') ? nvram['dhcp' + j + '_lease'] : ''
75 ] ) ;
76 numBridges++;
79 lg.canDelete = false;
80 lg.sort(0);
81 elem.removeClass(lg.header.cells[lg.sortColumn], 'sortasc', 'sortdes');
82 lg.showNewEditor();
83 lg.resetNewEditor();
86 lg.dataToView = function(data) {
87 return ['br' + data[0],
88 (data[1].toString() == '1') ? '<small><i>Enabled</i></small>' : '<small><i>Disabled</i></small>',
89 data[2],
90 data[3],
91 (data[4].toString() == '1') ? '<small><i>Enabled</i></small>' : '<small><i>Disabled</i></small>',
92 (((data[5] != null) && (data[5] != '')) ? (data[5] + ' - ') : '') + (((data[6] != null) && (data[6] != '')) ? data[6] : ''),
93 (((data[7] != null) && (data[7] != '')) ? data[7] : '') ];
96 lg.dataToFieldValues = function (data) {
97 return [data[0],
98 (data[1] != 0) ? 'checked' : '',
99 data[2].toString(),
100 data[3].toString(),
101 (data[4].toString() == '1') ? 'checked' : '',
102 data[5].toString(),
103 (data[6] != '') ? fixIP(getNetworkAddress(data[2], data[3]).split('.').splice(0, 3).join('.') + '.' + parseInt(data[6])) : '',
104 data[7].toString() ];
107 lg.fieldValuesToData = function(row) {
108 var f = fields.getAll(row);
109 var g = f[6].value.split('.');
110 return [f[0].value,
111 f[1].checked ? 1 : 0,
112 f[2].value,
113 f[3].value,
114 f[4].checked ? 1 : 0,
115 f[5].value,
116 (g[3] != null) ? g[3] : '',
117 f[7].value ];
120 lg.resetNewEditor = function() {
121 var f = fields.getAll(this.newEditor);
122 f[0].selectedIndex=0;
123 var t = MAX_BRIDGE_ID;
124 while((this.countBridge(f[0].selectedIndex) > 0) && (t > 0)) {
125 f[0].selectedIndex = (f[0].selectedIndex%(MAX_BRIDGE_ID))+1;
126 t--;
128 for(var j=0; j<= MAX_BRIDGE_ID ; j++) {
129 f[0].options[j].disabled = (this.countBridge(j) > 0);
131 f[1].checked = 0;
132 f[2].value = '';
133 f[3].value = '';
134 f[5].value = '';
135 f[6].value = '';
136 f[7].value = '';
137 f[4].checked = 0;
138 f[4].disabled = 1;
139 f[5].disabled = 1;
140 f[6].disabled = 1;
141 f[7].disabled = 1;
142 ferror.clearAll(fields.getAll(this.newEditor));
145 lg.onCancel = function() {
146 this.removeEditor();
147 this.showSource();
148 this.disableNewEditor(false);
150 this.resetNewEditor();
153 lg.onAdd = function() {
154 var data;
156 this.moving = null;
157 this.rpHide();
159 if (!this.verifyFields(this.newEditor, false)) return;
161 data = this.fieldValuesToData(this.newEditor);
162 this.insertData(-1, data);
164 this.disableNewEditor(false);
165 this.resetNewEditor();
167 this.resort();
170 lg.onOK = function() {
171 var i, data, view;
173 if (!this.verifyFields(this.editor, false)) return;
175 data = this.fieldValuesToData(this.editor);
176 view = this.dataToView(data);
178 this.source.setRowData(data);
179 for (i = 0; i < this.source.cells.length; ++i) {
180 this.source.cells[i].innerHTML = view[i];
183 this.removeEditor();
184 this.showSource();
185 this.disableNewEditor(false);
187 this.resort();
188 this.resetNewEditor();
191 lg.onDelete = function() {
192 this.removeEditor();
193 elem.remove(this.source);
194 this.source = null;
195 this.disableNewEditor(false);
197 this.resetNewEditor();
200 lg.countElem = function(f, v) {
201 var data = this.getAllData();
202 var total = 0;
203 for (var i = 0; i < data.length; ++i) {
204 total += (data[i][f] == v) ? 1 : 0;
206 return total;
209 lg.countBridge = function (v) {
210 return this.countElem(0,v);
213 lg.countOverlappingNetworks = function (ip) {
214 var data = this.getAllData();
215 var total = 0;
216 for (var i = 0; i < data.length; ++i) {
217 var net = getNetworkAddress(data[i][2], data[i][3]);
218 var brd = getBroadcastAddress(net, data[i][3]);
219 total += ((aton(ip) <= aton(brd)) && (aton(ip) >= aton(net))) ? 1 : 0;
221 return total;
224 lg.verifyFields = function(row, quiet) {
225 var ok=1;
226 var f;
228 f = fields.getAll(row);
230 for(var j=0; j<= MAX_BRIDGE_ID ; j++) {
231 f[0].options[j].disabled = (this.countBridge(j) > 0);
234 if(this.countBridge(f[0].selectedIndex) > 0) {
235 ferror.set(f[0], 'Cannot add another entry for bridge br' + f[0].selectedIndex, quiet);
236 ok = 0;
237 } else {
238 ferror.clear(f[0]);
240 // valid IP address?
241 if(!v_ip(f[2], quiet || !ok))
242 ok = 0;
243 // if we have a properly defined IP address - 0.0.0.0 is NOT a valid IP address for our intents/purposes!
244 if ((f[2].value != '') && (f[2].value != '0.0.0.0')) {
245 // allow DHCP to be enabled
246 f[4].disabled = 0;
247 // validate netmask
248 if(!v_netmask(f[3], quiet || !ok)) {
249 return 0;
250 } else {
251 // must be class C or smaller network
252 if (numberOfBitsOnNetMask(f[3].value) < 24) {
253 ferror.set(f[3], 'Netmask must have at least 24 bits set (255.255.255.0)', quiet);
254 return 0;
255 } else {
256 ferror.clear(f[3]);
259 if (this.countOverlappingNetworks(f[2].value) > 0) {
260 var s = 'Invalid IP address or subnet mask (conflicts/overlaps with another LAN bridge)';
261 ferror.set(f[2], s, quiet);
262 ferror.set(f[3], s, quiet);
263 return 0;
264 } else {
265 ferror.clear(f[2]);
266 ferror.clear(f[3]);
268 } else {
269 f[4].checked = 0;
270 f[4].disabled = 1;
272 // dhcp enabled?
273 if( (f[4].checked) && (v_ip(f[2], 1)) && (v_netmask(f[3],1)) ) {
274 f[5].disabled = 0;
275 f[6].disabled = 0;
276 f[7].disabled = 0;
277 // first/last IP still unset?
278 // TODO: proper calculation of first IP available on a particular subnet
279 if (f[5].value == '') {
280 f[5].value = f[2].value.split('.').splice(0, 3).join('.') + '.' + '100'; // from nvram/defaults.c
282 if (f[6].value == '') {
283 f[6].value = f[2].value.split('.').splice(0, 3).join('.') + '.' + '149'; // from nvram/defaults.c
285 // first IP
286 if ((getNetworkAddress(f[5].value, f[3].value) != getNetworkAddress(f[2].value, f[3].value)) ||
287 (f[5].value == getBroadcastAddress(getNetworkAddress(f[2].value, f[3].value), f[3].value)) ||
288 (f[5].value == getNetworkAddress(f[2].value, f[3].value)) ||
289 (f[2].value == f[5].value)) {
290 ferror.set(f[5], 'Invalid first IP address or subnet mask', quiet || !ok);
291 return 0;
292 } else {
293 ferror.clear(f[5]);
295 // last IP
296 if ((getNetworkAddress(f[6].value, f[3].value) != getNetworkAddress(f[2].value, f[3].value)) ||
297 (f[6].value == getBroadcastAddress(getNetworkAddress(f[2].value, f[3].value), f[3].value)) ||
298 (f[6].value == getNetworkAddress(f[2].value, f[3].value)) ||
299 (f[2].value == f[6].value)) {
300 ferror.set(f[6], 'Invalid last IP address or subnet mask', quiet || !ok);
301 return 0;
302 } else {
303 ferror.clear(f[6]);
305 // validate range
306 if ((aton(f[6].value) - aton(f[5].value)) < 1) {
307 var s = 'Invalid first or last IP address';
308 ferror.set(f[5], s, quiet || !ok);
309 ferror.set(f[6], s, quiet || !ok);
310 return 0;
311 } else {
312 ferror.clear(f[5]);
313 ferror.clear(f[6]);
315 // lease time
316 if (parseInt(f[7].value*1) == 0)
317 f[7].value = 1440; // from nvram/defaults.c
318 if(!v_mins(f[7], quiet || !ok, 1, 10080))
319 ok = 0;
321 } else {
322 f[5].disabled = 1;
323 f[6].disabled = 1;
324 f[7].disabled = 1;
325 ferror.clear(f[5]);
326 ferror.clear(f[6]);
327 ferror.clear(f[7]);
330 return ok;
333 W('<style type=\'text/css\'>');
334 for (var u = 0; u < wl_ifaces.length; ++u) {
335 W('#spin'+wl_unit(u)+', ');
337 W('#spin {');
338 W(' visibility: hidden;');
339 W(' vertical-align: middle;');
340 W('}');
341 W('</style>');
343 var xob = null;
344 var refresher = [];
345 var nphy = features('11n');
347 var ghz = [];
348 var bands = [];
349 var nm_loaded = [], ch_loaded = [], max_channel = [];
351 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
352 var b;
353 b = [];
354 for (var i = 0; i < wl_bands[uidx].length; ++i) {
355 b.push([wl_bands[uidx][i] + '', (wl_bands[uidx][i] == '1') ? '5 GHz' : '2.4 GHz']);
357 bands.push(b);
359 b = [];
360 ghz.push(b);
362 nm_loaded.push(0);
363 ch_loaded.push(0);
364 max_channel.push(0);
365 refresher.push(null);
368 function selectedBand(uidx)
370 if (bands[uidx].length > 1) {
371 var e = E('_f_wl'+u+'_nband');
372 return (e.value + '' == '' ? eval('nvram.wl'+u+'_nband') : e.value);
373 } else if (bands[uidx].length > 0) {
374 return bands[uidx][0][0] || '0';
375 } else {
376 return '0';
380 function refreshNetModes(uidx)
382 var e, i, buf, val;
384 if (uidx >= wl_ifaces.length) return;
385 var u = wl_unit(uidx);
387 var m = [['mixed','Auto']];
388 if (selectedBand(uidx) == '1') {
389 m.push(['a-only','A Only']);
390 if (nphy) {
391 m.push(['n-only','N Only']);
394 else {
395 m.push(['b-only','B Only']);
396 m.push(['g-only','G Only']);
397 if (nphy) {
398 m.push(['bg-mixed','B/G Mixed']);
399 m.push(['n-only','N Only']);
403 e = E('_wl'+u+'_net_mode');
404 buf = '';
405 val = (!nm_loaded[uidx] || (e.value + '' == '')) ? eval('nvram.wl'+u+'_net_mode') : e.value;
406 if (val == 'disabled') val = 'mixed';
407 for (i = 0; i < m.length; ++i)
408 buf += '<option value="' + m[i][0] + '"' + ((m[i][0] == val) ? ' selected' : '') + '>' + m[i][1] + '</option>';
410 e = E('__wl'+u+'_net_mode');
411 buf = '<select name="wl'+u+'_net_mode" onchange="verifyFields(this, 1)" id = "_wl'+u+'_net_mode">' + buf + '</select>';
412 elem.setInnerHTML(e, buf);
413 nm_loaded[uidx] = 1;
416 function refreshChannels(uidx)
418 if (refresher[uidx] != null) return;
419 if (u >= wl_ifaces.length) return;
420 var u = wl_unit(uidx);
422 refresher[uidx] = new XmlHttp();
423 refresher[uidx].onCompleted = function(text, xml) {
424 try {
425 var e, i, buf, val;
427 var wl_channels = [];
428 eval(text);
430 ghz[uidx] = [];
431 max_channel[uidx] = 0;
432 for (i = 0; i < wl_channels.length; ++i) {
433 ghz[uidx].push([wl_channels[i][0] + '',
434 (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']);
435 max_channel[uidx] = wl_channels[i][0] * 1;
438 e = E('_wl'+u+'_channel');
439 buf = '';
440 val = (!ch_loaded[uidx] || (e.value + '' == '')) ? eval('nvram.wl'+u+'_channel') : e.value;
441 for (i = 0; i < ghz[uidx].length; ++i)
442 buf += '<option value="' + ghz[uidx][i][0] + '"' + ((ghz[uidx][i][0] == val) ? ' selected' : '') + '>' + ghz[uidx][i][1] + '</option>';
444 e = E('__wl'+u+'_channel');
445 buf = '<select name="wl'+u+'_channel" onchange="verifyFields(this, 1)" id = "_wl'+u+'_channel">' + buf + '</select>';
446 elem.setInnerHTML(e, buf);
447 ch_loaded[uidx] = 1;
449 refresher[uidx] = null;
450 verifyFields(null, 1);
452 catch (x) {
454 refresher[uidx] = null;
457 var bw, sb, e;
459 e = E('_f_wl'+u+'_nctrlsb');
460 sb = (e.value + '' == '' ? eval('nvram.wl'+u+'_nctrlsb') : e.value);
461 e = E('_wl'+u+'_nbw_cap');
462 bw = (e.value + '' == '' ? eval('nvram.wl'+u+'_nbw_cap') : e.value) == '0' ? '20' : '40';
464 refresher[uidx].onError = function(ex) { alert(ex); refresher[uidx] = null; reloadPage(); }
465 refresher[uidx].post('update.cgi', 'exec=wlchannels&arg0=' + u + '&arg1=' + (nphy ? '1' : '0') +
466 '&arg2=' + bw + '&arg3=' + selectedBand(uidx) + '&arg4=' + sb);
469 function spin(x, unit)
471 for (var u = 0; u < wl_ifaces.length; ++u) {
472 E('_f_wl'+wl_unit(u)+'_scan').disabled = x;
474 var e = E('_f_wl'+unit+'_scan');
475 if (x) e.value = 'Scan ' + (wscan.tries + 1);
476 else e.value = 'Scan';
477 E('spin'+unit).style.visibility = x ? 'visible' : 'hidden';
480 function scan()
482 if (xob) return;
484 var unit = wscan.unit;
485 var uidx = wl_uidx(unit);
487 xob = new XmlHttp();
488 xob.onCompleted = function(text, xml) {
489 try {
490 var i;
492 wlscandata = [];
493 eval(text);
495 for (i = 0; i < wlscandata.length; ++i) {
496 var data = wlscandata[i];
497 var ch = data[2];
498 var mac = data[0];
500 if (!wscan.inuse[ch]) {
501 wscan.inuse[ch] = {
502 count: 0,
503 rssi: -999,
504 ssid: ''
508 if (!wscan.seen[mac]) {
509 wscan.seen[mac] = 1;
510 ++wscan.inuse[ch].count;
513 if (data[4] > wscan.inuse[ch].rssi) {
514 wscan.inuse[ch].rssi = data[4];
515 wscan.inuse[ch].ssid = data[1];
518 var e = E('_wl'+unit+'_channel');
519 for (i = 1; i < ghz[uidx].length; ++i) {
520 var s = ghz[uidx][i][1];
521 var u = wscan.inuse[ghz[uidx][i][0]];
522 if (u) s += ' (' + u.count + ' AP' + (u.count == 1 ? '' : 's') + ' / strongest: "' + escapeHTML(ellipsis(u.ssid, 15)) + '" ' + u.rssi + ' dBm)';
523 e.options[i].innerHTML = s;
525 e.style.width = '400px';
527 xob = null;
529 if (wscan.tries < 4) {
530 ++wscan.tries;
531 setTimeout(scan, 1000);
532 return;
535 catch (x) {
537 spin(0, unit);
539 xob.onError = function(x) {
540 alert('error: ' + x);
541 spin(0, unit);
542 xob = null;
545 spin(1, unit);
546 xob.post('update.cgi', 'exec=wlscan&arg0='+unit);
549 function scanButton(u)
551 if (xob) return;
553 wscan = {
554 unit: u,
555 seen: [],
556 inuse: [],
557 tries: 0
560 scan();
563 function joinAddr(a) {
564 var r, i, s;
566 r = [];
567 for (i = 0; i < a.length; ++i) {
568 s = a[i];
569 if ((s != '00:00:00:00:00:00') && (s != '0.0.0.0')) r.push(s);
571 return r.join(' ');
574 function random_x(max)
576 var c = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
577 var s = '';
578 while (max-- > 0) s += c.substr(Math.floor(c.length * Math.random()), 1);
579 return s;
582 function random_psk(id)
584 var e = E(id);
585 e.value = random_x(63);
586 verifyFields(null, 1);
589 function random_wep(u)
591 E('_wl'+u+'_passphrase').value = random_x(16);
592 generate_wep(u);
595 function v_wep(e, quiet)
597 var s = e.value;
599 if (((s.length == 5) || (s.length == 13)) && (s.length == (e.maxLength >> 1))) {
600 // no checking
602 else {
603 s = s.toUpperCase().replace(/[^0-9A-F]/g, '');
604 if (s.length != e.maxLength) {
605 ferror.set(e, 'Invalid WEP key. Expecting ' + e.maxLength + ' hex or ' + (e.maxLength >> 1) + ' ASCII characters.', quiet);
606 return 0;
610 e.value = s;
611 ferror.clear(e);
612 return 1;
615 // compatible w/ Linksys' and Netgear's (key 1) method for 128-bits
616 function generate_wep(u)
618 function _wepgen(pass, i)
620 while (pass.length < 64) pass += pass;
621 return hex_md5(pass.substr(0, 64)).substr(i, (E('_wl'+u+'_wep_bit').value == 128) ? 26 : 10);
624 var e = E('_wl'+u+'_passphrase');
625 var pass = e.value;
626 if (!v_length(e, false, 3)) return;
627 E('_wl'+u+'_key1').value = _wepgen(pass, 0);
628 pass += '#$%';
629 E('_wl'+u+'_key2').value = _wepgen(pass, 2);
630 pass += '!@#';
631 E('_wl'+u+'_key3').value = _wepgen(pass, 4);
632 pass += '%&^';
633 E('_wl'+u+'_key4').value = _wepgen(pass, 6);
634 verifyFields(null, 1);
637 function verifyFields(focused, quiet)
639 var i;
640 var ok = 1;
641 var a, b, c, d, e;
642 var u, uidx;
643 var wmode, sm2;
645 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
646 u = wl_unit(uidx);
647 if (focused == E('_f_wl'+u+'_nband')) {
648 refreshNetModes(uidx);
649 refreshChannels(uidx);
651 else if (focused == E('_f_wl'+u+'_nctrlsb') || focused == E('_wl'+u+'_nbw_cap')) {
652 refreshChannels(uidx);
656 // --- visibility ---
658 var vis = {
659 _wan_proto: 1,
660 _ppp_username: 1,
661 _ppp_passwd: 1,
662 _ppp_service: 1,
663 _ppp_custom: 1,
664 _l2tp_server_ip: 1,
665 _wan_ipaddr: 1,
666 _wan_netmask: 1,
667 _wan_gateway: 1,
668 _pptp_server_ip: 1,
669 _f_pptp_dhcp: 1,
670 _ppp_demand: 1,
671 _ppp_idletime: 1,
672 _ppp_redialperiod: 1,
673 _mtu_enable: 1,
674 _f_wan_mtu: 1,
675 _f_wan_islan: 0,
677 /* REMOVE-BEGIN
678 // _dhcp_lease: 1,
679 // _f_dhcpd_enable: 1,
680 // _dhcpd_startip: 1,
681 // _dhcpd_endip: 1,
682 // _lan_ipaddr: 1,
683 // _lan_netmask: 1,
684 REMOVE-END */
685 _f_dns_1: 1,
686 _f_dns_2: 1,
687 _f_dns_3: 1,
688 _lan_gateway: 1,
689 _wan_wins: 1
692 var wl_vis = [];
693 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
694 a = {
695 _f_wl_radio: 1,
696 _f_wl_mode: 1,
697 _f_wl_nband: (bands[uidx].length > 1) ? 1 : 0,
698 _wl_net_mode: 1,
699 _wl_ssid: 1,
700 _f_wl_bcast: 1,
701 _wl_channel: 1,
702 _wl_nbw_cap: nphy ? 1 : 0,
703 _f_wl_nctrlsb: nphy ? 1 : 0,
704 _f_wl_scan: 1,
706 _wl_security_mode: 1,
707 _wl_crypto: 1,
708 _wl_wpa_psk: 1,
709 _f_wl_psk_random1: 1,
710 _f_wl_psk_random2: 1,
711 _wl_wpa_gtk_rekey: 1,
712 _wl_radius_key: 1,
713 _wl_radius_ipaddr: 1,
714 _wl_radius_port: 1,
715 _wl_wep_bit: 1,
716 _wl_passphrase: 1,
717 _f_wl_wep_gen: 1,
718 _f_wl_wep_random: 1,
719 _wl_key1: 1,
720 _wl_key2: 1,
721 _wl_key3: 1,
722 _wl_key4: 1,
724 _f_wl_lazywds: 1,
725 _f_wl_wds_0: 1
727 wl_vis.push(a);
730 var wan = E('_wan_proto').value;
732 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
733 wmode = E('_f_wl'+wl_unit(uidx)+'_mode').value;
735 if (wmode == 'wet') {
736 wan = 'disabled';
737 vis._wan_proto = 0;
738 /* REMOVE-BEGIN
739 // vis._f_dhcpd_enable = 0;
740 // vis._dhcp_lease = 0;
741 REMOVE-END */
744 if ((wan == 'disabled') || (wmode == 'sta') || (wmode == 'wet')) {
745 vis._f_wan_islan = 1;
749 switch (wan) {
750 case 'disabled':
751 vis._ppp_username = 0;
752 vis._ppp_service = 0;
753 vis._ppp_custom = 0;
754 vis._l2tp_server_ip = 0;
755 vis._wan_ipaddr = 0;
756 vis._wan_netmask = 0;
757 vis._wan_gateway = 0;
758 vis._pptp_server_ip = 0;
759 vis._f_pptp_dhcp = 0;
760 vis._ppp_demand = 0;
761 vis._mtu_enable = 0;
762 vis._f_wan_mtu = 0;
763 break;
764 case 'dhcp':
765 vis._l2tp_server_ip = 0;
766 vis._ppp_demand = 0;
767 vis._ppp_service = 0;
768 vis._ppp_username = 0;
769 vis._ppp_custom = 0;
770 vis._pptp_server_ip = 0;
771 vis._f_pptp_dhcp = 0;
772 vis._wan_gateway = 0;
773 vis._wan_ipaddr = 0;
774 vis._wan_netmask = 0;
776 vis._lan_gateway = 0;
777 break;
778 case 'pppoe':
779 vis._l2tp_server_ip = 0;
780 vis._pptp_server_ip = 0;
781 vis._f_pptp_dhcp = 0;
782 vis._wan_gateway = 0;
783 vis._wan_ipaddr = 0;
784 vis._wan_netmask = 0;
786 vis._lan_gateway = 0;
787 break;
788 case 'static':
789 vis._l2tp_server_ip = 0;
790 vis._ppp_demand = 0;
791 vis._ppp_service = 0;
792 vis._ppp_username = 0;
793 vis._ppp_custom = 0;
794 vis._pptp_server_ip = 0;
795 vis._f_pptp_dhcp = 0;
797 vis._lan_gateway = 0;
798 break;
799 case 'pptp':
800 vis._l2tp_server_ip = 0;
801 vis._ppp_service = 0;
802 vis._wan_gateway = (!E('_f_pptp_dhcp').checked);
803 vis._wan_ipaddr = (!E('_f_pptp_dhcp').checked);
805 vis._lan_gateway = 0;
806 break;
807 case 'l2tp':
808 vis._pptp_server_ip = 0;
809 vis._ppp_service = 0;
810 vis._wan_gateway = (!E('_f_pptp_dhcp').checked);
811 vis._wan_ipaddr = (!E('_f_pptp_dhcp').checked);
813 vis._lan_gateway = 0;
814 break;
817 vis._ppp_idletime = (E('_ppp_demand').value == 1) && vis._ppp_demand
818 vis._ppp_redialperiod = !vis._ppp_idletime && vis._ppp_demand;
820 if (vis._mtu_enable) {
821 if (E('_mtu_enable').value == 0) {
822 vis._f_wan_mtu = 2;
823 a = E('_f_wan_mtu');
824 switch (E('_wan_proto').value) {
825 case 'pppoe':
826 a.value = 1492;
827 break;
828 case 'pptp':
829 case 'l2tp':
830 a.value = 1460;
831 break;
832 default:
833 a.value = 1500;
834 break;
839 /* REMOVE-BEGIN
840 // if (!E('_f_dhcpd_enable').checked) vis._dhcp_lease = 0;
841 REMOVE-END */
843 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
844 u = wl_unit(uidx);
845 wmode = E('_f_wl'+u+'_mode').value;
847 if (!E('_f_wl'+u+'_radio').checked) {
848 for (a in wl_vis[uidx]) {
849 wl_vis[uidx][a] = 2;
851 wl_vis[uidx]._f_wl_radio = 1;
852 wl_vis[uidx]._wl_nbw_cap = nphy ? 2 : 0;
853 wl_vis[uidx]._f_wl_nband = (bands[uidx].length > 1) ? 2 : 0;
856 switch (wmode) {
857 case 'apwds':
858 case 'wds':
859 break;
860 case 'wet':
861 case 'sta':
862 wl_vis[uidx]._f_wl_bcast = 0;
863 wl_vis[uidx]._wl_channel = 0;
864 wl_vis[uidx]._wl_nbw_cap = 0;
865 default:
866 wl_vis[uidx]._f_wl_lazywds = 0;
867 wl_vis[uidx]._f_wl_wds_0 = 0;
868 break;
871 sm2 = E('_wl'+u+'_security_mode').value;
872 switch (sm2) {
873 case 'disabled':
874 wl_vis[uidx]._wl_crypto = 0;
875 wl_vis[uidx]._wl_wep_bit = 0;
876 wl_vis[uidx]._wl_wpa_psk = 0;
877 wl_vis[uidx]._wl_radius_key = 0;
878 wl_vis[uidx]._wl_radius_ipaddr = 0;
879 wl_vis[uidx]._wl_wpa_gtk_rekey = 0;
880 break;
881 case 'wep':
882 wl_vis[uidx]._wl_crypto = 0;
883 wl_vis[uidx]._wl_wpa_psk = 0;
884 wl_vis[uidx]._wl_radius_key = 0;
885 wl_vis[uidx]._wl_radius_ipaddr = 0;
886 wl_vis[uidx]._wl_wpa_gtk_rekey = 0;
887 break;
888 case 'radius':
889 wl_vis[uidx]._wl_crypto = 0;
890 wl_vis[uidx]._wl_wpa_psk = 0;
891 break;
892 default: // wpa*
893 wl_vis[uidx]._wl_wep_bit = 0;
894 if (sm2.indexOf('personal') != -1) {
895 wl_vis[uidx]._wl_radius_key = 0;
896 wl_vis[uidx]._wl_radius_ipaddr = 0;
898 else {
899 wl_vis[uidx]._wl_wpa_psk = 0;
901 break;
904 if ((E('_f_wl'+u+'_lazywds').value == 1) && (wl_vis[uidx]._f_wl_wds_0 == 1)) {
905 wl_vis[uidx]._f_wl_wds_0 = 2;
908 if (wl_vis[uidx]._wl_nbw_cap != 0) {
909 switch (E('_wl'+u+'_net_mode').value) {
910 case 'b-only':
911 case 'g-only':
912 case 'a-only':
913 case 'bg-mixed':
914 wl_vis[uidx]._wl_nbw_cap = 2;
915 if (E('_wl'+u+'_nbw_cap').value != '0') {
916 E('_wl'+u+'_nbw_cap').value = 0;
917 refreshChannels(uidx);
919 break;
921 // avoid Enterprise-TKIP with 40MHz
922 if ((sm2 == 'wpa_enterprise') && (E('_wl'+u+'_crypto').value == 'tkip')) {
923 wl_vis[uidx]._wl_nbw_cap = 2;
924 if (E('_wl'+u+'_nbw_cap').value != '0') {
925 E('_wl'+u+'_nbw_cap').value = 0;
926 refreshChannels(uidx);
931 wl_vis[uidx]._f_wl_nctrlsb = (E('_wl'+u+'_nbw_cap').value == 0) ? 0 : wl_vis[uidx]._wl_nbw_cap;
933 /* REMOVE-BEGIN
934 This is ugly...
935 Special case - 2.4GHz band, currently running in B/G-only mode,
936 with N/Auto and 40MHz selected in the GUI.
937 Channel list is not filtered in this case by the wl driver,
938 and includes all channels available with 20MHz channel width.
939 REMOVE-END */
940 b = selectedBand(uidx);
941 if (wl_vis[uidx]._wl_channel == 1 && wl_vis[uidx]._f_wl_nctrlsb != 0 &&
942 ((b == '2') || (wl_vis[uidx]._f_wl_nband == 0 && b == '0'))) {
943 switch (eval('nvram.wl'+u+'_net_mode')) {
944 case 'b-only':
945 case 'g-only':
946 case 'bg-mixed':
947 i = E('_wl'+u+'_channel').value * 1;
948 if (i > 0 && i < 5) {
949 E('_f_wl'+u+'_nctrlsb').value = 'lower';
950 wl_vis[uidx]._f_wl_nctrlsb = 2;
952 else if (i > max_channel[uidx] - 4) {
953 E('_f_wl'+u+'_nctrlsb').value = 'upper';
954 wl_vis[uidx]._f_wl_nctrlsb = 2;
956 break;
960 wl_vis[uidx]._f_wl_scan = wl_vis[uidx]._wl_channel;
961 wl_vis[uidx]._f_wl_psk_random1 = wl_vis[uidx]._wl_wpa_psk;
962 wl_vis[uidx]._f_wl_psk_random2 = wl_vis[uidx]._wl_radius_key;
963 wl_vis[uidx]._wl_radius_port = wl_vis[uidx]._wl_radius_ipaddr;
964 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;
966 for (i = 1; i < 10; ++i) {
967 wl_vis[uidx]['_f_wl_wds_' + i] = wl_vis[uidx]._f_wl_wds_0;
969 } // for each wl_iface
971 vis._ppp_passwd = vis._ppp_username;
972 /* REMOVE-BEGIN
973 // vis._dhcpd_startip = vis._dhcpd_endip = vis._wan_wins = vis._dhcp_lease;
974 REMOVE-END */
976 for (a in vis) {
977 b = E(a);
978 c = vis[a];
979 /* REMOVE-BEGIN
980 // if (b != null)
981 REMOVE-END */
982 b.disabled = (c != 1);
983 PR(b).style.display = c ? '' : 'none';
986 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
987 for (a in wl_vis[uidx]) {
988 i = 3;
989 if (a.substr(0, 6) == '_f_wl_') i = 5;
990 b = E(a.substr(0, i) + wl_unit(uidx) + a.substr(i, a.length));
991 c = wl_vis[uidx][a];
992 b.disabled = (c != 1);
993 PR(b).style.display = c ? '' : 'none';
997 // --- verify ---
999 ferror.clear('_wan_proto');
1001 var wlclnt = 0;
1002 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1003 u = wl_unit(uidx);
1004 wmode = E('_f_wl'+u+'_mode').value;
1005 sm2 = E('_wl'+u+'_security_mode').value;
1007 /* REMOVE-BEGIN
1008 if ((wl_vis[uidx]._f_wl_mode == 1) && (wmode != 'ap') && (sm2.substr(0, 4) == 'wpa2')) {
1009 ferror.set('_wl'+u+'_security_mode', 'WPA2 is supported only in AP mode.', quiet || !ok);
1010 ok = 0;
1012 else ferror.clear('_wl'+u+'_security_mode');
1013 REMOVE-END */
1015 // --- N standard does not support WPA+TKIP ---
1016 a = E('_wl'+u+'_crypto');
1017 switch (E('_wl'+u+'_net_mode').value) {
1018 case 'mixed':
1019 case 'n-only':
1020 if (nphy && (a.value == 'tkip') && (sm2.indexOf('wpa') != -1)) {
1021 ferror.set(a, 'TKIP encryption is not supported with WPA / WPA2 in N mode.', quiet || !ok);
1022 ok = 0;
1024 else ferror.clear(a);
1025 break;
1028 a = E('_wl'+u+'_net_mode');
1029 ferror.clear(a);
1030 b = E('_f_wl'+u+'_mode');
1031 ferror.clear(b);
1032 if ((wmode == 'sta') || (wmode == 'wet')) {
1033 ++wlclnt;
1034 if (wlclnt > 1) {
1035 ferror.set(b, 'Only one wireless interface can be configured in client mode.', quiet || !ok);
1036 ok = 0;
1038 else if (a.value == 'n-only') {
1039 ferror.set(a, 'N-only is not supported in wireless client modes, use Auto.', quiet || !ok);
1040 ok = 0;
1044 a = E('_wl'+u+'_wpa_psk');
1045 ferror.clear(a);
1046 if (wl_vis[uidx]._wl_wpa_psk == 1) {
1047 if ((a.value.length < 8) || ((a.value.length == 64) && (a.value.search(/[^0-9A-Fa-f]/) != -1))) {
1048 ferror.set('_wl'+u+'_wpa_psk', 'Invalid pre-shared key. Please enter at least 8 characters or 64 hexadecimal digits.', quiet || !ok);
1049 ok = 0;
1053 // wl channel
1054 if (((wmode == 'wds') || (wmode == 'apwds')) && (wl_vis[uidx]._wl_channel == 1) && (E('_wl'+u+'_channel').value == '0')) {
1055 ferror.set('_wl'+u+'_channel', 'Fixed wireless channel required in WDS mode.', quiet || !ok);
1056 ok = 0;
1058 else ferror.clear('_wl'+u+'_channel');
1060 if (E('_f_wl'+u+'_mode').value == 'sta') {
1061 if ((wan == 'disabled') && (E('_f_wl'+u+'_radio').checked)) {
1062 ferror.set('_wan_proto', 'Wireless Client mode requires a valid WAN setting (usually DHCP).', quiet || !ok);
1063 ok = 0;
1068 // domain name or IP address
1069 a = ['_l2tp_server_ip', '_pptp_server_ip'];
1070 for (i = a.length - 1; i >= 0; --i)
1071 if ((vis[a[i]]) && ((!v_length(a[i], 1, 1)) || ((!v_ip(a[i], 1)) && (!v_domain(a[i], 1))))) {
1072 if (!quiet && ok) ferror.show(a[i]);
1073 ok = 0;
1076 // IP address
1077 /* REMOVE-BEGIN
1078 // a = ['_wan_gateway','_wan_ipaddr','_lan_ipaddr', '_dhcpd_startip', '_dhcpd_endip'];
1079 REMOVE-END */
1080 a = ['_wan_gateway','_wan_ipaddr'];
1081 for (i = a.length - 1; i >= 0; --i)
1082 if ((vis[a[i]]) && (!v_ip(a[i], quiet || !ok))) ok = 0;
1084 // IP address, blank -> 0.0.0.0
1085 a = ['_f_dns_1', '_f_dns_2', '_f_dns_3','_wan_wins','_lan_gateway'];
1086 for (i = a.length - 1; i >= 0; --i)
1087 if ((vis[a[i]]) && (!v_dns(a[i], quiet || !ok))) ok = 0;
1089 // netmask
1090 /* REMOVE-BEGIN
1091 // a = ['_wan_netmask','_lan_netmask'];
1092 REMOVE-END */
1093 a = ['_wan_netmask'];
1094 for (i = a.length - 1; i >= 0; --i)
1095 if ((vis[a[i]]) && (!v_netmask(a[i], quiet || !ok))) ok = 0;
1097 // range
1098 /* REMOVE-BEGIN
1099 // a = [['_ppp_idletime', 3, 1440],['_ppp_redialperiod', 1, 86400],['_f_wan_mtu', 576, 1500],
1100 // ['_dhcp_lease', 1, 10080]];
1101 REMOVE-END */
1102 a = [['_ppp_idletime', 3, 1440],['_ppp_redialperiod', 1, 86400],['_f_wan_mtu', 576, 1500]];
1103 for (i = a.length - 1; i >= 0; --i) {
1104 v = a[i];
1105 if ((vis[v[0]]) && (!v_range(v[0], quiet || !ok, v[1], v[2]))) ok = 0;
1108 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1109 u = wl_unit(uidx);
1111 // IP address
1112 a = ['_radius_ipaddr'];
1113 for (i = a.length - 1; i >= 0; --i) {
1114 if ((wl_vis[uidx]['_wl'+a[i]]) && (!v_ip('_wl'+u+a[i], quiet || !ok))) ok = 0;
1117 // range
1118 a = [['_wpa_gtk_rekey', 60, 7200], ['_radius_port', 1, 65535]];
1119 for (i = a.length - 1; i >= 0; --i) {
1120 v = a[i];
1121 if ((wl_vis[uidx]['_wl'+v[0]]) && (!v_range('_wl'+u+v[0], quiet || !ok, v[1], v[2]))) ok = 0;
1124 // length
1125 a = [['_ssid', 1], ['_radius_key', 1]];
1126 for (i = a.length - 1; i >= 0; --i) {
1127 v = a[i];
1128 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;
1131 if (wl_vis[uidx]._wl_key1) {
1132 a = (E('_wl'+u+'_wep_bit').value == 128) ? 26 : 10;
1133 for (i = 1; i <= 4; ++i) {
1134 b = E('_wl'+u+'_key' + i);
1135 b.maxLength = a;
1136 if ((b.value.length > 0) || (E('_f_wl'+u+'_wepidx_' + i).checked)) {
1137 if (!v_wep(b, quiet || !ok)) ok = 0;
1139 else ferror.clear(b);
1143 ferror.clear('_f_wl'+u+'_wds_0');
1144 if (wl_vis[uidx]._f_wl_wds_0 == 1) {
1145 b = 0;
1146 for (i = 0; i < 10; ++i) {
1147 a = E('_f_wl'+u+'_wds_' + i);
1148 if (!v_macz(a, quiet || !ok)) ok = 0;
1149 else if (!isMAC0(a.value)) b = 1;
1151 if (!b) {
1152 ferror.set('_f_wl'+u+'_wds_0', 'WDS MAC address required.', quiet || !ok);
1153 ok = 0;
1157 /* REMOVE-BEGIN
1158 a = E('_dhcpd_startip');
1159 b = E('_dhcpd_endip');
1160 ferror.clear(a);
1161 ferror.clear(b);
1163 if ((vis._dhcp_lease) && (!a._error_msg) && (!b._error_msg)) {
1164 c = aton(E('_lan_netmask').value);
1165 d = aton(E('_lan_ipaddr').value) & c;
1166 e = 'Invalid IP address or subnet mask';
1167 if ((aton(a.value) & c) != d) {
1168 ferror.set(a, e, quiet || !ok);
1169 ok = 0;
1171 if ((aton(b.value) & c) != d) {
1172 ferror.set(b, e, quiet || !ok);
1173 ok = 0;
1177 if ((vis._dhcp_lease) && (!a._error_msg) && (!b._error_msg)) {
1178 if (aton(a.value) > aton(b.value)) {
1179 c = a.value;
1180 a.value = b.value;
1181 b.value = c;
1184 elem.setInnerHTML('dhcp_count', '(' + ((aton(b.value) - aton(a.value)) + 1) + ')');
1186 REMOVE-END */
1188 return ok;
1191 function earlyInit()
1193 verifyFields(null, 1);
1196 function save()
1198 if (lg.isEditing()) return;
1199 lg.resetNewEditor();
1201 var a, b, c;
1202 var i;
1203 var u, uidx, wmode, sm2, wradio;
1205 if (!verifyFields(null, false)) return;
1207 var fom = E('_fom');
1209 fom.wan_mtu.value = fom.f_wan_mtu.value;
1210 fom.wan_mtu.disabled = fom.f_wan_mtu.disabled;
1212 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1213 u = wl_unit(uidx);
1214 wmode = E('_f_wl'+u+'_mode').value;
1215 sm2 = E('_wl'+u+'_security_mode').value;
1216 wradio = E('_f_wl'+u+'_radio').checked;
1218 E('_wl'+u+'_nband').value = selectedBand(uidx);
1220 if (wmode == 'apwds') E('_wl'+u+'_mode').value = 'ap';
1221 else E('_wl'+u+'_mode').value = wmode;
1223 if (wmode == 'wet') {
1224 fom.wan_proto.value = 'disabled';
1225 fom.wan_proto.disabled = 0;
1226 /* REMOVE-BEGIN
1227 // fom.lan_proto.value = 'static';
1228 REMOVE-END */
1231 a = [];
1232 for (i = 0; i < 10; ++i) a.push(E('_f_wl'+u+'_wds_' + i).value);
1233 E('_wl'+u+'_wds').value = joinAddr(a);
1235 if (wmode.indexOf('wds') != -1) {
1236 E('_wl'+u+'_wds_enable').value = 1;
1237 E('_wl'+u+'_lazywds').value = E('_f_wl'+u+'_lazywds').value;
1238 if (E('_wl'+u+'_lazywds').value == 1) E('_wl'+u+'_wds').value = '';
1240 else {
1241 E('_wl'+u+'_wds_enable').value = 0;
1242 E('_wl'+u+'_wds').value = '';
1243 E('_wl'+u+'_lazywds').value = 0;
1246 E('_wl'+u+'_radio').value = wradio ? 1 : 0;
1247 E('_wl'+u+'_auth').value = eval('nvram.wl'+u+'_auth');
1249 e = E('_wl'+u+'_akm');
1250 switch (sm2) {
1251 case 'disabled':
1252 case 'radius':
1253 case 'wep':
1254 e.value = '';
1255 break;
1256 default:
1257 c = [];
1259 if (sm2.indexOf('personal') != -1) {
1260 if (sm2.indexOf('wpa2_') == -1) c.push('psk');
1261 if (sm2.indexOf('wpa_') == -1) c.push('psk2');
1263 else {
1264 if (sm2.indexOf('wpa2_') == -1) c.push('wpa');
1265 if (sm2.indexOf('wpa_') == -1) c.push('wpa2');
1267 c = c.join(' ');
1268 e.value = c;
1269 break;
1271 E('_wl'+u+'_auth_mode').value = (sm2 == 'radius') ? 'radius' : 'none';
1272 E('_wl'+u+'_wep').value = ((sm2 == 'radius') || (sm2 == 'wep')) ? 'enabled': 'disabled';
1274 if (sm2.indexOf('wpa') != -1) E('_wl'+u+'_auth').value = 0;
1276 E('_wl'+u+'_nreqd').value = 0;
1277 E('_wl'+u+'_gmode').value = 1;
1278 E('_wl'+u+'_nmode').value = 0;
1279 E('_wl'+u+'_nmcsidx').value = -2; // Legacy Rate
1280 E('_wl'+u+'_nbw').value = 0;
1281 switch (E('_wl'+u+'_net_mode').value) {
1282 case 'b-only':
1283 E('_wl'+u+'_gmode').value = 0;
1284 break;
1285 case 'g-only':
1286 E('_wl'+u+'_gmode').value = 4;
1287 break;
1288 case 'bg-mixed':
1289 break;
1290 case 'a-only':
1291 E('_wl'+u+'_nmcsidx').value = -1; // Auto
1292 break;
1293 case 'n-only':
1294 if (selectedBand(uidx) == '1') { // 5 GHz
1295 E('_wl'+u+'_nmode').value = -1;
1296 E('_wl'+u+'_nmcsidx').value = -1;
1297 } else {
1298 E('_wl'+u+'_nmode').value = 1;
1299 E('_wl'+u+'_nmcsidx').value = 32;
1301 E('_wl'+u+'_nreqd').value = 1;
1302 break;
1303 default: // Auto
1304 E('_wl'+u+'_nmode').value = -1;
1305 E('_wl'+u+'_nmcsidx').value = -1;
1306 break;
1309 E('_wl'+u+'_nctrlsb').value = eval('nvram.wl'+u+'_nctrlsb');
1310 if (E('_wl'+u+'_nmode').value != 0) {
1311 E('_wl'+u+'_nctrlsb').value = E('_f_wl'+u+'_nctrlsb').value;
1312 E('_wl'+u+'_nbw').value = (E('_wl'+u+'_nbw_cap').value == 0) ? 20 : 40;
1315 E('_wl'+u+'_closed').value = E('_f_wl'+u+'_bcast').checked ? 0 : 1;
1317 a = fields.radio.selected(eval('fom.f_wl'+u+'_wepidx'));
1318 if (a) E('_wl'+u+'_key').value = a.value;
1321 fom.wan_islan.value = fom.f_wan_islan.checked ? 1 : 0;
1322 fom.pptp_dhcp.value = fom.f_pptp_dhcp.checked ? 1 : 0;
1324 fom.wan_dns.value = joinAddr([fom.f_dns_1.value, fom.f_dns_2.value, fom.f_dns_3.value]);
1326 // initialize/wipe out relevant fields
1327 for (var i = 0 ; i <= MAX_BRIDGE_ID ; i++) {
1328 var j = (i == 0) ? '' : i.toString();
1329 fom['lan' + j + '_ifname'].value = '';
1330 fom['lan' + j + '_ipaddr'].value = '';
1331 fom['lan' + j + '_netmask'].value = '';
1332 fom['lan' + j + '_proto'].value = '';
1333 fom['lan' + j + '_stp'].value = '';
1334 fom['dhcp' + j + '_start'].value = '';
1335 fom['dhcp' + j + '_num'].value = '';
1336 fom['dhcp' + j + '_lease'].value = '';
1337 fom['dhcpd' + j + '_startip'].value = '';
1338 fom['dhcpd' + j + '_endip'].value = '';
1341 var d = lg.getAllData();
1342 for (var i = 0; i < d.length; ++i) {
1344 if (lg.countOverlappingNetworks(d[i][2]) > 1) {
1345 var s = 'Cannot proceed: two or more LAN bridges have conflicting IP addresses or overlapping subnets';
1346 alert(s);
1347 var e = E('footer-msg');
1348 e.innerHTML = s;
1349 e.style.visibility = 'visible';
1350 setTimeout(
1351 function() {
1352 e.innerHTML = '';
1353 e.style.visibility = 'hidden';
1354 }, 5000);
1355 return;
1358 var j = (parseInt(d[i][0]) == 0) ? '' : d[i][0].toString();
1359 fom['lan' + j + '_ifname'].value = 'br' + d[i][0];
1360 fom['lan' + j + '_stp'].value = d[i][1];
1361 fom['lan' + j + '_ipaddr'].value = d[i][2];
1362 fom['lan' + j + '_netmask'].value = d[i][3];
1363 fom['lan' + j + '_proto'].value = (d[i][4] != '0') ? 'dhcp' : 'static';
1364 fom['dhcp' + j + '_start'].value = (d[i][4] != '0') ? (d[i][5]).split('.').splice(3, 1) : '';
1365 fom['dhcp' + j + '_num'].value = (d[i][4] != '0') ? d[i][6] - fom['dhcp' + j + '_start'].value + 1 : '';
1366 fom['dhcp' + j + '_lease'].value = (d[i][4] != '0') ? d[i][7] : '';
1367 fom['dhcpd' + j + '_startip'].value = (d[i][4] != '0') ? d[i][5] : '';
1368 fom['dhcpd' + j + '_endip'].value = (d[i][4] != '0') ? fixIP(getNetworkAddress(d[i][2], d[i][3]).split('.').splice(0, 3).join('.') + '.' + parseInt(d[i][6])) : '';
1370 /* REMOVE-BEGIN
1371 alert('lan' + j + '_ifname=' + fom['lan' + j + '_ifname'].value +
1372 ', lan' + j + '_stp=' + fom['lan' + j + '_stp'].value +
1373 ', lan' + j + '_ipaddr=' + fom['lan' + j + '_ipaddr'].value +
1374 ', lan' + j + '_netmask=' + fom['lan' + j + '_netmask'].value +
1375 ', lan' + j + '_proto=' + fom['lan' + j + '_proto'].value +
1376 ', dhcp' + j + '_start=' + fom['dhcp' + j + '_start'].value +
1377 ', dhcp' + j + '_num=' + fom['dhcp' + j + '_num'].value +
1378 ', dhcp' + j + '_lease=' + fom['dhcp' + j + '_lease'].value +
1379 ', dhcpd' + j + '_startip=' + fom['dhcpd' + j + '_startip'].value +
1380 ', dhcpd' + j + '_endip=' + fom['dhcpd' + j + '_endip'].value);
1381 // fixIP(getNetworkAddress(data[2], data[3]).split('.').splice(0, 3).join('.') + '.' + parseInt(data[6]))
1382 REMOVE-END */
1385 var e = E('footer-msg');
1386 var t = fixIP(fom['lan_ipaddr'].value);
1387 if ((fom['lan_ifname'].value != 'br0') || (fom['lan_ipaddr'].value == '0.0.0.0') || (!t)) {
1388 e.innerHTML = 'Bridge br0 must be always defined and have a valid IP address set.';
1389 e.style.visibility = 'visible';
1390 setTimeout(
1391 function() {
1392 e.innerHTML = '';
1393 e.style.visibility = 'hidden';
1394 }, 5000);
1395 return;
1398 /* REMOVE-BEGIN
1399 // if ((nvram.lan_ipaddr != fom.lan_ipaddr.value) || (nvram.lan1_ipaddr != fom.lan1_ipaddr.value) ||
1400 // (nvram.lan2_ipaddr != fom.lan2_ipaddr.value) || (nvram.lan3_ipaddr != fom.lan3_ipaddr.value)){
1401 REMOVE-END */
1402 if (nvram.lan_ipaddr != fom.lan_ipaddr.value) {
1403 fom._moveip.value = 1;
1404 form.submit(fom);
1406 else {
1407 form.submit(fom, 1);
1411 function init()
1413 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1414 refreshNetModes(uidx);
1415 refreshChannels(uidx);
1418 </script>
1420 </head>
1421 <body onload='init()'>
1422 <form id='_fom' method='post' action='tomato.cgi'>
1423 <table id='container' cellspacing=0>
1424 <tr><td colspan=2 id='header'>
1425 <div class='title'>Tomato</div>
1426 <div class='version'>Version <% version(); %></div>
1427 </td></tr>
1428 <tr id='body'><td id='navi'><script type='text/javascript'>navi()</script></td>
1429 <td id='content'>
1430 <div id='ident'><% ident(); %></div>
1432 <!-- / / / -->
1434 <input type='hidden' name='_nextpage' value='basic-networks.asp'>
1435 <input type='hidden' name='_nextwait' value='10'>
1436 <input type='hidden' name='_service' value='*'>
1437 <input type='hidden' name='_moveip' value='0'>
1439 <input type='hidden' name='wan_mtu'>
1440 <input type='hidden' name='wan_islan'>
1441 <input type='hidden' name='pptp_dhcp'>
1442 <input type='hidden' name='ppp_defgw'>
1443 <input type='hidden' name='wan_dns'>
1445 <script type='text/javascript'>
1447 for (var i = 0 ; i <= MAX_BRIDGE_ID ; i++) {
1448 var j = (i == 0) ? '' : i.toString();
1449 W('<input type=\'hidden\' id=\'lan' + j + '_ifname\' name=\'lan' + j + '_ifname\'>');
1450 W('<input type=\'hidden\' id=\'lan' + j + '_ipaddr\' name=\'lan' + j + '_ipaddr\'>');
1451 W('<input type=\'hidden\' id=\'lan' + j + '_netmask\' name=\'lan' + j + '_netmask\'>');
1452 W('<input type=\'hidden\' id=\'lan' + j + '_proto\' name=\'lan' + j + '_proto\'>');
1453 W('<input type=\'hidden\' id=\'lan' + j + '_stp\' name=\'lan' + j + '_stp\'>');
1454 W('<input type=\'hidden\' id=\'dhcp' + j + '_start\' name=\'dhcp' + j + '_start\'>');
1455 W('<input type=\'hidden\' id=\'dhcp' + j + '_num\' name=\'dhcp' + j + '_num\'>');
1456 W('<input type=\'hidden\' id=\'dhcp' + j + '_lease\' name=\'dhcp' + j + '_lease\'>');
1457 W('<input type=\'hidden\' id=\'dhcpd' + j + '_startip\' name=\'dhcpd' + j + '_startip\'>');
1458 W('<input type=\'hidden\' id=\'dhcpd' + j + '_endip\' name=\'dhcpd' + j + '_endip\'>');
1460 </script>
1462 <div class='section-title'>WAN / Internet</div>
1463 <div class='section'>
1464 <script type='text/javascript'>
1465 createFieldTable('', [
1466 { title: 'Type', name: 'wan_proto', type: 'select', options: [['dhcp','DHCP'],['pppoe','PPPoE'],['static','Static'],['pptp','PPTP'],['l2tp','L2TP'],['disabled','Disabled']],
1467 value: nvram.wan_proto },
1468 { title: 'Username', name: 'ppp_username', type: 'text', maxlen: 60, size: 64, value: nvram.ppp_username },
1469 { title: 'Password', name: 'ppp_passwd', type: 'password', maxlen: 60, size: 64, peekaboo: 1, value: nvram.ppp_passwd },
1470 { title: 'Service Name', name: 'ppp_service', type: 'text', maxlen: 50, size: 64, value: nvram.ppp_service },
1471 { title: 'L2TP Server', name: 'l2tp_server_ip', type: 'text', maxlen: 128, size: 64, value: nvram.l2tp_server_ip },
1472 { title: 'Use DHCP', name: 'f_pptp_dhcp', type: 'checkbox', value: (nvram.pptp_dhcp == 1) },
1473 { title: 'IP Address', name: 'wan_ipaddr', type: 'text', maxlen: 15, size: 17, value: nvram.wan_ipaddr },
1474 { title: 'Subnet Mask', name: 'wan_netmask', type: 'text', maxlen: 15, size: 17, value: nvram.wan_netmask },
1475 { title: 'Gateway', name: 'wan_gateway', type: 'text', maxlen: 15, size: 17, value: nvram.wan_gateway },
1476 { title: 'PPTP Gateway', name: 'pptp_server_ip', type: 'text', maxlen: 128, size: 64, value: nvram.pptp_server_ip },
1477 { title: 'Options', name: 'ppp_custom', type: 'text', maxlen: 256, size: 64, value: nvram.ppp_custom },
1478 { title: 'Connect Mode', name: 'ppp_demand', type: 'select', options: [['1', 'Connect On Demand'],['0', 'Keep Alive']],
1479 value: nvram.ppp_demand },
1480 { title: 'Max Idle Time', indent: 2, name: 'ppp_idletime', type: 'text', maxlen: 5, size: 7, suffix: ' <i>(minutes)</i>',
1481 value: nvram.ppp_idletime },
1482 { title: 'Check Interval', indent: 2, name: 'ppp_redialperiod', type: 'text', maxlen: 5, size: 7, suffix: ' <i>(seconds)</i>',
1483 value: nvram.ppp_redialperiod },
1484 { title: 'MTU', multi: [
1485 { name: 'mtu_enable', type: 'select', options: [['0', 'Default'],['1','Manual']], value: nvram.mtu_enable },
1486 { name: 'f_wan_mtu', type: 'text', maxlen: 4, size: 6, value: nvram.wan_mtu } ] },
1487 { title: 'Bridge WAN port to primary LAN (br0)', name: 'f_wan_islan', type: 'checkbox', value: (nvram.wan_islan == 1) }
1489 </script>
1490 </div>
1492 <div class='section-title'>LAN</div>
1493 <div class='section'>
1494 <table class='tomato-grid' cellspacing=1 id='lan-grid'></table>
1495 <script type='text/javascript'>lg.setup();</script>
1496 <script type='text/javascript'>
1497 dns = nvram.wan_dns.split(/\s+/);
1498 //ipp = nvram.lan_ipaddr.split('.').splice(0, 3).join('.');
1500 createFieldTable('', [
1501 /* REMOVE-BEGIN
1502 // { title: 'Router IP Address', name: 'lan_ipaddr', type: 'text', maxlen: 15, size: 17, value: nvram.lan_ipaddr },
1503 // { title: 'Subnet Mask', name: 'lan_netmask', type: 'text', maxlen: 15, size: 17, value: nvram.lan_netmask },
1504 REMOVE-END */
1505 { title: 'Default Gateway', name: 'lan_gateway', type: 'text', maxlen: 15, size: 17, value: nvram.lan_gateway },
1506 { 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' },
1507 { title: '', name: 'f_dns_2', type: 'text', maxlen: 21, size: 25, value: dns[1] || '0.0.0.0' },
1508 { title: '', name: 'f_dns_3', type: 'text', maxlen: 21, size: 25, value: dns[2] || '0.0.0.0' },
1510 /* REMOVE-BEGIN
1511 // { title: 'DHCP Server', name: 'f_dhcpd_enable', type: 'checkbox', value: (nvram.lan_proto == 'dhcp') },
1512 // { title: 'IP Address Range', indent: 2, multi: [
1513 // { name: 'dhcpd_startip', type: 'text', maxlen: 15, size: 17, value: nvram.dhcpd_startip, suffix: ' - ' },
1514 // { name: 'dhcpd_endip', type: 'text', maxlen: 15, size: 17, value: nvram.dhcpd_endip, suffix: ' <i id="dhcp_count"></i>' }
1515 // ] },
1517 // { title: 'Lease Time', indent: 2, name: 'dhcp_lease', type: 'text', maxlen: 6, size: 8, suffix: ' <i>(minutes)</i>',
1518 // value: (nvram.dhcp_lease > 0) ? nvram.dhcp_lease : 1440 },
1519 // { title: 'WINS <i>(for DHCP)</i>', indent: 2, name: 'wan_wins', type: 'text', maxlen: 15, size: 17, value: nvram.wan_wins }
1520 REMOVE-END */
1521 { title: 'WINS <i>(for DHCP)</i>', name: 'wan_wins', type: 'text', maxlen: 15, size: 17, value: nvram.wan_wins }
1524 </script>
1525 </div>
1527 <script type='text/javascript'>
1529 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1531 var u = wl_unit(uidx);
1533 W('<input type=\'hidden\' id=\'_wl'+u+'_mode\' name=\'wl'+u+'_mode\'>');
1534 W('<input type=\'hidden\' id=\'_wl'+u+'_nband\' name=\'wl'+u+'_nband\'>');
1535 W('<input type=\'hidden\' id=\'_wl'+u+'_wds_enable\' name=\'wl'+u+'_wds_enable\'>');
1536 W('<input type=\'hidden\' id=\'_wl'+u+'_wds\' name=\'wl'+u+'_wds\'>');
1537 W('<input type=\'hidden\' id=\'_wl'+u+'_radio\' name=\'wl'+u+'_radio\'>');
1538 W('<input type=\'hidden\' id=\'_wl'+u+'_closed\' name=\'wl'+u+'_closed\'>');
1539 W('<input type=\'hidden\' id=\'_wl'+u+'_key\' name=\'wl'+u+'_key\'>');
1540 W('<input type=\'hidden\' id=\'_wl'+u+'_gmode\' name=\'wl'+u+'_gmode\'>');
1541 W('<input type=\'hidden\' id=\'_wl'+u+'_akm\' name=\'wl'+u+'_akm\'>');
1542 W('<input type=\'hidden\' id=\'_wl'+u+'_auth\' name=\'wl'+u+'_auth\'>');
1543 W('<input type=\'hidden\' id=\'_wl'+u+'_auth_mode\' name=\'wl'+u+'_auth_mode\'>');
1544 W('<input type=\'hidden\' id=\'_wl'+u+'_wep\' name=\'wl'+u+'_wep\'>');
1545 W('<input type=\'hidden\' id=\'_wl'+u+'_lazywds\' name=\'wl'+u+'_lazywds\'>');
1546 W('<input type=\'hidden\' id=\'_wl'+u+'_nmode\' name=\'wl'+u+'_nmode\'>');
1547 W('<input type=\'hidden\' id=\'_wl'+u+'_nmcsidx\' name=\'wl'+u+'_nmcsidx\'>');
1548 W('<input type=\'hidden\' id=\'_wl'+u+'_nreqd\' name=\'wl'+u+'_nreqd\'>');
1549 W('<input type=\'hidden\' id=\'_wl'+u+'_nctrlsb\' name=\'wl'+u+'_nctrlsb\'>');
1550 W('<input type=\'hidden\' id=\'_wl'+u+'_nbw\' name=\'wl'+u+'_nbw\'>');
1552 W('<div class=\'section-title\'>Wireless');
1553 if (wl_ifaces.length > 1)
1554 W(' (' + wl_display_ifname(uidx) + ')');
1555 W('</div>');
1557 W('<div class=\'section\'>');
1559 f = [
1560 { title: 'Enable Wireless', name: 'f_wl'+u+'_radio', type: 'checkbox',
1561 value: (eval('nvram.wl'+u+'_radio') == '1') && (eval('nvram.wl'+u+'_net_mode') != 'disabled') },
1562 { title: 'MAC Address', text: '<a href="advanced-mac.asp">' + eval('nvram.wl'+u+'_hwaddr') + '</a>' },
1563 { title: 'Wireless Mode', name: 'f_wl'+u+'_mode', type: 'select',
1564 options: [['ap', 'Access Point'],['apwds', 'Access Point + WDS'],['sta', 'Wireless Client'],['wet', 'Wireless Ethernet Bridge'],['wds', 'WDS']],
1565 value: ((eval('nvram.wl'+u+'_mode') == 'ap') && (eval('nvram.wl'+u+'_wds_enable') == '1')) ? 'apwds' : eval('nvram.wl'+u+'_mode') },
1566 { title: 'Radio Band', name: 'f_wl'+u+'_nband', type: 'select', options: bands[uidx],
1567 value: eval('nvram.wl'+u+'_nband') || '0' == '0' ? bands[uidx][0][0] : eval('nvram.wl'+u+'_nband') },
1568 { title: 'Wireless Network Mode', name: 'wl'+u+'_net_mode', type: 'select',
1569 value: (eval('nvram.wl'+u+'_net_mode') == 'disabled') ? 'mixed' : eval('nvram.wl'+u+'_net_mode'),
1570 options: [], prefix: '<span id="__wl'+u+'_net_mode">', suffix: '</span>' },
1571 { title: 'SSID', name: 'wl'+u+'_ssid', type: 'text', maxlen: 32, size: 34, value: eval('nvram.wl'+u+'_ssid') },
1572 { title: 'Broadcast', indent: 2, name: 'f_wl'+u+'_bcast', type: 'checkbox', value: (eval('nvram.wl'+u+'_closed') == '0') },
1573 { 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+'">',
1574 value: eval('nvram.wl'+u+'_channel') },
1575 { title: 'Channel Width', name: 'wl'+u+'_nbw_cap', type: 'select', options: [['0','20 MHz'],['1','40 MHz']],
1576 value: eval('nvram.wl'+u+'_nbw_cap') },
1577 { title: 'Control Sideband', name: 'f_wl'+u+'_nctrlsb', type: 'select', options: [['lower','Lower'],['upper','Upper']],
1578 value: eval('nvram.wl'+u+'_nctrlsb') == 'none' ? 'lower' : eval('nvram.wl'+u+'_nctrlsb') },
1579 null,
1580 { title: 'Security', name: 'wl'+u+'_security_mode', type: 'select',
1581 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']],
1582 value: eval('nvram.wl'+u+'_security_mode') },
1583 { title: 'Encryption', indent: 2, name: 'wl'+u+'_crypto', type: 'select',
1584 options: [['tkip','TKIP'],['aes','AES'],['tkip+aes','TKIP / AES']], value: eval('nvram.wl'+u+'_crypto') },
1585 { title: 'Shared Key', indent: 2, name: 'wl'+u+'_wpa_psk', type: 'password', maxlen: 64, size: 66, peekaboo: 1,
1586 suffix: ' <input type="button" id="_f_wl'+u+'_psk_random1" value="Random" onclick="random_psk(\'_wl'+u+'_wpa_psk\')">',
1587 value: eval('nvram.wl'+u+'_wpa_psk') },
1588 { title: 'Shared Key', indent: 2, name: 'wl'+u+'_radius_key', type: 'password', maxlen: 80, size: 32, peekaboo: 1,
1589 suffix: ' <input type="button" id="_f_wl'+u+'_psk_random2" value="Random" onclick="random_psk(\'_wl'+u+'_radius_key\')">',
1590 value: eval('nvram.wl'+u+'_radius_key') },
1591 { title: 'Group Key Renewal', indent: 2, name: 'wl'+u+'_wpa_gtk_rekey', type: 'text', maxlen: 4, size: 6, suffix: ' <i>(seconds)</i>',
1592 value: eval('nvram.wl'+u+'_wpa_gtk_rekey') },
1593 { title: 'Radius Server', indent: 2, multi: [
1594 { name: 'wl'+u+'_radius_ipaddr', type: 'text', maxlen: 15, size: 17, value: eval('nvram.wl'+u+'_radius_ipaddr') },
1595 { name: 'wl'+u+'_radius_port', type: 'text', maxlen: 5, size: 7, prefix: ' : ', value: eval('nvram.wl'+u+'_radius_port') } ] },
1596 { title: 'Encryption', indent: 2, name: 'wl'+u+'_wep_bit', type: 'select', options: [['128','128-bits'],['64','64-bits']],
1597 value: eval('nvram.wl'+u+'_wep_bit') },
1598 { title: 'Passphrase', indent: 2, name: 'wl'+u+'_passphrase', type: 'text', maxlen: 16, size: 20,
1599 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+')">',
1600 value: eval('nvram.wl'+u+'_passphrase') }
1603 for (i = 1; i <= 4; ++i) {
1604 f.push(
1605 { title: ('Key ' + i), indent: 2, name: ('wl'+u+'_key' + i), type: 'text', maxlen: 26, size: 34,
1606 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>' : '>'),
1607 value: nvram['wl'+u+'_key' + i] });
1610 f.push(null,
1611 { title: 'WDS', name: 'f_wl'+u+'_lazywds', type: 'select',
1612 options: [['0','Link With...'],['1','Automatic']], value: nvram['wl'+u+'_lazywds'] } );
1613 wds = eval('nvram.wl'+u+'_wds').split(/\s+/);
1614 for (i = 0; i < 10; i += 2) {
1615 f.push({ title: (i ? '' : 'MAC Address'), indent: 2, multi: [
1616 { name: 'f_wl'+u+'_wds_' + i, type: 'text', maxlen: 17, size: 20, value: wds[i] || '00:00:00:00:00:00' },
1617 { name: 'f_wl'+u+'_wds_' + (i + 1), type: 'text', maxlen: 17, size: 20, value: wds[i + 1] || '00:00:00:00:00:00' } ] } );
1620 createFieldTable('', f);
1621 W('</div>');
1624 // for each wlif
1625 </script>
1628 <!-- / / / -->
1630 </td></tr>
1631 <tr><td id='footer' colspan=2>
1632 <span id='footer-msg'></span>
1633 <input type='button' value='Save' id='save-button' onclick='save()'>
1634 <input type='button' value='Cancel' id='cancel-button' onclick='reloadPage();'>
1635 </td></tr>
1636 </table>
1637 </form>
1638 <script type='text/javascript'>earlyInit()</script>
1639 <div style='height:100px'></div>
1640 </body>
1641 </html>