Limit LAN subnet to 22 bits (255.255.252.0).
[tomato.git] / release / src / router / www / basic-network.asp
blobc101691e6834846c51f31511da5e4d56c28724dd
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 Tomato VLAN GUI
8 Copyright (C) 2011 Augusto Bott
9 http://code.google.com/p/tomato-sdhc-vlan/
11 For use with Tomato Firmware only.
12 No part of this file may be used without permission.
13 -->
14 <html>
15 <head>
16 <meta http-equiv='content-type' content='text/html;charset=utf-8'>
17 <meta name='robots' content='noindex,nofollow'>
18 <title>[<% ident(); %>] Basic: Network</title>
19 <link rel='stylesheet' type='text/css' href='tomato.css'>
20 <% css(); %>
21 <script type='text/javascript' src='tomato.js'></script>
23 <!-- / / / -->
25 <style type='text/css'>
26 #lan-grid .co1,
27 #lan-grid .co2,
28 #lan-grid .co3,
29 #lan-grid .co4,
30 #lan-grid .co5,
31 #lan-grid .co6,
32 #lan-grid .co7 {
33 text-align: center;
36 #lan-grid .centered {
37 text-align: center;
40 #spin {
41 visibility: hidden;
42 vertical-align: middle;
44 </style>
46 <script type='text/javascript' src='debug.js'></script>
48 <script type='text/javascript' src='md5.js'></script>
49 <script type='text/javascript' src='wireless.jsx?_http_id=<% nv(http_id); %>'></script>
50 <script type='text/javascript' src='interfaces.js'></script>
51 <script type='text/javascript'>
53 // <% 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_mlppp,ppp_idletime,ppp_passwd,ppp_redialperiod,ppp_service,ppp_username,ppp_custom,pptp_server_ip,pptp_dhcp,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"); %>
55 /* VLAN-BEGIN */
56 var lg = new TomatoGrid();
57 lg.setup = function() {
58 this.init('lan-grid', '', 4, [
59 { type: 'select', options: [[0, '0'],[1, '1'],[2, '2'],[3, '3']], prefix: '<div class="centered">', suffix: '</div>' },
60 { type: 'checkbox', prefix: '<div class="centered">', suffix: '</div>' },
61 { type: 'text', maxlen: 15, size: 17 },
62 { type: 'text', maxlen: 15, size: 17 },
63 { type: 'checkbox', prefix: '<div class="centered">', suffix: '</div>' },
64 { multi: [ { type: 'text', maxlen: 15, size: 17}, { type: 'text', maxlen: 15, size: 17 } ] },
65 { type: 'text', maxlen: 6, size: 8 }] );
66 this.headerSet(['Bridge', 'STP', 'IP Address', 'Netmask', 'DHCP', 'IP&nbsp;Range&nbsp;<i>(first/last)</i>', 'Lease&nbsp;Time&nbsp;<i>(mins)</i>']);
68 var numBridges = 0;
69 for (var i = 0 ; i <= MAX_BRIDGE_ID ; i++) {
70 var j = (i == 0) ? '' : i.toString();
71 if (nvram['lan' + j + '_ifname'].length > 0) {
72 if ((!fixIP(nvram['dhcpd' + j + '_startip'])) || (!fixIP(nvram['dhcpd' + j + '_endip']))) {
73 var x = nvram['lan' + j + '_ipaddr'].split('.').splice(0, 3).join('.') + '.';
74 nvram['dhcpd' + j + '_startip'] = x + nvram['dhcp' + j + '_start'];
75 nvram['dhcpd' + j + '_endip'] = x + ((nvram['dhcp' + j + '_start'] * 1) + (nvram['dhcp' + j + '_num'] * 1) - 1);
77 lg.insertData(-1, [
78 i.toString(),
79 nvram['lan' + j + '_stp'],
80 nvram['lan' + j + '_ipaddr'],
81 nvram['lan' + j + '_netmask'],
82 (nvram['lan' + j + '_proto'] == 'dhcp') ? '1' : '0',
83 (nvram['dhcp' + j + '_start'] != '') ? fixIP(getNetworkAddress(nvram['lan' + j + '_ipaddr'], nvram['lan' + j + '_netmask']).split('.').splice(0, 3).join('.') + '.' + nvram['dhcp' + j + '_start']) : '',
84 (nvram['dhcp' + j + '_start'] != '') ? parseInt(nvram['dhcp' + j + '_start']) + parseInt(nvram['dhcp' + j + '_num']) - 1 : '',
85 (nvram['lan' + j + '_proto'] == 'dhcp') ? (((nvram['dhcp' + j + '_lease'])*1 == 0) ? '1440' : (nvram['dhcp' + j + '_lease']).toString()) : ''
86 ] ) ;
87 numBridges++;
90 lg.canDelete = false;
91 lg.sort(0);
92 elem.removeClass(lg.header.cells[lg.sortColumn], 'sortasc', 'sortdes');
93 lg.showNewEditor();
94 lg.resetNewEditor();
97 lg.dataToView = function(data) {
98 return ['br' + data[0],
99 (data[1].toString() == '1') ? '<small><i>Enabled</i></small>' : '<small><i>Disabled</i></small>',
100 data[2],
101 data[3],
102 (data[4].toString() == '1') ? '<small><i>Enabled</i></small>' : '<small><i>Disabled</i></small>',
103 (((data[5] != null) && (data[5] != '')) ? (data[5] + ' - ') : '') + (((data[6] != null) && (data[6] != '')) ? data[6] : ''),
104 (((data[7] != null) && (data[7] != '')) ? data[7] : '') ];
107 lg.dataToFieldValues = function (data) {
108 return [data[0],
109 (data[1] != 0) ? 'checked' : '',
110 data[2].toString(),
111 data[3].toString(),
112 (data[4].toString() == '1') ? 'checked' : '',
113 data[5].toString(),
114 (data[6] != '') ? fixIP(getNetworkAddress(data[2], data[3]).split('.').splice(0, 3).join('.') + '.' + parseInt(data[6])) : '',
115 data[7].toString() ];
118 lg.fieldValuesToData = function(row) {
119 var f = fields.getAll(row);
120 var g = f[6].value.split('.');
121 return [f[0].value,
122 f[1].checked ? 1 : 0,
123 f[2].value,
124 f[3].value,
125 f[4].checked ? 1 : 0,
126 f[5].value,
127 (g[3] != null) ? g[3] : '',
128 f[7].value ];
131 lg.resetNewEditor = function() {
132 var f = fields.getAll(this.newEditor);
133 f[0].selectedIndex=0;
134 var t = MAX_BRIDGE_ID;
135 while((this.countBridge(f[0].selectedIndex) > 0) && (t > 0)) {
136 f[0].selectedIndex = (f[0].selectedIndex%(MAX_BRIDGE_ID))+1;
137 t--;
139 for(var j=0; j<= MAX_BRIDGE_ID ; j++) {
140 f[0].options[j].disabled = (this.countBridge(j) > 0);
142 f[1].checked = 0;
143 f[2].value = '';
144 f[3].value = '';
145 f[5].value = '';
146 f[6].value = '';
147 f[7].value = '';
148 f[4].checked = 0;
149 f[4].disabled = 1;
150 f[5].disabled = 1;
151 f[6].disabled = 1;
152 f[7].disabled = 1;
153 ferror.clearAll(fields.getAll(this.newEditor));
156 lg.onCancel = function() {
157 this.removeEditor();
158 this.showSource();
159 this.disableNewEditor(false);
161 this.resetNewEditor();
164 lg.onAdd = function() {
165 var data;
167 this.moving = null;
168 this.rpHide();
170 if (!this.verifyFields(this.newEditor, false)) return;
172 data = this.fieldValuesToData(this.newEditor);
173 this.insertData(-1, data);
175 this.disableNewEditor(false);
176 this.resetNewEditor();
178 this.resort();
181 lg.onOK = function() {
182 var i, data, view;
184 if (!this.verifyFields(this.editor, false)) return;
186 data = this.fieldValuesToData(this.editor);
187 view = this.dataToView(data);
189 this.source.setRowData(data);
190 for (i = 0; i < this.source.cells.length; ++i) {
191 this.source.cells[i].innerHTML = view[i];
194 this.removeEditor();
195 this.showSource();
196 this.disableNewEditor(false);
198 this.resort();
199 this.resetNewEditor();
202 lg.onDelete = function() {
203 this.removeEditor();
204 elem.remove(this.source);
205 this.source = null;
206 this.disableNewEditor(false);
208 this.resetNewEditor();
211 lg.countElem = function(f, v) {
212 var data = this.getAllData();
213 var total = 0;
214 for (var i = 0; i < data.length; ++i) {
215 total += (data[i][f] == v) ? 1 : 0;
217 return total;
220 lg.countBridge = function (v) {
221 return this.countElem(0,v);
224 lg.countOverlappingNetworks = function (ip) {
225 var data = this.getAllData();
226 var total = 0;
227 for (var i = 0; i < data.length; ++i) {
228 var net = getNetworkAddress(data[i][2], data[i][3]);
229 var brd = getBroadcastAddress(net, data[i][3]);
230 total += ((aton(ip) <= aton(brd)) && (aton(ip) >= aton(net))) ? 1 : 0;
232 return total;
235 lg.verifyFields = function(row, quiet) {
236 var ok=1;
237 var f;
239 f = fields.getAll(row);
241 for(var j=0; j<= MAX_BRIDGE_ID ; j++) {
242 f[0].options[j].disabled = (this.countBridge(j) > 0);
245 if(this.countBridge(f[0].selectedIndex) > 0) {
246 ferror.set(f[0], 'Cannot add another entry for bridge br' + f[0].selectedIndex, quiet);
247 ok = 0;
248 } else {
249 ferror.clear(f[0]);
251 // valid IP address?
252 if(!v_ip(f[2], quiet || !ok))
253 ok = 0;
254 // if we have a properly defined IP address - 0.0.0.0 is NOT a valid IP address for our intents/purposes!
255 if ((f[2].value != '') && (f[2].value != '0.0.0.0')) {
256 // allow DHCP to be enabled
257 f[4].disabled = 0;
258 // validate netmask
259 if(!v_netmask(f[3], quiet || !ok)) {
260 return 0;
261 } else {
262 // must be 22 bits or smaller network
263 if (numberOfBitsOnNetMask(f[3].value) < 22) {
264 ferror.set(f[3], 'Netmask must have at least 22 bits set (255.255.252.0)', quiet);
265 return 0;
266 } else {
267 ferror.clear(f[3]);
270 if(f[2].value == getNetworkAddress(f[2].value, f[3].value)) {
271 var s = 'Invalid IP address or subnet mask (the address of the network cannot be used)';
272 ferror.set(f[2], s, quiet);
273 ferror.set(f[3], s, quiet);
274 return 0;
275 } else
276 if(f[2].value == getBroadcastAddress(getNetworkAddress(f[2].value, f[3].value), f[3].value)) {
277 var s = 'Invalid IP address or subnet mask (the broadcast address cannot be used)';
278 ferror.set(f[2], s, quiet);
279 ferror.set(f[3], s, quiet);
280 return 0;
281 } else
282 if (this.countOverlappingNetworks(f[2].value) > 0) {
283 var s = 'Invalid IP address or subnet mask (conflicts/overlaps with another LAN bridge)';
284 ferror.set(f[2], s, quiet);
285 ferror.set(f[3], s, quiet);
286 return 0;
287 } else {
288 ferror.clear(f[2]);
289 ferror.clear(f[3]);
291 } else {
292 f[4].checked = 0;
293 f[4].disabled = 1;
295 // dhcp enabled?
296 if( (f[4].checked) && (v_ip(f[2], 1)) && (v_netmask(f[3],1)) ) {
297 f[5].disabled = 0;
298 f[6].disabled = 0;
299 f[7].disabled = 0;
300 // first/last IP still unset?
301 if (f[5].value == '') {
302 var l;
303 var m = aton(f[2].value) & aton(f[3].value);
304 var o = (m) ^ (~ aton(f[3].value))
305 var n = o - m;
306 do {
307 if (--n < 0) {
308 f[5].value = '';
309 return;
311 m++;
312 } while (((l = fixIP(ntoa(m), 1)) == null) || (l == f[2].value) );
313 f[5].value = l;
315 if (f[6].value == '') {
316 var l;
317 var m = aton(f[2].value) & aton(f[3].value);
318 var o = (m) ^ (~ aton(f[3].value));
319 var n = o - m;
320 do {
321 if (--n < 0) {
322 f[6].value = '';
323 return;
325 o--;
326 } while (((l = fixIP(ntoa(o), 1)) == null) || (l == f[2].value) );
327 f[6].value = l;
329 // first IP valid?
330 if ((getNetworkAddress(f[5].value, f[3].value) != getNetworkAddress(f[2].value, f[3].value)) ||
331 (f[5].value == getBroadcastAddress(getNetworkAddress(f[2].value, f[3].value), f[3].value)) ||
332 (f[5].value == getNetworkAddress(f[2].value, f[3].value)) ||
333 (f[2].value == f[5].value)) {
334 ferror.set(f[5], 'Invalid first IP address or subnet mask', quiet || !ok);
335 return 0;
336 } else {
337 ferror.clear(f[5]);
339 // last IP valid?
340 if ((getNetworkAddress(f[6].value, f[3].value) != getNetworkAddress(f[2].value, f[3].value)) ||
341 (f[6].value == getBroadcastAddress(getNetworkAddress(f[2].value, f[3].value), f[3].value)) ||
342 (f[6].value == getNetworkAddress(f[2].value, f[3].value)) ||
343 (f[2].value == f[6].value)) {
344 ferror.set(f[6], 'Invalid last IP address or subnet mask', quiet || !ok);
345 return 0;
346 } else {
347 ferror.clear(f[6]);
349 // validate range, swap first/last IP if needed
350 if (aton(f[6].value) < aton(f[5].value)) {
351 var t = f[5].value;
352 f[5].value = f[6].value;
353 f[6].value = t;
355 // lease time
356 if (parseInt(f[7].value*1) == 0)
357 f[7].value = 1440; // from nvram/defaults.c
358 if(!v_mins(f[7], quiet || !ok, 1, 10080))
359 ok = 0;
360 } else {
361 f[5].disabled = 1;
362 f[6].disabled = 1;
363 f[7].disabled = 1;
364 ferror.clear(f[5]);
365 ferror.clear(f[6]);
366 ferror.clear(f[7]);
368 return ok;
370 /* VLAN-END */
372 W('<style type=\'text/css\'>');
373 for (var u = 0; u < wl_ifaces.length; ++u) {
374 W('#spin'+wl_unit(u)+', ');
376 W('#spin {');
377 W(' visibility: hidden;');
378 W(' vertical-align: middle;');
379 W('}');
380 W('</style>');
382 var xob = null;
383 var refresher = [];
384 var nphy = features('11n');
386 /* NOVLAN-BEGIN */
387 if ((!fixIP(nvram.dhcpd_startip)) || (!fixIP(nvram.dhcpd_endip))) {
388 var x = nvram.lan_ipaddr.split('.').splice(0, 3).join('.') + '.';
389 nvram.dhcpd_startip = x + nvram.dhcp_start;
390 nvram.dhcpd_endip = x + ((nvram.dhcp_start * 1) + (nvram.dhcp_num * 1) - 1);
392 /* NOVLAN-END */
394 var ghz = [];
395 var bands = [];
396 var nm_loaded = [], ch_loaded = [], max_channel = [];
398 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
399 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
400 if (wl_sunit(uidx)<0) {
401 var b;
402 b = [];
403 for (var i = 0; i < wl_bands[uidx].length; ++i) {
404 b.push([wl_bands[uidx][i] + '', (wl_bands[uidx][i] == '1') ? '5 GHz' : '2.4 GHz']);
406 bands.push(b);
408 b = [];
409 ghz.push(b);
411 nm_loaded.push(0);
412 ch_loaded.push(0);
413 max_channel.push(0);
414 refresher.push(null);
418 function selectedBand(uidx)
420 if (bands[uidx].length > 1) {
421 var e = E('_f_wl'+u+'_nband');
422 return (e.value + '' == '' ? eval('nvram.wl'+u+'_nband') : e.value);
423 } else if (bands[uidx].length > 0) {
424 return bands[uidx][0][0] || '0';
425 } else {
426 return '0';
430 function refreshNetModes(uidx)
432 var e, i, buf, val;
434 if (uidx >= wl_ifaces.length) return;
435 var u = wl_unit(uidx);
437 var m = [['mixed','Auto']];
438 if (selectedBand(uidx) == '1') {
439 m.push(['a-only','A Only']);
440 if (nphy) {
441 m.push(['n-only','N Only']);
444 else {
445 m.push(['b-only','B Only']);
446 m.push(['g-only','G Only']);
447 if (nphy) {
448 m.push(['bg-mixed','B/G Mixed']);
449 m.push(['n-only','N Only']);
453 e = E('_wl'+u+'_net_mode');
454 buf = '';
455 val = (!nm_loaded[uidx] || (e.value + '' == '')) ? eval('nvram.wl'+u+'_net_mode') : e.value;
456 if (val == 'disabled') val = 'mixed';
457 for (i = 0; i < m.length; ++i)
458 buf += '<option value="' + m[i][0] + '"' + ((m[i][0] == val) ? ' selected' : '') + '>' + m[i][1] + '</option>';
460 e = E('__wl'+u+'_net_mode');
461 buf = '<select name="wl'+u+'_net_mode" onchange="verifyFields(this, 1)" id = "_wl'+u+'_net_mode">' + buf + '</select>';
462 elem.setInnerHTML(e, buf);
463 nm_loaded[uidx] = 1;
466 function refreshChannels(uidx)
468 if (refresher[uidx] != null) return;
469 if (u >= wl_ifaces.length) return;
470 var u = wl_unit(uidx);
472 refresher[uidx] = new XmlHttp();
473 refresher[uidx].onCompleted = function(text, xml) {
474 try {
475 var e, i, buf, val;
477 var wl_channels = [];
478 eval(text);
480 ghz[uidx] = [];
481 max_channel[uidx] = 0;
482 for (i = 0; i < wl_channels.length; ++i) {
483 ghz[uidx].push([wl_channels[i][0] + '',
484 (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']);
485 max_channel[uidx] = wl_channels[i][0] * 1;
488 e = E('_wl'+u+'_channel');
489 buf = '';
490 val = (!ch_loaded[uidx] || (e.value + '' == '')) ? eval('nvram.wl'+u+'_channel') : e.value;
491 for (i = 0; i < ghz[uidx].length; ++i)
492 buf += '<option value="' + ghz[uidx][i][0] + '"' + ((ghz[uidx][i][0] == val) ? ' selected' : '') + '>' + ghz[uidx][i][1] + '</option>';
494 e = E('__wl'+u+'_channel');
495 buf = '<select name="wl'+u+'_channel" onchange="verifyFields(this, 1)" id = "_wl'+u+'_channel">' + buf + '</select>';
496 elem.setInnerHTML(e, buf);
497 ch_loaded[uidx] = 1;
499 refresher[uidx] = null;
500 verifyFields(null, 1);
502 catch (x) {
504 refresher[uidx] = null;
507 var bw, sb, e;
509 e = E('_f_wl'+u+'_nctrlsb');
510 sb = (e.value + '' == '' ? eval('nvram.wl'+u+'_nctrlsb') : e.value);
511 e = E('_wl'+u+'_nbw_cap');
512 bw = (e.value + '' == '' ? eval('nvram.wl'+u+'_nbw_cap') : e.value) == '0' ? '20' : '40';
514 refresher[uidx].onError = function(ex) { alert(ex); refresher[uidx] = null; reloadPage(); }
515 refresher[uidx].post('update.cgi', 'exec=wlchannels&arg0=' + u + '&arg1=' + (nphy ? '1' : '0') +
516 '&arg2=' + bw + '&arg3=' + selectedBand(uidx) + '&arg4=' + sb);
519 function spin(x, unit)
521 for (var u = 0; u < wl_ifaces.length; ++u) {
522 E('_f_wl'+wl_unit(u)+'_scan').disabled = x;
524 var e = E('_f_wl'+unit+'_scan');
525 if (x) e.value = 'Scan ' + (wscan.tries + 1);
526 else e.value = 'Scan';
527 E('spin'+unit).style.visibility = x ? 'visible' : 'hidden';
530 function scan()
532 if (xob) return;
534 var unit = wscan.unit;
535 var uidx = wl_uidx(unit);
537 xob = new XmlHttp();
538 xob.onCompleted = function(text, xml) {
539 try {
540 var i;
542 wlscandata = [];
543 eval(text);
545 for (i = 0; i < wlscandata.length; ++i) {
546 var data = wlscandata[i];
547 var ch = data[2];
548 var mac = data[0];
550 if (!wscan.inuse[ch]) {
551 wscan.inuse[ch] = {
552 count: 0,
553 rssi: -999,
554 ssid: ''
558 if (!wscan.seen[mac]) {
559 wscan.seen[mac] = 1;
560 ++wscan.inuse[ch].count;
563 if (data[4] > wscan.inuse[ch].rssi) {
564 wscan.inuse[ch].rssi = data[4];
565 wscan.inuse[ch].ssid = data[1];
568 var e = E('_wl'+unit+'_channel');
569 for (i = 1; i < ghz[uidx].length; ++i) {
570 var s = ghz[uidx][i][1];
571 var u = wscan.inuse[ghz[uidx][i][0]];
572 if (u) s += ' (' + u.count + ' AP' + (u.count == 1 ? '' : 's') + ' / strongest: "' + escapeHTML(ellipsis(u.ssid, 15)) + '" ' + u.rssi + ' dBm)';
573 e.options[i].innerHTML = s;
575 e.style.width = '400px';
577 xob = null;
579 if (wscan.tries < 4) {
580 ++wscan.tries;
581 setTimeout(scan, 1000);
582 return;
585 catch (x) {
587 spin(0, unit);
589 xob.onError = function(x) {
590 alert('error: ' + x);
591 spin(0, unit);
592 xob = null;
595 spin(1, unit);
596 xob.post('update.cgi', 'exec=wlscan&arg0='+unit);
599 function scanButton(u)
601 if (xob) return;
603 wscan = {
604 unit: u,
605 seen: [],
606 inuse: [],
607 tries: 0
610 scan();
613 function joinAddr(a) {
614 var r, i, s;
616 r = [];
617 for (i = 0; i < a.length; ++i) {
618 s = a[i];
619 if ((s != '00:00:00:00:00:00') && (s != '0.0.0.0')) r.push(s);
621 return r.join(' ');
624 function random_x(max)
626 var c = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
627 var s = '';
628 while (max-- > 0) s += c.substr(Math.floor(c.length * Math.random()), 1);
629 return s;
632 function random_psk(id)
634 var e = E(id);
635 e.value = random_x(63);
636 verifyFields(null, 1);
639 function random_wep(u)
641 E('_wl'+u+'_passphrase').value = random_x(16);
642 generate_wep(u);
645 function v_wep(e, quiet)
647 var s = e.value;
649 if (((s.length == 5) || (s.length == 13)) && (s.length == (e.maxLength >> 1))) {
650 // no checking
652 else {
653 s = s.toUpperCase().replace(/[^0-9A-F]/g, '');
654 if (s.length != e.maxLength) {
655 ferror.set(e, 'Invalid WEP key. Expecting ' + e.maxLength + ' hex or ' + (e.maxLength >> 1) + ' ASCII characters.', quiet);
656 return 0;
660 e.value = s;
661 ferror.clear(e);
662 return 1;
665 // compatible w/ Linksys' and Netgear's (key 1) method for 128-bits
666 function generate_wep(u)
668 function _wepgen(pass, i)
670 while (pass.length < 64) pass += pass;
671 return hex_md5(pass.substr(0, 64)).substr(i, (E('_wl'+u+'_wep_bit').value == 128) ? 26 : 10);
674 var e = E('_wl'+u+'_passphrase');
675 var pass = e.value;
676 if (!v_length(e, false, 3)) return;
677 E('_wl'+u+'_key1').value = _wepgen(pass, 0);
678 pass += '#$%';
679 E('_wl'+u+'_key2').value = _wepgen(pass, 2);
680 pass += '!@#';
681 E('_wl'+u+'_key3').value = _wepgen(pass, 4);
682 pass += '%&^';
683 E('_wl'+u+'_key4').value = _wepgen(pass, 6);
684 verifyFields(null, 1);
687 function verifyFields(focused, quiet)
689 var i;
690 var ok = 1;
691 var a, b, c, d, e;
692 var u, uidx;
693 var wmode, sm2;
695 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
696 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
697 if (wl_sunit(uidx)<0) {
698 u = wl_unit(uidx);
699 if (focused == E('_f_wl'+u+'_nband')) {
700 refreshNetModes(uidx);
701 refreshChannels(uidx);
703 else if (focused == E('_f_wl'+u+'_nctrlsb') || focused == E('_wl'+u+'_nbw_cap')) {
704 refreshChannels(uidx);
709 // --- visibility ---
711 var vis = {
712 _wan_proto: 1,
713 _ppp_username: 1,
714 _ppp_passwd: 1,
715 _ppp_service: 1,
716 _ppp_custom: 1,
717 _l2tp_server_ip: 1,
718 _wan_ipaddr: 1,
719 _wan_netmask: 1,
720 _wan_gateway: 1,
721 _pptp_server_ip: 1,
722 _f_pptp_dhcp: 1,
723 _ppp_demand: 1,
724 _ppp_idletime: 1,
725 _ppp_redialperiod: 1,
726 _mtu_enable: 1,
727 _f_wan_mtu: 1,
728 _f_wan_islan: 0,
729 _f_ppp_mlppp: 1,
731 /* NOVLAN-BEGIN */
732 _dhcp_lease: 1,
733 _f_dhcpd_enable: 1,
734 _dhcpd_startip: 1,
735 _dhcpd_endip: 1,
736 _lan_ipaddr: 1,
737 _lan_netmask: 1,
738 /* NOVLAN-END */
739 _f_dns_1: 1,
740 _f_dns_2: 1,
741 _f_dns_3: 1,
742 _lan_gateway: 1,
743 _wan_wins: 1
746 var wl_vis = [];
747 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
748 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
749 if (wl_sunit(uidx)<0) {
750 a = {
751 _f_wl_radio: 1,
752 _f_wl_mode: 1,
753 _f_wl_nband: (bands[uidx].length > 1) ? 1 : 0,
754 _wl_net_mode: 1,
755 _wl_ssid: 1,
756 _f_wl_bcast: 1,
757 _wl_channel: 1,
758 _wl_nbw_cap: nphy ? 1 : 0,
759 _f_wl_nctrlsb: nphy ? 1 : 0,
760 _f_wl_scan: 1,
762 _wl_security_mode: 1,
763 _wl_crypto: 1,
764 _wl_wpa_psk: 1,
765 _f_wl_psk_random1: 1,
766 _f_wl_psk_random2: 1,
767 _wl_wpa_gtk_rekey: 1,
768 _wl_radius_key: 1,
769 _wl_radius_ipaddr: 1,
770 _wl_radius_port: 1,
771 _wl_wep_bit: 1,
772 _wl_passphrase: 1,
773 _f_wl_wep_gen: 1,
774 _f_wl_wep_random: 1,
775 _wl_key1: 1,
776 _wl_key2: 1,
777 _wl_key3: 1,
778 _wl_key4: 1,
780 _f_wl_lazywds: 1,
781 _f_wl_wds_0: 1
783 wl_vis.push(a);
787 var wan = E('_wan_proto').value;
789 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
790 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
791 if (wl_sunit(uidx)<0) {
792 wmode = E('_f_wl'+wl_unit(uidx)+'_mode').value;
794 if (wmode == 'wet') {
795 wan = 'disabled';
796 vis._wan_proto = 0;
797 /* NOVLAN-BEGIN */
798 vis._f_dhcpd_enable = 0;
799 vis._dhcp_lease = 0;
800 /* NOVLAN-END */
803 if ((wan == 'disabled') || (wmode == 'sta') || (wmode == 'wet')) {
804 vis._f_wan_islan = 1;
809 switch (wan) {
810 case 'disabled':
811 vis._ppp_username = 0;
812 vis._ppp_service = 0;
813 vis._ppp_custom = 0;
814 vis._l2tp_server_ip = 0;
815 vis._wan_ipaddr = 0;
816 vis._wan_netmask = 0;
817 vis._wan_gateway = 0;
818 vis._pptp_server_ip = 0;
819 vis._f_pptp_dhcp = 0;
820 vis._ppp_demand = 0;
821 vis._mtu_enable = 0;
822 vis._f_wan_mtu = 0;
823 vis._f_ppp_mlppp = 0;
824 break;
825 case 'dhcp':
826 vis._l2tp_server_ip = 0;
827 vis._ppp_demand = 0;
828 vis._ppp_service = 0;
829 vis._ppp_username = 0;
830 vis._ppp_custom = 0;
831 vis._pptp_server_ip = 0;
832 vis._f_pptp_dhcp = 0;
833 vis._wan_gateway = 0;
834 vis._wan_ipaddr = 0;
835 vis._wan_netmask = 0;
836 vis._f_ppp_mlppp = 0;
838 vis._lan_gateway = 0;
839 break;
840 case 'pppoe':
841 vis._l2tp_server_ip = 0;
842 vis._pptp_server_ip = 0;
843 vis._f_pptp_dhcp = 0;
844 vis._wan_gateway = 0;
845 vis._wan_ipaddr = 0;
846 vis._wan_netmask = 0;
848 vis._lan_gateway = 0;
849 break;
850 case 'static':
851 vis._l2tp_server_ip = 0;
852 vis._ppp_demand = 0;
853 vis._ppp_service = 0;
854 vis._ppp_username = 0;
855 vis._ppp_custom = 0;
856 vis._pptp_server_ip = 0;
857 vis._f_pptp_dhcp = 0;
858 vis._f_ppp_mlppp = 0;
860 vis._lan_gateway = 0;
861 break;
862 case 'pptp':
863 vis._l2tp_server_ip = 0;
864 vis._ppp_service = 0;
865 vis._wan_gateway = (!E('_f_pptp_dhcp').checked);
866 vis._wan_ipaddr = (!E('_f_pptp_dhcp').checked);
868 vis._lan_gateway = 0;
869 break;
870 case 'l2tp':
871 vis._pptp_server_ip = 0;
872 vis._ppp_service = 0;
873 vis._wan_gateway = (!E('_f_pptp_dhcp').checked);
874 vis._wan_ipaddr = (!E('_f_pptp_dhcp').checked);
876 vis._lan_gateway = 0;
877 break;
880 vis._ppp_idletime = (E('_ppp_demand').value == 1) && vis._ppp_demand
881 vis._ppp_redialperiod = !vis._ppp_idletime && vis._ppp_demand;
883 if (vis._mtu_enable) {
884 if (E('_mtu_enable').value == 0) {
885 vis._f_wan_mtu = 2;
886 a = E('_f_wan_mtu');
887 switch (E('_wan_proto').value) {
888 case 'pppoe':
889 a.value = 1492;
890 break;
891 case 'pptp':
892 case 'l2tp':
893 a.value = 1460;
894 break;
895 default:
896 a.value = 1500;
897 break;
902 /* NOVLAN-BEGIN */
903 if (!E('_f_dhcpd_enable').checked) vis._dhcp_lease = 0;
904 /* NOVLAN-END */
906 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
907 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
908 if (wl_sunit(uidx)<0) {
909 u = wl_unit(uidx);
910 wmode = E('_f_wl'+u+'_mode').value;
912 if (!E('_f_wl'+u+'_radio').checked) {
913 for (a in wl_vis[uidx]) {
914 wl_vis[uidx][a] = 2;
916 wl_vis[uidx]._f_wl_radio = 1;
917 wl_vis[uidx]._wl_nbw_cap = nphy ? 2 : 0;
918 wl_vis[uidx]._f_wl_nband = (bands[uidx].length > 1) ? 2 : 0;
921 switch (wmode) {
922 case 'apwds':
923 case 'wds':
924 break;
925 case 'wet':
926 case 'sta':
927 wl_vis[uidx]._f_wl_bcast = 0;
928 wl_vis[uidx]._wl_channel = 0;
929 wl_vis[uidx]._wl_nbw_cap = 0;
930 default:
931 wl_vis[uidx]._f_wl_lazywds = 0;
932 wl_vis[uidx]._f_wl_wds_0 = 0;
933 break;
936 sm2 = E('_wl'+u+'_security_mode').value;
937 switch (sm2) {
938 case 'disabled':
939 wl_vis[uidx]._wl_crypto = 0;
940 wl_vis[uidx]._wl_wep_bit = 0;
941 wl_vis[uidx]._wl_wpa_psk = 0;
942 wl_vis[uidx]._wl_radius_key = 0;
943 wl_vis[uidx]._wl_radius_ipaddr = 0;
944 wl_vis[uidx]._wl_wpa_gtk_rekey = 0;
945 break;
946 case 'wep':
947 wl_vis[uidx]._wl_crypto = 0;
948 wl_vis[uidx]._wl_wpa_psk = 0;
949 wl_vis[uidx]._wl_radius_key = 0;
950 wl_vis[uidx]._wl_radius_ipaddr = 0;
951 wl_vis[uidx]._wl_wpa_gtk_rekey = 0;
952 break;
953 case 'radius':
954 wl_vis[uidx]._wl_crypto = 0;
955 wl_vis[uidx]._wl_wpa_psk = 0;
956 break;
957 default: // wpa*
958 wl_vis[uidx]._wl_wep_bit = 0;
959 if (sm2.indexOf('personal') != -1) {
960 wl_vis[uidx]._wl_radius_key = 0;
961 wl_vis[uidx]._wl_radius_ipaddr = 0;
963 else {
964 wl_vis[uidx]._wl_wpa_psk = 0;
966 break;
969 if ((E('_f_wl'+u+'_lazywds').value == 1) && (wl_vis[uidx]._f_wl_wds_0 == 1)) {
970 wl_vis[uidx]._f_wl_wds_0 = 2;
973 if (wl_vis[uidx]._wl_nbw_cap != 0) {
974 switch (E('_wl'+u+'_net_mode').value) {
975 case 'b-only':
976 case 'g-only':
977 case 'a-only':
978 case 'bg-mixed':
979 wl_vis[uidx]._wl_nbw_cap = 2;
980 if (E('_wl'+u+'_nbw_cap').value != '0') {
981 E('_wl'+u+'_nbw_cap').value = 0;
982 refreshChannels(uidx);
984 break;
986 // avoid Enterprise-TKIP with 40MHz
987 if ((sm2 == 'wpa_enterprise') && (E('_wl'+u+'_crypto').value == 'tkip')) {
988 wl_vis[uidx]._wl_nbw_cap = 2;
989 if (E('_wl'+u+'_nbw_cap').value != '0') {
990 E('_wl'+u+'_nbw_cap').value = 0;
991 refreshChannels(uidx);
996 wl_vis[uidx]._f_wl_nctrlsb = (E('_wl'+u+'_nbw_cap').value == 0) ? 0 : wl_vis[uidx]._wl_nbw_cap;
998 /* REMOVE-BEGIN
999 This is ugly...
1000 Special case - 2.4GHz band, currently running in B/G-only mode,
1001 with N/Auto and 40MHz selected in the GUI.
1002 Channel list is not filtered in this case by the wl driver,
1003 and includes all channels available with 20MHz channel width.
1004 REMOVE-END */
1005 b = selectedBand(uidx);
1006 if (wl_vis[uidx]._wl_channel == 1 && wl_vis[uidx]._f_wl_nctrlsb != 0 &&
1007 ((b == '2') || (wl_vis[uidx]._f_wl_nband == 0 && b == '0'))) {
1008 switch (eval('nvram.wl'+u+'_net_mode')) {
1009 case 'b-only':
1010 case 'g-only':
1011 case 'bg-mixed':
1012 i = E('_wl'+u+'_channel').value * 1;
1013 if (i > 0 && i < 5) {
1014 E('_f_wl'+u+'_nctrlsb').value = 'lower';
1015 wl_vis[uidx]._f_wl_nctrlsb = 2;
1017 else if (i > max_channel[uidx] - 4) {
1018 E('_f_wl'+u+'_nctrlsb').value = 'upper';
1019 wl_vis[uidx]._f_wl_nctrlsb = 2;
1021 break;
1025 wl_vis[uidx]._f_wl_scan = wl_vis[uidx]._wl_channel;
1026 wl_vis[uidx]._f_wl_psk_random1 = wl_vis[uidx]._wl_wpa_psk;
1027 wl_vis[uidx]._f_wl_psk_random2 = wl_vis[uidx]._wl_radius_key;
1028 wl_vis[uidx]._wl_radius_port = wl_vis[uidx]._wl_radius_ipaddr;
1029 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;
1031 for (i = 1; i < 10; ++i) {
1032 wl_vis[uidx]['_f_wl_wds_' + i] = wl_vis[uidx]._f_wl_wds_0;
1035 } // for each wl_iface
1037 vis._ppp_passwd = vis._ppp_username;
1038 /* NOVLAN-BEGIN */
1039 vis._dhcpd_startip = vis._dhcpd_endip = vis._wan_wins = vis._dhcp_lease;
1040 /* NOVLAN-END */
1042 for (a in vis) {
1043 b = E(a);
1044 c = vis[a];
1045 /* REMOVE-BEGIN
1046 // if (b != null)
1047 REMOVE-END */
1048 b.disabled = (c != 1);
1049 PR(b).style.display = c ? '' : 'none';
1052 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1053 if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1054 for (a in wl_vis[uidx]) {
1055 i = 3;
1056 if (a.substr(0, 6) == '_f_wl_') i = 5;
1057 b = E(a.substr(0, i) + wl_unit(uidx) + a.substr(i, a.length));
1058 c = wl_vis[uidx][a];
1059 b.disabled = (c != 1);
1060 PR(b).style.display = c ? '' : 'none';
1065 // --- verify ---
1067 ferror.clear('_wan_proto');
1069 var wlclnt = 0;
1070 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1071 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1072 if (wl_sunit(uidx)<0) {
1073 u = wl_unit(uidx);
1074 wmode = E('_f_wl'+u+'_mode').value;
1075 sm2 = E('_wl'+u+'_security_mode').value;
1077 /* REMOVE-BEGIN
1078 if ((wl_vis[uidx]._f_wl_mode == 1) && (wmode != 'ap') && (sm2.substr(0, 4) == 'wpa2')) {
1079 ferror.set('_wl'+u+'_security_mode', 'WPA2 is supported only in AP mode.', quiet || !ok);
1080 ok = 0;
1082 else ferror.clear('_wl'+u+'_security_mode');
1083 REMOVE-END */
1085 // --- N standard does not support WPA+TKIP ---
1086 a = E('_wl'+u+'_crypto');
1087 switch (E('_wl'+u+'_net_mode').value) {
1088 case 'mixed':
1089 case 'n-only':
1090 if (nphy && (a.value == 'tkip') && (sm2.indexOf('wpa') != -1)) {
1091 ferror.set(a, 'TKIP encryption is not supported with WPA / WPA2 in N mode.', quiet || !ok);
1092 ok = 0;
1094 else ferror.clear(a);
1095 break;
1098 a = E('_wl'+u+'_net_mode');
1099 ferror.clear(a);
1100 b = E('_f_wl'+u+'_mode');
1101 ferror.clear(b);
1102 if ((wmode == 'sta') || (wmode == 'wet')) {
1103 ++wlclnt;
1104 if (wlclnt > 1) {
1105 ferror.set(b, 'Only one wireless interface can be configured in client mode.', quiet || !ok);
1106 ok = 0;
1108 else if (a.value == 'n-only') {
1109 ferror.set(a, 'N-only is not supported in wireless client modes, use Auto.', quiet || !ok);
1110 ok = 0;
1114 a = E('_wl'+u+'_wpa_psk');
1115 ferror.clear(a);
1116 if (wl_vis[uidx]._wl_wpa_psk == 1) {
1117 if ((a.value.length < 8) || ((a.value.length == 64) && (a.value.search(/[^0-9A-Fa-f]/) != -1))) {
1118 ferror.set('_wl'+u+'_wpa_psk', 'Invalid pre-shared key. Please enter at least 8 characters or 64 hexadecimal digits.', quiet || !ok);
1119 ok = 0;
1123 // wl channel
1124 if (((wmode == 'wds') || (wmode == 'apwds')) && (wl_vis[uidx]._wl_channel == 1) && (E('_wl'+u+'_channel').value == '0')) {
1125 ferror.set('_wl'+u+'_channel', 'Fixed wireless channel required in WDS mode.', quiet || !ok);
1126 ok = 0;
1128 else ferror.clear('_wl'+u+'_channel');
1130 if (E('_f_wl'+u+'_mode').value == 'sta') {
1131 if ((wan == 'disabled') && (E('_f_wl'+u+'_radio').checked)) {
1132 ferror.set('_wan_proto', 'Wireless Client mode requires a valid WAN setting (usually DHCP).', quiet || !ok);
1133 ok = 0;
1139 // domain name or IP address
1140 a = ['_l2tp_server_ip', '_pptp_server_ip'];
1141 for (i = a.length - 1; i >= 0; --i)
1142 if ((vis[a[i]]) && ((!v_length(a[i], 1, 1)) || ((!v_ip(a[i], 1)) && (!v_domain(a[i], 1))))) {
1143 if (!quiet && ok) ferror.show(a[i]);
1144 ok = 0;
1147 // IP address
1148 /* NOVLAN-BEGIN */
1149 a = ['_wan_gateway','_wan_ipaddr','_lan_ipaddr', '_dhcpd_startip', '_dhcpd_endip'];
1150 /* NOVLAN-END */
1151 /* VLAN-BEGIN */
1152 a = ['_wan_gateway','_wan_ipaddr'];
1153 /* VLAN-END */
1154 for (i = a.length - 1; i >= 0; --i)
1155 if ((vis[a[i]]) && (!v_ip(a[i], quiet || !ok))) ok = 0;
1157 // IP address, blank -> 0.0.0.0
1158 a = ['_f_dns_1', '_f_dns_2', '_f_dns_3','_wan_wins','_lan_gateway'];
1159 for (i = a.length - 1; i >= 0; --i)
1160 if ((vis[a[i]]) && (!v_dns(a[i], quiet || !ok))) ok = 0;
1162 // netmask
1163 /* NOVLAN-BEGIN */
1164 a = ['_wan_netmask','_lan_netmask'];
1165 /* NOVLAN-END */
1166 /* VLAN-BEGIN */
1167 a = ['_wan_netmask'];
1168 /* VLAN-END */
1169 for (i = a.length - 1; i >= 0; --i)
1170 if ((vis[a[i]]) && (!v_netmask(a[i], quiet || !ok))) ok = 0;
1172 // range
1173 /* NOVLAN-BEGIN */
1174 a = [['_ppp_idletime', 3, 1440],['_ppp_redialperiod', 1, 86400],['_f_wan_mtu', 576, 1500],
1175 ['_dhcp_lease', 1, 10080]];
1176 /* NOVLAN-END */
1177 /* VLAN-BEGIN */
1178 a = [['_ppp_idletime', 3, 1440],['_ppp_redialperiod', 1, 86400],['_f_wan_mtu', 576, 1500]];
1179 /* VLAN-END */
1180 for (i = a.length - 1; i >= 0; --i) {
1181 v = a[i];
1182 if ((vis[v[0]]) && (!v_range(v[0], quiet || !ok, v[1], v[2]))) ok = 0;
1185 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1186 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1187 if (wl_sunit(uidx)<0) {
1188 u = wl_unit(uidx);
1190 // IP address
1191 a = ['_radius_ipaddr'];
1192 for (i = a.length - 1; i >= 0; --i) {
1193 if ((wl_vis[uidx]['_wl'+a[i]]) && (!v_ip('_wl'+u+a[i], quiet || !ok))) ok = 0;
1196 // range
1197 a = [['_wpa_gtk_rekey', 60, 7200], ['_radius_port', 1, 65535]];
1198 for (i = a.length - 1; i >= 0; --i) {
1199 v = a[i];
1200 if ((wl_vis[uidx]['_wl'+v[0]]) && (!v_range('_wl'+u+v[0], quiet || !ok, v[1], v[2]))) ok = 0;
1203 // length
1204 a = [['_ssid', 1], ['_radius_key', 1]];
1205 for (i = a.length - 1; i >= 0; --i) {
1206 v = a[i];
1207 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;
1210 if (wl_vis[uidx]._wl_key1) {
1211 a = (E('_wl'+u+'_wep_bit').value == 128) ? 26 : 10;
1212 for (i = 1; i <= 4; ++i) {
1213 b = E('_wl'+u+'_key' + i);
1214 b.maxLength = a;
1215 if ((b.value.length > 0) || (E('_f_wl'+u+'_wepidx_' + i).checked)) {
1216 if (!v_wep(b, quiet || !ok)) ok = 0;
1218 else ferror.clear(b);
1222 ferror.clear('_f_wl'+u+'_wds_0');
1223 if (wl_vis[uidx]._f_wl_wds_0 == 1) {
1224 b = 0;
1225 for (i = 0; i < 10; ++i) {
1226 a = E('_f_wl'+u+'_wds_' + i);
1227 if (!v_macz(a, quiet || !ok)) ok = 0;
1228 else if (!isMAC0(a.value)) b = 1;
1230 if (!b) {
1231 ferror.set('_f_wl'+u+'_wds_0', 'WDS MAC address required.', quiet || !ok);
1232 ok = 0;
1238 /* NOVLAN-BEGIN */
1239 a = E('_dhcpd_startip');
1240 b = E('_dhcpd_endip');
1241 ferror.clear(a);
1242 ferror.clear(b);
1244 if ((vis._dhcp_lease) && (!a._error_msg) && (!b._error_msg)) {
1245 c = aton(E('_lan_netmask').value);
1246 d = aton(E('_lan_ipaddr').value) & c;
1247 e = 'Invalid IP address or subnet mask';
1248 if ((aton(a.value) & c) != d) {
1249 ferror.set(a, e, quiet || !ok);
1250 ok = 0;
1252 if ((aton(b.value) & c) != d) {
1253 ferror.set(b, e, quiet || !ok);
1254 ok = 0;
1258 if ((vis._dhcp_lease) && (!a._error_msg) && (!b._error_msg)) {
1259 if (aton(a.value) > aton(b.value)) {
1260 c = a.value;
1261 a.value = b.value;
1262 b.value = c;
1265 elem.setInnerHTML('dhcp_count', '(' + ((aton(b.value) - aton(a.value)) + 1) + ')');
1267 /* NOVLAN-END */
1269 return ok;
1272 function earlyInit()
1274 verifyFields(null, 1);
1277 function save()
1279 /* VLAN-BEGIN */
1280 if (lg.isEditing()) return;
1281 lg.resetNewEditor();
1282 /* VLAN-END */
1284 var a, b, c;
1285 var i;
1286 var u, uidx, wmode, sm2, wradio;
1288 if (!verifyFields(null, false)) return;
1290 var fom = E('_fom');
1292 fom.wan_mtu.value = fom.f_wan_mtu.value;
1293 fom.wan_mtu.disabled = fom.f_wan_mtu.disabled;
1295 /* NOVLAN-BEGIN */
1296 fom.lan_proto.value = fom.f_dhcpd_enable.checked ? 'dhcp' : 'static';
1297 /* NOVLAN-END */
1299 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1300 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1301 if (wl_sunit(uidx)<0) {
1302 u = wl_unit(uidx);
1303 wmode = E('_f_wl'+u+'_mode').value;
1304 sm2 = E('_wl'+u+'_security_mode').value;
1305 wradio = E('_f_wl'+u+'_radio').checked;
1307 E('_wl'+u+'_nband').value = selectedBand(uidx);
1309 if (wmode == 'apwds') E('_wl'+u+'_mode').value = 'ap';
1310 else E('_wl'+u+'_mode').value = wmode;
1312 if (wmode == 'wet') {
1313 fom.wan_proto.value = 'disabled';
1314 fom.wan_proto.disabled = 0;
1315 /* NOVLAN-BEGIN */
1316 fom.lan_proto.value = 'static';
1317 /* NOVLAN-END */
1318 /* VLAN-BEGIN */
1319 // TODO - what's required ? integrate with tomatogrid?
1320 /* VLAN-END */
1323 a = [];
1324 for (i = 0; i < 10; ++i) a.push(E('_f_wl'+u+'_wds_' + i).value);
1325 E('_wl'+u+'_wds').value = joinAddr(a);
1327 if (wmode.indexOf('wds') != -1) {
1328 E('_wl'+u+'_wds_enable').value = 1;
1329 E('_wl'+u+'_lazywds').value = E('_f_wl'+u+'_lazywds').value;
1330 if (E('_wl'+u+'_lazywds').value == 1) E('_wl'+u+'_wds').value = '';
1332 else {
1333 E('_wl'+u+'_wds_enable').value = 0;
1334 E('_wl'+u+'_wds').value = '';
1335 E('_wl'+u+'_lazywds').value = 0;
1338 E('_wl'+u+'_radio').value = wradio ? 1 : 0;
1339 E('_wl'+u+'_auth').value = eval('nvram.wl'+u+'_auth');
1341 e = E('_wl'+u+'_akm');
1342 switch (sm2) {
1343 case 'disabled':
1344 case 'radius':
1345 case 'wep':
1346 e.value = '';
1347 break;
1348 default:
1349 c = [];
1351 if (sm2.indexOf('personal') != -1) {
1352 if (sm2.indexOf('wpa2_') == -1) c.push('psk');
1353 if (sm2.indexOf('wpa_') == -1) c.push('psk2');
1355 else {
1356 if (sm2.indexOf('wpa2_') == -1) c.push('wpa');
1357 if (sm2.indexOf('wpa_') == -1) c.push('wpa2');
1359 c = c.join(' ');
1360 e.value = c;
1361 break;
1363 E('_wl'+u+'_auth_mode').value = (sm2 == 'radius') ? 'radius' : 'none';
1364 E('_wl'+u+'_wep').value = ((sm2 == 'radius') || (sm2 == 'wep')) ? 'enabled': 'disabled';
1366 if (sm2.indexOf('wpa') != -1) E('_wl'+u+'_auth').value = 0;
1368 E('_wl'+u+'_nreqd').value = 0;
1369 E('_wl'+u+'_gmode').value = 1;
1370 E('_wl'+u+'_nmode').value = 0;
1371 E('_wl'+u+'_nmcsidx').value = -2; // Legacy Rate
1372 E('_wl'+u+'_nbw').value = 0;
1373 switch (E('_wl'+u+'_net_mode').value) {
1374 case 'b-only':
1375 E('_wl'+u+'_gmode').value = 0;
1376 break;
1377 case 'g-only':
1378 E('_wl'+u+'_gmode').value = 4;
1379 break;
1380 case 'bg-mixed':
1381 break;
1382 case 'a-only':
1383 E('_wl'+u+'_nmcsidx').value = -1; // Auto
1384 break;
1385 case 'n-only':
1386 if (selectedBand(uidx) == '1') { // 5 GHz
1387 E('_wl'+u+'_nmode').value = -1;
1388 E('_wl'+u+'_nmcsidx').value = -1;
1389 } else {
1390 E('_wl'+u+'_nmode').value = 1;
1391 E('_wl'+u+'_nmcsidx').value = 32;
1393 E('_wl'+u+'_nreqd').value = 1;
1394 break;
1395 default: // Auto
1396 E('_wl'+u+'_nmode').value = -1;
1397 E('_wl'+u+'_nmcsidx').value = -1;
1398 break;
1401 E('_wl'+u+'_nctrlsb').value = eval('nvram.wl'+u+'_nctrlsb');
1402 if (E('_wl'+u+'_nmode').value != 0) {
1403 E('_wl'+u+'_nctrlsb').value = E('_f_wl'+u+'_nctrlsb').value;
1404 E('_wl'+u+'_nbw').value = (E('_wl'+u+'_nbw_cap').value == 0) ? 20 : 40;
1407 E('_wl'+u+'_closed').value = E('_f_wl'+u+'_bcast').checked ? 0 : 1;
1409 a = fields.radio.selected(eval('fom.f_wl'+u+'_wepidx'));
1410 if (a) E('_wl'+u+'_key').value = a.value;
1414 fom.wan_islan.value = fom.f_wan_islan.checked ? 1 : 0;
1415 fom.pptp_dhcp.value = fom.f_pptp_dhcp.checked ? 1 : 0;
1417 fom.wan_dns.value = joinAddr([fom.f_dns_1.value, fom.f_dns_2.value, fom.f_dns_3.value]);
1419 /* VLAN-BEGIN */
1420 // initialize/wipe out relevant fields
1421 for (var i = 0 ; i <= MAX_BRIDGE_ID ; i++) {
1422 var j = (i == 0) ? '' : i.toString();
1423 fom['lan' + j + '_ifname'].value = '';
1424 fom['lan' + j + '_ipaddr'].value = '';
1425 fom['lan' + j + '_netmask'].value = '';
1426 fom['lan' + j + '_proto'].value = '';
1427 fom['lan' + j + '_stp'].value = '';
1428 fom['dhcp' + j + '_start'].value = '';
1429 fom['dhcp' + j + '_num'].value = '';
1430 fom['dhcp' + j + '_lease'].value = '';
1431 fom['dhcpd' + j + '_startip'].value = '';
1432 fom['dhcpd' + j + '_endip'].value = '';
1435 var d = lg.getAllData();
1436 for (var i = 0; i < d.length; ++i) {
1438 if (lg.countOverlappingNetworks(d[i][2]) > 1) {
1439 var s = 'Cannot proceed: two or more LAN bridges have conflicting IP addresses or overlapping subnets';
1440 alert(s);
1441 var e = E('footer-msg');
1442 e.innerHTML = s;
1443 e.style.visibility = 'visible';
1444 setTimeout(
1445 function() {
1446 e.innerHTML = '';
1447 e.style.visibility = 'hidden';
1448 }, 5000);
1449 return;
1452 var j = (parseInt(d[i][0]) == 0) ? '' : d[i][0].toString();
1453 fom['lan' + j + '_ifname'].value = 'br' + d[i][0];
1454 fom['lan' + j + '_stp'].value = d[i][1];
1455 fom['lan' + j + '_ipaddr'].value = d[i][2];
1456 fom['lan' + j + '_netmask'].value = d[i][3];
1457 fom['lan' + j + '_proto'].value = (d[i][4] != '0') ? 'dhcp' : 'static';
1458 fom['dhcp' + j + '_start'].value = (d[i][4] != '0') ? (d[i][5]).split('.').splice(3, 1) : '';
1459 fom['dhcp' + j + '_num'].value = (d[i][4] != '0') ? d[i][6] - fom['dhcp' + j + '_start'].value + 1 : '';
1460 fom['dhcp' + j + '_lease'].value = (d[i][4] != '0') ? d[i][7] : '';
1461 fom['dhcpd' + j + '_startip'].value = (d[i][4] != '0') ? d[i][5] : '';
1462 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])) : '';
1464 /* REMOVE-BEGIN
1465 alert('lan' + j + '_ifname=' + fom['lan' + j + '_ifname'].value +
1466 ', lan' + j + '_stp=' + fom['lan' + j + '_stp'].value +
1467 ', lan' + j + '_ipaddr=' + fom['lan' + j + '_ipaddr'].value +
1468 ', lan' + j + '_netmask=' + fom['lan' + j + '_netmask'].value +
1469 ', lan' + j + '_proto=' + fom['lan' + j + '_proto'].value +
1470 ', dhcp' + j + '_start=' + fom['dhcp' + j + '_start'].value +
1471 ', dhcp' + j + '_num=' + fom['dhcp' + j + '_num'].value +
1472 ', dhcp' + j + '_lease=' + fom['dhcp' + j + '_lease'].value +
1473 ', dhcpd' + j + '_startip=' + fom['dhcpd' + j + '_startip'].value +
1474 ', dhcpd' + j + '_endip=' + fom['dhcpd' + j + '_endip'].value);
1475 // fixIP(getNetworkAddress(data[2], data[3]).split('.').splice(0, 3).join('.') + '.' + parseInt(data[6]))
1476 REMOVE-END */
1479 var e = E('footer-msg');
1480 var t = fixIP(fom['lan_ipaddr'].value);
1481 if ((fom['lan_ifname'].value != 'br0') || (fom['lan_ipaddr'].value == '0.0.0.0') || (!t)) {
1482 e.innerHTML = 'Bridge br0 must be always defined and have a valid IP address set.';
1483 e.style.visibility = 'visible';
1484 setTimeout(
1485 function() {
1486 e.innerHTML = '';
1487 e.style.visibility = 'hidden';
1488 }, 5000);
1489 return;
1491 /* VLAN-END */
1493 /* REMOVE-BEGIN
1494 // if ((nvram.lan_ipaddr != fom.lan_ipaddr.value) || (nvram.lan1_ipaddr != fom.lan1_ipaddr.value) ||
1495 // (nvram.lan2_ipaddr != fom.lan2_ipaddr.value) || (nvram.lan3_ipaddr != fom.lan3_ipaddr.value)){
1496 REMOVE-END */
1498 fom.ppp_mlppp.value = fom.f_ppp_mlppp.checked ? 1 : 0;
1500 if (nvram.lan_ipaddr != fom.lan_ipaddr.value) {
1501 fom._moveip.value = 1;
1502 form.submit(fom);
1504 else {
1505 form.submit(fom, 1);
1509 function init()
1511 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1512 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1513 if (wl_sunit(uidx)<0) {
1514 refreshNetModes(uidx);
1515 refreshChannels(uidx);
1519 </script>
1521 </head>
1522 <body onload='init()'>
1523 <form id='_fom' method='post' action='tomato.cgi'>
1524 <table id='container' cellspacing=0>
1525 <tr><td colspan=2 id='header'>
1526 <div class='title'>Tomato</div>
1527 <div class='version'>Version <% version(); %></div>
1528 </td></tr>
1529 <tr id='body'><td id='navi'><script type='text/javascript'>navi()</script></td>
1530 <td id='content'>
1531 <div id='ident'><% ident(); %></div>
1533 <!-- / / / -->
1535 <input type='hidden' name='_nextpage' value='basic-network.asp'>
1536 <input type='hidden' name='_nextwait' value='10'>
1537 <input type='hidden' name='_service' value='*'>
1538 <input type='hidden' name='_moveip' value='0'>
1540 <input type='hidden' name='wan_mtu'>
1541 <input type='hidden' name='wan_islan'>
1542 <input type='hidden' name='pptp_dhcp'>
1543 <!-- NOVLAN-BEGIN -->
1544 <input type='hidden' name='lan_proto'>
1545 <!-- NOVLAN-END -->
1546 <input type='hidden' name='wan_dns'>
1547 <input type='hidden' name='ppp_mlppp'>
1549 <!-- VLAN-BEGIN -->
1550 <script type='text/javascript'>
1552 for (var i = 0 ; i <= MAX_BRIDGE_ID ; i++) {
1553 var j = (i == 0) ? '' : i.toString();
1554 W('<input type=\'hidden\' id=\'lan' + j + '_ifname\' name=\'lan' + j + '_ifname\'>');
1555 W('<input type=\'hidden\' id=\'lan' + j + '_ipaddr\' name=\'lan' + j + '_ipaddr\'>');
1556 W('<input type=\'hidden\' id=\'lan' + j + '_netmask\' name=\'lan' + j + '_netmask\'>');
1557 W('<input type=\'hidden\' id=\'lan' + j + '_proto\' name=\'lan' + j + '_proto\'>');
1558 W('<input type=\'hidden\' id=\'lan' + j + '_stp\' name=\'lan' + j + '_stp\'>');
1559 W('<input type=\'hidden\' id=\'dhcp' + j + '_start\' name=\'dhcp' + j + '_start\'>');
1560 W('<input type=\'hidden\' id=\'dhcp' + j + '_num\' name=\'dhcp' + j + '_num\'>');
1561 W('<input type=\'hidden\' id=\'dhcp' + j + '_lease\' name=\'dhcp' + j + '_lease\'>');
1562 W('<input type=\'hidden\' id=\'dhcpd' + j + '_startip\' name=\'dhcpd' + j + '_startip\'>');
1563 W('<input type=\'hidden\' id=\'dhcpd' + j + '_endip\' name=\'dhcpd' + j + '_endip\'>');
1565 </script>
1566 <!-- VLAN-END -->
1568 <div class='section-title'>WAN / Internet</div>
1569 <div class='section'>
1570 <script type='text/javascript'>
1571 createFieldTable('', [
1572 { title: 'Type', name: 'wan_proto', type: 'select', options: [['dhcp','DHCP'],['pppoe','PPPoE'],['static','Static'],['pptp','PPTP'],['l2tp','L2TP'],['disabled','Disabled']],
1573 value: nvram.wan_proto },
1574 { title: 'Username', name: 'ppp_username', type: 'text', maxlen: 60, size: 64, value: nvram.ppp_username },
1575 { title: 'Password', name: 'ppp_passwd', type: 'password', maxlen: 60, size: 64, peekaboo: 1, value: nvram.ppp_passwd },
1576 { title: 'Service Name', name: 'ppp_service', type: 'text', maxlen: 50, size: 64, value: nvram.ppp_service },
1577 { title: 'L2TP Server', name: 'l2tp_server_ip', type: 'text', maxlen: 128, size: 64, value: nvram.l2tp_server_ip },
1578 { title: 'Use DHCP', name: 'f_pptp_dhcp', type: 'checkbox', value: (nvram.pptp_dhcp == 1) },
1579 { title: 'IP Address', name: 'wan_ipaddr', type: 'text', maxlen: 15, size: 17, value: nvram.wan_ipaddr },
1580 { title: 'Subnet Mask', name: 'wan_netmask', type: 'text', maxlen: 15, size: 17, value: nvram.wan_netmask },
1581 { title: 'Gateway', name: 'wan_gateway', type: 'text', maxlen: 15, size: 17, value: nvram.wan_gateway },
1582 { title: 'PPTP Gateway', name: 'pptp_server_ip', type: 'text', maxlen: 128, size: 64, value: nvram.pptp_server_ip },
1583 { title: 'Options', name: 'ppp_custom', type: 'text', maxlen: 256, size: 64, value: nvram.ppp_custom },
1584 { title: 'Connect Mode', name: 'ppp_demand', type: 'select', options: [['1', 'Connect On Demand'],['0', 'Keep Alive']],
1585 value: nvram.ppp_demand },
1586 { title: 'Max Idle Time', indent: 2, name: 'ppp_idletime', type: 'text', maxlen: 5, size: 7, suffix: ' <i>(minutes)</i>',
1587 value: nvram.ppp_idletime },
1588 { title: 'Check Interval', indent: 2, name: 'ppp_redialperiod', type: 'text', maxlen: 5, size: 7, suffix: ' <i>(seconds)</i>',
1589 value: nvram.ppp_redialperiod },
1590 { title: 'MTU', multi: [
1591 { name: 'mtu_enable', type: 'select', options: [['0', 'Default'],['1','Manual']], value: nvram.mtu_enable },
1592 { name: 'f_wan_mtu', type: 'text', maxlen: 4, size: 6, value: nvram.wan_mtu } ] },
1593 { title: 'Single Line MLPPP', name: 'f_ppp_mlppp', type: 'checkbox', value: (nvram.ppp_mlppp == 1) },
1594 /* NOVLAN-BEGIN */
1595 { title: 'Use WAN port for LAN', name: 'f_wan_islan', type: 'checkbox', value: (nvram.wan_islan == 1) }
1596 /* NOVLAN-END */
1597 /* VLAN-BEGIN */
1598 { title: 'Bridge WAN port to primary LAN (br0)', name: 'f_wan_islan', type: 'checkbox', value: (nvram.wan_islan == 1) }
1599 /* VLAN-END */
1601 </script>
1602 </div>
1604 <div class='section-title'>LAN</div>
1605 <div class='section'>
1606 <!-- VLAN-BEGIN -->
1607 <table class='tomato-grid' cellspacing=1 id='lan-grid'></table>
1609 <script type='text/javascript'>lg.setup();</script>
1610 <!-- VLAN-END -->
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 /* NOVLAN-BEGIN */
1619 { title: 'Router IP Address', name: 'lan_ipaddr', type: 'text', maxlen: 15, size: 17, value: nvram.lan_ipaddr },
1620 { title: 'Subnet Mask', name: 'lan_netmask', type: 'text', maxlen: 15, size: 17, value: nvram.lan_netmask },
1621 /* NOVLAN-END */
1622 { title: 'Default Gateway', name: 'lan_gateway', type: 'text', maxlen: 15, size: 17, value: nvram.lan_gateway },
1623 { 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' },
1624 { title: '', name: 'f_dns_2', type: 'text', maxlen: 21, size: 25, value: dns[1] || '0.0.0.0' },
1625 { title: '', name: 'f_dns_3', type: 'text', maxlen: 21, size: 25, value: dns[2] || '0.0.0.0' },
1626 /* NOVLAN-BEGIN */
1627 { title: 'DHCP Server', name: 'f_dhcpd_enable', type: 'checkbox', value: (nvram.lan_proto == 'dhcp') },
1628 { title: 'IP Address Range', indent: 2, multi: [
1629 { name: 'dhcpd_startip', type: 'text', maxlen: 15, size: 17, value: nvram.dhcpd_startip, suffix: ' - ' },
1630 { name: 'dhcpd_endip', type: 'text', maxlen: 15, size: 17, value: nvram.dhcpd_endip, suffix: ' <i id="dhcp_count"></i>' }
1631 ] },
1633 { title: 'Lease Time', indent: 2, name: 'dhcp_lease', type: 'text', maxlen: 6, size: 8, suffix: ' <i>(minutes)</i>',
1634 value: (nvram.dhcp_lease > 0) ? nvram.dhcp_lease : 1440 },
1635 { title: 'WINS', indent: 2, name: 'wan_wins', type: 'text', maxlen: 15, size: 17, value: nvram.wan_wins }
1636 /* NOVLAN-END */
1637 /* VLAN-BEGIN */
1638 { title: 'WINS <i>(for DHCP)</i>', name: 'wan_wins', type: 'text', maxlen: 15, size: 17, value: nvram.wan_wins }
1639 /* VLAN-END */
1641 </script>
1642 </div>
1644 <script type='text/javascript'>
1646 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1647 //if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1648 if (wl_sunit(uidx)<0) {
1649 var u = wl_unit(uidx);
1651 W('<input type=\'hidden\' id=\'_wl'+u+'_mode\' name=\'wl'+u+'_mode\'>');
1652 W('<input type=\'hidden\' id=\'_wl'+u+'_nband\' name=\'wl'+u+'_nband\'>');
1653 W('<input type=\'hidden\' id=\'_wl'+u+'_wds_enable\' name=\'wl'+u+'_wds_enable\'>');
1654 W('<input type=\'hidden\' id=\'_wl'+u+'_wds\' name=\'wl'+u+'_wds\'>');
1655 W('<input type=\'hidden\' id=\'_wl'+u+'_radio\' name=\'wl'+u+'_radio\'>');
1656 W('<input type=\'hidden\' id=\'_wl'+u+'_closed\' name=\'wl'+u+'_closed\'>');
1657 W('<input type=\'hidden\' id=\'_wl'+u+'_key\' name=\'wl'+u+'_key\'>');
1658 W('<input type=\'hidden\' id=\'_wl'+u+'_gmode\' name=\'wl'+u+'_gmode\'>');
1659 W('<input type=\'hidden\' id=\'_wl'+u+'_akm\' name=\'wl'+u+'_akm\'>');
1660 W('<input type=\'hidden\' id=\'_wl'+u+'_auth\' name=\'wl'+u+'_auth\'>');
1661 W('<input type=\'hidden\' id=\'_wl'+u+'_auth_mode\' name=\'wl'+u+'_auth_mode\'>');
1662 W('<input type=\'hidden\' id=\'_wl'+u+'_wep\' name=\'wl'+u+'_wep\'>');
1663 W('<input type=\'hidden\' id=\'_wl'+u+'_lazywds\' name=\'wl'+u+'_lazywds\'>');
1664 W('<input type=\'hidden\' id=\'_wl'+u+'_nmode\' name=\'wl'+u+'_nmode\'>');
1665 W('<input type=\'hidden\' id=\'_wl'+u+'_nmcsidx\' name=\'wl'+u+'_nmcsidx\'>');
1666 W('<input type=\'hidden\' id=\'_wl'+u+'_nreqd\' name=\'wl'+u+'_nreqd\'>');
1667 W('<input type=\'hidden\' id=\'_wl'+u+'_nctrlsb\' name=\'wl'+u+'_nctrlsb\'>');
1668 W('<input type=\'hidden\' id=\'_wl'+u+'_nbw\' name=\'wl'+u+'_nbw\'>');
1670 W('<div class=\'section-title\'>Wireless');
1671 // if (wl_ifaces.length > 1)
1672 W(' (' + wl_display_ifname(uidx) + ')');
1673 W('</div>');
1675 W('<div class=\'section\'>');
1677 f = [
1678 { title: 'Enable Wireless', name: 'f_wl'+u+'_radio', type: 'checkbox',
1679 value: (eval('nvram.wl'+u+'_radio') == '1') && (eval('nvram.wl'+u+'_net_mode') != 'disabled') },
1680 { title: 'MAC Address', text: '<a href="advanced-mac.asp">' + eval('nvram.wl'+u+'_hwaddr') + '</a>' },
1681 { title: 'Wireless Mode', name: 'f_wl'+u+'_mode', type: 'select',
1682 options: [['ap', 'Access Point'],['apwds', 'Access Point + WDS'],['sta', 'Wireless Client'],['wet', 'Wireless Ethernet Bridge'],['wds', 'WDS']],
1683 value: ((eval('nvram.wl'+u+'_mode') == 'ap') && (eval('nvram.wl'+u+'_wds_enable') == '1')) ? 'apwds' : eval('nvram.wl'+u+'_mode') },
1684 { title: 'Radio Band', name: 'f_wl'+u+'_nband', type: 'select', options: bands[uidx],
1685 value: eval('nvram.wl'+u+'_nband') || '0' == '0' ? bands[uidx][0][0] : eval('nvram.wl'+u+'_nband') },
1686 { title: 'Wireless Network Mode', name: 'wl'+u+'_net_mode', type: 'select',
1687 value: (eval('nvram.wl'+u+'_net_mode') == 'disabled') ? 'mixed' : eval('nvram.wl'+u+'_net_mode'),
1688 options: [], prefix: '<span id="__wl'+u+'_net_mode">', suffix: '</span>' },
1689 { title: 'SSID', name: 'wl'+u+'_ssid', type: 'text', maxlen: 32, size: 34, value: eval('nvram.wl'+u+'_ssid') },
1690 { title: 'Broadcast', indent: 2, name: 'f_wl'+u+'_bcast', type: 'checkbox', value: (eval('nvram.wl'+u+'_closed') == '0') },
1691 { 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+'">',
1692 value: eval('nvram.wl'+u+'_channel') },
1693 { title: 'Channel Width', name: 'wl'+u+'_nbw_cap', type: 'select', options: [['0','20 MHz'],['1','40 MHz']],
1694 value: eval('nvram.wl'+u+'_nbw_cap') },
1695 { title: 'Control Sideband', name: 'f_wl'+u+'_nctrlsb', type: 'select', options: [['lower','Lower'],['upper','Upper']],
1696 value: eval('nvram.wl'+u+'_nctrlsb') == 'none' ? 'lower' : eval('nvram.wl'+u+'_nctrlsb') },
1697 null,
1698 { title: 'Security', name: 'wl'+u+'_security_mode', type: 'select',
1699 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']],
1700 value: eval('nvram.wl'+u+'_security_mode') },
1701 { title: 'Encryption', indent: 2, name: 'wl'+u+'_crypto', type: 'select',
1702 options: [['tkip','TKIP'],['aes','AES'],['tkip+aes','TKIP / AES']], value: eval('nvram.wl'+u+'_crypto') },
1703 { title: 'Shared Key', indent: 2, name: 'wl'+u+'_wpa_psk', type: 'password', maxlen: 64, size: 66, peekaboo: 1,
1704 suffix: ' <input type="button" id="_f_wl'+u+'_psk_random1" value="Random" onclick="random_psk(\'_wl'+u+'_wpa_psk\')">',
1705 value: eval('nvram.wl'+u+'_wpa_psk') },
1706 { title: 'Shared Key', indent: 2, name: 'wl'+u+'_radius_key', type: 'password', maxlen: 80, size: 32, peekaboo: 1,
1707 suffix: ' <input type="button" id="_f_wl'+u+'_psk_random2" value="Random" onclick="random_psk(\'_wl'+u+'_radius_key\')">',
1708 value: eval('nvram.wl'+u+'_radius_key') },
1709 { title: 'Group Key Renewal', indent: 2, name: 'wl'+u+'_wpa_gtk_rekey', type: 'text', maxlen: 4, size: 6, suffix: ' <i>(seconds)</i>',
1710 value: eval('nvram.wl'+u+'_wpa_gtk_rekey') },
1711 { title: 'Radius Server', indent: 2, multi: [
1712 { name: 'wl'+u+'_radius_ipaddr', type: 'text', maxlen: 15, size: 17, value: eval('nvram.wl'+u+'_radius_ipaddr') },
1713 { name: 'wl'+u+'_radius_port', type: 'text', maxlen: 5, size: 7, prefix: ' : ', value: eval('nvram.wl'+u+'_radius_port') } ] },
1714 { title: 'Encryption', indent: 2, name: 'wl'+u+'_wep_bit', type: 'select', options: [['128','128-bits'],['64','64-bits']],
1715 value: eval('nvram.wl'+u+'_wep_bit') },
1716 { title: 'Passphrase', indent: 2, name: 'wl'+u+'_passphrase', type: 'text', maxlen: 16, size: 20,
1717 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+')">',
1718 value: eval('nvram.wl'+u+'_passphrase') }
1721 for (i = 1; i <= 4; ++i) {
1722 f.push(
1723 { title: ('Key ' + i), indent: 2, name: ('wl'+u+'_key' + i), type: 'text', maxlen: 26, size: 34,
1724 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>' : '>'),
1725 value: nvram['wl'+u+'_key' + i] });
1728 f.push(null,
1729 { title: 'WDS', name: 'f_wl'+u+'_lazywds', type: 'select',
1730 options: [['0','Link With...'],['1','Automatic']], value: nvram['wl'+u+'_lazywds'] } );
1731 wds = eval('nvram.wl'+u+'_wds').split(/\s+/);
1732 for (i = 0; i < 10; i += 2) {
1733 f.push({ title: (i ? '' : 'MAC Address'), indent: 2, multi: [
1734 { name: 'f_wl'+u+'_wds_' + i, type: 'text', maxlen: 17, size: 20, value: wds[i] || '00:00:00:00:00:00' },
1735 { name: 'f_wl'+u+'_wds_' + (i + 1), type: 'text', maxlen: 17, size: 20, value: wds[i + 1] || '00:00:00:00:00:00' } ] } );
1738 createFieldTable('', f);
1739 W('</div>');
1742 // for each wlif
1743 </script>
1745 <!-- / / / -->
1747 </td></tr>
1748 <tr><td id='footer' colspan=2>
1749 <span id='footer-msg'></span>
1750 <input type='button' value='Save' id='save-button' onclick='save()'>
1751 <input type='button' value='Cancel' id='cancel-button' onclick='reloadPage();'>
1752 </td></tr>
1753 </table>
1754 </form>
1755 <script type='text/javascript'>earlyInit()</script>
1756 <div style='height:100px'></div>
1757 </body>
1758 </html>