Remove limitation about 22 bits netmask.
[tomato.git] / release / src / router / www / basic-network.asp
blob80674ccd46e65d5b593b8e260b61cbb5640939e1
1 <!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0//EN'>
2 <!--
3 Tomato GUI
4 Copyright (C) 2006-2010 Jonathan Zarate
5 http://www.polarcloud.com/tomato/
7 For use with Tomato Firmware only.
8 No part of this file may be used without permission.
9 -->
10 <html>
11 <head>
12 <meta http-equiv='content-type' content='text/html;charset=utf-8'>
13 <meta name='robots' content='noindex,nofollow'>
14 <title>[<% ident(); %>] Basic: Network</title>
15 <link rel='stylesheet' type='text/css' href='tomato.css'>
16 <% css(); %>
17 <script type='text/javascript' src='tomato.js'></script>
19 <!-- / / / -->
21 <style type='text/css'>
22 #lan-grid .co1,
23 #lan-grid .co2,
24 #lan-grid .co3,
25 #lan-grid .co4,
26 #lan-grid .co5,
27 #lan-grid .co6,
28 #lan-grid .co7 {
29 text-align: center;
32 #lan-grid .centered {
33 text-align: center;
36 #spin {
37 visibility: hidden;
38 vertical-align: middle;
40 </style>
42 <script type='text/javascript' src='debug.js'></script>
44 <script type='text/javascript' src='md5.js'></script>
45 <script type='text/javascript' src='wireless.jsx?_http_id=<% nv(http_id); %>'></script>
46 <script type='text/javascript' src='interfaces.js'></script>
47 <script type='text/javascript'>
48 // <% nvram("dhcp_lease,dhcp_num,dhcp_start,dhcpd_startip,dhcpd_endip,l2tp_server_ip,lan_gateway,lan_ipaddr,lan_netmask,lan_proto,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,dnscrypt_proxy,wan_gateway,wan_ipaddr,wan_mtu,wan_netmask,wan_proto,wan_wins,wl_wds_enable,wl_channel,wl_closed,wl_crypto,wl_key,wl_key1,wl_key2,wl_key3,wl_key4,wl_lazywds,wl_mode,wl_net_mode,wl_passphrase,wl_radio,wl_radius_ipaddr,wl_radius_port,wl_ssid,wl_wds,wl_wep_bit,wl_wpa_gtk_rekey,wl_wpa_psk,wl_radius_key,wl_auth,wl_hwaddr,wan_islan,t_features,wl_nbw_cap,wl_nctrlsb,wl_nband,wl_phytype,lan_ifname,lan_stp,lan1_ifname,lan1_ipaddr,lan1_netmask,lan1_proto,lan1_stp,dhcp1_start,dhcp1_num,dhcp1_lease,dhcpd1_startip,dhcpd1_endip,lan2_ifname,lan2_ipaddr,lan2_netmask,lan2_proto,lan2_stp,dhcp2_start,dhcp2_num,dhcp2_lease,dhcpd2_startip,dhcpd2_endip,lan3_ifname,lan3_ipaddr,lan3_netmask,lan3_proto,lan3_stp,dhcp3_start,dhcp3_num,dhcp3_lease,dhcpd3_startip,dhcpd3_endip,ppp_mlppp,modem_ipaddr,modem_pin,modem_dev,modem_init,modem_apn,cstats_enable"); %>
50 var lg = new TomatoGrid();
51 lg.setup = function() {
52 this.init('lan-grid', '', 4, [
53 { type: 'select', options: [[0, '0'],[1, '1'],[2, '2'],[3, '3']], prefix: '<div class="centered">', suffix: '</div>' },
54 { type: 'checkbox', prefix: '<div class="centered">', suffix: '</div>' },
55 { type: 'text', maxlen: 15, size: 17 },
56 { type: 'text', maxlen: 15, size: 17 },
57 { type: 'checkbox', prefix: '<div class="centered">', suffix: '</div>' },
58 { multi: [ { type: 'text', maxlen: 15, size: 17}, { type: 'text', maxlen: 15, size: 17 } ] },
59 { type: 'text', maxlen: 6, size: 8 }] );
60 this.headerSet(['Bridge', 'STP', 'IP Address', 'Netmask', 'DHCP', 'IP&nbsp;Range&nbsp;<i>(first/last)</i>', 'Lease&nbsp;Time&nbsp;<i>(mins)</i>']);
62 var numBridges = 0;
63 for (var i = 0 ; i <= MAX_BRIDGE_ID ; i++) {
64 var j = (i == 0) ? '' : i.toString();
65 if (nvram['lan' + j + '_ifname'].length > 0) {
66 if ((!fixIP(nvram['dhcpd' + j + '_startip'])) || (!fixIP(nvram['dhcpd' + j + '_endip']))) {
67 if ((fixIP(nvram['lan' + j + '_ipaddr'])) && (fixIP(nvram['lan' + j + '_netmask'])) && (nvram['dhcp' + j + '_start'] != '')) {
68 var n = getNetworkAddress(nvram['lan' + j + '_ipaddr'], nvram['lan' + j + '_netmask']);
69 nvram['dhcpd' + j + '_startip'] = getAddress(('0.0.0.' + nvram['dhcp' + j + '_start'] * 1), n);
70 nvram['dhcpd' + j + '_endip'] = getAddress(('0.0.0.' + ((nvram['dhcp' + j + '_start'] * 1) + (nvram['dhcp' + j + '_num'] *1) - 1)), n);
73 lg.insertData(-1, [
74 i.toString(),
75 nvram['lan' + j + '_stp'],
76 nvram['lan' + j + '_ipaddr'],
77 nvram['lan' + j + '_netmask'],
78 (nvram['lan' + j + '_proto'] == 'dhcp') ? '1' : '0',
79 nvram['dhcpd' + j + '_startip'],
80 nvram['dhcpd' + j + '_endip'],
81 (nvram['lan' + j + '_proto'] == 'dhcp') ? (((nvram['dhcp' + j + '_lease'])*1 == 0) ? '1440' : (nvram['dhcp' + j + '_lease']).toString()) : ''
82 ] ) ;
83 numBridges++;
86 lg.canDelete = false;
87 lg.sort(0);
88 elem.removeClass(lg.header.cells[lg.sortColumn], 'sortasc', 'sortdes');
89 lg.showNewEditor();
90 lg.resetNewEditor();
93 lg.dataToView = function(data) {
94 return ['br' + data[0],
95 (data[1].toString() == '1') ? '<small><i>Enabled</i></small>' : '<small><i>Disabled</i></small>',
96 data[2],
97 data[3],
98 (data[4].toString() == '1') ? '<small><i>Enabled</i></small>' : '<small><i>Disabled</i></small>',
99 (data[5].toString() + ((numberOfBitsOnNetMask(data[3])>=24) ? (' - ' + data[6].split('.').splice(3, 1).toString()) : ('<br>' + data[6].toString()) )),
100 (((data[7] != null) && (data[7] != '')) ? data[7] : '') ];
103 lg.dataToFieldValues = function (data) {
104 return [data[0],
105 (data[1] != 0) ? 'checked' : '',
106 data[2].toString(),
107 data[3].toString(),
108 (data[4].toString() == '1') ? 'checked' : '',
109 data[5].toString(),
110 data[6].toString(),
111 data[7].toString() ];
114 lg.fieldValuesToData = function(row) {
115 var f = fields.getAll(row);
116 return [f[0].value,
117 f[1].checked ? 1 : 0,
118 f[2].value,
119 f[3].value,
120 f[4].checked ? 1 : 0,
121 f[5].value,
122 f[6].value,
123 f[7].value ];
126 lg.resetNewEditor = function() {
127 var f = fields.getAll(this.newEditor);
128 f[0].selectedIndex=0;
129 var t = MAX_BRIDGE_ID;
130 while((this.countBridge(f[0].selectedIndex) > 0) && (t > 0)) {
131 f[0].selectedIndex = (f[0].selectedIndex%(MAX_BRIDGE_ID))+1;
132 t--;
134 for(var j=0; j<= MAX_BRIDGE_ID ; j++) {
135 f[0].options[j].disabled = (this.countBridge(j) > 0);
137 f[1].checked = 0;
138 f[2].value = '';
139 f[3].value = '';
140 f[5].value = '';
141 f[6].value = '';
142 f[7].value = '';
143 f[4].checked = 0;
144 f[4].disabled = 1;
145 f[5].disabled = 1;
146 f[6].disabled = 1;
147 f[7].disabled = 1;
148 ferror.clearAll(fields.getAll(this.newEditor));
151 lg.onCancel = function() {
152 this.removeEditor();
153 this.showSource();
154 this.disableNewEditor(false);
156 this.resetNewEditor();
159 lg.onAdd = function() {
160 var data;
162 this.moving = null;
163 this.rpHide();
165 if (!this.verifyFields(this.newEditor, false)) return;
167 data = this.fieldValuesToData(this.newEditor);
168 this.insertData(-1, data);
170 this.disableNewEditor(false);
171 this.resetNewEditor();
173 this.resort();
176 lg.onOK = function() {
177 var i, data, view;
179 if (!this.verifyFields(this.editor, false)) return;
181 data = this.fieldValuesToData(this.editor);
182 view = this.dataToView(data);
184 this.source.setRowData(data);
185 for (i = 0; i < this.source.cells.length; ++i) {
186 this.source.cells[i].innerHTML = view[i];
189 this.removeEditor();
190 this.showSource();
191 this.disableNewEditor(false);
193 this.resort();
194 this.resetNewEditor();
197 lg.onDelete = function() {
198 this.removeEditor();
199 elem.remove(this.source);
200 this.source = null;
201 this.disableNewEditor(false);
203 this.resetNewEditor();
206 lg.countElem = function(f, v) {
207 var data = this.getAllData();
208 var total = 0;
209 for (var i = 0; i < data.length; ++i) {
210 total += (data[i][f] == v) ? 1 : 0;
212 return total;
215 lg.countBridge = function (v) {
216 return this.countElem(0,v);
219 lg.countOverlappingNetworks = function (ip) {
220 var data = this.getAllData();
221 var total = 0;
222 for (var i = 0; i < data.length; ++i) {
223 var net = getNetworkAddress(data[i][2], data[i][3]);
224 var brd = getBroadcastAddress(net, data[i][3]);
225 total += ((aton(ip) <= aton(brd)) && (aton(ip) >= aton(net))) ? 1 : 0;
227 return total;
230 lg.verifyFields = function(row, quiet) {
231 var ok=1;
232 var f;
234 f = fields.getAll(row);
236 for(var j=0; j<= MAX_BRIDGE_ID ; j++) {
237 f[0].options[j].disabled = (this.countBridge(j) > 0);
240 if(this.countBridge(f[0].selectedIndex) > 0) {
241 ferror.set(f[0], 'Cannot add another entry for bridge br' + f[0].selectedIndex, quiet);
242 ok = 0;
243 } else {
244 ferror.clear(f[0]);
246 // valid IP address?
247 if(!v_ip(f[2], quiet || !ok))
248 ok = 0;
249 // if we have a properly defined IP address - 0.0.0.0 is NOT a valid IP address for our intents/purposes!
250 if ((f[2].value != '') && (f[2].value != '0.0.0.0')) {
251 // allow DHCP to be enabled
252 f[4].disabled = 0;
253 // validate netmask
254 if(!v_netmask(f[3], quiet || !ok)) {
255 return 0;
256 } else {
257 // should be 22 bits or smaller network
258 if ((numberOfBitsOnNetMask(f[3].value) < 22) && (nvram.cstats_enable == '1' )) {
259 if (!confirm("Netmask should have at least 22 bits (255.255.252.0). You may continue anyway but remember - you was warned")) return;
260 } else {
261 ferror.clear(f[3]);
264 if(f[2].value == getNetworkAddress(f[2].value, f[3].value)) {
265 var s = 'Invalid IP address or subnet mask (the address of the network cannot be used)';
266 ferror.set(f[2], s, quiet);
267 ferror.set(f[3], s, quiet);
268 return 0;
269 } else
270 if(f[2].value == getBroadcastAddress(getNetworkAddress(f[2].value, f[3].value), f[3].value)) {
271 var s = 'Invalid IP address or subnet mask (the broadcast address cannot be used)';
272 ferror.set(f[2], s, quiet);
273 ferror.set(f[3], s, quiet);
274 return 0;
275 } else
276 if (this.countOverlappingNetworks(f[2].value) > 0) {
277 var s = 'Invalid IP address or subnet mask (conflicts/overlaps with another LAN bridge)';
278 ferror.set(f[2], s, quiet);
279 ferror.set(f[3], s, quiet);
280 return 0;
281 } else {
282 ferror.clear(f[2]);
283 ferror.clear(f[3]);
285 } else {
286 f[4].checked = 0;
287 f[4].disabled = 1;
289 // dhcp enabled?
290 if( (f[4].checked) && (v_ip(f[2], 1)) && (v_netmask(f[3],1)) ) {
291 f[5].disabled = 0;
292 f[6].disabled = 0;
293 f[7].disabled = 0;
294 // first/last IP still unset?
295 if (f[5].value == '') {
296 var l;
297 var m = aton(f[2].value) & aton(f[3].value);
298 var o = (m) ^ (~ aton(f[3].value))
299 var n = o - m;
300 do {
301 if (--n < 0) {
302 f[5].value = '';
303 return;
305 m++;
306 } while (((l = fixIP(ntoa(m), 1)) == null) || (l == f[2].value) );
307 f[5].value = l;
309 if (f[6].value == '') {
310 var l;
311 var m = aton(f[2].value) & aton(f[3].value);
312 var o = (m) ^ (~ aton(f[3].value));
313 var n = o - m;
314 do {
315 if (--n < 0) {
316 f[6].value = '';
317 return;
319 o--;
320 } while (((l = fixIP(ntoa(o), 1)) == null) || (l == f[2].value) );
321 f[6].value = l;
323 // first IP valid?
324 if ((getNetworkAddress(f[5].value, f[3].value) != getNetworkAddress(f[2].value, f[3].value)) ||
325 (f[5].value == getBroadcastAddress(getNetworkAddress(f[2].value, f[3].value), f[3].value)) ||
326 (f[5].value == getNetworkAddress(f[2].value, f[3].value)) ||
327 (f[2].value == f[5].value)) {
328 ferror.set(f[5], 'Invalid first IP address or subnet mask', quiet || !ok);
329 return 0;
330 } else {
331 ferror.clear(f[5]);
333 // last IP valid?
334 if ((getNetworkAddress(f[6].value, f[3].value) != getNetworkAddress(f[2].value, f[3].value)) ||
335 (f[6].value == getBroadcastAddress(getNetworkAddress(f[2].value, f[3].value), f[3].value)) ||
336 (f[6].value == getNetworkAddress(f[2].value, f[3].value)) ||
337 (f[2].value == f[6].value)) {
338 ferror.set(f[6], 'Invalid last IP address or subnet mask', quiet || !ok);
339 return 0;
340 } else {
341 ferror.clear(f[6]);
343 // validate range, swap first/last IP if needed
344 if (aton(f[6].value) < aton(f[5].value)) {
345 var t = f[5].value;
346 f[5].value = f[6].value;
347 f[6].value = t;
349 // lease time
350 if (parseInt(f[7].value*1) == 0)
351 f[7].value = 1440; // from nvram/defaults.c
352 if(!v_mins(f[7], quiet || !ok, 1, 10080))
353 ok = 0;
354 } else {
355 f[5].disabled = 1;
356 f[6].disabled = 1;
357 f[7].disabled = 1;
358 ferror.clear(f[5]);
359 ferror.clear(f[6]);
360 ferror.clear(f[7]);
362 return ok;
365 W('<style type=\'text/css\'>');
366 for (var u = 0; u < wl_ifaces.length; ++u) {
367 W('#spin'+wl_unit(u)+', ');
369 W('#spin {');
370 W(' visibility: hidden;');
371 W(' vertical-align: middle;');
372 W('}');
373 W('</style>');
375 var xob = null;
376 var refresher = [];
377 var nphy = features('11n');
379 var ghz = [];
380 var bands = [];
381 var nm_loaded = [], ch_loaded = [], max_channel = [];
383 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
384 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
385 if (wl_sunit(uidx)<0) {
386 var b;
387 b = [];
388 for (var i = 0; i < wl_bands[uidx].length; ++i) {
389 b.push([wl_bands[uidx][i] + '', (wl_bands[uidx][i] == '1') ? '5 GHz' : '2.4 GHz']);
391 bands.push(b);
393 b = [];
394 ghz.push(b);
396 nm_loaded.push(0);
397 ch_loaded.push(0);
398 max_channel.push(0);
399 refresher.push(null);
403 function selectedBand(uidx)
405 if (bands[uidx].length > 1) {
406 var e = E('_f_wl'+u+'_nband');
407 return (e.value + '' == '' ? eval('nvram.wl'+u+'_nband') : e.value);
408 } else if (bands[uidx].length > 0) {
409 return bands[uidx][0][0] || '0';
410 } else {
411 return '0';
415 function refreshNetModes(uidx)
417 var e, i, buf, val;
419 if (uidx >= wl_ifaces.length) return;
420 var u = wl_unit(uidx);
422 var m = [['mixed','Auto']];
423 if (selectedBand(uidx) == '1') {
424 m.push(['a-only','A Only']);
425 if (nphy) {
426 m.push(['n-only','N Only']);
429 else {
430 m.push(['b-only','B Only']);
431 m.push(['g-only','G Only']);
432 if (nphy) {
433 m.push(['bg-mixed','B/G Mixed']);
434 m.push(['n-only','N Only']);
438 e = E('_wl'+u+'_net_mode');
439 buf = '';
440 val = (!nm_loaded[uidx] || (e.value + '' == '')) ? eval('nvram.wl'+u+'_net_mode') : e.value;
441 if (val == 'disabled') val = 'mixed';
442 for (i = 0; i < m.length; ++i)
443 buf += '<option value="' + m[i][0] + '"' + ((m[i][0] == val) ? ' selected' : '') + '>' + m[i][1] + '</option>';
445 e = E('__wl'+u+'_net_mode');
446 buf = '<select name="wl'+u+'_net_mode" onchange="verifyFields(this, 1)" id = "_wl'+u+'_net_mode">' + buf + '</select>';
447 elem.setInnerHTML(e, buf);
448 nm_loaded[uidx] = 1;
451 function refreshChannels(uidx)
453 if (refresher[uidx] != null) return;
454 if (u >= wl_ifaces.length) return;
455 var u = wl_unit(uidx);
457 refresher[uidx] = new XmlHttp();
458 refresher[uidx].onCompleted = function(text, xml) {
459 try {
460 var e, i, buf, val;
462 var wl_channels = [];
463 eval(text);
465 ghz[uidx] = [];
466 max_channel[uidx] = 0;
467 for (i = 0; i < wl_channels.length; ++i) {
468 ghz[uidx].push([wl_channels[i][0] + '',
469 (wl_channels[i][0]) ? ((wl_channels[i][1]) ? wl_channels[i][0] + ' - ' + (wl_channels[i][1] / 1000.0).toFixed(3) + ' GHz' : wl_channels[i][0] + '') : 'Auto']);
470 max_channel[uidx] = wl_channels[i][0] * 1;
473 e = E('_wl'+u+'_channel');
474 buf = '';
475 val = (!ch_loaded[uidx] || (e.value + '' == '')) ? eval('nvram.wl'+u+'_channel') : e.value;
476 for (i = 0; i < ghz[uidx].length; ++i)
477 buf += '<option value="' + ghz[uidx][i][0] + '"' + ((ghz[uidx][i][0] == val) ? ' selected' : '') + '>' + ghz[uidx][i][1] + '</option>';
479 e = E('__wl'+u+'_channel');
480 buf = '<select name="wl'+u+'_channel" onchange="verifyFields(this, 1)" id = "_wl'+u+'_channel">' + buf + '</select>';
481 elem.setInnerHTML(e, buf);
482 ch_loaded[uidx] = 1;
484 refresher[uidx] = null;
485 verifyFields(null, 1);
487 catch (x) {
489 refresher[uidx] = null;
492 var bw, sb, e;
494 e = E('_f_wl'+u+'_nctrlsb');
495 sb = (e.value + '' == '' ? eval('nvram.wl'+u+'_nctrlsb') : e.value);
496 e = E('_wl'+u+'_nbw_cap');
497 bw = (e.value + '' == '' ? eval('nvram.wl'+u+'_nbw_cap') : e.value) == '0' ? '20' : '40';
499 refresher[uidx].onError = function(ex) { alert(ex); refresher[uidx] = null; reloadPage(); }
500 refresher[uidx].post('update.cgi', 'exec=wlchannels&arg0=' + u + '&arg1=' + (nphy ? '1' : '0') +
501 '&arg2=' + bw + '&arg3=' + selectedBand(uidx) + '&arg4=' + sb);
504 function spin(x, unit)
506 for (var u = 0; u < wl_ifaces.length; ++u) {
507 E('_f_wl'+wl_unit(u)+'_scan').disabled = x;
509 var e = E('_f_wl'+unit+'_scan');
510 if (x) e.value = 'Scan ' + (wscan.tries + 1);
511 else e.value = 'Scan';
512 E('spin'+unit).style.visibility = x ? 'visible' : 'hidden';
515 function scan()
517 if (xob) return;
519 var unit = wscan.unit;
520 var uidx = wl_uidx(unit);
522 xob = new XmlHttp();
523 xob.onCompleted = function(text, xml) {
524 try {
525 var i;
527 wlscandata = [];
528 eval(text);
530 for (i = 0; i < wlscandata.length; ++i) {
531 var data = wlscandata[i];
532 var ch = data[2];
533 var mac = data[0];
535 if (!wscan.inuse[ch]) {
536 wscan.inuse[ch] = {
537 count: 0,
538 rssi: -999,
539 ssid: ''
543 if (!wscan.seen[mac]) {
544 wscan.seen[mac] = 1;
545 ++wscan.inuse[ch].count;
548 if (data[4] > wscan.inuse[ch].rssi) {
549 wscan.inuse[ch].rssi = data[4];
550 wscan.inuse[ch].ssid = data[1];
553 var e = E('_wl'+unit+'_channel');
554 for (i = 1; i < ghz[uidx].length; ++i) {
555 var s = ghz[uidx][i][1];
556 var u = wscan.inuse[ghz[uidx][i][0]];
557 if (u) s += ' (' + u.count + ' AP' + (u.count == 1 ? '' : 's') + ' / strongest: "' + escapeHTML(ellipsis(u.ssid, 15)) + '" ' + u.rssi + ' dBm)';
558 e.options[i].innerHTML = s;
560 e.style.width = '400px';
562 xob = null;
564 if (wscan.tries < 4) {
565 ++wscan.tries;
566 setTimeout(scan, 1000);
567 return;
570 catch (x) {
572 spin(0, unit);
574 xob.onError = function(x) {
575 alert('error: ' + x);
576 spin(0, unit);
577 xob = null;
580 spin(1, unit);
581 xob.post('update.cgi', 'exec=wlscan&arg0='+unit);
584 function scanButton(u)
586 if (xob) return;
588 wscan = {
589 unit: u,
590 seen: [],
591 inuse: [],
592 tries: 0
595 scan();
598 function joinAddr(a) {
599 var r, i, s;
601 r = [];
602 for (i = 0; i < a.length; ++i) {
603 s = a[i];
604 if ((s != '00:00:00:00:00:00') && (s != '0.0.0.0')) r.push(s);
606 return r.join(' ');
609 function random_x(max)
611 var c = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
612 var s = '';
613 while (max-- > 0) s += c.substr(Math.floor(c.length * Math.random()), 1);
614 return s;
617 function random_psk(id)
619 var e = E(id);
620 e.value = random_x(63);
621 verifyFields(null, 1);
624 function random_wep(u)
626 E('_wl'+u+'_passphrase').value = random_x(16);
627 generate_wep(u);
630 function v_wep(e, quiet)
632 var s = e.value;
634 if (((s.length == 5) || (s.length == 13)) && (s.length == (e.maxLength >> 1))) {
635 // no checking
637 else {
638 s = s.toUpperCase().replace(/[^0-9A-F]/g, '');
639 if (s.length != e.maxLength) {
640 ferror.set(e, 'Invalid WEP key. Expecting ' + e.maxLength + ' hex or ' + (e.maxLength >> 1) + ' ASCII characters.', quiet);
641 return 0;
645 e.value = s;
646 ferror.clear(e);
647 return 1;
650 // compatible w/ Linksys' and Netgear's (key 1) method for 128-bits
651 function generate_wep(u)
653 function _wepgen(pass, i)
655 while (pass.length < 64) pass += pass;
656 return hex_md5(pass.substr(0, 64)).substr(i, (E('_wl'+u+'_wep_bit').value == 128) ? 26 : 10);
659 var e = E('_wl'+u+'_passphrase');
660 var pass = e.value;
661 if (!v_length(e, false, 3)) return;
662 E('_wl'+u+'_key1').value = _wepgen(pass, 0);
663 pass += '#$%';
664 E('_wl'+u+'_key2').value = _wepgen(pass, 2);
665 pass += '!@#';
666 E('_wl'+u+'_key3').value = _wepgen(pass, 4);
667 pass += '%&^';
668 E('_wl'+u+'_key4').value = _wepgen(pass, 6);
669 verifyFields(null, 1);
672 function verifyFields(focused, quiet)
674 var i;
675 var ok = 1;
676 var a, b, c, d, e;
677 var u, uidx;
678 var wmode, sm2;
680 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
681 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
682 if (wl_sunit(uidx)<0) {
683 u = wl_unit(uidx);
684 if (focused == E('_f_wl'+u+'_nband')) {
685 refreshNetModes(uidx);
686 refreshChannels(uidx);
688 else if (focused == E('_f_wl'+u+'_nctrlsb') || focused == E('_wl'+u+'_nbw_cap')) {
689 refreshChannels(uidx);
694 // --- visibility ---
696 var vis = {
697 _wan_proto: 1,
698 _ppp_username: 1,
699 _ppp_passwd: 1,
700 _ppp_service: 1,
701 _ppp_custom: 1,
702 _l2tp_server_ip: 1,
703 _wan_ipaddr: 1,
704 _wan_netmask: 1,
705 _wan_gateway: 1,
706 _pptp_server_ip: 1,
707 _f_pptp_dhcp: 1,
708 _ppp_demand: 1,
709 _ppp_idletime: 1,
710 _ppp_redialperiod: 1,
711 _mtu_enable: 1,
712 _f_wan_mtu: 1,
713 _f_wan_islan: 0,
714 _f_ppp_mlppp: 1,
715 _modem_ipaddr: 1,
717 _f_dns_1: 1,
718 _f_dns_2: 1,
719 _f_dns_3: 1,
720 /* DNSCRYPT-BEGIN */
721 _f_dnscrypt_proxy: 1,
722 /* DNSCRYPT-END */
723 _lan_gateway: 1,
724 _wan_wins: 1,
725 _modem_pin: 1,
726 _modem_dev: 1,
727 _modem_init: 1,
728 _modem_apn: 1
731 var wl_vis = [];
732 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
733 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
734 if (wl_sunit(uidx)<0) {
735 a = {
736 _f_wl_radio: 1,
737 _f_wl_mode: 1,
738 _f_wl_nband: (bands[uidx].length > 1) ? 1 : 0,
739 _wl_net_mode: 1,
740 _wl_ssid: 1,
741 _f_wl_bcast: 1,
742 _wl_channel: 1,
743 _wl_nbw_cap: nphy ? 1 : 0,
744 _f_wl_nctrlsb: nphy ? 1 : 0,
745 _f_wl_scan: 1,
747 _wl_security_mode: 1,
748 _wl_crypto: 1,
749 _wl_wpa_psk: 1,
750 _f_wl_psk_random1: 1,
751 _f_wl_psk_random2: 1,
752 _wl_wpa_gtk_rekey: 1,
753 _wl_radius_key: 1,
754 _wl_radius_ipaddr: 1,
755 _wl_radius_port: 1,
756 _wl_wep_bit: 1,
757 _wl_passphrase: 1,
758 _f_wl_wep_gen: 1,
759 _f_wl_wep_random: 1,
760 _wl_key1: 1,
761 _wl_key2: 1,
762 _wl_key3: 1,
763 _wl_key4: 1,
765 _f_wl_lazywds: 1,
766 _f_wl_wds_0: 1
768 wl_vis.push(a);
772 var wan = E('_wan_proto').value;
774 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
775 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
776 if (wl_sunit(uidx)<0) {
777 wmode = E('_f_wl'+wl_unit(uidx)+'_mode').value;
779 if (wmode == 'wet') {
780 wan = 'disabled';
781 vis._wan_proto = 0;
784 if ((wan == 'disabled') || (wmode == 'sta') || (wmode == 'wet')) {
785 vis._f_wan_islan = 1;
790 switch (wan) {
791 case 'disabled':
792 vis._ppp_username = 0;
793 vis._ppp_service = 0;
794 vis._ppp_custom = 0;
795 vis._l2tp_server_ip = 0;
796 vis._wan_ipaddr = 0;
797 vis._wan_netmask = 0;
798 vis._wan_gateway = 0;
799 vis._pptp_server_ip = 0;
800 vis._f_pptp_dhcp = 0;
801 vis._ppp_demand = 0;
802 vis._mtu_enable = 0;
803 vis._f_wan_mtu = 0;
804 vis._f_ppp_mlppp = 0;
805 vis._modem_ipaddr = 0;
806 vis._modem_pin = 0;
807 vis._modem_dev = 0;
808 vis._modem_init = 0;
809 vis._modem_apn = 0;
810 break;
811 case 'dhcp':
812 vis._l2tp_server_ip = 0;
813 vis._ppp_demand = 0;
814 vis._ppp_service = 0;
815 vis._ppp_username = 0;
816 vis._ppp_custom = 0;
817 vis._pptp_server_ip = 0;
818 vis._f_pptp_dhcp = 0;
819 vis._wan_gateway = 0;
820 vis._wan_ipaddr = 0;
821 vis._wan_netmask = 0;
822 vis._f_ppp_mlppp = 0;
823 vis._modem_ipaddr = 1;
825 vis._lan_gateway = 0;
826 vis._modem_pin = 0;
827 vis._modem_dev = 0;
828 vis._modem_init = 0;
829 vis._modem_apn = 0;
830 break;
831 case 'pppoe':
832 vis._l2tp_server_ip = 0;
833 vis._pptp_server_ip = 0;
834 vis._f_pptp_dhcp = 0;
835 vis._wan_gateway = 0;
836 vis._wan_ipaddr = 0;
837 vis._wan_netmask = 0;
838 vis._modem_ipaddr = 1;
840 vis._lan_gateway = 0;
841 vis._modem_pin = 0;
842 vis._modem_dev = 0;
843 vis._modem_init = 0;
844 vis._modem_apn = 0;
845 break;
846 case 'ppp3g':
847 vis._ppp_service = 0;
848 vis._l2tp_server_ip = 0;
849 vis._pptp_server_ip = 0;
850 vis._f_pptp_dhcp = 0;
851 vis._wan_gateway = 0;
852 vis._wan_ipaddr = 0;
853 vis._wan_netmask = 0;
854 vis._lan_gateway = 0;
855 vis._modem_ipaddr = 0;
856 vis._f_ppp_mlppp = 0;
857 break;
858 case 'static':
859 vis._l2tp_server_ip = 0;
860 vis._ppp_demand = 0;
861 vis._ppp_service = 0;
862 vis._ppp_username = 0;
863 vis._ppp_custom = 0;
864 vis._pptp_server_ip = 0;
865 vis._f_pptp_dhcp = 0;
866 vis._f_ppp_mlppp = 0;
867 vis._modem_ipaddr = 1;
869 vis._lan_gateway = 0;
870 vis._modem_pin = 0;
871 vis._modem_dev = 0;
872 vis._modem_init = 0;
873 vis._modem_apn = 0;
874 break;
875 case 'pptp':
876 vis._l2tp_server_ip = 0;
877 vis._ppp_service = 0;
878 vis._wan_gateway = (!E('_f_pptp_dhcp').checked);
879 vis._wan_ipaddr = (!E('_f_pptp_dhcp').checked);
880 vis._modem_ipaddr = 0;
882 vis._lan_gateway = 0;
883 vis._modem_pin = 0;
884 vis._modem_dev = 0;
885 vis._modem_init = 0;
886 vis._modem_apn = 0;
887 break;
888 case 'l2tp':
889 vis._pptp_server_ip = 0;
890 vis._ppp_service = 0;
891 vis._wan_gateway = (!E('_f_pptp_dhcp').checked);
892 vis._wan_ipaddr = (!E('_f_pptp_dhcp').checked);
893 vis._modem_ipaddr = 0;
895 vis._lan_gateway = 0;
896 vis._modem_pin = 0;
897 vis._modem_dev = 0;
898 vis._modem_init = 0;
899 vis._modem_apn = 0;
900 break;
903 vis._ppp_idletime = (E('_ppp_demand').value == 1) && vis._ppp_demand
904 vis._ppp_redialperiod = !vis._ppp_idletime && vis._ppp_demand;
906 if (vis._mtu_enable) {
907 if (E('_mtu_enable').value == 0) {
908 vis._f_wan_mtu = 2;
909 a = E('_f_wan_mtu');
910 switch (E('_wan_proto').value) {
911 case 'pppoe':
912 a.value = 1492;
913 break;
914 case 'pptp':
915 case 'l2tp':
916 a.value = 1460;
917 break;
918 default:
919 a.value = 1500;
920 break;
925 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
926 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
927 if (wl_sunit(uidx)<0) {
928 u = wl_unit(uidx);
929 wmode = E('_f_wl'+u+'_mode').value;
931 if (!E('_f_wl'+u+'_radio').checked) {
932 for (a in wl_vis[uidx]) {
933 wl_vis[uidx][a] = 2;
935 wl_vis[uidx]._f_wl_radio = 1;
936 wl_vis[uidx]._wl_nbw_cap = nphy ? 2 : 0;
937 wl_vis[uidx]._f_wl_nband = (bands[uidx].length > 1) ? 2 : 0;
940 switch (wmode) {
941 case 'apwds':
942 case 'wds':
943 break;
944 case 'wet':
945 case 'sta':
946 wl_vis[uidx]._f_wl_bcast = 0;
947 wl_vis[uidx]._wl_channel = 0;
948 wl_vis[uidx]._wl_nbw_cap = 0;
949 vis._modem_ipaddr = 0;
950 default:
951 wl_vis[uidx]._f_wl_lazywds = 0;
952 wl_vis[uidx]._f_wl_wds_0 = 0;
953 break;
956 sm2 = E('_wl'+u+'_security_mode').value;
957 switch (sm2) {
958 case 'disabled':
959 wl_vis[uidx]._wl_crypto = 0;
960 wl_vis[uidx]._wl_wep_bit = 0;
961 wl_vis[uidx]._wl_wpa_psk = 0;
962 wl_vis[uidx]._wl_radius_key = 0;
963 wl_vis[uidx]._wl_radius_ipaddr = 0;
964 wl_vis[uidx]._wl_wpa_gtk_rekey = 0;
965 break;
966 case 'wep':
967 wl_vis[uidx]._wl_crypto = 0;
968 wl_vis[uidx]._wl_wpa_psk = 0;
969 wl_vis[uidx]._wl_radius_key = 0;
970 wl_vis[uidx]._wl_radius_ipaddr = 0;
971 wl_vis[uidx]._wl_wpa_gtk_rekey = 0;
972 break;
973 case 'radius':
974 wl_vis[uidx]._wl_crypto = 0;
975 wl_vis[uidx]._wl_wpa_psk = 0;
976 break;
977 default: // wpa*
978 wl_vis[uidx]._wl_wep_bit = 0;
979 if (sm2.indexOf('personal') != -1) {
980 wl_vis[uidx]._wl_radius_key = 0;
981 wl_vis[uidx]._wl_radius_ipaddr = 0;
983 else {
984 wl_vis[uidx]._wl_wpa_psk = 0;
986 break;
989 if ((E('_f_wl'+u+'_lazywds').value == 1) && (wl_vis[uidx]._f_wl_wds_0 == 1)) {
990 wl_vis[uidx]._f_wl_wds_0 = 2;
993 if (wl_vis[uidx]._wl_nbw_cap != 0) {
994 switch (E('_wl'+u+'_net_mode').value) {
995 case 'b-only':
996 case 'g-only':
997 case 'a-only':
998 case 'bg-mixed':
999 wl_vis[uidx]._wl_nbw_cap = 2;
1000 if (E('_wl'+u+'_nbw_cap').value != '0') {
1001 E('_wl'+u+'_nbw_cap').value = 0;
1002 refreshChannels(uidx);
1004 break;
1006 // avoid Enterprise-TKIP with 40MHz
1007 if ((sm2 == 'wpa_enterprise') && (E('_wl'+u+'_crypto').value == 'tkip')) {
1008 wl_vis[uidx]._wl_nbw_cap = 2;
1009 if (E('_wl'+u+'_nbw_cap').value != '0') {
1010 E('_wl'+u+'_nbw_cap').value = 0;
1011 refreshChannels(uidx);
1016 wl_vis[uidx]._f_wl_nctrlsb = (E('_wl'+u+'_nbw_cap').value == 0) ? 0 : wl_vis[uidx]._wl_nbw_cap;
1018 /* REMOVE-BEGIN
1019 This is ugly...
1020 Special case - 2.4GHz band, currently running in B/G-only mode,
1021 with N/Auto and 40MHz selected in the GUI.
1022 Channel list is not filtered in this case by the wl driver,
1023 and includes all channels available with 20MHz channel width.
1024 REMOVE-END */
1025 b = selectedBand(uidx);
1026 if (wl_vis[uidx]._wl_channel == 1 && wl_vis[uidx]._f_wl_nctrlsb != 0 &&
1027 ((b == '2') || (wl_vis[uidx]._f_wl_nband == 0 && b == '0'))) {
1028 switch (eval('nvram.wl'+u+'_net_mode')) {
1029 case 'b-only':
1030 case 'g-only':
1031 case 'bg-mixed':
1032 i = E('_wl'+u+'_channel').value * 1;
1033 if (i > 0 && i < 5) {
1034 E('_f_wl'+u+'_nctrlsb').value = 'lower';
1035 wl_vis[uidx]._f_wl_nctrlsb = 2;
1037 else if (i > max_channel[uidx] - 4) {
1038 E('_f_wl'+u+'_nctrlsb').value = 'upper';
1039 wl_vis[uidx]._f_wl_nctrlsb = 2;
1041 break;
1045 wl_vis[uidx]._f_wl_scan = wl_vis[uidx]._wl_channel;
1046 wl_vis[uidx]._f_wl_psk_random1 = wl_vis[uidx]._wl_wpa_psk;
1047 wl_vis[uidx]._f_wl_psk_random2 = wl_vis[uidx]._wl_radius_key;
1048 wl_vis[uidx]._wl_radius_port = wl_vis[uidx]._wl_radius_ipaddr;
1049 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;
1051 for (i = 1; i < 10; ++i) {
1052 wl_vis[uidx]['_f_wl_wds_' + i] = wl_vis[uidx]._f_wl_wds_0;
1055 } // for each wl_iface
1057 vis._ppp_passwd = vis._ppp_username;
1059 for (a in vis) {
1060 b = E(a);
1061 c = vis[a];
1062 /* REMOVE-BEGIN
1063 // if (b != null)
1064 REMOVE-END */
1065 b.disabled = (c != 1);
1066 PR(b).style.display = c ? '' : 'none';
1069 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1070 if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1071 for (a in wl_vis[uidx]) {
1072 i = 3;
1073 if (a.substr(0, 6) == '_f_wl_') i = 5;
1074 b = E(a.substr(0, i) + wl_unit(uidx) + a.substr(i, a.length));
1075 c = wl_vis[uidx][a];
1076 b.disabled = (c != 1);
1077 PR(b).style.display = c ? '' : 'none';
1082 // --- verify ---
1084 ferror.clear('_wan_proto');
1086 var wlclnt = 0;
1087 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1088 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1089 if (wl_sunit(uidx)<0) {
1090 u = wl_unit(uidx);
1091 wmode = E('_f_wl'+u+'_mode').value;
1092 sm2 = E('_wl'+u+'_security_mode').value;
1094 /* REMOVE-BEGIN
1095 if ((wl_vis[uidx]._f_wl_mode == 1) && (wmode != 'ap') && (sm2.substr(0, 4) == 'wpa2')) {
1096 ferror.set('_wl'+u+'_security_mode', 'WPA2 is supported only in AP mode.', quiet || !ok);
1097 ok = 0;
1099 else ferror.clear('_wl'+u+'_security_mode');
1100 REMOVE-END */
1102 // --- N standard does not support WPA+TKIP ---
1103 a = E('_wl'+u+'_crypto');
1104 switch (E('_wl'+u+'_net_mode').value) {
1105 case 'mixed':
1106 case 'n-only':
1107 if (nphy && (a.value == 'tkip') && (sm2.indexOf('wpa') != -1)) {
1108 ferror.set(a, 'TKIP encryption is not supported with WPA / WPA2 in N mode.', quiet || !ok);
1109 ok = 0;
1111 else ferror.clear(a);
1112 break;
1115 a = E('_wl'+u+'_net_mode');
1116 ferror.clear(a);
1117 b = E('_f_wl'+u+'_mode');
1118 ferror.clear(b);
1119 if ((wmode == 'sta') || (wmode == 'wet')) {
1120 ++wlclnt;
1121 if (wlclnt > 1) {
1122 ferror.set(b, 'Only one wireless interface can be configured in client mode.', quiet || !ok);
1123 ok = 0;
1125 else if (a.value == 'n-only') {
1126 ferror.set(a, 'N-only is not supported in wireless client modes, use Auto.', quiet || !ok);
1127 ok = 0;
1131 a = E('_wl'+u+'_wpa_psk');
1132 ferror.clear(a);
1133 if (wl_vis[uidx]._wl_wpa_psk == 1) {
1134 if ((a.value.length < 8) || ((a.value.length == 64) && (a.value.search(/[^0-9A-Fa-f]/) != -1))) {
1135 ferror.set('_wl'+u+'_wpa_psk', 'Invalid pre-shared key. Please enter at least 8 characters or 64 hexadecimal digits.', quiet || !ok);
1136 ok = 0;
1140 // wl channel
1141 if (((wmode == 'wds') || (wmode == 'apwds')) && (wl_vis[uidx]._wl_channel == 1) && (E('_wl'+u+'_channel').value == '0')) {
1142 ferror.set('_wl'+u+'_channel', 'Fixed wireless channel required in WDS mode.', quiet || !ok);
1143 ok = 0;
1145 else ferror.clear('_wl'+u+'_channel');
1147 if (E('_f_wl'+u+'_mode').value == 'sta') {
1148 if ((wan == 'disabled') && (E('_f_wl'+u+'_radio').checked)) {
1149 ferror.set('_wan_proto', 'Wireless Client mode requires a valid WAN setting (usually DHCP).', quiet || !ok);
1150 ok = 0;
1156 // domain name or IP address
1157 a = ['_l2tp_server_ip', '_pptp_server_ip'];
1158 for (i = a.length - 1; i >= 0; --i)
1159 if ((vis[a[i]]) && ((!v_length(a[i], 1, 1)) || ((!v_ip(a[i], 1)) && (!v_domain(a[i], 1))))) {
1160 if (!quiet && ok) ferror.show(a[i]);
1161 ok = 0;
1164 // IP address
1165 a = ['_wan_gateway','_wan_ipaddr'];
1166 for (i = a.length - 1; i >= 0; --i)
1167 if ((vis[a[i]]) && (!v_ip(a[i], quiet || !ok))) ok = 0;
1169 // IP address, blank -> 0.0.0.0
1170 a = ['_f_dns_1', '_f_dns_2', '_f_dns_3','_wan_wins','_lan_gateway', '_modem_ipaddr'];
1171 for (i = a.length - 1; i >= 0; --i)
1172 if ((vis[a[i]]) && (!v_dns(a[i], quiet || !ok))) ok = 0;
1174 // netmask
1175 a = ['_wan_netmask'];
1176 for (i = a.length - 1; i >= 0; --i)
1177 if ((vis[a[i]]) && (!v_netmask(a[i], quiet || !ok))) ok = 0;
1179 // range
1180 a = [['_ppp_idletime', 3, 1440],['_ppp_redialperiod', 1, 86400],['_f_wan_mtu', 576, 1500]];
1181 for (i = a.length - 1; i >= 0; --i) {
1182 v = a[i];
1183 if ((vis[v[0]]) && (!v_range(v[0], quiet || !ok, v[1], v[2]))) ok = 0;
1186 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1187 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1188 if (wl_sunit(uidx)<0) {
1189 u = wl_unit(uidx);
1191 // IP address
1192 a = ['_radius_ipaddr'];
1193 for (i = a.length - 1; i >= 0; --i) {
1194 if ((wl_vis[uidx]['_wl'+a[i]]) && (!v_ip('_wl'+u+a[i], quiet || !ok))) ok = 0;
1197 // range
1198 a = [['_wpa_gtk_rekey', 60, 7200], ['_radius_port', 1, 65535]];
1199 for (i = a.length - 1; i >= 0; --i) {
1200 v = a[i];
1201 if ((wl_vis[uidx]['_wl'+v[0]]) && (!v_range('_wl'+u+v[0], quiet || !ok, v[1], v[2]))) ok = 0;
1204 // length
1205 a = [['_ssid', 1], ['_radius_key', 1]];
1206 for (i = a.length - 1; i >= 0; --i) {
1207 v = a[i];
1208 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;
1211 if (wl_vis[uidx]._wl_key1) {
1212 a = (E('_wl'+u+'_wep_bit').value == 128) ? 26 : 10;
1213 for (i = 1; i <= 4; ++i) {
1214 b = E('_wl'+u+'_key' + i);
1215 b.maxLength = a;
1216 if ((b.value.length > 0) || (E('_f_wl'+u+'_wepidx_' + i).checked)) {
1217 if (!v_wep(b, quiet || !ok)) ok = 0;
1219 else ferror.clear(b);
1223 ferror.clear('_f_wl'+u+'_wds_0');
1224 if (wl_vis[uidx]._f_wl_wds_0 == 1) {
1225 b = 0;
1226 for (i = 0; i < 10; ++i) {
1227 a = E('_f_wl'+u+'_wds_' + i);
1228 if (!v_macz(a, quiet || !ok)) ok = 0;
1229 else if (!isMAC0(a.value)) b = 1;
1231 if (!b) {
1232 ferror.set('_f_wl'+u+'_wds_0', 'WDS MAC address required.', quiet || !ok);
1233 ok = 0;
1239 return ok;
1242 function earlyInit()
1244 verifyFields(null, 1);
1247 function save()
1249 if (lg.isEditing()) return;
1250 lg.resetNewEditor();
1252 var a, b, c;
1253 var i;
1254 var u, uidx, wmode, sm2, wradio;
1256 if (!verifyFields(null, false)) return;
1258 var fom = E('_fom');
1260 fom.wan_mtu.value = fom.f_wan_mtu.value;
1261 fom.wan_mtu.disabled = fom.f_wan_mtu.disabled;
1263 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1264 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1265 if (wl_sunit(uidx)<0) {
1266 u = wl_unit(uidx);
1267 wmode = E('_f_wl'+u+'_mode').value;
1268 sm2 = E('_wl'+u+'_security_mode').value;
1269 wradio = E('_f_wl'+u+'_radio').checked;
1271 E('_wl'+u+'_nband').value = selectedBand(uidx);
1273 if (wmode == 'apwds') E('_wl'+u+'_mode').value = 'ap';
1274 else E('_wl'+u+'_mode').value = wmode;
1276 if (wmode == 'wet') {
1277 fom.wan_proto.value = 'disabled';
1278 fom.wan_proto.disabled = 0;
1279 /* REMOVE-BEGIN */
1280 // TODO - what's required ? integrate with tomatogrid?
1281 /* REMOVE-END */
1284 a = [];
1285 for (i = 0; i < 10; ++i) a.push(E('_f_wl'+u+'_wds_' + i).value);
1286 E('_wl'+u+'_wds').value = joinAddr(a);
1288 if (wmode.indexOf('wds') != -1) {
1289 E('_wl'+u+'_wds_enable').value = 1;
1290 E('_wl'+u+'_lazywds').value = E('_f_wl'+u+'_lazywds').value;
1291 if (E('_wl'+u+'_lazywds').value == 1) E('_wl'+u+'_wds').value = '';
1293 else {
1294 E('_wl'+u+'_wds_enable').value = 0;
1295 E('_wl'+u+'_wds').value = '';
1296 E('_wl'+u+'_lazywds').value = 0;
1299 E('_wl'+u+'_radio').value = wradio ? 1 : 0;
1300 E('_wl'+u+'_auth').value = eval('nvram.wl'+u+'_auth');
1302 e = E('_wl'+u+'_akm');
1303 switch (sm2) {
1304 case 'disabled':
1305 case 'radius':
1306 case 'wep':
1307 e.value = '';
1308 break;
1309 default:
1310 c = [];
1312 if (sm2.indexOf('personal') != -1) {
1313 if (sm2.indexOf('wpa2_') == -1) c.push('psk');
1314 if (sm2.indexOf('wpa_') == -1) c.push('psk2');
1316 else {
1317 if (sm2.indexOf('wpa2_') == -1) c.push('wpa');
1318 if (sm2.indexOf('wpa_') == -1) c.push('wpa2');
1320 c = c.join(' ');
1321 e.value = c;
1322 break;
1324 E('_wl'+u+'_auth_mode').value = (sm2 == 'radius') ? 'radius' : 'none';
1325 E('_wl'+u+'_wep').value = ((sm2 == 'radius') || (sm2 == 'wep')) ? 'enabled': 'disabled';
1327 if (sm2.indexOf('wpa') != -1) E('_wl'+u+'_auth').value = 0;
1329 E('_wl'+u+'_nreqd').value = 0;
1330 E('_wl'+u+'_gmode').value = 1;
1331 E('_wl'+u+'_nmode').value = 0;
1332 E('_wl'+u+'_nmcsidx').value = -2; // Legacy Rate
1333 E('_wl'+u+'_nbw').value = 0;
1334 switch (E('_wl'+u+'_net_mode').value) {
1335 case 'b-only':
1336 E('_wl'+u+'_gmode').value = 0;
1337 break;
1338 case 'g-only':
1339 E('_wl'+u+'_gmode').value = 4;
1340 break;
1341 case 'bg-mixed':
1342 break;
1343 case 'a-only':
1344 E('_wl'+u+'_nmcsidx').value = -1; // Auto
1345 break;
1346 case 'n-only':
1347 if (selectedBand(uidx) == '1') { // 5 GHz
1348 E('_wl'+u+'_nmode').value = -1;
1349 E('_wl'+u+'_nmcsidx').value = -1;
1350 } else {
1351 E('_wl'+u+'_nmode').value = 1;
1352 E('_wl'+u+'_nmcsidx').value = 32;
1354 E('_wl'+u+'_nreqd').value = 1;
1355 break;
1356 default: // Auto
1357 E('_wl'+u+'_nmode').value = -1;
1358 E('_wl'+u+'_nmcsidx').value = -1;
1359 break;
1362 E('_wl'+u+'_nctrlsb').value = eval('nvram.wl'+u+'_nctrlsb');
1363 if (E('_wl'+u+'_nmode').value != 0) {
1364 E('_wl'+u+'_nctrlsb').value = E('_f_wl'+u+'_nctrlsb').value;
1365 E('_wl'+u+'_nbw').value = (E('_wl'+u+'_nbw_cap').value == 0) ? 20 : 40;
1368 E('_wl'+u+'_closed').value = E('_f_wl'+u+'_bcast').checked ? 0 : 1;
1370 a = fields.radio.selected(eval('fom.f_wl'+u+'_wepidx'));
1371 if (a) E('_wl'+u+'_key').value = a.value;
1375 fom.wan_islan.value = fom.f_wan_islan.checked ? 1 : 0;
1376 fom.pptp_dhcp.value = fom.f_pptp_dhcp.checked ? 1 : 0;
1378 fom.wan_dns.value = joinAddr([fom.f_dns_1.value, fom.f_dns_2.value, fom.f_dns_3.value]);
1380 /* DNSCRYPT-BEGIN */
1381 fom.dnscrypt_proxy.value = fom.f_dnscrypt_proxy.checked ? 1 : 0;
1382 /* DNSCRYPT-END */
1384 // initialize/wipe out relevant fields
1385 for (var i = 0 ; i <= MAX_BRIDGE_ID ; i++) {
1386 var j = (i == 0) ? '' : i.toString();
1387 fom['lan' + j + '_ifname'].value = '';
1388 fom['lan' + j + '_ipaddr'].value = '';
1389 fom['lan' + j + '_netmask'].value = '';
1390 fom['lan' + j + '_proto'].value = '';
1391 fom['lan' + j + '_stp'].value = '';
1392 fom['dhcp' + j + '_start'].value = '';
1393 fom['dhcp' + j + '_num'].value = '';
1394 fom['dhcp' + j + '_lease'].value = '';
1395 fom['dhcpd' + j + '_startip'].value = '';
1396 fom['dhcpd' + j + '_endip'].value = '';
1399 var d = lg.getAllData();
1400 for (var i = 0; i < d.length; ++i) {
1402 if (lg.countOverlappingNetworks(d[i][2]) > 1) {
1403 var s = 'Cannot proceed: two or more LAN bridges have conflicting IP addresses or overlapping subnets';
1404 alert(s);
1405 var e = E('footer-msg');
1406 e.innerHTML = s;
1407 e.style.visibility = 'visible';
1408 setTimeout(
1409 function() {
1410 e.innerHTML = '';
1411 e.style.visibility = 'hidden';
1412 }, 5000);
1413 return;
1416 var j = (parseInt(d[i][0]) == 0) ? '' : d[i][0].toString();
1417 fom['lan' + j + '_ifname'].value = 'br' + d[i][0];
1418 fom['lan' + j + '_stp'].value = d[i][1];
1419 fom['lan' + j + '_ipaddr'].value = d[i][2];
1420 fom['lan' + j + '_netmask'].value = d[i][3];
1421 fom['lan' + j + '_proto'].value = (d[i][4] != '0') ? 'dhcp' : 'static';
1422 fom['dhcp' + j + '_start'].value = (d[i][4] != '0') ? (d[i][5]).split('.').splice(3, 1) : '';
1423 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)
1424 fom['dhcp' + j + '_lease'].value = (d[i][4] != '0') ? d[i][7] : '';
1425 fom['dhcpd' + j + '_startip'].value = (d[i][4] != '0') ? d[i][5] : '';
1426 fom['dhcpd' + j + '_endip'].value = (d[i][4] != '0') ? d[i][6] : '';
1428 /* REMOVE-BEGIN */
1429 alert('lan' + j + '_ifname=' + fom['lan' + j + '_ifname'].value + '\n' +
1430 'lan' + j + '_stp=' + fom['lan' + j + '_stp'].value + '\n' +
1431 'lan' + j + '_ipaddr=' + fom['lan' + j + '_ipaddr'].value + '\n' +
1432 'lan' + j + '_netmask=' + fom['lan' + j + '_netmask'].value + '\n' +
1433 'lan' + j + '_proto=' + fom['lan' + j + '_proto'].value + '\n' +
1434 'dhcp' + j + '_start=' + fom['dhcp' + j + '_start'].value + '\n' +
1435 'dhcp' + j + '_num=' + fom['dhcp' + j + '_num'].value + '\n' +
1436 'dhcp' + j + '_lease=' + fom['dhcp' + j + '_lease'].value + '\n' +
1437 'dhcpd' + j + '_startip=' + fom['dhcpd' + j + '_startip'].value + '\n' +
1438 'dhcpd' + j + '_endip=' + fom['dhcpd' + j + '_endip'].value);
1439 /* REMOVE-END */
1442 var e = E('footer-msg');
1443 var t = fixIP(fom['lan_ipaddr'].value);
1444 if ((fom['lan_ifname'].value != 'br0') || (fom['lan_ipaddr'].value == '0.0.0.0') || (!t)) {
1445 e.innerHTML = 'Bridge br0 must be always defined and have a valid IP address set.';
1446 e.style.visibility = 'visible';
1447 setTimeout(
1448 function() {
1449 e.innerHTML = '';
1450 e.style.visibility = 'hidden';
1451 }, 5000);
1452 return;
1455 /* REMOVE-BEGIN
1456 // if ((nvram.lan_ipaddr != fom.lan_ipaddr.value) || (nvram.lan1_ipaddr != fom.lan1_ipaddr.value) ||
1457 // (nvram.lan2_ipaddr != fom.lan2_ipaddr.value) || (nvram.lan3_ipaddr != fom.lan3_ipaddr.value)){
1458 REMOVE-END */
1460 fom.ppp_mlppp.value = fom.f_ppp_mlppp.checked ? 1 : 0;
1462 if (nvram.lan_ipaddr != fom.lan_ipaddr.value) {
1463 fom._moveip.value = 1;
1464 form.submit(fom);
1466 else {
1467 form.submit(fom, 1);
1471 function init()
1473 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1474 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1475 if (wl_sunit(uidx)<0) {
1476 refreshNetModes(uidx);
1477 refreshChannels(uidx);
1481 </script>
1483 </head>
1484 <body onload='init()'>
1485 <form id='_fom' method='post' action='tomato.cgi'>
1486 <table id='container' cellspacing=0>
1487 <tr><td colspan=2 id='header'>
1488 <div class='title'>Tomato</div>
1489 <div class='version'>Version <% version(); %></div>
1490 </td></tr>
1491 <tr id='body'><td id='navi'><script type='text/javascript'>navi()</script></td>
1492 <td id='content'>
1493 <div id='ident'><% ident(); %></div>
1495 <!-- / / / -->
1497 <input type='hidden' name='_nextpage' value='basic-network.asp'>
1498 <input type='hidden' name='_nextwait' value='10'>
1499 <input type='hidden' name='_service' value='*'>
1500 <input type='hidden' name='_moveip' value='0'>
1502 <input type='hidden' name='wan_mtu'>
1503 <input type='hidden' name='wan_islan'>
1504 <input type='hidden' name='pptp_dhcp'>
1505 <input type='hidden' name='wan_dns'>
1506 <input type='hidden' name='ppp_mlppp'>
1507 /* DNSCRYPT-BEGIN */
1508 <input type='hidden' name='dnscrypt_proxy'>
1509 /* DNSCRYPT-END */
1511 <script type='text/javascript'>
1513 for (var i = 0 ; i <= MAX_BRIDGE_ID ; i++) {
1514 var j = (i == 0) ? '' : i.toString();
1515 W('<input type=\'hidden\' id=\'lan' + j + '_ifname\' name=\'lan' + j + '_ifname\'>');
1516 W('<input type=\'hidden\' id=\'lan' + j + '_ipaddr\' name=\'lan' + j + '_ipaddr\'>');
1517 W('<input type=\'hidden\' id=\'lan' + j + '_netmask\' name=\'lan' + j + '_netmask\'>');
1518 W('<input type=\'hidden\' id=\'lan' + j + '_proto\' name=\'lan' + j + '_proto\'>');
1519 W('<input type=\'hidden\' id=\'lan' + j + '_stp\' name=\'lan' + j + '_stp\'>');
1520 W('<input type=\'hidden\' id=\'dhcp' + j + '_start\' name=\'dhcp' + j + '_start\'>');
1521 W('<input type=\'hidden\' id=\'dhcp' + j + '_num\' name=\'dhcp' + j + '_num\'>');
1522 W('<input type=\'hidden\' id=\'dhcp' + j + '_lease\' name=\'dhcp' + j + '_lease\'>');
1523 W('<input type=\'hidden\' id=\'dhcpd' + j + '_startip\' name=\'dhcpd' + j + '_startip\'>');
1524 W('<input type=\'hidden\' id=\'dhcpd' + j + '_endip\' name=\'dhcpd' + j + '_endip\'>');
1526 </script>
1528 <div class='section-title'>WAN / Internet</div>
1529 <div class='section'>
1530 <script type='text/javascript'>
1531 createFieldTable('', [
1532 { title: 'Type', name: 'wan_proto', type: 'select', options: [['dhcp','DHCP'],['pppoe','PPPoE'],['static','Static'],['pptp','PPTP'],['l2tp','L2TP'],
1533 /* LINUX26-BEGIN */
1534 /* USB-BEGIN */
1535 ['ppp3g','3G Modem'],
1536 /* USB-END */
1537 /* LINUX26-END */
1538 ['disabled','Disabled']],
1539 value: nvram.wan_proto },
1540 { title: 'Modem device', name: 'modem_dev', type: 'select', options: [['ttyUSB0', '/dev/ttyUSB0'],['ttyUSB1', '/dev/ttyUSB1'],['ttyUSB2', '/dev/ttyUSB2'],['ttyUSB3', '/dev/ttyUSB3'],['ttyACM0', '/dev/ttyACM0']], value: nvram.modem_dev },
1541 { title: 'PIN Code', name: 'modem_pin', type: 'text', maxlen: 6, size: 8, value: nvram.modem_pin },
1542 { title: 'Modem init string', name: 'modem_init', type: 'text', maxlen: 25, size: 32, value: nvram.modem_init },
1543 { title: 'APN', name: 'modem_apn', type: 'text', maxlen: 25, size: 32, value: nvram.modem_apn },
1544 { title: 'Username', name: 'ppp_username', type: 'text', maxlen: 60, size: 64, value: nvram.ppp_username },
1545 { title: 'Password', name: 'ppp_passwd', type: 'password', maxlen: 60, size: 64, peekaboo: 1, value: nvram.ppp_passwd },
1546 { title: 'Service Name', name: 'ppp_service', type: 'text', maxlen: 50, size: 64, value: nvram.ppp_service },
1547 { title: 'L2TP Server', name: 'l2tp_server_ip', type: 'text', maxlen: 128, size: 64, value: nvram.l2tp_server_ip },
1548 { title: 'Use DHCP', name: 'f_pptp_dhcp', type: 'checkbox', value: (nvram.pptp_dhcp == 1) },
1549 { title: 'IP Address', name: 'wan_ipaddr', type: 'text', maxlen: 15, size: 17, value: nvram.wan_ipaddr },
1550 { title: 'Subnet Mask', name: 'wan_netmask', type: 'text', maxlen: 15, size: 17, value: nvram.wan_netmask },
1551 { title: 'Gateway', name: 'wan_gateway', type: 'text', maxlen: 15, size: 17, value: nvram.wan_gateway },
1552 { title: 'PPTP Gateway', name: 'pptp_server_ip', type: 'text', maxlen: 128, size: 64, value: nvram.pptp_server_ip },
1553 { title: 'Options', name: 'ppp_custom', type: 'text', maxlen: 256, size: 64, value: nvram.ppp_custom },
1554 { title: 'Connect Mode', name: 'ppp_demand', type: 'select', options: [['1', 'Connect On Demand'],['0', 'Keep Alive']],
1555 value: nvram.ppp_demand },
1556 { title: 'Max Idle Time', indent: 2, name: 'ppp_idletime', type: 'text', maxlen: 5, size: 7, suffix: ' <i>(minutes)</i>',
1557 value: nvram.ppp_idletime },
1558 { title: 'Check Interval', indent: 2, name: 'ppp_redialperiod', type: 'text', maxlen: 5, size: 7, suffix: ' <i>(seconds)</i>',
1559 value: nvram.ppp_redialperiod },
1560 { title: 'MTU', multi: [
1561 { name: 'mtu_enable', type: 'select', options: [['0', 'Default'],['1','Manual']], value: nvram.mtu_enable },
1562 { name: 'f_wan_mtu', type: 'text', maxlen: 4, size: 6, value: nvram.wan_mtu } ] },
1563 { title: 'Single Line MLPPP', name: 'f_ppp_mlppp', type: 'checkbox', value: (nvram.ppp_mlppp == 1) },
1565 { 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 },
1567 { title: 'Bridge WAN port to primary LAN (br0)', name: 'f_wan_islan', type: 'checkbox', value: (nvram.wan_islan == 1) }
1570 </script>
1571 </div>
1573 <div class='section-title'>LAN</div>
1574 <div class='section'>
1575 <table class='tomato-grid' cellspacing=1 id='lan-grid'></table>
1577 <script type='text/javascript'>lg.setup();</script>
1579 <script type='text/javascript'>
1580 dns = nvram.wan_dns.split(/\s+/);
1581 /* REMOVE-BEGIN
1582 //ipp = nvram.lan_ipaddr.split('.').splice(0, 3).join('.');
1583 REMOVE-END */
1584 createFieldTable('', [
1585 { title: 'Default Gateway', name: 'lan_gateway', type: 'text', maxlen: 15, size: 17, value: nvram.lan_gateway },
1586 { 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' },
1587 { title: '', name: 'f_dns_2', type: 'text', maxlen: 21, size: 25, value: dns[1] || '0.0.0.0' },
1588 { title: '', name: 'f_dns_3', type: 'text', maxlen: 21, size: 25, value: dns[2] || '0.0.0.0' },
1589 /* DNSCRYPT-BEGIN */
1590 { title: 'Use dnscrypt-proxy', name: 'f_dnscrypt_proxy', type: 'checkbox', value: (nvram.dnscrypt_proxy == 1) },
1591 /* DNSCRYPT-END */
1592 { title: 'WINS <i>(for DHCP)</i>', name: 'wan_wins', type: 'text', maxlen: 15, size: 17, value: nvram.wan_wins }
1594 </script>
1595 </div>
1597 <script type='text/javascript'>
1599 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1600 //if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1601 if (wl_sunit(uidx)<0) {
1602 var u = wl_unit(uidx);
1604 W('<input type=\'hidden\' id=\'_wl'+u+'_mode\' name=\'wl'+u+'_mode\'>');
1605 W('<input type=\'hidden\' id=\'_wl'+u+'_nband\' name=\'wl'+u+'_nband\'>');
1606 W('<input type=\'hidden\' id=\'_wl'+u+'_wds_enable\' name=\'wl'+u+'_wds_enable\'>');
1607 W('<input type=\'hidden\' id=\'_wl'+u+'_wds\' name=\'wl'+u+'_wds\'>');
1608 W('<input type=\'hidden\' id=\'_wl'+u+'_radio\' name=\'wl'+u+'_radio\'>');
1609 W('<input type=\'hidden\' id=\'_wl'+u+'_closed\' name=\'wl'+u+'_closed\'>');
1610 W('<input type=\'hidden\' id=\'_wl'+u+'_key\' name=\'wl'+u+'_key\'>');
1611 W('<input type=\'hidden\' id=\'_wl'+u+'_gmode\' name=\'wl'+u+'_gmode\'>');
1612 W('<input type=\'hidden\' id=\'_wl'+u+'_akm\' name=\'wl'+u+'_akm\'>');
1613 W('<input type=\'hidden\' id=\'_wl'+u+'_auth\' name=\'wl'+u+'_auth\'>');
1614 W('<input type=\'hidden\' id=\'_wl'+u+'_auth_mode\' name=\'wl'+u+'_auth_mode\'>');
1615 W('<input type=\'hidden\' id=\'_wl'+u+'_wep\' name=\'wl'+u+'_wep\'>');
1616 W('<input type=\'hidden\' id=\'_wl'+u+'_lazywds\' name=\'wl'+u+'_lazywds\'>');
1617 W('<input type=\'hidden\' id=\'_wl'+u+'_nmode\' name=\'wl'+u+'_nmode\'>');
1618 W('<input type=\'hidden\' id=\'_wl'+u+'_nmcsidx\' name=\'wl'+u+'_nmcsidx\'>');
1619 W('<input type=\'hidden\' id=\'_wl'+u+'_nreqd\' name=\'wl'+u+'_nreqd\'>');
1620 W('<input type=\'hidden\' id=\'_wl'+u+'_nctrlsb\' name=\'wl'+u+'_nctrlsb\'>');
1621 W('<input type=\'hidden\' id=\'_wl'+u+'_nbw\' name=\'wl'+u+'_nbw\'>');
1623 W('<div class=\'section-title\'>Wireless');
1624 // if (wl_ifaces.length > 1)
1625 W(' (' + wl_display_ifname(uidx) + ')');
1626 W('</div>');
1628 W('<div class=\'section\'>');
1630 f = [
1631 { title: 'Enable Wireless', name: 'f_wl'+u+'_radio', type: 'checkbox',
1632 value: (eval('nvram.wl'+u+'_radio') == '1') && (eval('nvram.wl'+u+'_net_mode') != 'disabled') },
1633 { title: 'MAC Address', text: '<a href="advanced-mac.asp">' + eval('nvram.wl'+u+'_hwaddr') + '</a>' },
1634 { title: 'Wireless Mode', name: 'f_wl'+u+'_mode', type: 'select',
1635 options: [['ap', 'Access Point'],['apwds', 'Access Point + WDS'],['sta', 'Wireless Client'],['wet', 'Wireless Ethernet Bridge'],['wds', 'WDS']],
1636 value: ((eval('nvram.wl'+u+'_mode') == 'ap') && (eval('nvram.wl'+u+'_wds_enable') == '1')) ? 'apwds' : eval('nvram.wl'+u+'_mode') },
1637 { title: 'Radio Band', name: 'f_wl'+u+'_nband', type: 'select', options: bands[uidx],
1638 value: eval('nvram.wl'+u+'_nband') || '0' == '0' ? bands[uidx][0][0] : eval('nvram.wl'+u+'_nband') },
1639 { title: 'Wireless Network Mode', name: 'wl'+u+'_net_mode', type: 'select',
1640 value: (eval('nvram.wl'+u+'_net_mode') == 'disabled') ? 'mixed' : eval('nvram.wl'+u+'_net_mode'),
1641 options: [], prefix: '<span id="__wl'+u+'_net_mode">', suffix: '</span>' },
1642 { title: 'SSID', name: 'wl'+u+'_ssid', type: 'text', maxlen: 32, size: 34, value: eval('nvram.wl'+u+'_ssid') },
1643 { title: 'Broadcast', indent: 2, name: 'f_wl'+u+'_bcast', type: 'checkbox', value: (eval('nvram.wl'+u+'_closed') == '0') },
1644 { 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+'">',
1645 value: eval('nvram.wl'+u+'_channel') },
1646 { title: 'Channel Width', name: 'wl'+u+'_nbw_cap', type: 'select', options: [['0','20 MHz'],['1','40 MHz']],
1647 value: eval('nvram.wl'+u+'_nbw_cap') },
1648 { title: 'Control Sideband', name: 'f_wl'+u+'_nctrlsb', type: 'select', options: [['lower','Lower'],['upper','Upper']],
1649 value: eval('nvram.wl'+u+'_nctrlsb') == 'none' ? 'lower' : eval('nvram.wl'+u+'_nctrlsb') },
1650 null,
1651 { title: 'Security', name: 'wl'+u+'_security_mode', type: 'select',
1652 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']],
1653 value: eval('nvram.wl'+u+'_security_mode') },
1654 { title: 'Encryption', indent: 2, name: 'wl'+u+'_crypto', type: 'select',
1655 options: [['tkip','TKIP'],['aes','AES'],['tkip+aes','TKIP / AES']], value: eval('nvram.wl'+u+'_crypto') },
1656 { title: 'Shared Key', indent: 2, name: 'wl'+u+'_wpa_psk', type: 'password', maxlen: 64, size: 66, peekaboo: 1,
1657 suffix: ' <input type="button" id="_f_wl'+u+'_psk_random1" value="Random" onclick="random_psk(\'_wl'+u+'_wpa_psk\')">',
1658 value: eval('nvram.wl'+u+'_wpa_psk') },
1659 { title: 'Shared Key', indent: 2, name: 'wl'+u+'_radius_key', type: 'password', maxlen: 80, size: 32, peekaboo: 1,
1660 suffix: ' <input type="button" id="_f_wl'+u+'_psk_random2" value="Random" onclick="random_psk(\'_wl'+u+'_radius_key\')">',
1661 value: eval('nvram.wl'+u+'_radius_key') },
1662 { title: 'Group Key Renewal', indent: 2, name: 'wl'+u+'_wpa_gtk_rekey', type: 'text', maxlen: 4, size: 6, suffix: ' <i>(seconds)</i>',
1663 value: eval('nvram.wl'+u+'_wpa_gtk_rekey') },
1664 { title: 'Radius Server', indent: 2, multi: [
1665 { name: 'wl'+u+'_radius_ipaddr', type: 'text', maxlen: 15, size: 17, value: eval('nvram.wl'+u+'_radius_ipaddr') },
1666 { name: 'wl'+u+'_radius_port', type: 'text', maxlen: 5, size: 7, prefix: ' : ', value: eval('nvram.wl'+u+'_radius_port') } ] },
1667 { title: 'Encryption', indent: 2, name: 'wl'+u+'_wep_bit', type: 'select', options: [['128','128-bits'],['64','64-bits']],
1668 value: eval('nvram.wl'+u+'_wep_bit') },
1669 { title: 'Passphrase', indent: 2, name: 'wl'+u+'_passphrase', type: 'text', maxlen: 16, size: 20,
1670 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+')">',
1671 value: eval('nvram.wl'+u+'_passphrase') }
1674 for (i = 1; i <= 4; ++i) {
1675 f.push(
1676 { title: ('Key ' + i), indent: 2, name: ('wl'+u+'_key' + i), type: 'text', maxlen: 26, size: 34,
1677 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>' : '>'),
1678 value: nvram['wl'+u+'_key' + i] });
1681 f.push(null,
1682 { title: 'WDS', name: 'f_wl'+u+'_lazywds', type: 'select',
1683 options: [['0','Link With...'],['1','Automatic']], value: nvram['wl'+u+'_lazywds'] } );
1684 wds = eval('nvram.wl'+u+'_wds').split(/\s+/);
1685 for (i = 0; i < 10; i += 2) {
1686 f.push({ title: (i ? '' : 'MAC Address'), indent: 2, multi: [
1687 { name: 'f_wl'+u+'_wds_' + i, type: 'text', maxlen: 17, size: 20, value: wds[i] || '00:00:00:00:00:00' },
1688 { name: 'f_wl'+u+'_wds_' + (i + 1), type: 'text', maxlen: 17, size: 20, value: wds[i + 1] || '00:00:00:00:00:00' } ] } );
1691 createFieldTable('', f);
1692 W('</div>');
1695 // for each wlif
1696 </script>
1698 <!-- / / / -->
1700 </td></tr>
1701 <tr><td id='footer' colspan=2>
1702 <span id='footer-msg'></span>
1703 <input type='button' value='Save' id='save-button' onclick='save()'>
1704 <input type='button' value='Cancel' id='cancel-button' onclick='reloadPage();'>
1705 </td></tr>
1706 </table>
1707 </form>
1708 <script type='text/javascript'>earlyInit()</script>
1709 <div style='height:100px'></div>
1710 </body>
1711 </html>