usbmodeswitch: Updated to v.1.2.6 from shibby's branch.
[tomato.git] / release / src / router / www / advanced-wlanvifs.asp
blob9ff75601d78e3a4e6c3e5257352e6a0269e4d5d1
1 <!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0//EN'>
2 <!--
3 Tomato GUI
4 Copyright (C) 2006-2007 Jonathan Zarate
5 http://www.polarcloud.com/tomato/
7 Virtual Wireless Interfaces web interface & extensions
8 Copyright (C) 2012 Augusto Bott
9 http://code.google.com/p/tomato-sdhc-vlan/
10 Some portions Copyright (C) Jean-Yves Avenard
11 mailto:jean-yves@avenard.org
13 For use with Tomato Firmware only.
14 No part of this file may be used without permission.
15 LAN Access admin module by Augusto Bott
16 -->
17 <html>
18 <head>
19 <meta http-equiv='content-type' content='text/html;charset=utf-8'>
20 <meta name='robots' content='noindex,nofollow'>
21 <title>[<% ident(); %>] Advanced: Virtual Wireless Interfaces</title>
22 <link rel='stylesheet' type='text/css' href='tomato.css'>
23 <% css(); %>
24 <script type='text/javascript' src='tomato.js'></script>
25 <style type='text/css'>
26 #wlif-grid .co2,
27 #wlif-grid .co3,
28 #wlif-grid .co4 {
29 text-align: center;
31 #wlif-grid .centered {
32 text-align: center;
34 #spin {
35 visibility: hidden;
36 vertical-align: middle;
38 ul.tabs a,
39 #tabs a {
40 width: 140px;
42 </style>
44 <script type='text/javascript' src='debug.js'></script>
46 <script type='text/javascript' src='md5.js'></script>
47 <script type='text/javascript' src='wireless.jsx?_http_id=<% nv(http_id); %>'></script>
48 <script type='text/javascript' src='interfaces.js'></script>
49 <script type='text/javascript' src='wireless.js'></script>
51 <script type='text/javascript'>
53 // <% nvram("nas_alternate,wl_auth,wl_auth_mode,wl_bss_enabled,wl_channel,wl_closed,wl_corerev,wl_crypto,wl_hwaddr,wl_ifname,wl_key,wl_key1,wl_key2,wl_key3,wl_key4,wl_lazywds,wl_mode,wl_nband,wl_nbw_cap,wl_nctrlsb,wl_net_mode,wl_passphrase,wl_phytype,wl_radio,wl_radius_ipaddr,wl_radius_key,wl_radius_port,wl_security_mode,wl_ssid,wl_vifs,wl_wds,wl_wds_enable,wl_wep_bit,wl_wpa_gtk_rekey,wl_wpa_psk,wl_bss_maxassoc,wl_wme,lan_ifname,lan_ifnames,lan1_ifname,lan1_ifnames,lan2_ifname,lan2_ifnames,lan3_ifname,lan3_ifnames,t_features");%>
55 var vifs_possible = [];
56 var vifs_defined = [];
57 var vifs_deleted = [];
58 var max_no_vifs = 0;
60 var wl_modes_available = [];
62 wmo = {'ap':'Access Point','apwds':'Access Point + WDS','sta':'Wireless Client','wet':'Wireless Ethernet Bridge','wds':'WDS'};
64 tabs = [['overview', 'Overview']];
66 var xob = null;
67 var refresher = [];
68 var nphy = features('11n');
70 var ghz = [];
71 var bands = [];
72 var nm_loaded = [], ch_loaded = [], max_channel = [];
74 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
75 if (wl_sunit(uidx) < 0) {
76 var b;
77 b = [];
78 for (var i = 0; i < wl_bands[uidx].length; ++i) {
79 b.push([wl_bands[uidx][i] + '', (wl_bands[uidx][i] == '1') ? '5 GHz' : '2.4 GHz']);
81 bands.push(b);
83 b = [];
84 ghz.push(b);
86 nm_loaded.push(0);
87 ch_loaded.push(0);
88 max_channel.push(0);
89 refresher.push(null);
93 function spin(x, unit) {
94 for (var u = 0; u < wl_ifaces.length; ++u) {
95 E('_f_wl'+wl_unit(u)+'_scan').disabled = x;
97 var e = E('_f_wl'+unit+'_scan');
98 if (x) e.value = 'Scan ' + (wscan.tries + 1);
99 else e.value = 'Scan';
100 E('spin'+unit).style.visibility = x ? 'visible' : 'hidden';
102 </script>
104 <script type='text/javascript'>
105 earlyInit();
107 wlg = new TomatoGrid();
109 wlg.setup = function() {
110 this.init('wlif-grid', '', max_no_vifs, [
111 { type: 'select', options: vifs_possible },
112 { type: 'checkbox', prefix: '<div class="centered">', suffix: '</div>' },
113 { type: 'text', maxlen: 32, size: 34, prefix: '<div class="centered">', suffix: '</div>' },
114 { type: 'select', options: wl_modes_available , prefix: '<div class="centered">', suffix: '</div>' },
115 { type: 'select', options: [[0,'LAN (br0)'],[1,'LAN1 (br1)'],[2,'LAN2 (br2)'],[3,'LAN3 (br3)'],[4,'none']] }
118 this.headerSet(['Interface', 'Enabled', 'SSID', 'Mode', 'Bridge']);
120 wlg.populate();
122 wlg.canDelete = false;
123 wlg.showNewEditor();
124 wlg.resetNewEditor();
125 if (wlg.getAllData().length >= max_no_vifs) {
126 wlg.disableNewEditor(true);
130 wlg.populate = function() {
131 if (wlg.tb != null) {
132 wlg.removeAllData();
133 for (var uidx in vifs_defined) {
134 if (typeof(vifs_defined[uidx][0]) == 'undefined') continue;
135 var wmode = (((vifs_defined[uidx][7]) == 'ap') && ((nvram['wl' + u + '_wds_enable']) == '1')) ? 'apwds': (vifs_defined[uidx][7]);
136 this.insertData(-1, [
137 vifs_defined[uidx][0],
138 vifs_defined[uidx][4],
139 vifs_defined[uidx][8],
140 wmode,
141 vifs_defined[uidx][11].toString()
147 wlg.resetNewEditor = function() {
148 var f = fields.getAll(this.newEditor);
149 f[2].value = '';
150 f[1].checked = 1;
152 f[0].selectedIndex=0;
153 var t = max_no_vifs;
154 while((this.countVIF(f[0].options[f[0].selectedIndex].value) > 0) && (t > 0)) {
155 f[0].selectedIndex = (f[0].selectedIndex%(max_no_vifs-1))+1;
156 t--;
159 for(var i = 0; i < f[0].options.length ; i++) {
160 f[0].options[i].disabled = (this.countVIF(f[0].options[i].value) > 0);
163 /* REMOVE-BEGIN */
164 // f[3].options[1].disabled = 1; // AP + WDS
165 // f[3].options[2].disabled = 1; // Wireless Client
166 // f[3].options[4].disabled = 1; // WDS
167 /* REMOVE-END */
168 f[3].selectedIndex = 0;
169 for(var i = 0; i < f[3].options.length ; i++) {
170 /* REMOVE-BEGIN */
171 // f[3].options[i].disabled = ((f[3].options[i].value != 'ap') && (f[3].options[i].value != 'wet'));
172 /* REMOVE-END */
173 f[3].options[i].disabled = (f[3].options[i].value != 'ap');
176 if (nvram.lan_ifname.length < 1)
177 f[4].options[0].disabled=1;
178 if (nvram.lan1_ifname.length < 1)
179 f[4].options[1].disabled=1;
180 if (nvram.lan2_ifname.length < 1)
181 f[4].options[2].disabled=1;
182 if (nvram.lan3_ifname.length < 1)
183 f[4].options[3].disabled=1;
185 f[4].selectedIndex = 4;
186 ferror.clearAll(fields.getAll(this.newEditor));
189 wlg.verifyFields = function(row, quiet) {
190 var ok = 1;
191 var f = fields.getAll(row);
193 if (nvram.lan_ifname.length < 1)
194 f[4].options[0].disabled=1;
195 if (nvram.lan1_ifname.length < 1)
196 f[4].options[1].disabled=1;
197 if (nvram.lan2_ifname.length < 1)
198 f[4].options[2].disabled=1;
199 if (nvram.lan3_ifname.length < 1)
200 f[4].options[3].disabled=1;
202 if (f[0].value.indexOf('.') < 0) {
203 /* REMOVE-BEGIN */
204 // fields.disableAll(row, 1);
205 // return 1;
206 /* REMOVE-END */
207 } else {
208 for(var i = 0; i < f[3].options.length ; i++) {
209 /* REMOVE-BEGIN */
210 // f[3].options[i].disabled = ((f[3].options[i].value != 'ap') && (f[3].options[i].value != 'wet'));
211 /* REMOVE-END */
212 f[3].options[i].disabled = (f[3].options[i].value != 'ap');
216 /* REMOVE-BEGIN */
217 // AB: user can't change WLIF name on gridObj, only by deleting/adding WLIf (destroying/recreating)
218 /* REMOVE-END */
219 if (this.isEditing())
220 f[0].disabled = 1;
222 for(var i=0; i < f[0].options.length ; i++) {
223 f[0].options[i].disabled = (this.countVIF(f[0].options[i].value) > 0);
226 if (!v_length(f[2], quiet || !ok, 1, 32)) ok = 0;
228 return ok;
231 wlg.dataToView = function(data) {
232 var ifname, uidx, ssid;
233 uidx = wl_ifidxx(data[0]);
234 if (uidx < 0) {
235 ifname = 'wl' + data[0];
236 } else {
237 ifname = wl_ifaces[uidx][0] + ((wl_sunit(uidx) < 0) ? ' (wl' + wl_fface(uidx) + ')' : '');
239 ssid = data[2];
241 return ([ifname,
242 (data[1] == 1) ? 'Yes' : 'No',
243 ssid || '<small><i>(unset)</i></small>',
244 wmo[data[3]] || '<small><i>(unset)</i></small>',
245 ['LAN (br0)', 'LAN1 (br1)', 'LAN2 (br2)', 'LAN3 (br3)', 'none' ][data[4]]
249 wlg.dataToFieldValues = function (data) {
250 return ([data[0],
251 (data[1] == '1') ? 'checked' : '',
252 data[2],
253 data[3],
254 data[4]
258 wlg.fieldValuesToData = function(row) {
259 var f = fields.getAll(row);
260 return ([f[0].value,
261 f[1].checked ? '1' : '0',
262 f[2].value,
263 f[3].value,
264 f[4].value
268 wlg.onDelete = function() {
269 this.removeEditor();
270 if (this.source._data[0].indexOf('.') > 0) {
271 var vif = definedVIFidx(this.source._data[0]);
272 vifs_defined.splice(vif,1);
273 vifs_deleted.push(this.source._data[0]);
274 elem.remove(this.source);
275 this.source = null;
276 } else {
277 this.showSource();
279 this.disableNewEditor(false);
280 this.resetNewEditor();
283 wlg.onCancel = function() {
284 this.removeEditor();
285 this.showSource();
286 this.disableNewEditor(false);
287 this.resetNewEditor();
290 wlg.onAdd = function() {
291 var data, u, wmode;
293 this.moving = null;
294 this.rpHide();
296 if (!this.verifyFields(this.newEditor, false)) return;
298 data = this.fieldValuesToData(this.newEditor);
299 this.insertData(-1, data);
301 u = data[0].toString();
302 E('_f_wl'+u+'_radio').checked = (data[1] == '1');
303 E('_wl'+u+'_ssid').value = data[2];
304 E('_f_wl'+u+'_mode').value = data[3];
306 vifs_defined.push([
307 u.toString(), // fface == wl_ifaces[uidx][1]
308 (nvram['wl' + u + '_ifname']) || ('wl'+u), // ifname =~ wl_ifaces[uidx][0]
309 u.substr(0, u.indexOf('.')), // unit
310 u.substr(u.indexOf('.')+1) || '-1', // subunit
311 data[1] || '1', // radio
312 '0', // iface up?
313 data[1] || '1', // bss_enabled
314 data[3], // WL net mode
315 data[2], // nvram['wl' + u + '_ssid'],
316 (eval('nvram["wl'+u+'_hwaddr"]')) || '00:00:00:00:00:00', // MAC addr
317 '0', // VIFs supported
318 data[4]
321 this.resort();
323 this.disableNewEditor(false);
324 this.resetNewEditor();
326 /* if we had previously deleted this entry, remove it from deleted table */
327 for (var i = 0; i < vifs_deleted.length; i++) {
328 if (vifs_deleted[i] == u) {
329 vifs_deleted.splice(i, 1);
330 break;
334 tabSelect(u);
335 verifyFields(null,1);
337 var e = E('footer-msg');
338 e.innerHTML = 'After configuring this VIF, review and save your settings on the Overview tab.';
339 e.style.visibility = 'visible';
340 /* REMOVE-BEGIN */
341 // setTimeout(
342 // function() {
343 // e.innerHTML = '';
344 // e.style.visibility = 'hidden';
345 // }, 5000);
346 /* REMOVE-END */
349 wlg.onOK = function() {
350 //TODO: update info on VIF tab
351 // var i, data, view, e, u;
352 var i, data, view, u;
354 if (!this.verifyFields(this.editor, false)) return;
356 data = this.fieldValuesToData(this.editor);
357 view = this.dataToView(data);
359 u = data[0].toString();
361 E('_f_wl'+u+'_radio').checked = (data[1] == '1');
362 E('_wl'+u+'_ssid').value = data[2];
363 E('_f_wl'+u+'_mode').value = data[3];
365 var vif = definedVIFidx(u);
366 /* REMOVE-BEGIN */
367 // vifs_defined[vif][4] = data[1]; // radio
368 // vifs_defined[vif][6] = data[2]; // bss_enabled
369 // vifs_defined[vif][8] = data[3]; // SSID
370 // vifs_defined[vif][7] = data[4]; // WL mode
371 /* REMOVE-END */
372 vifs_defined[vif][4] = data[1]; // radio
373 /* REMOVE-BEGIN */
374 // vifs_defined[vif][6] = data[2]; // bss_enabled
375 /* REMOVE-END */
376 vifs_defined[vif][8] = data[2]; // SSID
377 vifs_defined[vif][7] = data[3]; // WL mode
378 vifs_defined[vif][11] = data[4]; // LAN bridge
379 /* REMOVE-BEGIN */
380 //alert(data.join('\n'));
381 /* REMOVE-END */
383 this.source.setRowData(data);
384 for (i = 0; i < this.source.cells.length; ++i) {
385 this.source.cells[i].innerHTML = view[i];
388 this.removeEditor();
389 this.showSource();
390 this.disableNewEditor(false);
391 this.resetNewEditor();
393 verifyFields(null,1);
396 wlg.countElem = function(f, v) {
397 var data = this.getAllData();
398 var total = 0;
399 for (var i = 0; i < data.length; ++i) {
400 total += (data[i][f] == v) ? 1 : 0;
402 return total;
405 wlg.countVIF = function (v) {
406 return this.countElem(0,v);
409 function earlyInit() {
411 for (var mode in wmo) {
412 wl_modes_available.push([mode, wmo[mode]]);
414 /* REMOVE-BEGIN */
415 // for (var mode in auth) {
416 // wl_sec_modes_available.push([mode, auth[mode]]);
417 // }
418 // for (var mode in enc) {
419 // wl_enc_modes_available.push([mode, enc[mode]]);
420 // }
422 //wl_ifaces = [ ['eth1','0',0,-1,'bott','00:1C:10:9E:8C:8E',1,4],['wl0.1','0.1',0,1,'ghetto','02:1C:10:9E:8C:8F',1,0],
423 // ['eth2','1',1,-1,'lixo','04:1C:10:9E:8C:8E',1,4]];
424 //wl_bands = [ [ '2'],[ '2'],[ '2'] ];
425 /* REMOVE-END */
427 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
428 var u = wl_fface(uidx).toString();
429 var bridged = 4;
430 if (u) {
431 var wmode = (((nvram['wl' + u + '_mode']) == 'ap') && ((nvram['wl' + u + '_wds_enable']) == '1')) ? 'apwds': (nvram['wl' + u + '_mode']);
433 for (var i = 0 ; i <= MAX_BRIDGE_ID ; i++) {
434 var j = (i == 0) ? '' : i.toString();
435 var l = nvram['lan' + j + '_ifnames'].split(' ');
436 for (var k = 0 ; k < l.length; k++) {
437 if(l[k].indexOf(wl_ifaces[uidx][0]) != -1) {
438 bridged = i;
443 var wlvifs = ((wl_ifaces[uidx][7] > 4) ? '4' : wl_ifaces[uidx][7].toString());
444 vifs_defined.push([
445 u.toString(), // fface == wl_ifaces[uidx][1]
446 wl_ifaces[uidx][0],
447 // (nvram['wl' + u + '_ifname']) || ('wl'u), // ifname =~ wl_ifaces[uidx][0]
448 wl_ifaces[uidx][2] || '0', // unit
449 wl_ifaces[uidx][3] || '0', // subunit
450 nvram['wl' + u + '_radio'] || '0', // radio
451 wl_ifaces[uidx][6] || '0', // iface up/operational status
452 nvram['wl' + u + '_bss_enabled'] || '1', // bss_enabled
453 wmode || 'disabled', // WL net mode
454 wl_ifaces[uidx][4] || '', // nvram['wl' + u + '_ssid'],
455 // wl_ifaces[uidx][4], // nvram['wl' + u + '_ssid'],
456 nvram['wl' + u + '_hwaddr'], // MAC addr
457 // (wl_ifaces[uidx][7] * 1).toString(), // VIFs supported
458 wlvifs, // VIFs supported
459 bridged
461 // max_no_vifs = max_no_vifs + ((wl_ifaces[uidx][7] > 4) ? 4 : wl_ifaces[uidx][7]);
462 max_no_vifs = max_no_vifs + parseInt(wlvifs);
466 W('<style type=\'text/css\'>');
467 for (var uidx in vifs_defined) {
468 if (typeof(vifs_defined[uidx][0]) == 'undefined') continue;
470 var total = vifs_defined[uidx][10] * 1;
471 if (isNaN(total)) continue;
472 if (total >= 4) total = 4;
474 W('#spin'+vifs_defined[uidx][2]+', ');
476 for (var i = 0; i < total; ++i) {
477 var u = vifs_defined[uidx][2].toString();
478 var s = (i == 0) ? '' : '.' + i.toString();
479 var t = u + s;
480 var v = wl_ifidxx(t);
481 var w = (v < 0) ? ('wl' + t) : (wl_ifaces[v][0] + ((wl_sunit(v) < 0) ? ' (wl' + t + ')' : ''));
482 vifs_possible.push([ t, w ]);
483 tabs.push([ t, w ]);
487 W('#spin {');
488 W(' visibility: hidden;');
489 W(' vertical-align: middle;');
490 W('}');
491 W('</style>');
495 function init() {
497 var uninit = wl_ifaces.length - 1;
498 while (uninit > 0) {
499 if (((nvram['wl' + wl_unit(uninit) + '_corerev']) *1) >= 9) break;
500 uninit--;
503 E('sesdiv').style.display = '';
504 if (uninit < 0) {
505 E('sesdiv').innerHTML = '<i>This feature is not supported on this router.</i>';
506 return;
509 tabSelect(cookie.get('advanced_wlanvifs_tab') || tabs[0][0]);
511 var c;
513 if (((c = cookie.get('adv_wlvifs_notes_vis')) != null) && (c == '1')) {
514 toggleVisibility("notes");
517 if (((c = cookie.get('adv_wlvifs_details_vis')) != null) && (c == '1')) {
518 toggleVisibility("details");
520 /* LINUX24-BEGIN */
521 if (((c = cookie.get('adv_wlvifs_options_vis')) != null) && (c == '1')) {
522 toggleVisibility("options");
524 /* LINUX24-END */
526 wlg.setup();
529 function toggleVisibility(whichone) {
530 if(E('sesdiv' + whichone).style.display=='') {
531 E('sesdiv' + whichone).style.display='none';
532 E('sesdiv' + whichone + 'showhide').innerHTML='(Click here to show)';
533 cookie.set('adv_wlvifs_' + whichone + '_vis', 0);
534 } else {
535 E('sesdiv' + whichone).style.display='';
536 E('sesdiv' + whichone + 'showhide').innerHTML='(Click here to hide)';
537 cookie.set('adv_wlvifs_' + whichone + '_vis', 1);
541 function definedVIFidx(vif) {
542 for (var i = 0; i < vifs_defined.length; ++i)
543 if (vifs_defined[i][0] == vif) return i;
544 return -1;
547 function tabSelect(name) {
548 if (wlg.isEditing()) return;
550 tgHideIcons();
552 tabHigh(name);
554 if (!E('save-button').disabled) E('footer-msg').style.visibility = 'hidden';
556 if (name == 'overview') {
557 wlg.populate();
560 elem.display('overview-tab', (name == 'overview'));
561 E('save-button').value = (name != 'overview') ? 'Overview' : 'Save';
563 for (var i = 1; i < tabs.length; ++i) {
564 if (name == tabs[i][0]) {
565 if (definedVIFidx(name) < 0) {
566 elem.display(tabs[i][0] + '-tab-disabled', 1);
567 elem.display(tabs[i][0] + '-tab', 0);
568 } else {
569 elem.display(tabs[i][0] + '-tab-disabled', 0);
570 elem.display(tabs[i][0] + '-tab', 1);
572 } else {
573 elem.display(tabs[i][0] + '-tab', 0);
574 elem.display(tabs[i][0] + '-tab-disabled', 0);
578 cookie.set('advanced_wlanvifs_tab', name);
581 function verifyFields(focused, quiet) {
582 var i;
583 var ok = 1;
584 var a, b, c, d, e;
585 var u, uidx;
586 var wmode, sm2;
588 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
589 u = wl_fface(uidx);
590 if (u)
591 E('wl'+u+'_hwaddr_msg').style.visibility = ((wl_ifaces[uidx][8] == 'ap') && (wl_ifaces[uidx][5] != wl_ifaces[uidx][9])) ? 'visible' : 'hidden';
592 if (wl_sunit(uidx) < 0) {
593 if (focused == E('_f_wl'+u+'_nband')) {
594 refreshNetModes(uidx);
595 refreshChannels(uidx);
597 else if (focused == E('_f_wl'+u+'_nctrlsb') || focused == E('_wl'+u+'_nbw_cap')) {
598 refreshChannels(uidx);
603 var wl_vis = [];
604 for (var vidx = 0; vidx < vifs_possible.length; ++vidx) {
605 var u = vifs_possible[vidx][0];
606 if (definedVIFidx(u) < 0) continue;
608 if (u.toString().indexOf('.') < 0) {
609 var uidx = wl_ifidxx(u);
610 a = {
611 _f_wl_radio: 1,
612 _f_wl_mode: 1,
613 // AB disabled for VIFs?!
614 _f_wl_nband: (bands[uidx].length > 1) ? 1 : 0,
615 // AB disabled for VIFs?!
616 _wl_net_mode: 1,
617 _wl_ssid: 1,
618 _f_wl_bcast: 1,
619 // AB disabled for VIFs?!
620 _wl_channel: 1,
621 // AB disabled for VIFs?!
622 _wl_nbw_cap: nphy ? 1 : 0,
623 // AB disabled for VIFs?!
624 _f_wl_nctrlsb: nphy ? 1 : 0,
625 // AB disabled for VIFs?!
626 _f_wl_scan: 1,
628 _wl_security_mode: 1,
629 _wl_crypto: 1,
630 _wl_wpa_psk: 1,
631 _f_wl_psk_random1: 1,
632 _f_wl_psk_random2: 1,
633 _wl_wpa_gtk_rekey: 1,
634 _wl_radius_key: 1,
635 _wl_radius_ipaddr: 1,
636 _wl_radius_port: 1,
637 _wl_wep_bit: 1,
638 _wl_passphrase: 1,
639 _f_wl_wep_gen: 1,
640 _f_wl_wep_random: 1,
641 _wl_key1: 1,
642 _wl_key2: 1,
643 _wl_key3: 1,
644 _wl_key4: 1,
646 _f_wl_lazywds: 1,
647 _f_wl_wds_0: 1
649 } else {
650 a = {
651 _f_wl_radio: 1,
652 _f_wl_mode: 1,
653 /* REMOVE-BEGIN */
654 // AB disabled for VIFs?!
655 // _f_wl_nband: (bands[uidx].length > 1) ? 1 : 0,
656 // AB disabled for VIFs?!
657 // _wl_net_mode: 1,
658 /* REMOVE-END */
659 _wl_ssid: 1,
660 _f_wl_bcast: 1,
661 /* REMOVE-BEGIN */
662 // AB disabled for VIFs?!
663 // _wl_channel: 1,
664 // _wl_nbw_cap: nphy ? 1 : 0,
665 // _f_wl_nctrlsb: nphy ? 1 : 0,
666 // _f_wl_scan: 1,
667 /* REMOVE-END */
669 _wl_security_mode: 1,
670 _wl_crypto: 1,
671 _wl_wpa_psk: 1,
672 _f_wl_psk_random1: 1,
673 _f_wl_psk_random2: 1,
674 _wl_wpa_gtk_rekey: 1,
675 _wl_radius_key: 1,
676 _wl_radius_ipaddr: 1,
677 _wl_radius_port: 1,
678 _wl_wep_bit: 1,
679 _wl_passphrase: 1,
680 _f_wl_wep_gen: 1,
681 _f_wl_wep_random: 1,
682 _wl_key1: 1,
683 _wl_key2: 1,
684 _wl_key3: 1,
685 _wl_key4: 1,
687 _f_wl_lazywds: 1,
688 _f_wl_wds_0: 1
691 wl_vis[vidx] = a;
694 for (var vidx = 0; vidx < vifs_possible.length; ++vidx) {
695 var u = vifs_possible[vidx][0];
696 if (definedVIFidx(u) < 0) continue;
698 wmode = E('_f_wl'+u+'_mode').value;
700 if (!E('_f_wl'+u+'_radio').checked) {
701 for (a in wl_vis[vidx]) {
702 wl_vis[vidx][a] = 2;
704 wl_vis[vidx]._f_wl_radio = 1;
705 if (u.toString().indexOf('.') < 0) {
706 var uidx = wl_ifidxx(u);
707 wl_vis[vidx]._wl_nbw_cap = nphy ? 2 : 0;
708 wl_vis[vidx]._f_wl_nband = (bands[uidx].length > 1) ? 2 : 0;
712 E('wl'+u+'_mode_msg').style.visibility = ((wmode == 'sta') || (wmode == 'wet')) ? 'visible' : 'hidden';
714 switch (wmode) {
715 case 'apwds':
716 case 'wds':
717 break;
718 case 'wet':
719 case 'sta':
720 wl_vis[vidx]._f_wl_bcast = 0;
721 if (u.toString().indexOf('.') < 0) {
722 wl_vis[vidx]._wl_channel = 0;
723 wl_vis[vidx]._wl_nbw_cap = 0;
725 default:
726 wl_vis[vidx]._f_wl_lazywds = 0;
727 wl_vis[vidx]._f_wl_wds_0 = 0;
728 break;
731 sm2 = E('_wl'+u+'_security_mode').value;
732 switch (sm2) {
733 case 'disabled':
734 wl_vis[vidx]._wl_crypto = 0;
735 wl_vis[vidx]._wl_wep_bit = 0;
736 wl_vis[vidx]._wl_wpa_psk = 0;
737 wl_vis[vidx]._wl_radius_key = 0;
738 wl_vis[vidx]._wl_radius_ipaddr = 0;
739 wl_vis[vidx]._wl_wpa_gtk_rekey = 0;
740 break;
741 case 'wep':
742 wl_vis[vidx]._wl_crypto = 0;
743 wl_vis[vidx]._wl_wpa_psk = 0;
744 wl_vis[vidx]._wl_radius_key = 0;
745 wl_vis[vidx]._wl_radius_ipaddr = 0;
746 wl_vis[vidx]._wl_wpa_gtk_rekey = 0;
747 break;
748 case 'radius':
749 wl_vis[vidx]._wl_crypto = 0;
750 wl_vis[vidx]._wl_wpa_psk = 0;
751 break;
752 default: // wpa*
753 wl_vis[vidx]._wl_wep_bit = 0;
754 if (sm2.indexOf('personal') != -1) {
755 wl_vis[vidx]._wl_radius_key = 0;
756 wl_vis[vidx]._wl_radius_ipaddr = 0;
758 else {
759 wl_vis[vidx]._wl_wpa_psk = 0;
761 break;
764 if ((E('_f_wl'+u+'_lazywds').value == 1) && (wl_vis[vidx]._f_wl_wds_0 == 1)) {
765 wl_vis[vidx]._f_wl_wds_0 = 2;
768 if (u.toString().indexOf('.') < 0) {
769 if (wl_vis[vidx]._wl_nbw_cap != 0) {
770 switch (E('_wl'+u+'_net_mode').value) {
771 case 'b-only':
772 case 'g-only':
773 case 'a-only':
774 case 'bg-mixed':
775 wl_vis[vidx]._wl_nbw_cap = 2;
776 if (E('_wl'+u+'_nbw_cap').value != '0') {
777 E('_wl'+u+'_nbw_cap').value = 0;
778 refreshChannels(wl_ifidxx(u));
780 break;
782 // avoid Enterprise-TKIP with 40MHz
783 if ((sm2 == 'wpa_enterprise') && (E('_wl'+u+'_crypto').value == 'tkip')) {
784 wl_vis[vidx]._wl_nbw_cap = 2;
785 if (E('_wl'+u+'_nbw_cap').value != '0') {
786 E('_wl'+u+'_nbw_cap').value = 0;
787 /* REMOVE-BEGIN */
788 // refreshChannels(uidx);
789 /* REMOVE-END */
790 refreshChannels(wl_ifidxx(u));
794 wl_vis[vidx]._f_wl_nctrlsb = (E('_wl'+u+'_nbw_cap').value == 0) ? 0 : wl_vis[vidx]._wl_nbw_cap;
796 /* REMOVE-BEGIN
797 This is ugly...
798 Special case - 2.4GHz band, currently running in B/G-only mode,
799 with N/Auto and 40MHz selected in the GUI.
800 Channel list is not filtered in this case by the wl driver,
801 and includes all channels available with 20MHz channel width.
802 REMOVE-END */
804 /* REMOVE-BEGIN */
805 // b = selectedBand(uidx);
806 /* REMOVE-END */
807 b = selectedBand(wl_ifidxx(u));
809 if (wl_vis[vidx]._wl_channel == 1 && wl_vis[vidx]._f_wl_nctrlsb != 0 &&
810 ((b == '2') || (wl_vis[vidx]._f_wl_nband == 0 && b == '0'))) {
811 switch (eval('nvram["wl'+u+'_net_mode"]')) {
812 case 'b-only':
813 case 'g-only':
814 case 'bg-mixed':
815 i = E('_wl'+u+'_channel').value * 1;
816 if (i > 0 && i < 5) {
817 E('_f_wl'+u+'_nctrlsb').value = 'lower';
818 wl_vis[vidx]._f_wl_nctrlsb = 2;
820 /* REMOVE-BEGIN */
821 // else if (i > max_channel[uidx] - 4) {
822 /* REMOVE-END */
823 else if (i > max_channel[wl_ifidxx(u)] - 4) {
824 E('_f_wl'+u+'_nctrlsb').value = 'upper';
825 wl_vis[vidx]._f_wl_nctrlsb = 2;
827 break;
830 wl_vis[vidx]._f_wl_scan = wl_vis[vidx]._wl_channel;
831 } else {
833 e = E('_f_wl'+u+'_mode');
834 for(var i = 0; i < e.options.length ; i++) {
835 /* REMOVE-BEGIN */
836 // e.options[i].disabled = ((e.options[i].value != 'ap') && (e.options[i].value != 'wet'));
837 /* REMOVE-END */
838 e.options[i].disabled = (e.options[i].value != 'ap');
842 wl_vis[vidx]._f_wl_psk_random1 = wl_vis[vidx]._wl_wpa_psk;
843 wl_vis[vidx]._f_wl_psk_random2 = wl_vis[vidx]._wl_radius_key;
844 wl_vis[vidx]._wl_radius_port = wl_vis[vidx]._wl_radius_ipaddr;
845 wl_vis[vidx]._wl_key1 = wl_vis[vidx]._wl_key2 = wl_vis[vidx]._wl_key3 = wl_vis[vidx]._wl_key4 = wl_vis[vidx]._f_wl_wep_gen = wl_vis[vidx]._f_wl_wep_random = wl_vis[vidx]._wl_passphrase = wl_vis[vidx]._wl_wep_bit;
847 for (i = 1; i < 10; ++i) {
848 wl_vis[vidx]['_f_wl_wds_' + i] = wl_vis[vidx]._f_wl_wds_0;
851 } // for each wl_iface
853 for (var vidx = 0; vidx < vifs_possible.length; ++vidx) {
854 var u = vifs_possible[vidx][0];
855 if (definedVIFidx(u) < 0) continue;
856 for (a in wl_vis[vidx]) {
857 i = 3;
858 if (a.substr(0, 6) == '_f_wl_') i = 5;
859 b = E(a.substr(0, i) + u + a.substr(i, a.length));
860 c = wl_vis[vidx][a];
861 b.disabled = (c != 1);
862 PR(b).style.display = c ? '' : 'none';
866 // --- verify ---
868 var wlclnt = 0;
869 for (var vidx = 0; vidx < vifs_possible.length; ++vidx) {
870 var u = vifs_possible[vidx][0];
871 if (definedVIFidx(u) < 0) continue;
873 wmode = E('_f_wl'+u+'_mode').value;
874 sm2 = E('_wl'+u+'_security_mode').value;
876 // --- N standard does not support WPA+TKIP ---
877 if (u.toString().indexOf('.') < 0) {
878 a = E('_wl'+u+'_crypto');
879 switch (E('_wl'+u+'_net_mode').value) {
880 case 'mixed':
881 case 'n-only':
882 if (nphy && (a.value == 'tkip') && (sm2.indexOf('wpa') != -1)) {
883 ferror.set(a, 'TKIP encryption is not supported with WPA / WPA2 in N mode.', quiet || !ok);
884 ok = 0;
886 else ferror.clear(a);
887 break;
890 a = E('_wl'+u+'_net_mode');
891 ferror.clear(a);
894 b = E('_f_wl'+u+'_mode');
895 ferror.clear(b);
897 if ((wmode == 'sta') || (wmode == 'wet')) {
898 ++wlclnt;
899 if (wlclnt > 1) {
900 ferror.set(b, 'Only one wireless interface can be configured in client mode.', quiet || !ok);
901 ok = 0;
903 else if (a.value == 'n-only') {
904 ferror.set(a, 'N-only is not supported in wireless client modes, use Auto.', quiet || !ok);
905 ok = 0;
909 a = E('_wl'+u+'_wpa_psk');
910 ferror.clear(a);
911 if (wl_vis[vidx]._f_wl_wpa_psk == 1) {
912 if ((a.value.length < 8) || ((a.value.length == 64) && (a.value.search(/[^0-9A-Fa-f]/) != -1))) {
913 ferror.set('_wl'+u+'_wpa_psk', 'Invalid pre-shared key. Please enter at least 8 characters or 64 hexadecimal digits.', quiet || !ok);
914 ok = 0;
918 if (u.toString().indexOf('.') < 0) {
919 // wl channel
920 if (((wmode == 'wds') || (wmode == 'apwds')) && (wl_vis[vidx]._wl_channel == 1) && (E('_wl'+u+'_channel').value == '0')) {
921 ferror.set('_wl'+u+'_channel', 'Fixed wireless channel required in WDS mode.', quiet || !ok);
922 ok = 0;
924 else ferror.clear('_wl'+u+'_channel');
926 /* REMOVE-BEGIN */
928 if (E('_f_wl'+u+'_mode').value == 'sta') {
929 if ((wan == 'disabled') && (E('_f_wl'+u+'_radio').checked)) {
930 ferror.set('_wan_proto', 'Wireless Client mode requires a valid WAN setting (usually DHCP).', quiet || !ok);
931 ok = 0;
935 /* REMOVE-END */
938 for (var vidx = 0; vidx < vifs_possible.length; ++vidx) {
939 var u = vifs_possible[vidx][0];
940 if (definedVIFidx(u) < 0) continue;
942 // IP address
943 a = ['_radius_ipaddr'];
944 for (i = a.length - 1; i >= 0; --i) {
945 if ((wl_vis[vidx]['_wl'+a[i]]) && (!v_ip('_wl'+u+a[i], quiet || !ok))) ok = 0;
948 // range
949 a = [['_wpa_gtk_rekey', 60, 7200], ['_radius_port', 1, 65535]];
950 for (i = a.length - 1; i >= 0; --i) {
951 v = a[i];
952 if ((wl_vis[vidx]['_wl'+v[0]]) && (!v_range('_wl'+u+v[0], quiet || !ok, v[1], v[2]))) ok = 0;
955 // length
956 a = [['_ssid', 1], ['_radius_key', 1]];
957 for (i = a.length - 1; i >= 0; --i) {
958 v = a[i];
959 if ((wl_vis[vidx]['_wl'+v[0]]) && (!v_length('_wl'+u+v[0], quiet || !ok, v[1], E('_wl'+u+v[0]).maxlength))) ok = 0;
962 if (wl_vis[vidx]._wl_key1) {
963 a = (E('_wl'+u+'_wep_bit').value == 128) ? 26 : 10;
964 for (i = 1; i <= 4; ++i) {
965 b = E('_wl'+u+'_key' + i);
966 b.maxLength = a;
967 if ((b.value.length > 0) || (E('_f_wl'+u+'_wepidx_' + i).checked)) {
968 if (!v_wep(b, quiet || !ok)) ok = 0;
970 else ferror.clear(b);
974 ferror.clear('_f_wl'+u+'_wds_0');
975 if (wl_vis[vidx]._f_wl_wds_0 == 1) {
976 b = 0;
977 for (i = 0; i < 10; ++i) {
978 a = E('_f_wl'+u+'_wds_' + i);
979 if (!v_macz(a, quiet || !ok)) ok = 0;
980 else if (!isMAC0(a.value)) b = 1;
982 if (!b) {
983 ferror.set('_f_wl'+u+'_wds_0', 'WDS MAC address required.', quiet || !ok);
984 ok = 0;
988 if ((ok) && (focused)) {
989 var w = definedVIFidx(u);
990 if (focused.id == '_wl'+u+'_ssid') {
991 vifs_defined[w][8] = focused.value;
993 if (focused.id == '_f_wl'+u+'_mode') {
994 vifs_defined[w][7] = focused.value;
996 if (focused.id == '_f_wl'+u+'_radio') {
997 vifs_defined[w][4] = (focused.checked) ? '1' : '0';
998 vifs_defined[w][6] = (focused.checked) ? '1' : '0';
1004 return ok;
1007 function cancel() {
1008 cookie.set('advanced_wlanvifs_tab', 'overview');
1009 javascript:reloadPage();
1012 function save() {
1013 if (E('save-button').value != 'Save') {
1014 tabSelect('overview');
1015 return;
1018 if (wlg.isEditing()) return;
1019 wlg.resetNewEditor();
1020 if (!verifyFields(null, false)) return;
1022 var a, b, c;
1023 var w, uidx, wmode, sm2, wradio;
1025 var i, u, vidx, vif;
1027 var fom = E('_fom');
1028 /* LINUX24-BEGIN */
1029 fom.nas_alternate.value = E('_f_nas_alternate').checked ? '1' : '0';
1030 /* LINUX24-END */
1032 for (var i = 0 ; i <= MAX_BRIDGE_ID ; i++) {
1033 var j = (i == 0) ? '' : i.toString();
1034 fom['lan'+j+'_ifnames'].value = '';
1035 var l = nvram['lan' + j + '_ifnames'].split(' ');
1036 for (var k = 0 ; k < l.length; ++k) {
1037 if(l[k].indexOf('vlan') != -1) {
1038 fom['lan'+j+'_ifnames'].value += l[k] + ' ';
1041 fom['lan'+j+'_ifnames'].value = fom['lan'+j+'_ifnames'].value.trim();
1044 for (vidx = 0; vidx < vifs_possible.length; ++vidx) {
1045 u = vifs_possible[vidx][0].toString(); // WL unit (primary) or unit.subunit (virtual)
1046 vif = definedVIFidx(u);
1048 /* REMOVE-BEGIN */
1049 // AB TODO: try to play this safer - save some vital info on primary BSS (just in case?)
1050 // AB TODO: with the UNSET part later on - is this really needed?
1051 /* REMOVE-END */
1052 if (vif < 0) {
1053 a = [ ['radio', '0'], ['bss_enabled', '0'], ['ifname', ('wl'+u)] ];
1054 b = 'wl'+u+'_';
1055 for (i = 0; i < a.length; ++i) {
1056 c = '' + b + a[i][0];
1057 if (typeof(nvram[c]) != 'undefined')
1058 E('_'+c).value = a[i][1];
1060 continue;
1063 if (vifs_defined[vif][11]*1 != 4) {
1064 var x = (vifs_defined[vif][11] == '0') ? '' : vifs_defined[vif][11].toString();
1065 fom['lan'+x+'_ifnames'].value += ' ' + vifs_defined[vif][1];
1066 fom['lan'+x+'_ifnames'].value = fom['lan'+x+'_ifnames'].value.trim();
1069 /* REMOVE-BEGIN */
1070 // AB TODO: cleanup in advance or just bail out later?
1071 /* REMOVE-END */
1072 if (u.indexOf('.') < 0) {
1073 a = [];
1074 for (i = 0; i < vifs_defined.length; ++i) {
1075 if (vifs_defined[i][2].toString() != u) continue;
1076 if ((vifs_defined[i][3] * 1) < 1) continue;
1077 a.push('wl'+vifs_defined[i][0]);
1079 E('_wl'+u+'_vifs').value = a.join(' ');
1080 E('_wl'+u+'_ifname').value = nvram['wl'+u+'_ifname'] || vifs_defined[vif][1];
1081 } else {
1082 E('_wl'+u+'_ifname').value = nvram['wl'+u+'_ifname'] || 'wl'+u;
1085 wmode = E('_f_wl'+u+'_mode').value;
1086 sm2 = E('_wl'+u+'_security_mode').value;
1087 wradio = E('_f_wl'+u+'_radio').checked;
1089 if (wmode == 'apwds') E('_wl'+u+'_mode').value = 'ap';
1090 else E('_wl'+u+'_mode').value = wmode;
1092 /* REMOVE-BEGIN */
1093 // primary VIF
1094 /* REMOVE-END */
1095 if (u.indexOf('.') < 0) {
1096 E('_wl'+u+'_nband').value = selectedBand(wl_ifidxx(u));
1098 a = [];
1099 for (i = 0; i < 10; ++i) a.push(E('_f_wl'+u+'_wds_' + i).value);
1100 E('_wl'+u+'_wds').value = joinAddr(a);
1102 if (wmode.indexOf('wds') != -1) {
1103 E('_wl'+u+'_wds_enable').value = 1;
1104 E('_wl'+u+'_lazywds').value = E('_f_wl'+u+'_lazywds').value;
1105 if (E('_wl'+u+'_lazywds').value == 1) E('_wl'+u+'_wds').value = '';
1107 else {
1108 E('_wl'+u+'_wds_enable').value = 0;
1109 E('_wl'+u+'_wds').value = '';
1110 E('_wl'+u+'_lazywds').value = 0;
1114 E('_wl'+u+'_radio').value = wradio ? 1 : 0;
1115 E('_wl'+u+'_bss_enabled').value = wradio ? 1 : 0;
1117 E('_wl'+u+'_auth').value = eval('nvram["wl'+u+'_auth"]') || '0';
1119 e = E('_wl'+u+'_akm');
1120 switch (sm2) {
1121 case 'disabled':
1122 case 'radius':
1123 case 'wep':
1124 e.value = '';
1125 break;
1126 default:
1127 c = [];
1129 if (sm2.indexOf('personal') != -1) {
1130 if (sm2.indexOf('wpa2_') == -1) c.push('psk');
1131 if (sm2.indexOf('wpa_') == -1) c.push('psk2');
1133 else {
1134 if (sm2.indexOf('wpa2_') == -1) c.push('wpa');
1135 if (sm2.indexOf('wpa_') == -1) c.push('wpa2');
1137 c = c.join(' ');
1138 e.value = c;
1139 break;
1141 E('_wl'+u+'_auth_mode').value = (sm2 == 'radius') ? 'radius' : 'none';
1142 E('_wl'+u+'_wep').value = ((sm2 == 'radius') || (sm2 == 'wep')) ? 'enabled': 'disabled';
1144 if (sm2.indexOf('wpa') != -1) E('_wl'+u+'_auth').value = '0';
1146 /* REMOVE-BEGIN */
1147 // primary VIF
1148 /* REMOVE-END */
1149 if (u.indexOf('.') < 0) {
1151 E('_wl'+u+'_nreqd').value = 0;
1152 E('_wl'+u+'_gmode').value = 1;
1153 E('_wl'+u+'_nmode').value = 0;
1154 E('_wl'+u+'_nmcsidx').value = -2; // Legacy Rate
1155 E('_wl'+u+'_nbw').value = 0;
1156 switch (E('_wl'+u+'_net_mode').value) {
1157 case 'b-only':
1158 E('_wl'+u+'_gmode').value = 0;
1159 break;
1160 case 'g-only':
1161 E('_wl'+u+'_gmode').value = 4;
1162 break;
1163 case 'bg-mixed':
1164 break;
1165 case 'a-only':
1166 E('_wl'+u+'_nmcsidx').value = -1; // Auto
1167 break;
1168 case 'n-only':
1169 if (selectedBand(wl_ifidxx(u)) == '1') { // 5 GHz
1170 E('_wl'+u+'_nmode').value = -1;
1171 E('_wl'+u+'_nmcsidx').value = -1;
1172 } else {
1173 E('_wl'+u+'_nmode').value = 1;
1174 E('_wl'+u+'_nmcsidx').value = 32;
1176 E('_wl'+u+'_nreqd').value = 1;
1177 break;
1178 default: // Auto
1179 E('_wl'+u+'_nmode').value = -1;
1180 E('_wl'+u+'_nmcsidx').value = -1;
1181 break;
1184 E('_wl'+u+'_nctrlsb').value = eval('nvram.wl'+u+'_nctrlsb');
1185 if (E('_wl'+u+'_nmode').value != 0) {
1186 E('_wl'+u+'_nctrlsb').value = E('_f_wl'+u+'_nctrlsb').value;
1187 E('_wl'+u+'_nbw').value = (E('_wl'+u+'_nbw_cap').value == 0) ? 20 : 40;
1191 E('_wl'+u+'_closed').value = E('_f_wl'+u+'_bcast').checked ? 0 : 1;
1193 a = fields.radio.selected(eval('fom["f_wl'+u+'_wepidx"]'));
1194 /* REMOVE-BEGIN */
1195 // if (a) E('_wl'+u+'_key').value = a.value;
1196 /* REMOVE-END */
1197 E('_wl'+u+'_key').value = (a) ? a.value : '1';
1200 do_pre_submit_form(fom);
1202 /* REMOVE-BEGIN */
1203 // form.submit(fom,1);
1204 /* REMOVE-END */
1207 function submit_complete() {
1208 reloadPage();
1212 var cmdresult = '';
1213 var cmd = null;
1215 function do_pre_submit_form(fom) {
1217 var footermsg = E('footer-msg');
1218 footermsg.innerHTML = 'Saving...';
1219 footermsg.style.visibility = 'visible';
1221 E('save-button').disabled = 1;
1222 E('cancel-button').disabled = 1;
1224 var elem = fom.elements;
1226 var s = '';
1228 for (var vidx = 0; vidx < vifs_possible.length; ++vidx) {
1229 var u = vifs_possible[vidx][0].toString(); // WL unit (primary) or unit.subunit (virtual)
1230 if (u.indexOf('.') > 0) { // only if virtual VIF
1231 var vif = definedVIFidx(u);
1232 if (vif >= 0)
1234 for (var i = 0; i < elem.length ; ++i) {
1235 if (elem[i].name.indexOf('wl' + u) == 0) {
1236 s += 'nvram set ' + elem[i].name + '=\'' + elem[i].value + '\'\n';
1240 /* REMOVE-BEGIN */
1241 // unset HWADDR for any/all non-primary VIFs we have configured
1242 // s += 'nvram unset wl' + u + '_hwaddr\n';
1243 // AB TODO: figure out what to do with pre-existing/set MAC addresses
1244 // if (vif >= 0) {
1245 // if ((vifs_defined[vif][9] == '00:00:00:00:00:00') || (vifs_defined[vif][9] == '')) {
1246 // s += 'nvram unset wl' + u + '_hwaddr\n';
1247 // }
1248 // }
1249 /* REMOVE-END */
1253 /* Clean-up deleted interfaces */
1254 var lan_ifnames = nvram['lan_ifnames'];
1255 var lan1_ifnames = nvram['lan1_ifnames'];
1256 var lan2_ifnames = nvram['lan2_ifnames'];
1257 var lan3_ifnames = nvram['lan3_ifnames'];
1258 var wl0_vifs = nvram['wl0_vifs'];
1259 var wl1_vifs = nvram['wl1_vifs'];
1261 for (var vidx = 0; vidx < vifs_deleted.length; ++vidx) {
1262 var u = vifs_deleted[vidx];
1263 for (var i = 0; i < elem.length ; ++i) {
1264 if (elem[i].name.indexOf('wl' + u) == 0) {
1265 s += 'nvram unset ' + elem[i].name + '\n';
1268 lan_ifnames = lan_ifnames.replace('wl'+u, '');
1269 lan1_ifnames = lan1_ifnames.replace('wl'+u, '');
1270 lan2_ifnames = lan2_ifnames.replace('wl'+u, '');
1271 lan3_ifnames = lan3_ifnames.replace('wl'+u, '');
1272 if (typeof(wl0_vifs) != 'undefined') {
1273 wl0_vifs = wl0_vifs.replace('wl'+u, '');
1275 if (typeof(wl1_vifs) != 'undefined') {
1276 wl1_vifs = wl1_vifs.replace('wl'+u, '');
1278 s += 'nvram unset wl' + u + '_wme\n';
1279 s += 'nvram unset wl' + u + '_bss_maxassoc\n';
1281 if (vifs_deleted.length > 0)
1283 s += 'nvram set lan_ifnames=\'' + lan_ifnames + '\'\n';
1284 s += 'nvram set lan1_ifnames=\'' + lan1_ifnames + '\'\n';
1285 s += 'nvram set lan2_ifnames=\'' + lan2_ifnames + '\'\n';
1286 s += 'nvram set lan3_ifnames=\'' + lan3_ifnames + '\'\n';
1287 if (typeof(wl0_vifs) != 'undefined')
1288 s += 'nvram set wl0_vifs=\'' + wl0_vifs + '\'\n';
1289 if (typeof(wl1_vifs) != 'undefined')
1290 s += 'nvram set wl1_vifs=\'' + wl1_vifs + '\'\n';
1292 post_pre_submit_form(s);
1295 function error_pre_submit_form() {
1296 var footermsg = E('footer-msg');
1298 footermsg.innerHTML = '<tt>' + escapeText(cmdresult) + '</tt>';
1299 footermsg.style.visibility = 'visible';
1301 cmdresult = '';
1304 function post_pre_submit_form(s) {
1305 if (cmd) return;
1307 cmd = new XmlHttp();
1308 cmd.onCompleted = function(text, xml) {
1309 form.submit(E('_fom'),1);
1311 cmd.onError = function(x) {
1312 cmdresult = 'ERROR: ' + x;
1313 error_pre_submit_form();
1316 cmd.post('shell.cgi', 'action=execute&command=' + escapeCGI(s.replace(/\r/g, '')));
1319 function escapeText(s) {
1320 function esc(c) {
1321 return '&#' + c.charCodeAt(0) + ';';
1323 return s.replace(/[&"'<>]/g, esc).replace(/\n/g, ' <br>').replace(/ /g, '&nbsp;');
1326 </script>
1328 </head>
1329 <body onload='init()'>
1330 <form id='_fom' method='post' action='tomato.cgi'>
1331 <table id='container' cellspacing=0>
1332 <tr><td colspan=2 id='header'>
1333 <div class='title'>Tomato</div>
1334 <div class='version'>Version <% version(); %></div>
1335 </td></tr>
1336 <tr id='body'><td id='navi'><script type='text/javascript'>navi()</script></td>
1337 <td id='content'>
1338 <div id='ident'><% ident(); %></div>
1340 <!-- / / / -->
1342 <input type='hidden' name='_nextpage' value='advanced-wlanvifs.asp'>
1343 <input type='hidden' name='_nextwait' value='10'>
1344 <input type='hidden' name='_service' value='wireless-restart'>
1345 <input type='hidden' name='_force_commit' value='1'>
1347 <!-- LINUX24-BEGIN -->
1348 <input type='hidden' name='nas_alternate' value=''>
1349 <!-- LINUX24-END -->
1350 <input type='hidden' name='lan_ifnames' value=''>
1351 <input type='hidden' name='lan1_ifnames' value=''>
1352 <input type='hidden' name='lan2_ifnames' value=''>
1353 <input type='hidden' name='lan3_ifnames' value=''>
1355 <!-- / / / -->
1357 <div id='sesdiv' style='display:none'>
1359 <!-- / / / -->
1360 <div class='section-title'>Virtual Wireless Interfaces</div>
1361 <div class='section'>
1363 <script type='text/javascript'>
1364 tabCreate.apply(this, tabs);
1365 </script>
1367 <div id='overview-tab'>
1368 <br>
1369 <table class='tomato-grid' cellspacing=1 id='wlif-grid'></table>
1370 <br>
1372 <!-- / / / -->
1374 <div class='section-title'>Wireless Interfaces Details <small><i><a href='javascript:toggleVisibility("details");'><span id='sesdivdetailsshowhide'>(Click here to show)</span></a></i></small></div>
1375 <div class='section' id='sesdivdetails' style='display:none'>
1377 <script type='text/javascript'>
1378 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1379 if (wl_sunit(uidx)<0) {
1380 var c = [];
1381 c.push({ title: 'Interface', text: 'wl' + wl_fface(uidx) + ' <small>(' + wl_display_ifname(uidx) + ')</small>' });
1382 c.push({ title: 'Virtual Interfaces', indent: 2, rid: 'wl' + wl_fface(uidx) + '_vifs',
1383 text: 'wl' + wl_fface(uidx) + ' ' + nvram['wl' + wl_fface(uidx) + '_vifs'] + ' <small>(max ' + wl_ifaces[uidx][7] + ')</small>' });
1384 createFieldTable('',c);
1387 </script>
1388 </div>
1390 <!-- / / / -->
1392 <!-- LINUX24-BEGIN -->
1393 <div class='section-title'>Options <small><i><a href='javascript:toggleVisibility("options");'><span id='sesdivoptionsshowhide'>(Click here to show)</span></a></i></small></div>
1394 <div class='section' id='sesdivoptions' style='display:none'>
1395 <script type='text/javascript'>
1396 createFieldTable('', [
1397 { title: 'Use alternate NAS startup sequence', name: 'f_nas_alternate', type: 'checkbox', value: nvram.nas_alternate == '1' }
1399 </script>
1400 </div>
1401 <!-- LINUX24-END -->
1403 <!-- / / / -->
1405 <div class='section-title'>Notes <small><i><a href='javascript:toggleVisibility("notes");'><span id='sesdivnotesshowhide'>(Click here to show)</span></a></i></small></div>
1406 <div class='section' id='sesdivnotes' style='display:none'>
1408 <ul>
1409 <li><b>Interface</b> - Wireless VIF name.</li>
1410 <li><b>Enabled</b> - If this VIF should be active and brought online.</li>
1411 <li><b>SSID</b> - Wireless Service Set Identifier.</li>
1412 <li><b>Mode</b> - Interface mode: Access Point, WDS, Wireless Client, etc...</li>
1413 <li><b>Bridge</b> - Which LAN bridge this VIF should be assigned.</li>
1414 </ul>
1416 <ul>
1417 <!-- LINUX24-BEGIN -->
1418 <li><b>Use alternate NAS startup(...)</b> - <i>Only meaningful for K24 builds</i> - Enable this option if you need more than one NAS process running (i.e. to handle WPAx encryption on more than one WLVIF).</li>
1419 <!-- LINUX24-END -->
1420 </ul>
1422 <small>
1423 <ul>
1424 <li><b>Other relevant notes/hints:</b>
1425 <ul>
1426 <li>When creating/defining a new wireless VIF, it's MAC address will be shown (incorrectly) as '00:00:00:00:00:00', as it's unknown at that moment (until network is restarted and this page is reloaded).</li>
1427 <li>When saving changes, the MAC addresses of all defined non-primary wireless VIFs could sometimes be (already) <i>set</i> but might be <i>recreated</i> by the WL driver (so that previously defined/saved settings might need to be updated/changed accordingly on <a href=advanced-mac.asp>Advanced/MAC Address</a> after saving settings and rebooting your router).</li>
1428 <li>This web interface allows configuring a maximum of 4 VIFs for each physical wireless interface available - up to 3 extra VIFs can be defined in addition to the primary VIF (<i>on devices with multiple VIF capabilities</i>).</li>
1429 <li>By definition, configuration settings for the <i>primary VIF</i> of any physical wireless interfaces shouldn't be touched here (use the <a href=basic-network.asp>Basic/Network</a> page instead).</li>
1430 </ul>
1431 </ul>
1432 </small>
1434 </div>
1436 <!-- / / / -->
1438 </div>
1440 <!-- / / / -->
1442 <script type='text/javascript'>
1443 for (var i = 1; i < tabs.length; ++i) {
1444 var t = tabs[i][0];
1445 var uidx = wl_ifidxx(t);
1446 var u = t;
1448 W('<div id=\''+t+'-tab-disabled\'>');
1449 W('<br>');
1450 W('VIF ' + tabs[i][1] + ' is not defined.');
1451 W('</div>');
1453 W('<div id=\''+t+'-tab\'>');
1454 W('<br>');
1456 // common to all VIFs
1457 W('<input type=\'hidden\' id=\'_wl'+u+'_radio\' name=\'wl'+u+'_radio\' >');
1458 W('<input type=\'hidden\' id=\'_wl'+u+'_mode\' name=\'wl'+u+'_mode\' >');
1459 W('<input type=\'hidden\' id=\'_wl'+u+'_closed\' name=\'wl'+u+'_closed\' >');
1460 W('<input type=\'hidden\' id=\'_wl'+u+'_key\' name=\'wl'+u+'_key\' >');
1461 W('<input type=\'hidden\' id=\'_wl'+u+'_akm\' name=\'wl'+u+'_akm\' >');
1462 W('<input type=\'hidden\' id=\'_wl'+u+'_auth_mode\' name=\'wl'+u+'_auth_mode\' >');
1463 W('<input type=\'hidden\' id=\'_wl'+u+'_wep\' name=\'wl'+u+'_wep\' >');
1464 W('<input type=\'hidden\' id=\'_wl'+u+'_auth\' name=\'wl'+u+'_auth\' >');
1465 W('<input type=\'hidden\' id=\'_wl'+u+'_bss_enabled\' name=\'wl'+u+'_bss_enabled\' >');
1466 W('<input type=\'hidden\' id=\'_wl'+u+'_ifname\' name=\'wl'+u+'_ifname\' >');
1468 // only if primary VIF
1469 if (u.toString().indexOf('.') < 0) {
1470 W('<input type=\'hidden\' id=\'_wl'+u+'_nband\' name=\'wl'+u+'_nband\' >');
1471 W('<input type=\'hidden\' id=\'_wl'+u+'_wds_enable\' name=\'wl'+u+'_wds_enable\' >');
1472 W('<input type=\'hidden\' id=\'_wl'+u+'_wds\' name=\'wl'+u+'_wds\' >');
1473 W('<input type=\'hidden\' id=\'_wl'+u+'_lazywds\' name=\'wl'+u+'_lazywds\' >');
1474 W('<input type=\'hidden\' id=\'_wl'+u+'_gmode\' name=\'wl'+u+'_gmode\' >');
1476 W('<input type=\'hidden\' id=\'_wl'+u+'_nmode\' name=\'wl'+u+'_nmode\' >');
1477 W('<input type=\'hidden\' id=\'_wl'+u+'_nmcsidx\' name=\'wl'+u+'_nmcsidx\' >');
1478 W('<input type=\'hidden\' id=\'_wl'+u+'_nreqd\' name=\'wl'+u+'_nreqd\' >');
1479 W('<input type=\'hidden\' id=\'_wl'+u+'_nctrlsb\' name=\'wl'+u+'_nctrlsb\' >');
1480 W('<input type=\'hidden\' id=\'_wl'+u+'_nbw\' name=\'wl'+u+'_nbw\' >');
1482 W('<input type=\'hidden\' id=\'_wl'+u+'_vifs\' name=\'wl'+u+'_vifs\' >');
1485 var f = [];
1486 f.push (
1487 { title: 'Enable Interface', name: 'f_wl'+u+'_radio', type: 'checkbox',
1488 value: (eval('nvram["wl'+u+'_radio"]') == '1') && (eval('nvram["wl'+u+'_net_mode"]') != 'disabled') },
1489 { title: 'MAC Address', text: '<a href="advanced-mac.asp">' + (eval('nvram["wl'+u+'_hwaddr"]') || '00:00:00:00:00:00') + '</a>' +
1490 ' &nbsp; <b id="wl'+u+'_hwaddr_msg" style="visibility:hidden"><small>(warning: WL driver reports BSSID <a href=advanced-mac.asp>' + ((typeof(wl_ifaces[wl_ifidxx(u)]) != 'undefined')? wl_ifaces[wl_ifidxx(u)][9] : '') + '</a>)</small></b>' },
1491 { title: 'Wireless Mode', name: 'f_wl'+u+'_mode', type: 'select',
1492 options: wl_modes_available,
1493 value: ((eval('nvram["wl'+u+'_mode"]') == 'ap') && (eval('nvram["wl'+u+'_wds_enable"]') == '1')) ? 'apwds' : eval('nvram["wl'+u+'_mode"]'),
1494 suffix: ' &nbsp; <b id="wl'+u+'_mode_msg" style="visibility:hidden"><small>(note: you might wish to cross-check settings later on <a href=basic-network.asp>Basic/Network</a>)</small></b>' }
1497 // only if primary VIF
1498 if (u.toString().indexOf('.') < 0) {
1499 f.push (
1500 { title: 'Radio Band', name: 'f_wl'+u+'_nband', type: 'select', options: bands[uidx],
1501 value: eval('nvram["wl'+u+'_nband"]') || '0' == '0' ? bands[uidx][0][0] : eval('nvram["wl'+u+'_nband"]') },
1502 { title: 'Wireless Network Mode', name: 'wl'+u+'_net_mode', type: 'select',
1503 value: (eval('nvram["wl'+u+'_net_mode"]') == 'disabled') ? 'mixed' : eval('nvram["wl'+u+'_net_mode"]'),
1504 options: [], prefix: '<span id="__wl'+u+'_net_mode">', suffix: '</span>' }
1508 if (typeof(eval('nvram["wl'+u+'_closed"]')) == 'undefined')
1509 nvram['wl'+u+'_closed'] = '0';
1511 f.push (
1512 { title: 'SSID', name: 'wl'+u+'_ssid', type: 'text', maxlen: 32, size: 34, value: eval('nvram["wl'+u+'_ssid"]') },
1513 { title: 'Broadcast', indent: 2, name: 'f_wl'+u+'_bcast', type: 'checkbox', value: (eval('nvram["wl'+u+'_closed"]') == '0') }
1516 // only if primary VIF
1517 if (u.toString().indexOf('.') < 0) {
1518 f.push (
1519 { 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+'">',
1520 value: eval('nvram["wl'+u+'_channel"]') },
1521 { title: 'Channel Width', name: 'wl'+u+'_nbw_cap', type: 'select', options: [['0','20 MHz'],['1','40 MHz']],
1522 value: eval('nvram["wl'+u+'_nbw_cap"]') },
1523 { title: 'Control Sideband', name: 'f_wl'+u+'_nctrlsb', type: 'select', options: [['lower','Lower'],['upper','Upper']],
1524 value: eval('nvram["wl'+u+'_nctrlsb"]') == 'none' ? 'lower' : eval('nvram["wl'+u+'_nctrlsb"]') }
1528 if (typeof(eval('nvram["wl'+u+'_crypto"]')) == 'undefined')
1529 nvram['wl'+u+'_crypto'] = 'aes';
1531 f.push (
1532 null,
1533 { title: 'Security', name: 'wl'+u+'_security_mode', type: 'select',
1534 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']],
1535 value: eval('nvram["wl'+u+'_security_mode"]') },
1536 { title: 'Encryption', indent: 2, name: 'wl'+u+'_crypto', type: 'select',
1537 options: [['tkip','TKIP'],['aes','AES'],['tkip+aes','TKIP / AES']], value: eval('nvram["wl'+u+'_crypto"]') },
1538 { title: 'Shared Key', indent: 2, name: 'wl'+u+'_wpa_psk', type: 'password', maxlen: 64, size: 66, peekaboo: 1,
1539 suffix: ' <input type="button" id="_f_wl'+u+'_psk_random1" value="Random" onclick="random_psk(\'_wl'+u+'_wpa_psk\')">',
1540 value: eval('nvram["wl'+u+'_wpa_psk"]') },
1541 { title: 'Shared Key', indent: 2, name: 'wl'+u+'_radius_key', type: 'password', maxlen: 80, size: 32, peekaboo: 1,
1542 suffix: ' <input type="button" id="_f_wl'+u+'_psk_random2" value="Random" onclick="random_psk(\'_wl'+u+'_radius_key\')">',
1543 value: eval('nvram["wl'+u+'_radius_key"]') },
1544 { title: 'Group Key Renewal', indent: 2, name: 'wl'+u+'_wpa_gtk_rekey', type: 'text', maxlen: 4, size: 6, suffix: ' <i>(seconds)</i>',
1545 value: eval('nvram["wl'+u+'_wpa_gtk_rekey"]') || '3600' },
1546 { title: 'Radius Server', indent: 2, multi: [
1547 { name: 'wl'+u+'_radius_ipaddr', type: 'text', maxlen: 15, size: 17, value: eval('nvram["wl'+u+'_radius_ipaddr"]') },
1548 { name: 'wl'+u+'_radius_port', type: 'text', maxlen: 5, size: 7, prefix: ' : ', value: eval('nvram["wl'+u+'_radius_port"]') || '1812' } ] },
1549 { title: 'Encryption', indent: 2, name: 'wl'+u+'_wep_bit', type: 'select', options: [['128','128-bits'],['64','64-bits']],
1550 value: eval('nvram["wl'+u+'_wep_bit"]') },
1551 { title: 'Passphrase', indent: 2, name: 'wl'+u+'_passphrase', type: 'text', maxlen: 16, size: 20,
1552 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+')">',
1553 value: eval('nvram["wl'+u+'_passphrase"]') }
1556 if (typeof(eval('nvram["wl'+u+'_key"]')) == 'undefined')
1557 nvram['wl'+u+'_key'] = '1';
1558 /* REMOVE-BEGIN */
1559 // eval('nvram["wl'+u+'_key"] = 1');
1560 /* REMOVE-END */
1562 for (var j = 1; j <= 4; ++j) {
1563 f.push(
1564 { title: ('Key ' + j), indent: 2, name: ('wl'+u+'_key' + j), type: 'text', maxlen: 26, size: 34,
1565 suffix: '<input type="radio" onchange="verifyFields(this,1)" onclick="verifyFields(this,1)" name="f_wl'+u+'_wepidx" id="_f_wl'+u+'_wepidx_' + j + '" value="' + j + '"' + ((eval('nvram["wl'+u+'_key"]') == j) ? ' checked>' : '>'),
1566 value: nvram['wl'+u+'_key' + j] });
1569 f.push(null,
1570 { title: 'WDS', name: 'f_wl'+u+'_lazywds', type: 'select',
1571 options: [['0','Link With...'],['1','Automatic']], value: nvram['wl'+u+'_lazywds'] } );
1572 /* REMOVE-BEGIN */
1573 // alert('nvram["wl'+u+'_wds"]=' + eval('nvram["wl'+u+'_wds"]'));
1574 /* REMOVE-END */
1575 wds = eval('nvram["wl'+u+'_wds"]');
1576 if (typeof(wds) == 'undefined') {
1577 nvram['wl'+u+'_wds'] = '';
1580 wds = eval('nvram["wl'+u+'_wds"]').split(/\s+/);
1581 /* REMOVE-BEGIN */
1582 // wds = (nvram['wl'+u+'_wds']).split(/\s+/);
1583 /* REMOVE-END */
1584 for (var k = 0; k < 10; k += 2) {
1585 f.push({ title: (k ? '' : 'MAC Address'), indent: 2, multi: [
1586 { name: 'f_wl'+u+'_wds_' + k, type: 'text', maxlen: 17, size: 20, value: wds[k] || '00:00:00:00:00:00' },
1587 { name: 'f_wl'+u+'_wds_' + (k + 1), type: 'text', maxlen: 17, size: 20, value: wds[k + 1] || '00:00:00:00:00:00' } ] } );
1590 createFieldTable('', f);
1591 W('</div>');
1595 </script>
1597 <!-- / / / -->
1600 <!-- / WLIFDIV / -->
1601 </div>
1603 <!-- / SESDIV / -->
1604 </div>
1606 </td></tr>
1607 <tr><td id='footer' colspan=2>
1608 <span id='footer-msg'></span>
1609 <input type='button' value='Save' id='save-button' onclick='save()'>
1610 <input type='button' value='Cancel' id='cancel-button' onclick='cancel()'>
1611 </td></tr>
1612 </table>
1613 </form>
1614 <script type='text/javascript'>
1615 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1616 if (wl_sunit(uidx) < 0) {
1617 refreshNetModes(uidx);
1618 refreshChannels(uidx);
1621 verifyFields(null, 1);
1622 </script>
1623 </body>
1624 </html>