Remove limitation about 22 bits netmask.
[tomato.git] / release / src / router / www / basic-network.asp
blob1e3dd42bdbe38ea1b0035caadd4067f77cd9e9b8
1 <!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0//EN'>
2 <!--
3 Tomato GUI
4 Copyright (C) 2006-2010 Jonathan Zarate
5 http://www.polarcloud.com/tomato/
7 For use with Tomato Firmware only.
8 No part of this file may be used without permission.
9 -->
10 <html>
11 <head>
12 <meta http-equiv='content-type' content='text/html;charset=utf-8'>
13 <meta name='robots' content='noindex,nofollow'>
14 <title>[<% ident(); %>] Basic: Network</title>
15 <link rel='stylesheet' type='text/css' href='tomato.css'>
16 <% css(); %>
17 <script type='text/javascript' src='tomato.js'></script>
19 <!-- / / / -->
21 <style type='text/css'>
22 #lan-grid .co1,
23 #lan-grid .co2,
24 #lan-grid .co3,
25 #lan-grid .co4,
26 #lan-grid .co5,
27 #lan-grid .co6,
28 #lan-grid .co7 {
29 text-align: center;
32 #lan-grid .centered {
33 text-align: center;
36 #spin {
37 visibility: hidden;
38 vertical-align: middle;
40 </style>
42 <script type='text/javascript' src='debug.js'></script>
44 <script type='text/javascript' src='md5.js'></script>
45 <script type='text/javascript' src='wireless.jsx?_http_id=<% nv(http_id); %>'></script>
46 <script type='text/javascript' src='interfaces.js'></script>
47 <script type='text/javascript'>
49 // <% 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,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,ppp_mlppp,modem_ipaddr,cstats_enable"); %>
51 /* VLAN-BEGIN */
52 var lg = new TomatoGrid();
53 lg.setup = function() {
54 this.init('lan-grid', '', 4, [
55 { type: 'select', options: [[0, '0'],[1, '1'],[2, '2'],[3, '3']], prefix: '<div class="centered">', suffix: '</div>' },
56 { type: 'checkbox', prefix: '<div class="centered">', suffix: '</div>' },
57 { type: 'text', maxlen: 15, size: 17 },
58 { type: 'text', maxlen: 15, size: 17 },
59 { type: 'checkbox', prefix: '<div class="centered">', suffix: '</div>' },
60 { multi: [ { type: 'text', maxlen: 15, size: 17}, { type: 'text', maxlen: 15, size: 17 } ] },
61 { type: 'text', maxlen: 6, size: 8 }] );
62 this.headerSet(['Bridge', 'STP', 'IP Address', 'Netmask', 'DHCP', 'IP&nbsp;Range&nbsp;<i>(first/last)</i>', 'Lease&nbsp;Time&nbsp;<i>(mins)</i>']);
64 var numBridges = 0;
65 for (var i = 0 ; i <= MAX_BRIDGE_ID ; i++) {
66 var j = (i == 0) ? '' : i.toString();
67 if (nvram['lan' + j + '_ifname'].length > 0) {
68 if ((!fixIP(nvram['dhcpd' + j + '_startip'])) || (!fixIP(nvram['dhcpd' + j + '_endip']))) {
69 if ((fixIP(nvram['lan' + j + '_ipaddr'])) && (fixIP(nvram['lan' + j + '_netmask'])) && (nvram['dhcp' + j + '_start'] != '')) {
70 var n = getNetworkAddress(nvram['lan' + j + '_ipaddr'], nvram['lan' + j + '_netmask']);
71 nvram['dhcpd' + j + '_startip'] = getAddress(('0.0.0.' + nvram['dhcp' + j + '_start'] * 1), n);
72 nvram['dhcpd' + j + '_endip'] = getAddress(('0.0.0.' + ((nvram['dhcp' + j + '_start'] * 1) + (nvram['dhcp' + j + '_num'] *1) - 1)), n);
75 lg.insertData(-1, [
76 i.toString(),
77 nvram['lan' + j + '_stp'],
78 nvram['lan' + j + '_ipaddr'],
79 nvram['lan' + j + '_netmask'],
80 (nvram['lan' + j + '_proto'] == 'dhcp') ? '1' : '0',
81 nvram['dhcpd' + j + '_startip'],
82 nvram['dhcpd' + j + '_endip'],
83 (nvram['lan' + j + '_proto'] == 'dhcp') ? (((nvram['dhcp' + j + '_lease'])*1 == 0) ? '1440' : (nvram['dhcp' + j + '_lease']).toString()) : ''
84 ] ) ;
85 numBridges++;
88 lg.canDelete = false;
89 lg.sort(0);
90 elem.removeClass(lg.header.cells[lg.sortColumn], 'sortasc', 'sortdes');
91 lg.showNewEditor();
92 lg.resetNewEditor();
95 lg.dataToView = function(data) {
96 return ['br' + data[0],
97 (data[1].toString() == '1') ? '<small><i>Enabled</i></small>' : '<small><i>Disabled</i></small>',
98 data[2],
99 data[3],
100 (data[4].toString() == '1') ? '<small><i>Enabled</i></small>' : '<small><i>Disabled</i></small>',
101 (data[5].toString() + ((numberOfBitsOnNetMask(data[3])>=24) ? (' - ' + data[6].split('.').splice(3, 1).toString()) : ('<br>' + data[6].toString()) )),
102 (((data[7] != null) && (data[7] != '')) ? data[7] : '') ];
105 lg.dataToFieldValues = function (data) {
106 return [data[0],
107 (data[1] != 0) ? 'checked' : '',
108 data[2].toString(),
109 data[3].toString(),
110 (data[4].toString() == '1') ? 'checked' : '',
111 data[5].toString(),
112 data[6].toString(),
113 data[7].toString() ];
116 lg.fieldValuesToData = function(row) {
117 var f = fields.getAll(row);
118 return [f[0].value,
119 f[1].checked ? 1 : 0,
120 f[2].value,
121 f[3].value,
122 f[4].checked ? 1 : 0,
123 f[5].value,
124 f[6].value,
125 f[7].value ];
128 lg.resetNewEditor = function() {
129 var f = fields.getAll(this.newEditor);
130 f[0].selectedIndex=0;
131 var t = MAX_BRIDGE_ID;
132 while((this.countBridge(f[0].selectedIndex) > 0) && (t > 0)) {
133 f[0].selectedIndex = (f[0].selectedIndex%(MAX_BRIDGE_ID))+1;
134 t--;
136 for(var j=0; j<= MAX_BRIDGE_ID ; j++) {
137 f[0].options[j].disabled = (this.countBridge(j) > 0);
139 f[1].checked = 0;
140 f[2].value = '';
141 f[3].value = '';
142 f[5].value = '';
143 f[6].value = '';
144 f[7].value = '';
145 f[4].checked = 0;
146 f[4].disabled = 1;
147 f[5].disabled = 1;
148 f[6].disabled = 1;
149 f[7].disabled = 1;
150 ferror.clearAll(fields.getAll(this.newEditor));
153 lg.onCancel = function() {
154 this.removeEditor();
155 this.showSource();
156 this.disableNewEditor(false);
158 this.resetNewEditor();
161 lg.onAdd = function() {
162 var data;
164 this.moving = null;
165 this.rpHide();
167 if (!this.verifyFields(this.newEditor, false)) return;
169 data = this.fieldValuesToData(this.newEditor);
170 this.insertData(-1, data);
172 this.disableNewEditor(false);
173 this.resetNewEditor();
175 this.resort();
178 lg.onOK = function() {
179 var i, data, view;
181 if (!this.verifyFields(this.editor, false)) return;
183 data = this.fieldValuesToData(this.editor);
184 view = this.dataToView(data);
186 this.source.setRowData(data);
187 for (i = 0; i < this.source.cells.length; ++i) {
188 this.source.cells[i].innerHTML = view[i];
191 this.removeEditor();
192 this.showSource();
193 this.disableNewEditor(false);
195 this.resort();
196 this.resetNewEditor();
199 lg.onDelete = function() {
200 this.removeEditor();
201 elem.remove(this.source);
202 this.source = null;
203 this.disableNewEditor(false);
205 this.resetNewEditor();
208 lg.countElem = function(f, v) {
209 var data = this.getAllData();
210 var total = 0;
211 for (var i = 0; i < data.length; ++i) {
212 total += (data[i][f] == v) ? 1 : 0;
214 return total;
217 lg.countBridge = function (v) {
218 return this.countElem(0,v);
221 lg.countOverlappingNetworks = function (ip) {
222 var data = this.getAllData();
223 var total = 0;
224 for (var i = 0; i < data.length; ++i) {
225 var net = getNetworkAddress(data[i][2], data[i][3]);
226 var brd = getBroadcastAddress(net, data[i][3]);
227 total += ((aton(ip) <= aton(brd)) && (aton(ip) >= aton(net))) ? 1 : 0;
229 return total;
232 lg.verifyFields = function(row, quiet) {
233 var ok=1;
234 var f;
236 f = fields.getAll(row);
238 for(var j=0; j<= MAX_BRIDGE_ID ; j++) {
239 f[0].options[j].disabled = (this.countBridge(j) > 0);
242 if(this.countBridge(f[0].selectedIndex) > 0) {
243 ferror.set(f[0], 'Cannot add another entry for bridge br' + f[0].selectedIndex, quiet);
244 ok = 0;
245 } else {
246 ferror.clear(f[0]);
248 // valid IP address?
249 if(!v_ip(f[2], quiet || !ok))
250 ok = 0;
251 // if we have a properly defined IP address - 0.0.0.0 is NOT a valid IP address for our intents/purposes!
252 if ((f[2].value != '') && (f[2].value != '0.0.0.0')) {
253 // allow DHCP to be enabled
254 f[4].disabled = 0;
255 // validate netmask
256 if(!v_netmask(f[3], quiet || !ok)) {
257 return 0;
258 } else {
260 // should be 22 bits or smaller network
261 if ((numberOfBitsOnNetMask(f[3].value) < 22) && (nvram.cstats_enable == '1' )) {
262 if (!confirm("Netmask should have at least 22 bits (255.255.252.0). You may continue anyway but remember - you were warned!")) return;
263 } else {
264 ferror.clear(f[3]);
267 if(f[2].value == getNetworkAddress(f[2].value, f[3].value)) {
268 var s = 'Invalid IP address or subnet mask (the address of the network cannot be used)';
269 ferror.set(f[2], s, quiet);
270 ferror.set(f[3], s, quiet);
271 return 0;
272 } else
273 if(f[2].value == getBroadcastAddress(getNetworkAddress(f[2].value, f[3].value), f[3].value)) {
274 var s = 'Invalid IP address or subnet mask (the broadcast address cannot be used)';
275 ferror.set(f[2], s, quiet);
276 ferror.set(f[3], s, quiet);
277 return 0;
278 } else
279 if (this.countOverlappingNetworks(f[2].value) > 0) {
280 var s = 'Invalid IP address or subnet mask (conflicts/overlaps with another LAN bridge)';
281 ferror.set(f[2], s, quiet);
282 ferror.set(f[3], s, quiet);
283 return 0;
284 } else {
285 ferror.clear(f[2]);
286 ferror.clear(f[3]);
288 } else {
289 f[4].checked = 0;
290 f[4].disabled = 1;
292 // dhcp enabled?
293 if( (f[4].checked) && (v_ip(f[2], 1)) && (v_netmask(f[3],1)) ) {
294 f[5].disabled = 0;
295 f[6].disabled = 0;
296 f[7].disabled = 0;
297 // first/last IP still unset?
298 if (f[5].value == '') {
299 var l;
300 var m = aton(f[2].value) & aton(f[3].value);
301 var o = (m) ^ (~ aton(f[3].value))
302 var n = o - m;
303 do {
304 if (--n < 0) {
305 f[5].value = '';
306 return;
308 m++;
309 } while (((l = fixIP(ntoa(m), 1)) == null) || (l == f[2].value) );
310 f[5].value = l;
312 if (f[6].value == '') {
313 var l;
314 var m = aton(f[2].value) & aton(f[3].value);
315 var o = (m) ^ (~ aton(f[3].value));
316 var n = o - m;
317 do {
318 if (--n < 0) {
319 f[6].value = '';
320 return;
322 o--;
323 } while (((l = fixIP(ntoa(o), 1)) == null) || (l == f[2].value) );
324 f[6].value = l;
326 // first IP valid?
327 if ((getNetworkAddress(f[5].value, f[3].value) != getNetworkAddress(f[2].value, f[3].value)) ||
328 (f[5].value == getBroadcastAddress(getNetworkAddress(f[2].value, f[3].value), f[3].value)) ||
329 (f[5].value == getNetworkAddress(f[2].value, f[3].value)) ||
330 (f[2].value == f[5].value)) {
331 ferror.set(f[5], 'Invalid first IP address or subnet mask', quiet || !ok);
332 return 0;
333 } else {
334 ferror.clear(f[5]);
336 // last IP valid?
337 if ((getNetworkAddress(f[6].value, f[3].value) != getNetworkAddress(f[2].value, f[3].value)) ||
338 (f[6].value == getBroadcastAddress(getNetworkAddress(f[2].value, f[3].value), f[3].value)) ||
339 (f[6].value == getNetworkAddress(f[2].value, f[3].value)) ||
340 (f[2].value == f[6].value)) {
341 ferror.set(f[6], 'Invalid last IP address or subnet mask', quiet || !ok);
342 return 0;
343 } else {
344 ferror.clear(f[6]);
346 // validate range, swap first/last IP if needed
347 if (aton(f[6].value) < aton(f[5].value)) {
348 var t = f[5].value;
349 f[5].value = f[6].value;
350 f[6].value = t;
352 // lease time
353 if (parseInt(f[7].value*1) == 0)
354 f[7].value = 1440; // from nvram/defaults.c
355 if(!v_mins(f[7], quiet || !ok, 1, 10080))
356 ok = 0;
357 } else {
358 f[5].disabled = 1;
359 f[6].disabled = 1;
360 f[7].disabled = 1;
361 ferror.clear(f[5]);
362 ferror.clear(f[6]);
363 ferror.clear(f[7]);
365 return ok;
367 /* VLAN-END */
369 W('<style type=\'text/css\'>');
370 for (var u = 0; u < wl_ifaces.length; ++u) {
371 W('#spin'+wl_unit(u)+', ');
373 W('#spin {');
374 W(' visibility: hidden;');
375 W(' vertical-align: middle;');
376 W('}');
377 W('</style>');
379 var xob = null;
380 var refresher = [];
381 var nphy = features('11n');
383 /* NOVLAN-BEGIN */
384 if ((!fixIP(nvram.dhcpd_startip)) || (!fixIP(nvram.dhcpd_endip))) {
385 var x = nvram.lan_ipaddr.split('.').splice(0, 3).join('.') + '.';
386 nvram.dhcpd_startip = x + nvram.dhcp_start;
387 nvram.dhcpd_endip = x + ((nvram.dhcp_start * 1) + (nvram.dhcp_num * 1) - 1);
389 /* NOVLAN-END */
391 var ghz = [];
392 var bands = [];
393 var nm_loaded = [], ch_loaded = [], max_channel = [];
395 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
396 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
397 if (wl_sunit(uidx)<0) {
398 var b;
399 b = [];
400 for (var i = 0; i < wl_bands[uidx].length; ++i) {
401 b.push([wl_bands[uidx][i] + '', (wl_bands[uidx][i] == '1') ? '5 GHz' : '2.4 GHz']);
403 bands.push(b);
405 b = [];
406 ghz.push(b);
408 nm_loaded.push(0);
409 ch_loaded.push(0);
410 max_channel.push(0);
411 refresher.push(null);
415 function selectedBand(uidx)
417 if (bands[uidx].length > 1) {
418 var e = E('_f_wl'+u+'_nband');
419 return (e.value + '' == '' ? eval('nvram.wl'+u+'_nband') : e.value);
420 } else if (bands[uidx].length > 0) {
421 return bands[uidx][0][0] || '0';
422 } else {
423 return '0';
427 function refreshNetModes(uidx)
429 var e, i, buf, val;
431 if (uidx >= wl_ifaces.length) return;
432 var u = wl_unit(uidx);
434 var m = [['mixed','Auto']];
435 if (selectedBand(uidx) == '1') {
436 m.push(['a-only','A Only']);
437 if (nphy) {
438 m.push(['n-only','N Only']);
441 else {
442 m.push(['b-only','B Only']);
443 m.push(['g-only','G Only']);
444 if (nphy) {
445 m.push(['bg-mixed','B/G Mixed']);
446 m.push(['n-only','N Only']);
450 e = E('_wl'+u+'_net_mode');
451 buf = '';
452 val = (!nm_loaded[uidx] || (e.value + '' == '')) ? eval('nvram.wl'+u+'_net_mode') : e.value;
453 if (val == 'disabled') val = 'mixed';
454 for (i = 0; i < m.length; ++i)
455 buf += '<option value="' + m[i][0] + '"' + ((m[i][0] == val) ? ' selected' : '') + '>' + m[i][1] + '</option>';
457 e = E('__wl'+u+'_net_mode');
458 buf = '<select name="wl'+u+'_net_mode" onchange="verifyFields(this, 1)" id = "_wl'+u+'_net_mode">' + buf + '</select>';
459 elem.setInnerHTML(e, buf);
460 nm_loaded[uidx] = 1;
463 function refreshChannels(uidx)
465 if (refresher[uidx] != null) return;
466 if (u >= wl_ifaces.length) return;
467 var u = wl_unit(uidx);
469 refresher[uidx] = new XmlHttp();
470 refresher[uidx].onCompleted = function(text, xml) {
471 try {
472 var e, i, buf, val;
474 var wl_channels = [];
475 eval(text);
477 ghz[uidx] = [];
478 max_channel[uidx] = 0;
479 for (i = 0; i < wl_channels.length; ++i) {
480 ghz[uidx].push([wl_channels[i][0] + '',
481 (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']);
482 max_channel[uidx] = wl_channels[i][0] * 1;
485 e = E('_wl'+u+'_channel');
486 buf = '';
487 val = (!ch_loaded[uidx] || (e.value + '' == '')) ? eval('nvram.wl'+u+'_channel') : e.value;
488 for (i = 0; i < ghz[uidx].length; ++i)
489 buf += '<option value="' + ghz[uidx][i][0] + '"' + ((ghz[uidx][i][0] == val) ? ' selected' : '') + '>' + ghz[uidx][i][1] + '</option>';
491 e = E('__wl'+u+'_channel');
492 buf = '<select name="wl'+u+'_channel" onchange="verifyFields(this, 1)" id = "_wl'+u+'_channel">' + buf + '</select>';
493 elem.setInnerHTML(e, buf);
494 ch_loaded[uidx] = 1;
496 refresher[uidx] = null;
497 verifyFields(null, 1);
499 catch (x) {
501 refresher[uidx] = null;
504 var bw, sb, e;
506 e = E('_f_wl'+u+'_nctrlsb');
507 sb = (e.value + '' == '' ? eval('nvram.wl'+u+'_nctrlsb') : e.value);
508 e = E('_wl'+u+'_nbw_cap');
509 bw = (e.value + '' == '' ? eval('nvram.wl'+u+'_nbw_cap') : e.value) == '0' ? '20' : '40';
511 refresher[uidx].onError = function(ex) { alert(ex); refresher[uidx] = null; reloadPage(); }
512 refresher[uidx].post('update.cgi', 'exec=wlchannels&arg0=' + u + '&arg1=' + (nphy ? '1' : '0') +
513 '&arg2=' + bw + '&arg3=' + selectedBand(uidx) + '&arg4=' + sb);
516 function spin(x, unit)
518 for (var u = 0; u < wl_ifaces.length; ++u) {
519 E('_f_wl'+wl_unit(u)+'_scan').disabled = x;
521 var e = E('_f_wl'+unit+'_scan');
522 if (x) e.value = 'Scan ' + (wscan.tries + 1);
523 else e.value = 'Scan';
524 E('spin'+unit).style.visibility = x ? 'visible' : 'hidden';
527 function scan()
529 if (xob) return;
531 var unit = wscan.unit;
532 var uidx = wl_uidx(unit);
534 xob = new XmlHttp();
535 xob.onCompleted = function(text, xml) {
536 try {
537 var i;
539 wlscandata = [];
540 eval(text);
542 for (i = 0; i < wlscandata.length; ++i) {
543 var data = wlscandata[i];
544 var ch = data[2];
545 var mac = data[0];
547 if (!wscan.inuse[ch]) {
548 wscan.inuse[ch] = {
549 count: 0,
550 rssi: -999,
551 ssid: ''
555 if (!wscan.seen[mac]) {
556 wscan.seen[mac] = 1;
557 ++wscan.inuse[ch].count;
560 if (data[4] > wscan.inuse[ch].rssi) {
561 wscan.inuse[ch].rssi = data[4];
562 wscan.inuse[ch].ssid = data[1];
565 var e = E('_wl'+unit+'_channel');
566 for (i = 1; i < ghz[uidx].length; ++i) {
567 var s = ghz[uidx][i][1];
568 var u = wscan.inuse[ghz[uidx][i][0]];
569 if (u) s += ' (' + u.count + ' AP' + (u.count == 1 ? '' : 's') + ' / strongest: "' + escapeHTML(ellipsis(u.ssid, 15)) + '" ' + u.rssi + ' dBm)';
570 e.options[i].innerHTML = s;
572 e.style.width = '400px';
574 xob = null;
576 if (wscan.tries < 4) {
577 ++wscan.tries;
578 setTimeout(scan, 1000);
579 return;
582 catch (x) {
584 spin(0, unit);
586 xob.onError = function(x) {
587 alert('error: ' + x);
588 spin(0, unit);
589 xob = null;
592 spin(1, unit);
593 xob.post('update.cgi', 'exec=wlscan&arg0='+unit);
596 function scanButton(u)
598 if (xob) return;
600 wscan = {
601 unit: u,
602 seen: [],
603 inuse: [],
604 tries: 0
607 scan();
610 function joinAddr(a) {
611 var r, i, s;
613 r = [];
614 for (i = 0; i < a.length; ++i) {
615 s = a[i];
616 if ((s != '00:00:00:00:00:00') && (s != '0.0.0.0')) r.push(s);
618 return r.join(' ');
621 function random_x(max)
623 var c = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
624 var s = '';
625 while (max-- > 0) s += c.substr(Math.floor(c.length * Math.random()), 1);
626 return s;
629 function random_psk(id)
631 var e = E(id);
632 e.value = random_x(63);
633 verifyFields(null, 1);
636 function random_wep(u)
638 E('_wl'+u+'_passphrase').value = random_x(16);
639 generate_wep(u);
642 function v_wep(e, quiet)
644 var s = e.value;
646 if (((s.length == 5) || (s.length == 13)) && (s.length == (e.maxLength >> 1))) {
647 // no checking
649 else {
650 s = s.toUpperCase().replace(/[^0-9A-F]/g, '');
651 if (s.length != e.maxLength) {
652 ferror.set(e, 'Invalid WEP key. Expecting ' + e.maxLength + ' hex or ' + (e.maxLength >> 1) + ' ASCII characters.', quiet);
653 return 0;
657 e.value = s;
658 ferror.clear(e);
659 return 1;
662 // compatible w/ Linksys' and Netgear's (key 1) method for 128-bits
663 function generate_wep(u)
665 function _wepgen(pass, i)
667 while (pass.length < 64) pass += pass;
668 return hex_md5(pass.substr(0, 64)).substr(i, (E('_wl'+u+'_wep_bit').value == 128) ? 26 : 10);
671 var e = E('_wl'+u+'_passphrase');
672 var pass = e.value;
673 if (!v_length(e, false, 3)) return;
674 E('_wl'+u+'_key1').value = _wepgen(pass, 0);
675 pass += '#$%';
676 E('_wl'+u+'_key2').value = _wepgen(pass, 2);
677 pass += '!@#';
678 E('_wl'+u+'_key3').value = _wepgen(pass, 4);
679 pass += '%&^';
680 E('_wl'+u+'_key4').value = _wepgen(pass, 6);
681 verifyFields(null, 1);
684 function verifyFields(focused, quiet)
686 var i;
687 var ok = 1;
688 var a, b, c, d, e;
689 var u, uidx;
690 var wmode, sm2;
692 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
693 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
694 if (wl_sunit(uidx)<0) {
695 u = wl_unit(uidx);
696 if (focused == E('_f_wl'+u+'_nband')) {
697 refreshNetModes(uidx);
698 refreshChannels(uidx);
700 else if (focused == E('_f_wl'+u+'_nctrlsb') || focused == E('_wl'+u+'_nbw_cap')) {
701 refreshChannels(uidx);
706 // --- visibility ---
708 var vis = {
709 _wan_proto: 1,
710 _ppp_username: 1,
711 _ppp_passwd: 1,
712 _ppp_service: 1,
713 _ppp_custom: 1,
714 _l2tp_server_ip: 1,
715 _wan_ipaddr: 1,
716 _wan_netmask: 1,
717 _wan_gateway: 1,
718 _pptp_server_ip: 1,
719 _f_pptp_dhcp: 1,
720 _ppp_demand: 1,
721 _ppp_idletime: 1,
722 _ppp_redialperiod: 1,
723 _mtu_enable: 1,
724 _f_wan_mtu: 1,
725 _f_wan_islan: 0,
726 _f_ppp_mlppp: 1,
727 _modem_ipaddr: 1,
729 /* NOVLAN-BEGIN */
730 _dhcp_lease: 1,
731 _f_dhcpd_enable: 1,
732 _dhcpd_startip: 1,
733 _dhcpd_endip: 1,
734 _lan_ipaddr: 1,
735 _lan_netmask: 1,
736 /* NOVLAN-END */
737 _f_dns_1: 1,
738 _f_dns_2: 1,
739 _f_dns_3: 1,
740 _lan_gateway: 1,
741 _wan_wins: 1
744 var wl_vis = [];
745 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
746 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
747 if (wl_sunit(uidx)<0) {
748 a = {
749 _f_wl_radio: 1,
750 _f_wl_mode: 1,
751 _f_wl_nband: (bands[uidx].length > 1) ? 1 : 0,
752 _wl_net_mode: 1,
753 _wl_ssid: 1,
754 _f_wl_bcast: 1,
755 _wl_channel: 1,
756 _wl_nbw_cap: nphy ? 1 : 0,
757 _f_wl_nctrlsb: nphy ? 1 : 0,
758 _f_wl_scan: 1,
760 _wl_security_mode: 1,
761 _wl_crypto: 1,
762 _wl_wpa_psk: 1,
763 _f_wl_psk_random1: 1,
764 _f_wl_psk_random2: 1,
765 _wl_wpa_gtk_rekey: 1,
766 _wl_radius_key: 1,
767 _wl_radius_ipaddr: 1,
768 _wl_radius_port: 1,
769 _wl_wep_bit: 1,
770 _wl_passphrase: 1,
771 _f_wl_wep_gen: 1,
772 _f_wl_wep_random: 1,
773 _wl_key1: 1,
774 _wl_key2: 1,
775 _wl_key3: 1,
776 _wl_key4: 1,
778 _f_wl_lazywds: 1,
779 _f_wl_wds_0: 1
781 wl_vis.push(a);
785 var wan = E('_wan_proto').value;
787 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
788 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
789 if (wl_sunit(uidx)<0) {
790 wmode = E('_f_wl'+wl_unit(uidx)+'_mode').value;
792 if (wmode == 'wet') {
793 wan = 'disabled';
794 vis._wan_proto = 0;
795 /* NOVLAN-BEGIN */
796 vis._f_dhcpd_enable = 0;
797 vis._dhcp_lease = 0;
798 /* NOVLAN-END */
801 if ((wan == 'disabled') || (wmode == 'sta') || (wmode == 'wet')) {
802 vis._f_wan_islan = 1;
807 switch (wan) {
808 case 'disabled':
809 vis._ppp_username = 0;
810 vis._ppp_service = 0;
811 vis._ppp_custom = 0;
812 vis._l2tp_server_ip = 0;
813 vis._wan_ipaddr = 0;
814 vis._wan_netmask = 0;
815 vis._wan_gateway = 0;
816 vis._pptp_server_ip = 0;
817 vis._f_pptp_dhcp = 0;
818 vis._ppp_demand = 0;
819 vis._mtu_enable = 0;
820 vis._f_wan_mtu = 0;
821 vis._f_ppp_mlppp = 0;
822 vis._modem_ipaddr = 0;
823 break;
824 case 'dhcp':
825 vis._l2tp_server_ip = 0;
826 vis._ppp_demand = 0;
827 vis._ppp_service = 0;
828 vis._ppp_username = 0;
829 vis._ppp_custom = 0;
830 vis._pptp_server_ip = 0;
831 vis._f_pptp_dhcp = 0;
832 vis._wan_gateway = 0;
833 vis._wan_ipaddr = 0;
834 vis._wan_netmask = 0;
835 vis._f_ppp_mlppp = 0;
836 vis._modem_ipaddr = 1;
838 vis._lan_gateway = 0;
839 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;
847 vis._modem_ipaddr = 1;
849 vis._lan_gateway = 0;
850 break;
851 case 'static':
852 vis._l2tp_server_ip = 0;
853 vis._ppp_demand = 0;
854 vis._ppp_service = 0;
855 vis._ppp_username = 0;
856 vis._ppp_custom = 0;
857 vis._pptp_server_ip = 0;
858 vis._f_pptp_dhcp = 0;
859 vis._f_ppp_mlppp = 0;
860 vis._modem_ipaddr = 1;
862 vis._lan_gateway = 0;
863 break;
864 case 'pptp':
865 vis._l2tp_server_ip = 0;
866 vis._ppp_service = 0;
867 vis._wan_gateway = (!E('_f_pptp_dhcp').checked);
868 vis._wan_ipaddr = (!E('_f_pptp_dhcp').checked);
869 vis._modem_ipaddr = 0;
871 vis._lan_gateway = 0;
872 break;
873 case 'l2tp':
874 vis._pptp_server_ip = 0;
875 vis._ppp_service = 0;
876 vis._wan_gateway = (!E('_f_pptp_dhcp').checked);
877 vis._wan_ipaddr = (!E('_f_pptp_dhcp').checked);
878 vis._modem_ipaddr = 0;
880 vis._lan_gateway = 0;
881 break;
884 vis._ppp_idletime = (E('_ppp_demand').value == 1) && vis._ppp_demand
885 vis._ppp_redialperiod = !vis._ppp_idletime && vis._ppp_demand;
887 if (vis._mtu_enable) {
888 if (E('_mtu_enable').value == 0) {
889 vis._f_wan_mtu = 2;
890 a = E('_f_wan_mtu');
891 switch (E('_wan_proto').value) {
892 case 'pppoe':
893 a.value = 1492;
894 break;
895 case 'pptp':
896 case 'l2tp':
897 a.value = 1460;
898 break;
899 default:
900 a.value = 1500;
901 break;
906 /* NOVLAN-BEGIN */
907 if (!E('_f_dhcpd_enable').checked) vis._dhcp_lease = 0;
908 /* NOVLAN-END */
910 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
911 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
912 if (wl_sunit(uidx)<0) {
913 u = wl_unit(uidx);
914 wmode = E('_f_wl'+u+'_mode').value;
916 if (!E('_f_wl'+u+'_radio').checked) {
917 for (a in wl_vis[uidx]) {
918 wl_vis[uidx][a] = 2;
920 wl_vis[uidx]._f_wl_radio = 1;
921 wl_vis[uidx]._wl_nbw_cap = nphy ? 2 : 0;
922 wl_vis[uidx]._f_wl_nband = (bands[uidx].length > 1) ? 2 : 0;
925 switch (wmode) {
926 case 'apwds':
927 case 'wds':
928 break;
929 case 'wet':
930 case 'sta':
931 wl_vis[uidx]._f_wl_bcast = 0;
932 wl_vis[uidx]._wl_channel = 0;
933 wl_vis[uidx]._wl_nbw_cap = 0;
934 vis._modem_ipaddr = 0;
935 default:
936 wl_vis[uidx]._f_wl_lazywds = 0;
937 wl_vis[uidx]._f_wl_wds_0 = 0;
938 break;
941 sm2 = E('_wl'+u+'_security_mode').value;
942 switch (sm2) {
943 case 'disabled':
944 wl_vis[uidx]._wl_crypto = 0;
945 wl_vis[uidx]._wl_wep_bit = 0;
946 wl_vis[uidx]._wl_wpa_psk = 0;
947 wl_vis[uidx]._wl_radius_key = 0;
948 wl_vis[uidx]._wl_radius_ipaddr = 0;
949 wl_vis[uidx]._wl_wpa_gtk_rekey = 0;
950 break;
951 case 'wep':
952 wl_vis[uidx]._wl_crypto = 0;
953 wl_vis[uidx]._wl_wpa_psk = 0;
954 wl_vis[uidx]._wl_radius_key = 0;
955 wl_vis[uidx]._wl_radius_ipaddr = 0;
956 wl_vis[uidx]._wl_wpa_gtk_rekey = 0;
957 break;
958 case 'radius':
959 wl_vis[uidx]._wl_crypto = 0;
960 wl_vis[uidx]._wl_wpa_psk = 0;
961 break;
962 default: // wpa*
963 wl_vis[uidx]._wl_wep_bit = 0;
964 if (sm2.indexOf('personal') != -1) {
965 wl_vis[uidx]._wl_radius_key = 0;
966 wl_vis[uidx]._wl_radius_ipaddr = 0;
968 else {
969 wl_vis[uidx]._wl_wpa_psk = 0;
971 break;
974 if ((E('_f_wl'+u+'_lazywds').value == 1) && (wl_vis[uidx]._f_wl_wds_0 == 1)) {
975 wl_vis[uidx]._f_wl_wds_0 = 2;
978 if (wl_vis[uidx]._wl_nbw_cap != 0) {
979 switch (E('_wl'+u+'_net_mode').value) {
980 case 'b-only':
981 case 'g-only':
982 case 'a-only':
983 case 'bg-mixed':
984 wl_vis[uidx]._wl_nbw_cap = 2;
985 if (E('_wl'+u+'_nbw_cap').value != '0') {
986 E('_wl'+u+'_nbw_cap').value = 0;
987 refreshChannels(uidx);
989 break;
991 // avoid Enterprise-TKIP with 40MHz
992 if ((sm2 == 'wpa_enterprise') && (E('_wl'+u+'_crypto').value == 'tkip')) {
993 wl_vis[uidx]._wl_nbw_cap = 2;
994 if (E('_wl'+u+'_nbw_cap').value != '0') {
995 E('_wl'+u+'_nbw_cap').value = 0;
996 refreshChannels(uidx);
1001 wl_vis[uidx]._f_wl_nctrlsb = (E('_wl'+u+'_nbw_cap').value == 0) ? 0 : wl_vis[uidx]._wl_nbw_cap;
1003 /* REMOVE-BEGIN
1004 This is ugly...
1005 Special case - 2.4GHz band, currently running in B/G-only mode,
1006 with N/Auto and 40MHz selected in the GUI.
1007 Channel list is not filtered in this case by the wl driver,
1008 and includes all channels available with 20MHz channel width.
1009 REMOVE-END */
1010 b = selectedBand(uidx);
1011 if (wl_vis[uidx]._wl_channel == 1 && wl_vis[uidx]._f_wl_nctrlsb != 0 &&
1012 ((b == '2') || (wl_vis[uidx]._f_wl_nband == 0 && b == '0'))) {
1013 switch (eval('nvram.wl'+u+'_net_mode')) {
1014 case 'b-only':
1015 case 'g-only':
1016 case 'bg-mixed':
1017 i = E('_wl'+u+'_channel').value * 1;
1018 if (i > 0 && i < 5) {
1019 E('_f_wl'+u+'_nctrlsb').value = 'lower';
1020 wl_vis[uidx]._f_wl_nctrlsb = 2;
1022 else if (i > max_channel[uidx] - 4) {
1023 E('_f_wl'+u+'_nctrlsb').value = 'upper';
1024 wl_vis[uidx]._f_wl_nctrlsb = 2;
1026 break;
1030 wl_vis[uidx]._f_wl_scan = wl_vis[uidx]._wl_channel;
1031 wl_vis[uidx]._f_wl_psk_random1 = wl_vis[uidx]._wl_wpa_psk;
1032 wl_vis[uidx]._f_wl_psk_random2 = wl_vis[uidx]._wl_radius_key;
1033 wl_vis[uidx]._wl_radius_port = wl_vis[uidx]._wl_radius_ipaddr;
1034 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;
1036 for (i = 1; i < 10; ++i) {
1037 wl_vis[uidx]['_f_wl_wds_' + i] = wl_vis[uidx]._f_wl_wds_0;
1040 } // for each wl_iface
1042 vis._ppp_passwd = vis._ppp_username;
1043 /* NOVLAN-BEGIN */
1044 vis._dhcpd_startip = vis._dhcpd_endip = vis._wan_wins = vis._dhcp_lease;
1045 /* NOVLAN-END */
1047 for (a in vis) {
1048 b = E(a);
1049 c = vis[a];
1050 /* REMOVE-BEGIN
1051 // if (b != null)
1052 REMOVE-END */
1053 b.disabled = (c != 1);
1054 PR(b).style.display = c ? '' : 'none';
1057 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1058 if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1059 for (a in wl_vis[uidx]) {
1060 i = 3;
1061 if (a.substr(0, 6) == '_f_wl_') i = 5;
1062 b = E(a.substr(0, i) + wl_unit(uidx) + a.substr(i, a.length));
1063 c = wl_vis[uidx][a];
1064 b.disabled = (c != 1);
1065 PR(b).style.display = c ? '' : 'none';
1070 // --- verify ---
1072 ferror.clear('_wan_proto');
1074 var wlclnt = 0;
1075 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1076 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1077 if (wl_sunit(uidx)<0) {
1078 u = wl_unit(uidx);
1079 wmode = E('_f_wl'+u+'_mode').value;
1080 sm2 = E('_wl'+u+'_security_mode').value;
1082 /* REMOVE-BEGIN
1083 if ((wl_vis[uidx]._f_wl_mode == 1) && (wmode != 'ap') && (sm2.substr(0, 4) == 'wpa2')) {
1084 ferror.set('_wl'+u+'_security_mode', 'WPA2 is supported only in AP mode.', quiet || !ok);
1085 ok = 0;
1087 else ferror.clear('_wl'+u+'_security_mode');
1088 REMOVE-END */
1090 // --- N standard does not support WPA+TKIP ---
1091 a = E('_wl'+u+'_crypto');
1092 switch (E('_wl'+u+'_net_mode').value) {
1093 case 'mixed':
1094 case 'n-only':
1095 if (nphy && (a.value == 'tkip') && (sm2.indexOf('wpa') != -1)) {
1096 ferror.set(a, 'TKIP encryption is not supported with WPA / WPA2 in N mode.', quiet || !ok);
1097 ok = 0;
1099 else ferror.clear(a);
1100 break;
1103 a = E('_wl'+u+'_net_mode');
1104 ferror.clear(a);
1105 b = E('_f_wl'+u+'_mode');
1106 ferror.clear(b);
1107 if ((wmode == 'sta') || (wmode == 'wet')) {
1108 ++wlclnt;
1109 if (wlclnt > 1) {
1110 ferror.set(b, 'Only one wireless interface can be configured in client mode.', quiet || !ok);
1111 ok = 0;
1113 else if (a.value == 'n-only') {
1114 ferror.set(a, 'N-only is not supported in wireless client modes, use Auto.', quiet || !ok);
1115 ok = 0;
1119 a = E('_wl'+u+'_wpa_psk');
1120 ferror.clear(a);
1121 if (wl_vis[uidx]._wl_wpa_psk == 1) {
1122 if ((a.value.length < 8) || ((a.value.length == 64) && (a.value.search(/[^0-9A-Fa-f]/) != -1))) {
1123 ferror.set('_wl'+u+'_wpa_psk', 'Invalid pre-shared key. Please enter at least 8 characters or 64 hexadecimal digits.', quiet || !ok);
1124 ok = 0;
1128 // wl channel
1129 if (((wmode == 'wds') || (wmode == 'apwds')) && (wl_vis[uidx]._wl_channel == 1) && (E('_wl'+u+'_channel').value == '0')) {
1130 ferror.set('_wl'+u+'_channel', 'Fixed wireless channel required in WDS mode.', quiet || !ok);
1131 ok = 0;
1133 else ferror.clear('_wl'+u+'_channel');
1135 if (E('_f_wl'+u+'_mode').value == 'sta') {
1136 if ((wan == 'disabled') && (E('_f_wl'+u+'_radio').checked)) {
1137 ferror.set('_wan_proto', 'Wireless Client mode requires a valid WAN setting (usually DHCP).', quiet || !ok);
1138 ok = 0;
1144 // domain name or IP address
1145 a = ['_l2tp_server_ip', '_pptp_server_ip'];
1146 for (i = a.length - 1; i >= 0; --i)
1147 if ((vis[a[i]]) && ((!v_length(a[i], 1, 1)) || ((!v_ip(a[i], 1)) && (!v_domain(a[i], 1))))) {
1148 if (!quiet && ok) ferror.show(a[i]);
1149 ok = 0;
1152 // IP address
1153 /* NOVLAN-BEGIN */
1154 a = ['_wan_gateway','_wan_ipaddr','_lan_ipaddr', '_dhcpd_startip', '_dhcpd_endip'];
1155 /* NOVLAN-END */
1156 /* VLAN-BEGIN */
1157 a = ['_wan_gateway','_wan_ipaddr'];
1158 /* VLAN-END */
1159 for (i = a.length - 1; i >= 0; --i)
1160 if ((vis[a[i]]) && (!v_ip(a[i], quiet || !ok))) ok = 0;
1162 // IP address, blank -> 0.0.0.0
1163 a = ['_f_dns_1', '_f_dns_2', '_f_dns_3','_wan_wins','_lan_gateway', '_modem_ipaddr'];
1164 for (i = a.length - 1; i >= 0; --i)
1165 if ((vis[a[i]]) && (!v_dns(a[i], quiet || !ok))) ok = 0;
1167 // netmask
1168 /* NOVLAN-BEGIN */
1169 a = ['_wan_netmask','_lan_netmask'];
1170 /* NOVLAN-END */
1171 /* VLAN-BEGIN */
1172 a = ['_wan_netmask'];
1173 /* VLAN-END */
1174 for (i = a.length - 1; i >= 0; --i)
1175 if ((vis[a[i]]) && (!v_netmask(a[i], quiet || !ok))) ok = 0;
1177 // range
1178 /* NOVLAN-BEGIN */
1179 a = [['_ppp_idletime', 3, 1440],['_ppp_redialperiod', 1, 86400],['_f_wan_mtu', 576, 1500],
1180 ['_dhcp_lease', 1, 10080]];
1181 /* NOVLAN-END */
1182 /* VLAN-BEGIN */
1183 a = [['_ppp_idletime', 3, 1440],['_ppp_redialperiod', 1, 86400],['_f_wan_mtu', 576, 1500]];
1184 /* VLAN-END */
1185 for (i = a.length - 1; i >= 0; --i) {
1186 v = a[i];
1187 if ((vis[v[0]]) && (!v_range(v[0], quiet || !ok, v[1], v[2]))) ok = 0;
1190 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1191 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1192 if (wl_sunit(uidx)<0) {
1193 u = wl_unit(uidx);
1195 // IP address
1196 a = ['_radius_ipaddr'];
1197 for (i = a.length - 1; i >= 0; --i) {
1198 if ((wl_vis[uidx]['_wl'+a[i]]) && (!v_ip('_wl'+u+a[i], quiet || !ok))) ok = 0;
1201 // range
1202 a = [['_wpa_gtk_rekey', 60, 7200], ['_radius_port', 1, 65535]];
1203 for (i = a.length - 1; i >= 0; --i) {
1204 v = a[i];
1205 if ((wl_vis[uidx]['_wl'+v[0]]) && (!v_range('_wl'+u+v[0], quiet || !ok, v[1], v[2]))) ok = 0;
1208 // length
1209 a = [['_ssid', 1], ['_radius_key', 1]];
1210 for (i = a.length - 1; i >= 0; --i) {
1211 v = a[i];
1212 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;
1215 if (wl_vis[uidx]._wl_key1) {
1216 a = (E('_wl'+u+'_wep_bit').value == 128) ? 26 : 10;
1217 for (i = 1; i <= 4; ++i) {
1218 b = E('_wl'+u+'_key' + i);
1219 b.maxLength = a;
1220 if ((b.value.length > 0) || (E('_f_wl'+u+'_wepidx_' + i).checked)) {
1221 if (!v_wep(b, quiet || !ok)) ok = 0;
1223 else ferror.clear(b);
1227 ferror.clear('_f_wl'+u+'_wds_0');
1228 if (wl_vis[uidx]._f_wl_wds_0 == 1) {
1229 b = 0;
1230 for (i = 0; i < 10; ++i) {
1231 a = E('_f_wl'+u+'_wds_' + i);
1232 if (!v_macz(a, quiet || !ok)) ok = 0;
1233 else if (!isMAC0(a.value)) b = 1;
1235 if (!b) {
1236 ferror.set('_f_wl'+u+'_wds_0', 'WDS MAC address required.', quiet || !ok);
1237 ok = 0;
1243 /* NOVLAN-BEGIN */
1244 a = E('_dhcpd_startip');
1245 b = E('_dhcpd_endip');
1246 ferror.clear(a);
1247 ferror.clear(b);
1249 if ((vis._dhcp_lease) && (!a._error_msg) && (!b._error_msg)) {
1250 c = aton(E('_lan_netmask').value);
1251 d = aton(E('_lan_ipaddr').value) & c;
1252 e = 'Invalid IP address or subnet mask';
1253 if ((aton(a.value) & c) != d) {
1254 ferror.set(a, e, quiet || !ok);
1255 ok = 0;
1257 if ((aton(b.value) & c) != d) {
1258 ferror.set(b, e, quiet || !ok);
1259 ok = 0;
1263 if ((vis._dhcp_lease) && (!a._error_msg) && (!b._error_msg)) {
1264 if (aton(a.value) > aton(b.value)) {
1265 c = a.value;
1266 a.value = b.value;
1267 b.value = c;
1270 elem.setInnerHTML('dhcp_count', '(' + ((aton(b.value) - aton(a.value)) + 1) + ')');
1273 /* REMOVE-BEGIN */
1274 /* TODO: same validation for builds with VLAN-GUI enabled */
1275 /* REMOVE-END */
1276 ferror.clear('_modem_ipaddr');
1277 a = E('_modem_ipaddr');
1278 b = E('_lan_ipaddr');
1279 c = E('_lan_netmask');
1280 if ( vis['_modem_ipaddr'] && !(a._error_msg || b._error_msg || c._error_msg) && a.value != "0.0.0.0" ) {
1281 c = aton(c.value);
1282 if ( (aton(a.value) & c) == (aton(b.value) & c) ) {
1283 ferror.set('_modem_ipaddr', 'Modem IP address may not be within your local address space.', quiet);
1284 ok = 0;
1287 /* NOVLAN-END */
1289 return ok;
1292 function earlyInit()
1294 verifyFields(null, 1);
1297 function save()
1299 /* VLAN-BEGIN */
1300 if (lg.isEditing()) return;
1301 lg.resetNewEditor();
1302 /* VLAN-END */
1304 var a, b, c;
1305 var i;
1306 var u, uidx, wmode, sm2, wradio;
1308 if (!verifyFields(null, false)) return;
1310 var fom = E('_fom');
1312 fom.wan_mtu.value = fom.f_wan_mtu.value;
1313 fom.wan_mtu.disabled = fom.f_wan_mtu.disabled;
1315 /* NOVLAN-BEGIN */
1316 fom.lan_proto.value = fom.f_dhcpd_enable.checked ? 'dhcp' : 'static';
1317 /* NOVLAN-END */
1319 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1320 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1321 if (wl_sunit(uidx)<0) {
1322 u = wl_unit(uidx);
1323 wmode = E('_f_wl'+u+'_mode').value;
1324 sm2 = E('_wl'+u+'_security_mode').value;
1325 wradio = E('_f_wl'+u+'_radio').checked;
1327 E('_wl'+u+'_nband').value = selectedBand(uidx);
1329 if (wmode == 'apwds') E('_wl'+u+'_mode').value = 'ap';
1330 else E('_wl'+u+'_mode').value = wmode;
1332 if (wmode == 'wet') {
1333 fom.wan_proto.value = 'disabled';
1334 fom.wan_proto.disabled = 0;
1335 /* NOVLAN-BEGIN */
1336 fom.lan_proto.value = 'static';
1337 /* NOVLAN-END */
1338 /* VLAN-BEGIN */
1339 /* REMOVE-BEGIN */
1340 // TODO - what's required ? integrate with tomatogrid?
1341 /* REMOVE-END */
1342 /* VLAN-END */
1345 a = [];
1346 for (i = 0; i < 10; ++i) a.push(E('_f_wl'+u+'_wds_' + i).value);
1347 E('_wl'+u+'_wds').value = joinAddr(a);
1349 if (wmode.indexOf('wds') != -1) {
1350 E('_wl'+u+'_wds_enable').value = 1;
1351 E('_wl'+u+'_lazywds').value = E('_f_wl'+u+'_lazywds').value;
1352 if (E('_wl'+u+'_lazywds').value == 1) E('_wl'+u+'_wds').value = '';
1354 else {
1355 E('_wl'+u+'_wds_enable').value = 0;
1356 E('_wl'+u+'_wds').value = '';
1357 E('_wl'+u+'_lazywds').value = 0;
1360 E('_wl'+u+'_radio').value = wradio ? 1 : 0;
1361 E('_wl'+u+'_auth').value = eval('nvram.wl'+u+'_auth');
1363 e = E('_wl'+u+'_akm');
1364 switch (sm2) {
1365 case 'disabled':
1366 case 'radius':
1367 case 'wep':
1368 e.value = '';
1369 break;
1370 default:
1371 c = [];
1373 if (sm2.indexOf('personal') != -1) {
1374 if (sm2.indexOf('wpa2_') == -1) c.push('psk');
1375 if (sm2.indexOf('wpa_') == -1) c.push('psk2');
1377 else {
1378 if (sm2.indexOf('wpa2_') == -1) c.push('wpa');
1379 if (sm2.indexOf('wpa_') == -1) c.push('wpa2');
1381 c = c.join(' ');
1382 e.value = c;
1383 break;
1385 E('_wl'+u+'_auth_mode').value = (sm2 == 'radius') ? 'radius' : 'none';
1386 E('_wl'+u+'_wep').value = ((sm2 == 'radius') || (sm2 == 'wep')) ? 'enabled': 'disabled';
1388 if (sm2.indexOf('wpa') != -1) E('_wl'+u+'_auth').value = 0;
1390 E('_wl'+u+'_nreqd').value = 0;
1391 E('_wl'+u+'_gmode').value = 1;
1392 E('_wl'+u+'_nmode').value = 0;
1393 E('_wl'+u+'_nmcsidx').value = -2; // Legacy Rate
1394 E('_wl'+u+'_nbw').value = 0;
1395 switch (E('_wl'+u+'_net_mode').value) {
1396 case 'b-only':
1397 E('_wl'+u+'_gmode').value = 0;
1398 break;
1399 case 'g-only':
1400 E('_wl'+u+'_gmode').value = 4;
1401 break;
1402 case 'bg-mixed':
1403 break;
1404 case 'a-only':
1405 E('_wl'+u+'_nmcsidx').value = -1; // Auto
1406 break;
1407 case 'n-only':
1408 if (selectedBand(uidx) == '1') { // 5 GHz
1409 E('_wl'+u+'_nmode').value = -1;
1410 E('_wl'+u+'_nmcsidx').value = -1;
1411 } else {
1412 E('_wl'+u+'_nmode').value = 1;
1413 E('_wl'+u+'_nmcsidx').value = 32;
1415 E('_wl'+u+'_nreqd').value = 1;
1416 break;
1417 default: // Auto
1418 E('_wl'+u+'_nmode').value = -1;
1419 E('_wl'+u+'_nmcsidx').value = -1;
1420 break;
1423 E('_wl'+u+'_nctrlsb').value = eval('nvram.wl'+u+'_nctrlsb');
1424 if (E('_wl'+u+'_nmode').value != 0) {
1425 E('_wl'+u+'_nctrlsb').value = E('_f_wl'+u+'_nctrlsb').value;
1426 E('_wl'+u+'_nbw').value = (E('_wl'+u+'_nbw_cap').value == 0) ? 20 : 40;
1429 E('_wl'+u+'_closed').value = E('_f_wl'+u+'_bcast').checked ? 0 : 1;
1431 a = fields.radio.selected(eval('fom.f_wl'+u+'_wepidx'));
1432 if (a) E('_wl'+u+'_key').value = a.value;
1436 fom.wan_islan.value = fom.f_wan_islan.checked ? 1 : 0;
1437 fom.pptp_dhcp.value = fom.f_pptp_dhcp.checked ? 1 : 0;
1439 fom.wan_dns.value = joinAddr([fom.f_dns_1.value, fom.f_dns_2.value, fom.f_dns_3.value]);
1441 /* VLAN-BEGIN */
1442 // initialize/wipe out relevant fields
1443 for (var i = 0 ; i <= MAX_BRIDGE_ID ; i++) {
1444 var j = (i == 0) ? '' : i.toString();
1445 fom['lan' + j + '_ifname'].value = '';
1446 fom['lan' + j + '_ipaddr'].value = '';
1447 fom['lan' + j + '_netmask'].value = '';
1448 fom['lan' + j + '_proto'].value = '';
1449 fom['lan' + j + '_stp'].value = '';
1450 fom['dhcp' + j + '_start'].value = '';
1451 fom['dhcp' + j + '_num'].value = '';
1452 fom['dhcp' + j + '_lease'].value = '';
1453 fom['dhcpd' + j + '_startip'].value = '';
1454 fom['dhcpd' + j + '_endip'].value = '';
1457 var d = lg.getAllData();
1458 for (var i = 0; i < d.length; ++i) {
1460 if (lg.countOverlappingNetworks(d[i][2]) > 1) {
1461 var s = 'Cannot proceed: two or more LAN bridges have conflicting IP addresses or overlapping subnets';
1462 alert(s);
1463 var e = E('footer-msg');
1464 e.innerHTML = s;
1465 e.style.visibility = 'visible';
1466 setTimeout(
1467 function() {
1468 e.innerHTML = '';
1469 e.style.visibility = 'hidden';
1470 }, 5000);
1471 return;
1474 var j = (parseInt(d[i][0]) == 0) ? '' : d[i][0].toString();
1475 fom['lan' + j + '_ifname'].value = 'br' + d[i][0];
1476 fom['lan' + j + '_stp'].value = d[i][1];
1477 fom['lan' + j + '_ipaddr'].value = d[i][2];
1478 fom['lan' + j + '_netmask'].value = d[i][3];
1479 fom['lan' + j + '_proto'].value = (d[i][4] != '0') ? 'dhcp' : 'static';
1480 fom['dhcp' + j + '_start'].value = (d[i][4] != '0') ? (d[i][5]).split('.').splice(3, 1) : '';
1481 fom['dhcp' + j + '_num'].value = (d[i][4] != '0') ? d[i][6].split('.').splice(3, 1) - (d[i][5]).split('.').splice(3, 1) + 1 : ''; // presuming /24 subnet (legacy)
1482 fom['dhcp' + j + '_lease'].value = (d[i][4] != '0') ? d[i][7] : '';
1483 fom['dhcpd' + j + '_startip'].value = (d[i][4] != '0') ? d[i][5] : '';
1484 fom['dhcpd' + j + '_endip'].value = (d[i][4] != '0') ? d[i][6] : '';
1486 /* REMOVE-BEGIN */
1487 alert('lan' + j + '_ifname=' + fom['lan' + j + '_ifname'].value + '\n' +
1488 'lan' + j + '_stp=' + fom['lan' + j + '_stp'].value + '\n' +
1489 'lan' + j + '_ipaddr=' + fom['lan' + j + '_ipaddr'].value + '\n' +
1490 'lan' + j + '_netmask=' + fom['lan' + j + '_netmask'].value + '\n' +
1491 'lan' + j + '_proto=' + fom['lan' + j + '_proto'].value + '\n' +
1492 'dhcp' + j + '_start=' + fom['dhcp' + j + '_start'].value + '\n' +
1493 'dhcp' + j + '_num=' + fom['dhcp' + j + '_num'].value + '\n' +
1494 'dhcp' + j + '_lease=' + fom['dhcp' + j + '_lease'].value + '\n' +
1495 'dhcpd' + j + '_startip=' + fom['dhcpd' + j + '_startip'].value + '\n' +
1496 'dhcpd' + j + '_endip=' + fom['dhcpd' + j + '_endip'].value);
1497 /* REMOVE-END */
1500 var e = E('footer-msg');
1501 var t = fixIP(fom['lan_ipaddr'].value);
1502 if ((fom['lan_ifname'].value != 'br0') || (fom['lan_ipaddr'].value == '0.0.0.0') || (!t)) {
1503 e.innerHTML = 'Bridge br0 must be always defined and have a valid IP address set.';
1504 e.style.visibility = 'visible';
1505 setTimeout(
1506 function() {
1507 e.innerHTML = '';
1508 e.style.visibility = 'hidden';
1509 }, 5000);
1510 return;
1512 /* VLAN-END */
1514 /* REMOVE-BEGIN
1515 // if ((nvram.lan_ipaddr != fom.lan_ipaddr.value) || (nvram.lan1_ipaddr != fom.lan1_ipaddr.value) ||
1516 // (nvram.lan2_ipaddr != fom.lan2_ipaddr.value) || (nvram.lan3_ipaddr != fom.lan3_ipaddr.value)){
1517 REMOVE-END */
1519 fom.ppp_mlppp.value = fom.f_ppp_mlppp.checked ? 1 : 0;
1521 if (nvram.lan_ipaddr != fom.lan_ipaddr.value) {
1522 fom._moveip.value = 1;
1523 form.submit(fom);
1525 else {
1526 form.submit(fom, 1);
1530 function init()
1532 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1533 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1534 if (wl_sunit(uidx)<0) {
1535 refreshNetModes(uidx);
1536 refreshChannels(uidx);
1540 </script>
1542 </head>
1543 <body onload='init()'>
1544 <form id='_fom' method='post' action='tomato.cgi'>
1545 <table id='container' cellspacing=0>
1546 <tr><td colspan=2 id='header'>
1547 <div class='title'>Tomato</div>
1548 <div class='version'>Version <% version(); %></div>
1549 </td></tr>
1550 <tr id='body'><td id='navi'><script type='text/javascript'>navi()</script></td>
1551 <td id='content'>
1552 <div id='ident'><% ident(); %></div>
1554 <!-- / / / -->
1556 <input type='hidden' name='_nextpage' value='basic-network.asp'>
1557 <input type='hidden' name='_nextwait' value='10'>
1558 <input type='hidden' name='_service' value='*'>
1559 <input type='hidden' name='_moveip' value='0'>
1561 <input type='hidden' name='wan_mtu'>
1562 <input type='hidden' name='wan_islan'>
1563 <input type='hidden' name='pptp_dhcp'>
1564 <!-- NOVLAN-BEGIN -->
1565 <input type='hidden' name='lan_proto'>
1566 <!-- NOVLAN-END -->
1567 <input type='hidden' name='wan_dns'>
1568 <input type='hidden' name='ppp_mlppp'>
1570 <!-- VLAN-BEGIN -->
1571 <script type='text/javascript'>
1573 for (var i = 0 ; i <= MAX_BRIDGE_ID ; i++) {
1574 var j = (i == 0) ? '' : i.toString();
1575 W('<input type=\'hidden\' id=\'lan' + j + '_ifname\' name=\'lan' + j + '_ifname\'>');
1576 W('<input type=\'hidden\' id=\'lan' + j + '_ipaddr\' name=\'lan' + j + '_ipaddr\'>');
1577 W('<input type=\'hidden\' id=\'lan' + j + '_netmask\' name=\'lan' + j + '_netmask\'>');
1578 W('<input type=\'hidden\' id=\'lan' + j + '_proto\' name=\'lan' + j + '_proto\'>');
1579 W('<input type=\'hidden\' id=\'lan' + j + '_stp\' name=\'lan' + j + '_stp\'>');
1580 W('<input type=\'hidden\' id=\'dhcp' + j + '_start\' name=\'dhcp' + j + '_start\'>');
1581 W('<input type=\'hidden\' id=\'dhcp' + j + '_num\' name=\'dhcp' + j + '_num\'>');
1582 W('<input type=\'hidden\' id=\'dhcp' + j + '_lease\' name=\'dhcp' + j + '_lease\'>');
1583 W('<input type=\'hidden\' id=\'dhcpd' + j + '_startip\' name=\'dhcpd' + j + '_startip\'>');
1584 W('<input type=\'hidden\' id=\'dhcpd' + j + '_endip\' name=\'dhcpd' + j + '_endip\'>');
1586 </script>
1587 <!-- VLAN-END -->
1589 <div class='section-title'>WAN / Internet</div>
1590 <div class='section'>
1591 <script type='text/javascript'>
1592 createFieldTable('', [
1593 { title: 'Type', name: 'wan_proto', type: 'select', options: [['dhcp','DHCP'],['pppoe','PPPoE'],['static','Static'],['pptp','PPTP'],['l2tp','L2TP'],['disabled','Disabled']],
1594 value: nvram.wan_proto },
1595 { title: 'Username', name: 'ppp_username', type: 'text', maxlen: 60, size: 64, value: nvram.ppp_username },
1596 { title: 'Password', name: 'ppp_passwd', type: 'password', maxlen: 60, size: 64, peekaboo: 1, value: nvram.ppp_passwd },
1597 { title: 'Service Name', name: 'ppp_service', type: 'text', maxlen: 50, size: 64, value: nvram.ppp_service },
1598 { title: 'L2TP Server', name: 'l2tp_server_ip', type: 'text', maxlen: 128, size: 64, value: nvram.l2tp_server_ip },
1599 { title: 'Use DHCP', name: 'f_pptp_dhcp', type: 'checkbox', value: (nvram.pptp_dhcp == 1) },
1600 { title: 'IP Address', name: 'wan_ipaddr', type: 'text', maxlen: 15, size: 17, value: nvram.wan_ipaddr },
1601 { title: 'Subnet Mask', name: 'wan_netmask', type: 'text', maxlen: 15, size: 17, value: nvram.wan_netmask },
1602 { title: 'Gateway', name: 'wan_gateway', type: 'text', maxlen: 15, size: 17, value: nvram.wan_gateway },
1603 { title: 'PPTP Gateway', name: 'pptp_server_ip', type: 'text', maxlen: 128, size: 64, value: nvram.pptp_server_ip },
1604 { title: 'Options', name: 'ppp_custom', type: 'text', maxlen: 256, size: 64, value: nvram.ppp_custom },
1605 { title: 'Connect Mode', name: 'ppp_demand', type: 'select', options: [['1', 'Connect On Demand'],['0', 'Keep Alive']],
1606 value: nvram.ppp_demand },
1607 { title: 'Max Idle Time', indent: 2, name: 'ppp_idletime', type: 'text', maxlen: 5, size: 7, suffix: ' <i>(minutes)</i>',
1608 value: nvram.ppp_idletime },
1609 { title: 'Check Interval', indent: 2, name: 'ppp_redialperiod', type: 'text', maxlen: 5, size: 7, suffix: ' <i>(seconds)</i>',
1610 value: nvram.ppp_redialperiod },
1611 { title: 'MTU', multi: [
1612 { name: 'mtu_enable', type: 'select', options: [['0', 'Default'],['1','Manual']], value: nvram.mtu_enable },
1613 { name: 'f_wan_mtu', type: 'text', maxlen: 4, size: 6, value: nvram.wan_mtu } ] },
1614 { title: 'Single Line MLPPP', name: 'f_ppp_mlppp', type: 'checkbox', value: (nvram.ppp_mlppp == 1) },
1615 { title: 'Route Modem IP', name: 'modem_ipaddr', type: 'text', maxlen: 15, size: 17, suffix: ' <i>(must be in different subnet to router, 0.0.0.0 to disable)</i>', value: nvram.modem_ipaddr },
1617 /* NOVLAN-BEGIN */
1618 { title: 'Use WAN port for LAN', name: 'f_wan_islan', type: 'checkbox', value: (nvram.wan_islan == 1) }
1619 /* NOVLAN-END */
1620 /* VLAN-BEGIN */
1621 { title: 'Bridge WAN port to primary LAN (br0)', name: 'f_wan_islan', type: 'checkbox', value: (nvram.wan_islan == 1) }
1622 /* VLAN-END */
1624 </script>
1625 </div>
1627 <div class='section-title'>LAN</div>
1628 <div class='section'>
1629 <!-- VLAN-BEGIN -->
1630 <table class='tomato-grid' cellspacing=1 id='lan-grid'></table>
1632 <script type='text/javascript'>lg.setup();</script>
1633 <!-- VLAN-END -->
1635 <script type='text/javascript'>
1636 dns = nvram.wan_dns.split(/\s+/);
1637 /* REMOVE-BEGIN
1638 //ipp = nvram.lan_ipaddr.split('.').splice(0, 3).join('.');
1639 REMOVE-END */
1640 createFieldTable('', [
1641 /* NOVLAN-BEGIN */
1642 { title: 'Router IP Address', name: 'lan_ipaddr', type: 'text', maxlen: 15, size: 17, value: nvram.lan_ipaddr },
1643 { title: 'Subnet Mask', name: 'lan_netmask', type: 'text', maxlen: 15, size: 17, value: nvram.lan_netmask },
1644 /* NOVLAN-END */
1645 { title: 'Default Gateway', name: 'lan_gateway', type: 'text', maxlen: 15, size: 17, value: nvram.lan_gateway },
1646 { 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' },
1647 { title: '', name: 'f_dns_2', type: 'text', maxlen: 21, size: 25, value: dns[1] || '0.0.0.0' },
1648 { title: '', name: 'f_dns_3', type: 'text', maxlen: 21, size: 25, value: dns[2] || '0.0.0.0' },
1649 /* NOVLAN-BEGIN */
1650 { title: 'DHCP Server', name: 'f_dhcpd_enable', type: 'checkbox', value: (nvram.lan_proto == 'dhcp') },
1651 { title: 'IP Address Range', indent: 2, multi: [
1652 { name: 'dhcpd_startip', type: 'text', maxlen: 15, size: 17, value: nvram.dhcpd_startip, suffix: ' - ' },
1653 { name: 'dhcpd_endip', type: 'text', maxlen: 15, size: 17, value: nvram.dhcpd_endip, suffix: ' <i id="dhcp_count"></i>' }
1654 ] },
1656 { title: 'Lease Time', indent: 2, name: 'dhcp_lease', type: 'text', maxlen: 6, size: 8, suffix: ' <i>(minutes)</i>',
1657 value: (nvram.dhcp_lease > 0) ? nvram.dhcp_lease : 1440 },
1658 { title: 'WINS', indent: 2, name: 'wan_wins', type: 'text', maxlen: 15, size: 17, value: nvram.wan_wins }
1659 /* NOVLAN-END */
1660 /* VLAN-BEGIN */
1661 { title: 'WINS <i>(for DHCP)</i>', name: 'wan_wins', type: 'text', maxlen: 15, size: 17, value: nvram.wan_wins }
1662 /* VLAN-END */
1664 </script>
1665 </div>
1667 <script type='text/javascript'>
1669 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1670 //if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1671 if (wl_sunit(uidx)<0) {
1672 var u = wl_unit(uidx);
1674 W('<input type=\'hidden\' id=\'_wl'+u+'_mode\' name=\'wl'+u+'_mode\'>');
1675 W('<input type=\'hidden\' id=\'_wl'+u+'_nband\' name=\'wl'+u+'_nband\'>');
1676 W('<input type=\'hidden\' id=\'_wl'+u+'_wds_enable\' name=\'wl'+u+'_wds_enable\'>');
1677 W('<input type=\'hidden\' id=\'_wl'+u+'_wds\' name=\'wl'+u+'_wds\'>');
1678 W('<input type=\'hidden\' id=\'_wl'+u+'_radio\' name=\'wl'+u+'_radio\'>');
1679 W('<input type=\'hidden\' id=\'_wl'+u+'_closed\' name=\'wl'+u+'_closed\'>');
1680 W('<input type=\'hidden\' id=\'_wl'+u+'_key\' name=\'wl'+u+'_key\'>');
1681 W('<input type=\'hidden\' id=\'_wl'+u+'_gmode\' name=\'wl'+u+'_gmode\'>');
1682 W('<input type=\'hidden\' id=\'_wl'+u+'_akm\' name=\'wl'+u+'_akm\'>');
1683 W('<input type=\'hidden\' id=\'_wl'+u+'_auth\' name=\'wl'+u+'_auth\'>');
1684 W('<input type=\'hidden\' id=\'_wl'+u+'_auth_mode\' name=\'wl'+u+'_auth_mode\'>');
1685 W('<input type=\'hidden\' id=\'_wl'+u+'_wep\' name=\'wl'+u+'_wep\'>');
1686 W('<input type=\'hidden\' id=\'_wl'+u+'_lazywds\' name=\'wl'+u+'_lazywds\'>');
1687 W('<input type=\'hidden\' id=\'_wl'+u+'_nmode\' name=\'wl'+u+'_nmode\'>');
1688 W('<input type=\'hidden\' id=\'_wl'+u+'_nmcsidx\' name=\'wl'+u+'_nmcsidx\'>');
1689 W('<input type=\'hidden\' id=\'_wl'+u+'_nreqd\' name=\'wl'+u+'_nreqd\'>');
1690 W('<input type=\'hidden\' id=\'_wl'+u+'_nctrlsb\' name=\'wl'+u+'_nctrlsb\'>');
1691 W('<input type=\'hidden\' id=\'_wl'+u+'_nbw\' name=\'wl'+u+'_nbw\'>');
1693 W('<div class=\'section-title\'>Wireless');
1694 // if (wl_ifaces.length > 1)
1695 W(' (' + wl_display_ifname(uidx) + ')');
1696 W('</div>');
1698 W('<div class=\'section\'>');
1700 f = [
1701 { title: 'Enable Wireless', name: 'f_wl'+u+'_radio', type: 'checkbox',
1702 value: (eval('nvram.wl'+u+'_radio') == '1') && (eval('nvram.wl'+u+'_net_mode') != 'disabled') },
1703 { title: 'MAC Address', text: '<a href="advanced-mac.asp">' + eval('nvram.wl'+u+'_hwaddr') + '</a>' },
1704 { title: 'Wireless Mode', name: 'f_wl'+u+'_mode', type: 'select',
1705 options: [['ap', 'Access Point'],['apwds', 'Access Point + WDS'],['sta', 'Wireless Client'],['wet', 'Wireless Ethernet Bridge'],['wds', 'WDS']],
1706 value: ((eval('nvram.wl'+u+'_mode') == 'ap') && (eval('nvram.wl'+u+'_wds_enable') == '1')) ? 'apwds' : eval('nvram.wl'+u+'_mode') },
1707 { title: 'Radio Band', name: 'f_wl'+u+'_nband', type: 'select', options: bands[uidx],
1708 value: eval('nvram.wl'+u+'_nband') || '0' == '0' ? bands[uidx][0][0] : eval('nvram.wl'+u+'_nband') },
1709 { title: 'Wireless Network Mode', name: 'wl'+u+'_net_mode', type: 'select',
1710 value: (eval('nvram.wl'+u+'_net_mode') == 'disabled') ? 'mixed' : eval('nvram.wl'+u+'_net_mode'),
1711 options: [], prefix: '<span id="__wl'+u+'_net_mode">', suffix: '</span>' },
1712 { title: 'SSID', name: 'wl'+u+'_ssid', type: 'text', maxlen: 32, size: 34, value: eval('nvram.wl'+u+'_ssid') },
1713 { title: 'Broadcast', indent: 2, name: 'f_wl'+u+'_bcast', type: 'checkbox', value: (eval('nvram.wl'+u+'_closed') == '0') },
1714 { 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+'">',
1715 value: eval('nvram.wl'+u+'_channel') },
1716 { title: 'Channel Width', name: 'wl'+u+'_nbw_cap', type: 'select', options: [['0','20 MHz'],['1','40 MHz']],
1717 value: eval('nvram.wl'+u+'_nbw_cap') },
1718 { title: 'Control Sideband', name: 'f_wl'+u+'_nctrlsb', type: 'select', options: [['lower','Lower'],['upper','Upper']],
1719 value: eval('nvram.wl'+u+'_nctrlsb') == 'none' ? 'lower' : eval('nvram.wl'+u+'_nctrlsb') },
1720 null,
1721 { title: 'Security', name: 'wl'+u+'_security_mode', type: 'select',
1722 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']],
1723 value: eval('nvram.wl'+u+'_security_mode') },
1724 { title: 'Encryption', indent: 2, name: 'wl'+u+'_crypto', type: 'select',
1725 options: [['tkip','TKIP'],['aes','AES'],['tkip+aes','TKIP / AES']], value: eval('nvram.wl'+u+'_crypto') },
1726 { title: 'Shared Key', indent: 2, name: 'wl'+u+'_wpa_psk', type: 'password', maxlen: 64, size: 66, peekaboo: 1,
1727 suffix: ' <input type="button" id="_f_wl'+u+'_psk_random1" value="Random" onclick="random_psk(\'_wl'+u+'_wpa_psk\')">',
1728 value: eval('nvram.wl'+u+'_wpa_psk') },
1729 { title: 'Shared Key', indent: 2, name: 'wl'+u+'_radius_key', type: 'password', maxlen: 80, size: 32, peekaboo: 1,
1730 suffix: ' <input type="button" id="_f_wl'+u+'_psk_random2" value="Random" onclick="random_psk(\'_wl'+u+'_radius_key\')">',
1731 value: eval('nvram.wl'+u+'_radius_key') },
1732 { title: 'Group Key Renewal', indent: 2, name: 'wl'+u+'_wpa_gtk_rekey', type: 'text', maxlen: 4, size: 6, suffix: ' <i>(seconds)</i>',
1733 value: eval('nvram.wl'+u+'_wpa_gtk_rekey') },
1734 { title: 'Radius Server', indent: 2, multi: [
1735 { name: 'wl'+u+'_radius_ipaddr', type: 'text', maxlen: 15, size: 17, value: eval('nvram.wl'+u+'_radius_ipaddr') },
1736 { name: 'wl'+u+'_radius_port', type: 'text', maxlen: 5, size: 7, prefix: ' : ', value: eval('nvram.wl'+u+'_radius_port') } ] },
1737 { title: 'Encryption', indent: 2, name: 'wl'+u+'_wep_bit', type: 'select', options: [['128','128-bits'],['64','64-bits']],
1738 value: eval('nvram.wl'+u+'_wep_bit') },
1739 { title: 'Passphrase', indent: 2, name: 'wl'+u+'_passphrase', type: 'text', maxlen: 16, size: 20,
1740 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+')">',
1741 value: eval('nvram.wl'+u+'_passphrase') }
1744 for (i = 1; i <= 4; ++i) {
1745 f.push(
1746 { title: ('Key ' + i), indent: 2, name: ('wl'+u+'_key' + i), type: 'text', maxlen: 26, size: 34,
1747 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>' : '>'),
1748 value: nvram['wl'+u+'_key' + i] });
1751 f.push(null,
1752 { title: 'WDS', name: 'f_wl'+u+'_lazywds', type: 'select',
1753 options: [['0','Link With...'],['1','Automatic']], value: nvram['wl'+u+'_lazywds'] } );
1754 wds = eval('nvram.wl'+u+'_wds').split(/\s+/);
1755 for (i = 0; i < 10; i += 2) {
1756 f.push({ title: (i ? '' : 'MAC Address'), indent: 2, multi: [
1757 { name: 'f_wl'+u+'_wds_' + i, type: 'text', maxlen: 17, size: 20, value: wds[i] || '00:00:00:00:00:00' },
1758 { name: 'f_wl'+u+'_wds_' + (i + 1), type: 'text', maxlen: 17, size: 20, value: wds[i + 1] || '00:00:00:00:00:00' } ] } );
1761 createFieldTable('', f);
1762 W('</div>');
1765 // for each wlif
1766 </script>
1768 <!-- / / / -->
1770 </td></tr>
1771 <tr><td id='footer' colspan=2>
1772 <span id='footer-msg'></span>
1773 <input type='button' value='Save' id='save-button' onclick='save()'>
1774 <input type='button' value='Cancel' id='cancel-button' onclick='reloadPage();'>
1775 </td></tr>
1776 </table>
1777 </form>
1778 <script type='text/javascript'>earlyInit()</script>
1779 <div style='height:100px'></div>
1780 </body>
1781 </html>