· 11 months ago · Feb 22, 2025, 09:20 AM
1<!DOCTYPE html>
2<!--
3 Tomato GUI
4 Copyright (C) 2006-2007 Jonathan Zarate
5 http://www.polarcloud.com/tomato/
6
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
12
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 lang="en-GB">
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?rel=<% version(); %>">
23<% css(); %>
24<script src="tomato.js?rel=<% version(); %>"></script>
25<script src="md5.js?rel=<% version(); %>"></script>
26<script src="interfaces.js?rel=<% version(); %>"></script>
27<script src="wireless.js?rel=<% version(); %>"></script>
28<script>
29var lastjiffiestotal = 0, lastjiffiesidle = 0, lastjiffiesusage = 100;
30</script>
31<script src="wireless.jsx?_http_id=<% nv(http_id); %>"></script>
32<script src="status-data.jsx?_http_id=<% nv(http_id); %>"></script>
33
34<script>
35
36// <% nvram("wl_auth,wl_auth_mode,wl_ap_isolate,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,wl_macmode,wl_maclist");%>
37
38var cprefix = 'advanced_wlanvifs';
39var vifs_possible = [];
40var vifs_defined = [];
41var vifs_deleted = [];
42var max_no_vifs = 0;
43
44var wl_modes_available = [];
45
46var wmo = {'ap':'Access Point','apwds':'Access Point + WDS','sta':'Wireless Client','wet':'Wireless Ethernet Bridge','wds':'WDS'
47/* BCMWL6-BEGIN */
48 ,'psta':'Media Bridge'
49/* BCMWL6-END */
50 };
51var macmode = {'disabled':'Disabled','deny':'Block','allow':'Permit'};
52
53var tabs = [['overview','Overview']];
54
55var xob = null;
56var refresher = [];
57var nphy = features('11n');
58var acphy = features('11ac');
59
60var ghz = [];
61var bands = [];
62var nm_loaded = [], ch_loaded = [], max_channel = [];
63
64for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
65 if (wl_sunit(uidx) < 0) {
66 var b;
67 b = [];
68 for (var i = 0; i < wl_bands[uidx].length; ++i) {
69 b.push([wl_bands[uidx][i]+'', (wl_bands[uidx][i] == '1') ? '5 GHz' : '2.4 GHz']);
70 }
71 bands.push(b);
72
73 b = [];
74 ghz.push(b);
75
76 nm_loaded.push(0);
77 ch_loaded.push(0);
78 max_channel.push(0);
79 refresher.push(null);
80 }
81}
82
83earlyInit();
84
85var wlg = new TomatoGrid();
86
87wlg.setup = function() {
88 this.init('wlif-grid', '', max_no_vifs, [
89 { type: 'select', options: vifs_possible },
90 { type: 'checkbox', prefix: '<div class="centered">', suffix: '<\/div>' },
91 { type: 'text', maxlen: 32, size: 34, prefix: '<div class="centered">', suffix: '<\/div>' },
92 { type: 'select', options: wl_modes_available , prefix: '<div class="centered">', suffix: '<\/div>' },
93 { type: 'select', options: [[0,'LAN0 (br0)'],[1,'LAN1 (br1)'],[2,'LAN2 (br2)'],[3,'LAN3 (br3)'],[4,'none']] },
94 { type: 'select', options: [['disabled','Disabled'],['deny','Block'],['allow','Permit']] }
95 ]);
96
97 this.headerSet(['Interface', 'Enabled', 'SSID', 'Mode', 'Bridge', 'WFilter']);
98
99 wlg.populate();
100
101 wlg.canDelete = false;
102 wlg.showNewEditor();
103 wlg.resetNewEditor();
104 if (wlg.getAllData().length >= max_no_vifs)
105 wlg.disableNewEditor(true);
106}
107
108wlg.populate = function() {
109 if (wlg.tb != null) {
110 wlg.removeAllData();
111 for (var uidx in vifs_defined) {
112 if (typeof(vifs_defined[uidx][0]) == 'undefined')
113 continue;
114
115 var wmode = (((vifs_defined[uidx][7]) == 'ap') && ((nvram['wl'+u+'_wds_enable']) == '1')) ? 'apwds': (vifs_defined[uidx][7]);
116 this.insertData(-1, [
117 vifs_defined[uidx][0],
118 vifs_defined[uidx][4],
119 vifs_defined[uidx][8],
120 wmode,
121 vifs_defined[uidx][11].toString(),
122 vifs_defined[uidx][12].toString()
123 ]);
124 }
125 }
126}
127
128wlg.resetNewEditor = function() {
129 var f = fields.getAll(this.newEditor);
130 f[2].value = '';
131 f[1].checked = 1;
132
133 f[0].selectedIndex=0;
134 var t = max_no_vifs;
135 while ((this.countVIF(f[0].options[f[0].selectedIndex].value) > 0) && (t > 0)) {
136 f[0].selectedIndex = (f[0].selectedIndex%(max_no_vifs-1))+1;
137 t--;
138 }
139
140 for (var i = 0; i < f[0].options.length ; i++) {
141 f[0].options[i].disabled = (this.countVIF(f[0].options[i].value) > 0);
142 }
143
144/* REMOVE-BEGIN
145 f[3].options[1].disabled = 1; // AP + WDS
146 f[3].options[2].disabled = 1; // Wireless Client
147 f[3].options[4].disabled = 1; // WDS
148REMOVE-END */
149 f[3].selectedIndex = 0;
150 for (var i = 0; i < f[3].options.length ; i++) {
151/* REMOVE-BEGIN
152 f[3].options[i].disabled = ((f[3].options[i].value != 'ap') && (f[3].options[i].value != 'wet'));
153REMOVE-END */
154 f[3].options[i].disabled = (f[3].options[i].value != 'ap');
155 }
156
157 if (nvram.lan_ifname.length < 1)
158 f[4].options[0].disabled = 1;
159 if (nvram.lan1_ifname.length < 1)
160 f[4].options[1].disabled = 1;
161 if (nvram.lan2_ifname.length < 1)
162 f[4].options[2].disabled = 1;
163 if (nvram.lan3_ifname.length < 1)
164 f[4].options[3].disabled = 1;
165
166 f[4].selectedIndex = 4;
167 f[5].selectedIndex = 0;
168 ferror.clearAll(fields.getAll(this.newEditor));
169}
170
171wlg.dataToView = function(data) {
172 var ifname, uidx;
173 uidx = wl_ifidxx(data[0]);
174 if (uidx < 0)
175 ifname = 'wl'+data[0];
176 else
177 ifname = wl_display_ifname(uidx);
178
179 return ([ifname,(data[1] == 1) ? '⭐' : '',
180 data[2] || '<small><i>(unset)<\/i><\/small>',
181 wmo[data[3]] || '<small><i>(unset)<\/i><\/small>',
182 ['LAN0 (br0)','LAN1 (br1)','LAN2 (br2)','LAN3 (br3)','none' ][data[4]],
183 macmode[data[5]] || macmode[nvram['wl'+data[0].toString()+'_macmode']]
184 ]);
185}
186
187wlg.dataToFieldValues = function (data) {
188 return ([data[0],(data[1] == '1') ? 'checked' : '',data[2],data[3],data[4],data[5]]);
189}
190
191wlg.fieldValuesToData = function(row) {
192 var f = fields.getAll(row);
193
194 return ([f[0].value,f[1].checked ? '1' : '0',f[2].value,f[3].value,f[4].value,f[5].value]);
195}
196
197wlg.onDelete = function() {
198 this.removeEditor();
199 if (this.source._data[0].indexOf('.') > 0) {
200 var vif = definedVIFidx(this.source._data[0]);
201 vifs_defined.splice(vif,1);
202 vifs_deleted.push(this.source._data[0]);
203 elem.remove(this.source);
204 this.source = null;
205 }
206 else
207 this.showSource();
208
209 this.disableNewEditor(false);
210 this.resetNewEditor();
211}
212
213wlg.onCancel = function() {
214 this.removeEditor();
215 this.showSource();
216 this.disableNewEditor(false);
217 this.resetNewEditor();
218}
219
220wlg.onAdd = function() {
221 var data, u, wmode;
222
223 this.moving = null;
224 this.rpHide();
225
226 if (!this.verifyFields(this.newEditor, 0))
227 return;
228
229 data = this.fieldValuesToData(this.newEditor);
230 this.insertData(-1, data);
231
232 u = data[0].toString();
233 E('_f_wl'+u+'_radio').checked = (data[1] == '1');
234 E('_wl'+u+'_ssid').value = data[2];
235 E('_f_wl'+u+'_mode').value = data[3];
236 E('_f_wl'+u+'_macmode').value = data[5];
237
238 vifs_defined.push([
239 u.toString(), /* fface == wl_ifaces[uidx][1] */
240 (nvram['wl'+u+'_ifname']) || ('wl'+u), /* ifname =~ wl_ifaces[uidx][0] */
241 u.substr(0, u.indexOf('.')), /* unit */
242 u.substr(u.indexOf('.')+1) || '-1', /* subunit */
243 data[1] || '1', /* radio */
244 '0', /* iface up? */
245 data[1] || '1', /* bss_enabled */
246 data[3], /* WL net mode */
247 data[2], /* nvram['wl'+u+'_ssid'] */
248 (eval('nvram["wl'+u+'_hwaddr"]')) || mac_null, /* MAC addr */
249 '0', /* VIFs supported */
250 data[4],
251 data[5] /* Wireless Filter */
252 ]);
253
254 this.resort();
255 this.disableNewEditor(false);
256 this.resetNewEditor();
257
258 /* if we had previously deleted this entry, remove it from deleted table */
259 for (var i = 0; i < vifs_deleted.length; i++) {
260 if (vifs_deleted[i] == u) {
261 vifs_deleted.splice(i, 1);
262 break;
263 }
264 }
265
266 tabSelect(u);
267 verifyFields(null, 1);
268
269 var e = E('footer-msg');
270 e.innerHTML = 'After configuring this VIF, review and save your settings on the Overview tab.';
271 e.style.display = 'inline';
272/* REMOVE-BEGIN
273 setTimeout(
274 function() {
275 e.innerHTML = '';
276 e.style.display = 'none';
277 }, 5000);
278REMOVE-END */
279}
280
281wlg.onOK = function() {
282/* TODO: update info on VIF tab
283// var i, data, view, e, u;
284*/
285 var i, data, view, u;
286
287 if (!this.verifyFields(this.editor, 0))
288 return;
289
290 data = this.fieldValuesToData(this.editor);
291 view = this.dataToView(data);
292
293 u = data[0].toString();
294
295 E('_f_wl'+u+'_radio').checked = (data[1] == '1');
296 E('_wl'+u+'_ssid').value = data[2];
297 E('_f_wl'+u+'_mode').value = data[3];
298 E('_f_wl'+u+'_macmode').value = data[5];
299
300 var vif = definedVIFidx(u);
301
302 vifs_defined[vif][4] = data[1]; /* radio */
303/* REMOVE-BEGIN
304 vifs_defined[vif][6] = data[2]; // bss_enabled
305 vifs_defined[vif][8] = data[3]; // SSID
306 vifs_defined[vif][7] = data[4]; // WL mode
307REMOVE-END */
308 vifs_defined[vif][8] = data[2]; /* SSID */
309 vifs_defined[vif][7] = data[3]; /* WL mode */
310 vifs_defined[vif][11] = data[4]; /* LAN bridge */
311 vifs_defined[vif][12] = data[5]; /* Wireless Filter */
312/* REMOVE-BEGIN
313 alert(data.join('\n'));
314REMOVE-END */
315
316 this.source.setRowData(data);
317 for (i = 0; i < this.source.cells.length; ++i) {
318 this.source.cells[i].innerHTML = view[i];
319 }
320
321 this.removeEditor();
322 this.showSource();
323 this.disableNewEditor(false);
324 this.resetNewEditor();
325
326 verifyFields(null, 1);
327}
328
329wlg.countElem = function(f, v) {
330 var data = this.getAllData();
331 var total = 0;
332 for (var i = 0; i < data.length; ++i) {
333 total += (data[i][f] == v) ? 1 : 0;
334 }
335
336 return total;
337}
338
339wlg.countVIF = function (v) {
340 return this.countElem(0, v);
341}
342
343wlg.verifyFields = function(row, quiet) {
344 var ok = 1;
345 var f = fields.getAll(row);
346
347 if (nvram.lan_ifname.length < 1)
348 f[4].options[0].disabled = 1;
349 if (nvram.lan1_ifname.length < 1)
350 f[4].options[1].disabled = 1;
351 if (nvram.lan2_ifname.length < 1)
352 f[4].options[2].disabled = 1;
353 if (nvram.lan3_ifname.length < 1)
354 f[4].options[3].disabled = 1;
355
356 if (f[0].value.indexOf('.') < 0) {
357/* REMOVE-BEGIN
358 fields.disableAll(row, 1);
359 return 1;
360REMOVE-END */
361 }
362 else {
363 for (var i = 0; i < f[3].options.length ; i++) {
364/* REMOVE-BEGIN
365 f[3].options[i].disabled = ((f[3].options[i].value != 'ap') && (f[3].options[i].value != 'wet'));
366REMOVE-END */
367 f[3].options[i].disabled = (f[3].options[i].value != 'ap');
368 }
369
370 }
371/* REMOVE-BEGIN
372// AB: user can't change WLIF name on gridObj, only by deleting/adding WLIf (destroying/recreating)
373REMOVE-END */
374 if (this.isEditing())
375 f[0].disabled = 1;
376
377 for (var i=0; i < f[0].options.length ; i++) {
378 f[0].options[i].disabled = (this.countVIF(f[0].options[i].value) > 0);
379 }
380
381 if (!v_length(f[2], quiet || !ok, 1, 32))
382 ok = 0;
383
384 return ok;
385}
386
387function definedVIFidx(vif) {
388 for (var i = 0; i < vifs_defined.length; ++i) {
389 if (vifs_defined[i][0] == vif)
390 return i;
391 }
392 return -1;
393}
394
395function tabSelect(name) {
396 if (wlg.isEditing())
397 return;
398
399 tgHideIcons();
400 tabHigh(name);
401
402 if (!E('save-button').disabled)
403 E('footer-msg').style.display = 'none';
404
405 if (name == 'overview')
406 wlg.populate();
407
408 elem.display('overview-tab', (name == 'overview'));
409 E('save-button').value = (name != 'overview') ? 'Overview' : 'Save';
410
411 for (var i = 1; i < tabs.length; ++i) {
412 if (name == tabs[i][0]) {
413 if (definedVIFidx(name) < 0) {
414 elem.display(tabs[i][0]+'-tab-disabled', 1);
415 elem.display(tabs[i][0]+'-tab-enabled', 0);
416 }
417 else {
418 elem.display(tabs[i][0]+'-tab-disabled', 0);
419 elem.display(tabs[i][0]+'-tab-enabled', 1);
420 }
421 }
422 else {
423 elem.display(tabs[i][0]+'-tab-enabled', 0);
424 elem.display(tabs[i][0]+'-tab-disabled', 0);
425 }
426 }
427
428 cookie.set(cprefix+'_tab', name);
429}
430
431function submit_complete() {
432 reloadPage();
433}
434
435function cancel() {
436 cookie.set(cprefix+'_tab', 'overview');
437 reloadPage();
438}
439
440function do_pre_submit_form(fom) {
441
442 var footermsg = E('footer-msg');
443 footermsg.innerHTML = 'Saving...';
444 footermsg.style.display = 'inline';
445
446 E('save-button').disabled = 1;
447 E('cancel-button').disabled = 1;
448
449 var elem = fom.elements;
450 var s = '';
451
452 for (var vidx = 0; vidx < vifs_possible.length; ++vidx) {
453 var u = vifs_possible[vidx][0].toString();/* WL unit (primary) or unit.subunit (virtual) */
454 if (u.indexOf('.') > 0) { /* only if virtual VIF */
455 var vif = definedVIFidx(u);
456 if (vif >= 0) {
457 for (var i = 0; i < elem.length ; ++i) {
458 if (elem[i].name.indexOf('wl'+u) == 0)
459 s += 'nvram set '+elem[i].name+'="'+elem[i].value+'"\n';
460 }
461 }
462/* REMOVE-BEGIN
463 // unset HWADDR for any/all non-primary VIFs we have configured
464 s += 'nvram unset wl'+u+'_hwaddr\n';
465 // AB TODO: figure out what to do with pre-existing/set MAC addresses
466 if (vif >= 0) {
467 if ((vifs_defined[vif][9] == mac_null) || (vifs_defined[vif][9] == '')) {
468 s += 'nvram unset wl'+u+'_hwaddr\n';
469 }
470 }
471REMOVE-END */
472 }
473 }
474
475 /* Clean-up deleted interfaces */
476 var lan_ifnames = nvram['lan_ifnames'];
477 var lan1_ifnames = nvram['lan1_ifnames'];
478 var lan2_ifnames = nvram['lan2_ifnames'];
479 var lan3_ifnames = nvram['lan3_ifnames'];
480 var wl0_vifs = nvram['wl0_vifs'];
481 var wl1_vifs = nvram['wl1_vifs'];
482 var wl2_vifs = nvram['wl2_vifs'];
483
484 for (var vidx = 0; vidx < vifs_deleted.length; ++vidx) {
485 var u = vifs_deleted[vidx];
486 for (var i = 0; i < elem.length ; ++i) {
487 if (elem[i].name.indexOf('wl'+u) == 0)
488 s += 'nvram unset '+elem[i].name+'\n';
489 }
490 lan_ifnames = lan_ifnames.replace('wl'+u, '');
491 lan1_ifnames = lan1_ifnames.replace('wl'+u, '');
492 lan2_ifnames = lan2_ifnames.replace('wl'+u, '');
493 lan3_ifnames = lan3_ifnames.replace('wl'+u, '');
494
495 if (typeof(wl0_vifs) != 'undefined')
496 wl0_vifs = wl0_vifs.replace('wl'+u, '');
497 if (typeof(wl1_vifs) != 'undefined')
498 wl1_vifs = wl1_vifs.replace('wl'+u, '');
499 if (typeof(wl2_vifs) != 'undefined')
500 wl2_vifs = wl2_vifs.replace('wl'+u, '');
501
502 s += 'nvram unset wl'+u+'_wme\n';
503 s += 'nvram unset wl'+u+'_bss_maxassoc\n';
504 s += 'nvram unset wl'+u+'_macmode\n';
505 s += 'nvram unset wl'+u+'_maclist\n';
506 }
507 if (vifs_deleted.length > 0) {
508 s += 'nvram set lan_ifnames="'+lan_ifnames+'"\n';
509 s += 'nvram set lan1_ifnames="'+lan1_ifnames+'"\n';
510 s += 'nvram set lan2_ifnames="'+lan2_ifnames+'"\n';
511 s += 'nvram set lan3_ifnames="'+lan3_ifnames+'"\n';
512
513 if (typeof(wl0_vifs) != 'undefined')
514 s += 'nvram set wl0_vifs="'+wl0_vifs+'"\n';
515 if (typeof(wl1_vifs) != 'undefined')
516 s += 'nvram set wl1_vifs="'+wl1_vifs+'"\n';
517 if (typeof(wl2_vifs) != 'undefined')
518 s += 'nvram set wl2_vifs="'+wl2_vifs+'"\n';
519 }
520 post_pre_submit_form(s);
521}
522
523var cmdresult = '';
524var cmd = null;
525
526function error_pre_submit_form() {
527 var footermsg = E('footer-msg');
528
529 footermsg.innerHTML = '<tt>'+escapeText(cmdresult)+'<\/tt>';
530 footermsg.style.display = 'inline';
531
532 cmdresult = '';
533}
534
535function post_pre_submit_form(s) {
536 if (cmd)
537 return;
538
539 cmd = new XmlHttp();
540 cmd.onCompleted = function(text, xml) {
541 form.submit(E('t_fom'), 1);
542 }
543 cmd.onError = function(x) {
544 cmdresult = 'ERROR: '+x;
545 error_pre_submit_form();
546 }
547
548 cmd.post('shell.cgi', 'action=execute&command='+escapeCGI(s.replace(/\r/g, '')));
549}
550
551function verifyFields(focused, quiet) {
552 var i;
553 var ok = 1;
554 var a, b, c, d, e;
555 var u, uidx;
556 var wmode, sm2;
557
558 for (uidx = 0; uidx < wl_ifaces.length; ++uidx) {
559 u = wl_fface(uidx);
560 if (u)
561 E('wl'+u+'_hwaddr_msg').style.display = (((wl_ifaces[uidx][8] == 'ap') && (wl_ifaces[uidx][5] != wl_ifaces[uidx][9])) ? 'inline' : 'none');
562
563 if (wl_sunit(uidx) < 0) {
564 if (focused == E('_f_wl'+u+'_nband')) {
565 refreshNetModes(uidx);
566 refreshChannels(uidx);
567 refreshBandWidth(uidx);
568 }
569 else if (focused == E('_f_wl'+u+'_nctrlsb') || focused == E('_wl'+u+'_nbw_cap'))
570 refreshChannels(uidx);
571 }
572 }
573
574 var wl_vis = [];
575 for (var vidx = 0; vidx < vifs_possible.length; ++vidx) {
576 var u = vifs_possible[vidx][0];
577 if (definedVIFidx(u) < 0)
578 continue;
579
580 if (u.toString().indexOf('.') < 0) {
581 var uidx = wl_ifidxx(u);
582 a = {
583 _f_wl_radio: 1,
584 _f_wl_ap_isolate: 1,
585 _f_wl_mode: 1,
586/* AB disabled for VIFs?! */
587 _f_wl_nband: (bands[uidx].length > 1) ? 1 : 0,
588/* AB disabled for VIFs?! */
589 _wl_net_mode: 1,
590 _wl_ssid: 1,
591 _f_wl_bcast: 1,
592/* AB disabled for VIFs?! */
593 _wl_channel: 1,
594/* AB disabled for VIFs?! */
595 _wl_nbw_cap: nphy || acphy ? 1 : 0,
596/* AB disabled for VIFs?! */
597 _f_wl_nctrlsb: nphy || acphy ? 1 : 0,
598/* AB disabled for VIFs?! */
599 _f_wl_scan: 1,
600
601 _wl_security_mode: 1,
602 _wl_crypto: 1,
603 _wl_wpa_psk: 1,
604 _f_wl_psk_random1: 1,
605 _f_wl_psk_random2: 1,
606 _wl_wpa_gtk_rekey: 1,
607 _wl_radius_key: 1,
608 _wl_radius_ipaddr: 1,
609 _wl_radius_port: 1,
610 _wl_wep_bit: 1,
611 _wl_passphrase: 1,
612 _f_wl_wep_gen: 1,
613 _f_wl_wep_random: 1,
614 _wl_key1: 1,
615 _wl_key2: 1,
616 _wl_key3: 1,
617 _wl_key4: 1,
618
619 _f_wl_lazywds: 1,
620 _f_wl_wds_0: 1,
621 _f_wl_macmode: 1
622 };
623 }
624 else {
625 a = {
626 _f_wl_radio: 1,
627 _f_wl_ap_isolate: 1,
628 _f_wl_mode: 1,
629/* REMOVE-BEGIN
630// AB disabled for VIFs?!
631 _f_wl_nband: (bands[uidx].length > 1) ? 1 : 0,
632// AB disabled for VIFs?!
633 _wl_net_mode: 1,
634REMOVE-END */
635 _wl_ssid: 1,
636 _f_wl_bcast: 1,
637/* REMOVE-BEGIN
638// AB disabled for VIFs?!
639 _wl_channel: 1,
640 _wl_nbw_cap: nphy ? 1 : 0,
641 _f_wl_nctrlsb: nphy ? 1 : 0,
642 _f_wl_scan: 1,
643REMOVE-END */
644
645 _wl_security_mode: 1,
646 _wl_crypto: 1,
647 _wl_wpa_psk: 1,
648 _f_wl_psk_random1: 1,
649 _f_wl_psk_random2: 1,
650 _wl_wpa_gtk_rekey: 1,
651 _wl_radius_key: 1,
652 _wl_radius_ipaddr: 1,
653 _wl_radius_port: 1,
654 _wl_wep_bit: 1,
655 _wl_passphrase: 1,
656 _f_wl_wep_gen: 1,
657 _f_wl_wep_random: 1,
658 _wl_key1: 1,
659 _wl_key2: 1,
660 _wl_key3: 1,
661 _wl_key4: 1,
662
663 _f_wl_lazywds: 1,
664 _f_wl_wds_0: 1,
665 _f_wl_macmode: 1
666 };
667 }
668 wl_vis[vidx] = a;
669 }
670
671 for (var vidx = 0; vidx < vifs_possible.length; ++vidx) {
672 var u = vifs_possible[vidx][0];
673 if (definedVIFidx(u) < 0)
674 continue;
675
676 wmode = E('_f_wl'+u+'_mode').value;
677
678 if (!E('_f_wl'+u+'_radio').checked) {
679 for (a in wl_vis[vidx]) {
680 wl_vis[vidx][a] = 2;
681 }
682 wl_vis[vidx]._f_wl_radio = 1;
683 if (u.toString().indexOf('.') < 0) {
684 var uidx = wl_ifidxx(u);
685 wl_vis[vidx]._wl_nbw_cap = nphy || acphy ? 2 : 0;
686 wl_vis[vidx]._f_wl_nband = (bands[uidx].length > 1) ? 2 : 0;
687 }
688 }
689
690 E('wl'+u+'_mode_msg').style.display = (((wmode == 'sta') || (wmode == 'wet') ||
691/* BCMWL6-BEGIN */
692 (wmode == 'psta') ||
693/* BCMWL6-END */
694 0) ? 'inline' : 'none');
695
696 switch (wmode) {
697 case 'apwds':
698 case 'wds':
699 break;
700 case 'wet':
701/* BCMWL6-BEGIN */
702 case 'psta':
703/* BCMWL6-END */
704 case 'sta':
705 wl_vis[vidx]._f_wl_bcast = 0;
706 if (u.toString().indexOf('.') < 0) {
707 wl_vis[vidx]._wl_channel = 0;
708 wl_vis[vidx]._wl_nbw_cap = 0;
709 }
710 default:
711 wl_vis[vidx]._f_wl_lazywds = 0;
712 wl_vis[vidx]._f_wl_wds_0 = 0;
713 break;
714 }
715
716 sm2 = E('_wl'+u+'_security_mode').value;
717 switch (sm2) {
718 case 'disabled':
719 wl_vis[vidx]._wl_crypto = 0;
720 wl_vis[vidx]._wl_wep_bit = 0;
721 wl_vis[vidx]._wl_wpa_psk = 0;
722 wl_vis[vidx]._wl_radius_key = 0;
723 wl_vis[vidx]._wl_radius_ipaddr = 0;
724 wl_vis[vidx]._wl_wpa_gtk_rekey = 0;
725 break;
726 case 'wep':
727 wl_vis[vidx]._wl_crypto = 0;
728 wl_vis[vidx]._wl_wpa_psk = 0;
729 wl_vis[vidx]._wl_radius_key = 0;
730 wl_vis[vidx]._wl_radius_ipaddr = 0;
731 wl_vis[vidx]._wl_wpa_gtk_rekey = 0;
732 break;
733 case 'radius':
734 wl_vis[vidx]._wl_crypto = 0;
735 wl_vis[vidx]._wl_wpa_psk = 0;
736 break;
737 default: /* wpaX */
738 wl_vis[vidx]._wl_wep_bit = 0;
739 if (sm2.indexOf('personal') != -1) {
740 wl_vis[vidx]._wl_radius_key = 0;
741 wl_vis[vidx]._wl_radius_ipaddr = 0;
742 }
743 else
744 wl_vis[vidx]._wl_wpa_psk = 0;
745 break;
746 }
747
748 if ((E('_f_wl'+u+'_lazywds').value == 1) && (wl_vis[vidx]._f_wl_wds_0 == 1))
749 wl_vis[vidx]._f_wl_wds_0 = 2;
750
751 if (u.toString().indexOf('.') < 0) {
752 if (wl_vis[vidx]._wl_nbw_cap != 0) {
753 switch (E('_wl'+u+'_net_mode').value) {
754 case 'b-only':
755 case 'g-only':
756 case 'a-only':
757 case 'bg-mixed':
758 wl_vis[vidx]._wl_nbw_cap = 2;
759 if (E('_wl'+u+'_nbw_cap').value != '0') {
760 E('_wl'+u+'_nbw_cap').value = 0;
761 refreshChannels(wl_ifidxx(u));
762 }
763 break;
764 }
765 /* avoid Enterprise-TKIP with 40MHz */
766 if ((sm2 == 'wpa_enterprise') && (E('_wl'+u+'_crypto').value == 'tkip')) {
767 wl_vis[vidx]._wl_nbw_cap = 2;
768 if (E('_wl'+u+'_nbw_cap').value != '0') {
769 E('_wl'+u+'_nbw_cap').value = 0;
770 refreshChannels(wl_ifidxx(u));
771 }
772 }
773 }
774
775 wl_vis[vidx]._f_wl_nctrlsb = (E('_wl'+u+'_nbw_cap').value == 0) ? 0 : wl_vis[vidx]._wl_nbw_cap;
776
777/* REMOVE-BEGIN
778 This is ugly...
779 Special case - 2.4GHz band, currently running in B/G-only mode,
780 with N/Auto and 40MHz selected in the GUI.
781 Channel list is not filtered in this case by the wl driver,
782 and includes all channels available with 20MHz channel width.
783REMOVE-END */
784
785 b = selectedBand(wl_ifidxx(u));
786
787 if (wl_vis[vidx]._wl_channel == 1 && wl_vis[vidx]._f_wl_nctrlsb != 0 && ((b == '2') || (wl_vis[vidx]._f_wl_nband == 0 && b == '0'))) {
788 switch (eval('nvram["wl'+u+'_net_mode"]')) {
789 case 'b-only':
790 case 'g-only':
791 case 'bg-mixed':
792 i = E('_wl'+u+'_channel').value * 1;
793 if (i > 0 && i < 5) {
794 E('_f_wl'+u+'_nctrlsb').value = 'lower';
795 wl_vis[vidx]._f_wl_nctrlsb = 2;
796 }
797 else if (i > max_channel[wl_ifidxx(u)] - 4) {
798 E('_f_wl'+u+'_nctrlsb').value = 'upper';
799 wl_vis[vidx]._f_wl_nctrlsb = 2;
800 }
801 break;
802 }
803 }
804 wl_vis[vidx]._f_wl_scan = wl_vis[vidx]._wl_channel;
805 }
806 else {
807 e = E('_f_wl'+u+'_mode');
808 for (var i = 0; i < e.options.length ; i++) {
809 e.options[i].disabled = (e.options[i].value != 'ap');
810 }
811 }
812
813 wl_vis[vidx]._f_wl_psk_random1 = wl_vis[vidx]._wl_wpa_psk;
814 wl_vis[vidx]._f_wl_psk_random2 = wl_vis[vidx]._wl_radius_key;
815 wl_vis[vidx]._wl_radius_port = wl_vis[vidx]._wl_radius_ipaddr;
816 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;
817
818 for (i = 1; i < 10; ++i) {
819 wl_vis[vidx]['_f_wl_wds_'+i] = wl_vis[vidx]._f_wl_wds_0;
820 }
821
822 } /* for each wl_iface */
823
824 for (var vidx = 0; vidx < vifs_possible.length; ++vidx) {
825 var u = vifs_possible[vidx][0];
826 if (definedVIFidx(u) < 0)
827 continue;
828
829 for (a in wl_vis[vidx]) {
830 i = 3;
831 if (a.substr(0, 6) == '_f_wl_')
832 i = 5;
833
834 b = E(a.substr(0, i)+u+a.substr(i, a.length));
835 c = wl_vis[vidx][a];
836 b.disabled = (c != 1);
837 PR(b).style.display = (c ? 'table-row' : 'none');
838 }
839 }
840
841/* --- verify --- */
842
843 var wlclnt = 0;
844 for (var vidx = 0; vidx < vifs_possible.length; ++vidx) {
845 var u = vifs_possible[vidx][0];
846 if (definedVIFidx(u) < 0)
847 continue;
848
849 wmode = E('_f_wl'+u+'_mode').value;
850 sm2 = E('_wl'+u+'_security_mode').value;
851
852 /* --- N standard does not support WPA+TKIP --- */
853 if (u.toString().indexOf('.') < 0) {
854 a = E('_wl'+u+'_crypto');
855 switch (E('_wl'+u+'_net_mode').value) {
856 case 'mixed':
857 case 'n-only':
858/* BCMWL6-BEGIN */
859 case 'nac-mixed':
860 case 'ac-only':
861/* BCMWL6-END */
862 if ((nphy || acphy) && (a.value == 'tkip') && (sm2.indexOf('wpa') != -1)) {
863 ferror.set(a, 'TKIP encryption is not supported with WPA / WPA2 in N and/or AC mode.', quiet || !ok);
864 ok = 0;
865 }
866 else
867 ferror.clear(a);
868
869 break;
870 }
871
872 a = E('_wl'+u+'_net_mode');
873 ferror.clear(a);
874 }
875
876 b = E('_f_wl'+u+'_mode');
877 ferror.clear(b);
878
879 if ((wmode == 'sta') || (wmode == 'wet') ||
880/* BCMWL6-BEGIN */
881 (wmode == 'psta') ||
882/* BCMWL6-END */
883 0) {
884 ++wlclnt;
885 if (wlclnt > 1) {
886 ferror.set(b, 'Only one wireless interface can be configured in client mode.', quiet || !ok);
887 ok = 0;
888 }
889 else if (a.value == 'n-only') {
890 ferror.set(a, 'N-only is not supported in wireless client modes, use Auto.', quiet || !ok);
891 ok = 0;
892 }
893/* BCMWL6-BEGIN */
894 else if (a.value == 'nac-mixed') {
895 ferror.set(a, 'N/AC Mixed is not supported in wireless client modes, use Auto.', quiet || !ok);
896 ok = 0;
897 }
898 else if (a.value == 'ac-only') {
899 ferror.set(a, 'AC-only is not supported in wireless client modes, use Auto.', quiet || !ok);
900 ok = 0;
901 }
902/* BCMWL6-END */
903 }
904
905 a = E('_wl'+u+'_wpa_psk');
906 ferror.clear(a);
907 if (wl_vis[vidx]._f_wl_wpa_psk == 1) {
908 if ((a.value.length < 8) || ((a.value.length == 64) && (a.value.search(/[^0-9A-Fa-f]/) != -1))) {
909 ferror.set('_wl'+u+'_wpa_psk', 'Invalid pre-shared key. Please enter at least 8 characters or 64 hexadecimal digits.', quiet || !ok);
910 ok = 0;
911 }
912 }
913
914 if (u.toString().indexOf('.') < 0) {
915 /* wl channel */
916 if (((wmode == 'wds') || (wmode == 'apwds')) && (wl_vis[vidx]._wl_channel == 1) && (E('_wl'+u+'_channel').value == '0')) {
917 ferror.set('_wl'+u+'_channel', 'Fixed wireless channel required in WDS mode.', quiet || !ok);
918 ok = 0;
919 }
920 else
921 ferror.clear('_wl'+u+'_channel');
922 }
923/* REMOVE-BEGIN
924 if (E('_f_wl'+u+'_mode').value == 'sta') {
925 if ((wan == 'disabled') && (E('_f_wl'+u+'_radio').checked)) {
926 ferror.set('_wan_proto', 'Wireless Client mode requires a valid WAN setting (usually DHCP).', quiet || !ok);
927 ok = 0;
928 }
929 }
930REMOVE-END */
931 }
932
933 for (var vidx = 0; vidx < vifs_possible.length; ++vidx) {
934 var v;
935 var u = vifs_possible[vidx][0];
936 if (definedVIFidx(u) < 0)
937 continue;
938
939 /* IP address */
940 a = ['_radius_ipaddr'];
941 for (i = a.length - 1; i >= 0; --i) {
942 if ((wl_vis[vidx]['_wl'+a[i]]) && (!v_ip('_wl'+u+a[i], quiet || !ok)))
943 ok = 0;
944 }
945
946 /* range */
947 a = [['_wpa_gtk_rekey', 0, 2592000], ['_radius_port', 1, 65535]];
948 for (i = a.length - 1; i >= 0; --i) {
949 v = a[i];
950 if ((wl_vis[vidx]['_wl'+v[0]]) && (!v_range('_wl'+u+v[0], quiet || !ok, v[1], v[2])))
951 ok = 0;
952 }
953
954 /* length */
955 a = [['_ssid', 1], ['_radius_key', 1]];
956 for (i = a.length - 1; i >= 0; --i) {
957 v = a[i];
958 if ((wl_vis[vidx]['_wl'+v[0]]) && (!v_length('_wl'+u+v[0], quiet || !ok, v[1], E('_wl'+u+v[0]).maxlength)))
959 ok = 0;
960 }
961
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))
969 ok = 0;
970 }
971 else
972 ferror.clear(b);
973 }
974 }
975
976 ferror.clear('_f_wl'+u+'_wds_0');
977 if (wl_vis[vidx]._f_wl_wds_0 == 1) {
978 b = 0;
979 for (i = 0; i < 10; ++i) {
980 a = E('_f_wl'+u+'_wds_'+i);
981 if (!v_macz(a, quiet || !ok))
982 ok = 0;
983 else if (!isMAC0(a.value))
984 b = 1;
985 }
986 if (!b) {
987 ferror.set('_f_wl'+u+'_wds_0', 'WDS MAC address required.', quiet || !ok);
988 ok = 0;
989 }
990 }
991
992 ferror.clear('_f_wl'+u+'_macmode');
993 a = E('_f_wl'+u+'_macmode').value;
994 if (a != 'disabled' && a != 'deny' && a != 'allow') {
995 ferror.set('_f_wl'+u+'_macmode', 'Wrong Wireless Filter settings.', quiet || !ok);
996 ok = 0;
997 }
998
999 if ((ok) && (focused)) {
1000 var w = definedVIFidx(u);
1001 if (focused.id == '_wl'+u+'_ssid')
1002 vifs_defined[w][8] = focused.value;
1003 if (focused.id == '_f_wl'+u+'_mode')
1004 vifs_defined[w][7] = focused.value;
1005 if (focused.id == '_f_wl'+u+'_radio') {
1006 vifs_defined[w][4] = (focused.checked) ? '1' : '0';
1007 vifs_defined[w][6] = (focused.checked) ? '1' : '0';
1008 }
1009 if (focused.id == '_f_wl'+u+'_macmode')
1010 vifs_defined[w][12] = focused.value;
1011 }
1012 }
1013
1014 return ok;
1015}
1016
1017function save() {
1018 if (E('save-button').value != 'Save') {
1019 tabSelect('overview');
1020 return;
1021 }
1022
1023 if (wlg.isEditing())
1024 return;
1025
1026 wlg.resetNewEditor();
1027
1028 if (!verifyFields(null, 0))
1029 return;
1030
1031 var a, b, c;
1032 var w, uidx, wmode, sm2, wradio;
1033
1034 var i, u, vidx, vif;
1035/* BCMWL6-BEGIN */
1036 var router_restart = 0;
1037/* BCMWL6-END */
1038
1039 var fom = E('t_fom');
1040
1041 for (var i = 0 ; i <= MAX_BRIDGE_ID ; i++) {
1042 var j = (i == 0) ? '' : i.toString();
1043 fom['lan'+j+'_ifnames'].value = '';
1044 var l = nvram['lan'+j+'_ifnames'].split(' ');
1045 for (var k = 0 ; k < l.length; ++k) {
1046 if (l[k].indexOf('vlan') != -1)
1047 fom['lan'+j+'_ifnames'].value += l[k]+' ';
1048 }
1049 fom['lan'+j+'_ifnames'].value = fom['lan'+j+'_ifnames'].value.trim();
1050 }
1051
1052 for (vidx = 0; vidx < vifs_possible.length; ++vidx) {
1053 u = vifs_possible[vidx][0].toString(); /* WL unit (primary) or unit.subunit (virtual) */
1054 vif = definedVIFidx(u);
1055
1056 if (u == 0)
1057 fom.wl_macmode.value = E('_f_wl'+u+'_macmode').value; /* rewrite for backward compatibility */
1058
1059 if (vif < 0)
1060 E('_wl'+u+'_macmode').name = '_f_wl'+u+'_macmode_'; /* use fake input name to delete */
1061 else {
1062 E('_wl'+u+'_macmode').value = E('_f_wl'+u+'_macmode').value;
1063 E('_wl'+u+'_maclist').value = nvram['wl_maclist'].toString(); /* copy base maclist to 'u' interface */
1064 }
1065/* REMOVE-BEGIN
1066// AB TODO: try to play this safer - save some vital info on primary BSS (just in case?)
1067// AB TODO: with the UNSET part later on - is this really needed?
1068REMOVE-END */
1069 if (vif < 0) {
1070 a = [ ['radio', '0'], ['bss_enabled', '0'], ['ifname', ('wl'+u)] ];
1071 b = 'wl'+u+'_';
1072 for (i = 0; i < a.length; ++i) {
1073 c = ''+b+a[i][0];
1074 if (typeof(nvram[c]) != 'undefined')
1075 E('_'+c).value = a[i][1];
1076 }
1077 continue;
1078 }
1079
1080 if (vifs_defined[vif][11]*1 != 4) {
1081 var x = (vifs_defined[vif][11] == '0') ? '' : vifs_defined[vif][11].toString();
1082 fom['lan'+x+'_ifnames'].value += ' '+vifs_defined[vif][1];
1083 fom['lan'+x+'_ifnames'].value = fom['lan'+x+'_ifnames'].value.trim();
1084 }
1085
1086/* REMOVE-BEGIN
1087// AB TODO: cleanup in advance or just bail out later?
1088REMOVE-END */
1089 if (u.indexOf('.') < 0) {
1090 a = [];
1091 for (i = 0; i < vifs_defined.length; ++i) {
1092 if (vifs_defined[i][2].toString() != u)
1093 continue;
1094 if ((vifs_defined[i][3] * 1) < 1)
1095 continue;
1096 a.push('wl'+vifs_defined[i][0]);
1097 }
1098 E('_wl'+u+'_vifs').value = a.join(' ');
1099 E('_wl'+u+'_ifname').value = nvram['wl'+u+'_ifname'] || vifs_defined[vif][1];
1100 }
1101 else
1102 E('_wl'+u+'_ifname').value = nvram['wl'+u+'_ifname'] || 'wl'+u;
1103
1104 wmode = E('_f_wl'+u+'_mode').value;
1105 sm2 = E('_wl'+u+'_security_mode').value;
1106 wradio = E('_f_wl'+u+'_radio').checked;
1107
1108 if (wmode == 'apwds')
1109 E('_wl'+u+'_mode').value = 'ap';
1110 else
1111 E('_wl'+u+'_mode').value = wmode;
1112
1113/* primary VIF */
1114 if (u.indexOf('.') < 0) {
1115 E('_wl'+u+'_nband').value = selectedBand(wl_ifidxx(u));
1116
1117 a = [];
1118 for (i = 0; i < 10; ++i) {
1119 a.push(E('_f_wl'+u+'_wds_'+i).value);
1120 }
1121 E('_wl'+u+'_wds').value = joinAddr(a);
1122
1123 if (wmode.indexOf('wds') != -1) {
1124 E('_wl'+u+'_wds_enable').value = 1;
1125 E('_wl'+u+'_lazywds').value = E('_f_wl'+u+'_lazywds').value;
1126 if (E('_wl'+u+'_lazywds').value == 1) E('_wl'+u+'_wds').value = '';
1127 }
1128 else {
1129 E('_wl'+u+'_wds_enable').value = 0;
1130 E('_wl'+u+'_wds').value = '';
1131 E('_wl'+u+'_lazywds').value = 0;
1132 }
1133 }
1134
1135 E('_wl'+u+'_radio').value = wradio ? 1 : 0;
1136 E('_wl'+u+'_bss_enabled').value = wradio ? 1 : 0;
1137 E('_wl'+u+'_ap_isolate').value = E('_f_wl'+u+'_ap_isolate').checked ? 1 : 0;
1138
1139 E('_wl'+u+'_auth').value = eval('nvram["wl'+u+'_auth"]') || '0';
1140
1141 e = E('_wl'+u+'_akm');
1142 switch (sm2) {
1143 case 'disabled':
1144 case 'radius':
1145 case 'wep':
1146 e.value = '';
1147 break;
1148 default:
1149 c = [];
1150
1151 if (sm2.indexOf('personal') != -1) {
1152 if (sm2.indexOf('wpa2_') == -1) c.push('psk');
1153 if (sm2.indexOf('wpa_') == -1) c.push('psk2');
1154 }
1155 else {
1156 if (sm2.indexOf('wpa2_') == -1) c.push('wpa');
1157 if (sm2.indexOf('wpa_') == -1) c.push('wpa2');
1158 }
1159 c = c.join(' ');
1160 e.value = c;
1161 break;
1162 }
1163 E('_wl'+u+'_auth_mode').value = (sm2 == 'radius') ? 'radius' : 'none';
1164 E('_wl'+u+'_wep').value = ((sm2 == 'radius') || (sm2 == 'wep')) ? 'enabled': 'disabled';
1165
1166 if (sm2.indexOf('wpa') != -1)
1167 E('_wl'+u+'_auth').value = '0';
1168
1169/* primary VIF */
1170 if (u.indexOf('.') < 0) {
1171 E('_wl'+u+'_nreqd').value = 0;
1172 E('_wl'+u+'_gmode').value = 1;
1173 E('_wl'+u+'_nmode').value = 0;
1174 E('_wl'+u+'_nmcsidx').value = -2; /* Legacy Rate */
1175 E('_wl'+u+'_nbw').value = 0;
1176/* BCMWL6-BEGIN */
1177 E('_wl'+u+'_bss_opmode_cap_reqd').value = 0; /* no requirements for joining clients */
1178/* BCMWL6-END */
1179 switch (E('_wl'+u+'_net_mode').value) {
1180 case 'b-only':
1181 E('_wl'+u+'_gmode').value = 0;
1182 break;
1183 case 'g-only':
1184 E('_wl'+u+'_gmode').value = 2;
1185/* BCMWL6-BEGIN */
1186 E('_wl'+u+'_bss_opmode_cap_reqd').value = 1; /* client must advertise ERP / 11g cap. to be able to join */
1187/* BCMWL6-END */
1188 break;
1189 case 'bg-mixed':
1190 break;
1191 case 'a-only':
1192 E('_wl'+u+'_nmcsidx').value = -1; /* Auto */
1193 break;
1194 case 'n-only':
1195 if (selectedBand(wl_ifidxx(u)) == '1') { /* 5 GHz */
1196 E('_wl'+u+'_nmode').value = -1;
1197 E('_wl'+u+'_nmcsidx').value = -1;
1198 }
1199 else { /* 2.4 GHz */
1200 E('_wl'+u+'_nmode').value = 1;
1201 E('_wl'+u+'_nmcsidx').value = 32;
1202 }
1203 E('_wl'+u+'_nreqd').value = 1; /* require 11n support (SDK5) */
1204/* BCMWL6-BEGIN */
1205 E('_wl'+u+'_bss_opmode_cap_reqd').value = 2; /* client must advertise HT / 11n cap. to be able to join */
1206/* BCMWL6-END */
1207 break;
1208/* BCMWL6-BEGIN */
1209 case 'nac-mixed': /* only 5 GHz */
1210 E('_wl'+u+'_nmode').value = -1; /* Auto */
1211 E('_wl'+u+'_nmcsidx').value = -1; /* Auto */
1212 E('_wl'+u+'_bss_opmode_cap_reqd').value = 2; /* client must advertise HT / 11n cap. to be able to join */
1213 break;
1214 case 'ac-only': /* only 5 GHz */
1215 E('_wl'+u+'_nmode').value = -1; /* Auto */
1216 E('_wl'+u+'_nmcsidx').value = -1; /* Auto */
1217 E('_wl'+u+'_bss_opmode_cap_reqd').value = 3; /* client must advertise VHT / 11ac cap. to be able to join */
1218 break;
1219/* BCMWL6-END */
1220 default: /* Auto */
1221 E('_wl'+u+'_nmode').value = -1;
1222 E('_wl'+u+'_nmcsidx').value = -1;
1223 break;
1224 }
1225
1226 E('_wl'+u+'_nctrlsb').value = eval('nvram.wl'+u+'_nctrlsb');
1227 if (E('_wl'+u+'_nmode').value != 0) {
1228 E('_wl'+u+'_nctrlsb').value = E('_f_wl'+u+'_nctrlsb').value;
1229 E('_wl'+u+'_nbw').value = (E('_wl'+u+'_nbw_cap').value == 0) ? 20 : ((E('_wl'+u+'_nbw_cap').value == 3) ? 80 : 40);
1230 }
1231 }
1232
1233 E('_wl'+u+'_closed').value = E('_f_wl'+u+'_bcast').checked ? 0 : 1;
1234
1235 a = fields.radio.selected(eval('fom["f_wl'+u+'_wepidx"]'));
1236/* REMOVE-BEGIN
1237 if (a) E('_wl'+u+'_key').value = a.value;
1238REMOVE-END */
1239 E('_wl'+u+'_key').value = (a) ? a.value : '1';
1240 }
1241
1242/* BCMWL6-BEGIN */
1243 for (vidx = 0; vidx < vifs_possible.length; ++vidx) {
1244 u = vifs_possible[vidx][0].toString();
1245 if (definedVIFidx(u) < 0)
1246 continue;
1247
1248 var check_psta = fom['wl'+u+'_mode'].value;
1249
1250 if ((check_psta == 'psta') && (nvram['wl'+u+'_mode'] != check_psta))
1251 router_restart = 1;
1252 }
1253
1254 if (router_restart) {
1255 fom._service.value = '*'; /* special case for Media Bridge mode: restart all */
1256 }
1257 else {
1258 fom._service.value = 'wlgui-restart'; /* always restart wireless */
1259 }
1260/* BCMWL6-END */
1261
1262 do_pre_submit_form(fom);
1263
1264/* REMOVE-BEGIN
1265 form.submit(fom, 1);
1266REMOVE-END */
1267}
1268
1269function earlyInit() {
1270
1271 for (var mode in wmo) {
1272 wl_modes_available.push([mode, wmo[mode]]);
1273 }
1274
1275 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1276 var u = wl_fface(uidx).toString();
1277 var bridged = 4;
1278 if (u) {
1279 var wmode = (((nvram['wl'+u+'_mode']) == 'ap') && ((nvram['wl'+u+'_wds_enable']) == '1')) ? 'apwds': (nvram['wl'+u+'_mode']);
1280
1281 for (var i = 0 ; i <= MAX_BRIDGE_ID ; i++) {
1282 var j = (i == 0) ? '' : i.toString();
1283 var l = nvram['lan'+j+'_ifnames'].split(' ');
1284 for (var k = 0 ; k < l.length; k++) {
1285 if(l[k].indexOf(wl_ifaces[uidx][0]) != -1)
1286 bridged = i;
1287 }
1288 }
1289
1290 var wlvifs = ((wl_ifaces[uidx][7] > 4) ? '4' : wl_ifaces[uidx][7].toString());
1291 vifs_defined.push([
1292 u.toString(), /* fface == wl_ifaces[uidx][1] */
1293 wl_ifaces[uidx][0],
1294 wl_ifaces[uidx][2] || '0', /* unit */
1295 wl_ifaces[uidx][3] || '0', /* subunit */
1296 nvram['wl'+u+'_radio'] || '0', /* radio */
1297 wl_ifaces[uidx][6] || '0', /* iface up/operational status */
1298 nvram['wl'+u+'_bss_enabled'] || '1', /* bss_enabled */
1299 wmode || 'disabled', /* WL net mode */
1300 wl_ifaces[uidx][4] || '', /* nvram['wl'+u+'_ssid'] */
1301 nvram['wl'+u+'_hwaddr'], /* MAC addr */
1302 wlvifs, /* VIFs supported */
1303 bridged,
1304 nvram['wl'+u+'_macmode'] || 'disabled' /* Wireless Filter */
1305 ]);
1306 /* max_no_vifs = max_no_vifs+((wl_ifaces[uidx][7] > 4) ? 4 : wl_ifaces[uidx][7]); */
1307 max_no_vifs = max_no_vifs + parseInt(wlvifs);
1308 }
1309 }
1310
1311 W('<style>\n');
1312 for (var uidx in vifs_defined) {
1313 if (typeof(vifs_defined[uidx][0]) == 'undefined')
1314 continue;
1315
1316 var total = vifs_defined[uidx][10] * 1;
1317 if (isNaN(total))
1318 continue;
1319 if (total >= 4)
1320 total = 4;
1321
1322 W('#spin'+vifs_defined[uidx][2]+', \n');
1323
1324 for (var i = 0; i < total; ++i) {
1325 var u = vifs_defined[uidx][2].toString();
1326 var s = (i == 0) ? '' : '.'+i.toString();
1327 var t = u+s;
1328 var v = wl_ifidxx(t);
1329 var w = (v < 0 ? 'wl'+t : wl_display_ifname(v));
1330 vifs_possible.push([t, w]);
1331 tabs.push([t, w]);
1332 }
1333 }
1334
1335 W('#spin {\ndisplay:none;\nvertical-align:middle;\n}\n<\/style>\n');
1336}
1337
1338function init() {
1339 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1340 if (wl_sunit(uidx) < 0) {
1341 var u = wl_unit(uidx);
1342 var wmode = E('_f_wl'+u+'_mode').value;
1343 var ssidScanButton = document.getElementById('_f_wl' + u + '_ssidscan');
1344 if (wmode === 'ap') {
1345 ssidScanButton.style.display = 'none';
1346 } else {
1347 ssidScanButton.style.display = '';
1348 }
1349 }
1350 }
1351 var uninit = wl_ifaces.length - 1;
1352 while (uninit > 0) {
1353 if (((nvram['wl'+wl_unit(uninit)+'_corerev']) * 1) >= 9)
1354 break;
1355
1356 uninit--;
1357 }
1358
1359 E('sesdiv_vifs').style.display = 'block';
1360 if (uninit < 0) {
1361 E('sesdiv_vifs').innerHTML = '<div id="notice">This feature is not supported on this router.<\/div>';
1362 return;
1363 }
1364
1365 tabSelect(cookie.get(cprefix+'_tab') || tabs[0][0]);
1366
1367 var c;
1368
1369 if (((c = cookie.get(cprefix+'_notes_vis')) != null) && (c == '1'))
1370 toggleVisibility(cprefix, 'notes');
1371
1372 if (((c = cookie.get(cprefix+'_details_vis')) != null) && (c == '1'))
1373 toggleVisibility(cprefix, 'details');
1374
1375 wlg.setup();
1376 eventHandler();
1377}
1378</script>
1379</head>
1380
1381<body onload="init()">
1382<form id="t_fom" method="post" action="tomato.cgi">
1383<table id="container">
1384<tr><td colspan="2" id="header">
1385 <div class="title"><a href="/">FreshTomato</a></div>
1386 <div class="version">Version <% version(); %> on <% nv("t_model_name"); %></div>
1387</td></tr>
1388<tr id="body"><td id="navi"><script>navi()</script></td>
1389<td id="content">
1390<div id="ident"><% ident(); %> | <script>wikiLink();</script></div>
1391
1392<!-- / / / -->
1393
1394<input type="hidden" name="_nextpage" value="advanced-wlanvifs.asp">
1395<input type="hidden" name="_nextwait" value="10">
1396<input type="hidden" name="_service" value="wlgui-restart">
1397<input type="hidden" name="_force_commit" value="1">
1398<input type="hidden" name="lan_ifnames" value="">
1399<input type="hidden" name="lan1_ifnames" value="">
1400<input type="hidden" name="lan2_ifnames" value="">
1401<input type="hidden" name="lan3_ifnames" value="">
1402<input type="hidden" name="wl_macmode" value="">
1403
1404<!-- / / / -->
1405
1406<div class="section-title">Virtual Wireless Interfaces</div>
1407
1408<div id="sesdiv_vifs" style="display:none">
1409
1410 <div class="section">
1411 <script>tabCreate.apply(this, tabs);</script>
1412 </div>
1413
1414<!-- / / / -->
1415
1416 <div id="overview-tab">
1417 <div class="tomato-grid" id="wlif-grid"></div>
1418
1419<!-- / / / -->
1420
1421 <div class="section-title">Wireless Interfaces Details <small><i><a href="javascript:toggleVisibility(cprefix,'details');"><span id="sesdiv_details_showhide">(Show)</span></a></i></small></div>
1422 <div class="section" id="sesdiv_details" style="display:none">
1423 <script>
1424 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1425 if (wl_sunit(uidx) < 0) {
1426 var c = [];
1427 c.push({ title: 'Interface'+(wlstats[uidx].radio ? '' : ' <span style="color:red">Disabled<\/span>'), text: wl_display_ifname(uidx) });
1428 c.push({ title: 'Virtual Interfaces', indent: 2, rid: 'wl'+wl_fface(uidx)+'_vifs', text: 'wl'+wl_fface(uidx)+' '+nvram['wl'+wl_fface(uidx)+'_vifs']+' <small>(max '+wl_ifaces[uidx][7]+')<\/small>' });
1429 createFieldTable('',c);
1430 }
1431 }
1432 </script>
1433 </div>
1434
1435<!-- / / / -->
1436
1437 <div class="section-title">Notes <small><i><a href="javascript:toggleVisibility(cprefix,'notes');"><span id="sesdiv_notes_showhide">(Show)</span></a></i></small></div>
1438 <div class="section" id="sesdiv_notes" style="display:none">
1439 <ul>
1440 <li><b>Warning!</b> Avoid using 'virtual interfaces' on interface in Wireless Ethernet Bridge or Media Bridge mode due to possible problems.</li>
1441 </ul>
1442 <br>
1443 <ul>
1444 <li><b>Interface</b> - Wireless VIF name.</li>
1445 <li><b>Enabled</b> - If this VIF should be active and brought online.</li>
1446 <li><b>SSID</b> - Wireless Service Set Identifier.</li>
1447 <li><b>Mode</b> - Interface mode: Access Point, WDS, Wireless Client, etc...</li>
1448 <li><b>Bridge</b> - Which LAN bridge this VIF should be assigned.</li>
1449 <li><b>WFilter</b> - <a href="basic-wfilter.asp" class="new_window">Wireless Filter</a>:
1450 <ul>
1451 <li><i>Disabled</i> - Disable filter on that interface.</li>
1452 <li><i>Block</i> - Block clients from the <a href="basic-wfilter.asp" class="new_window">list</a> on that interface.</li>
1453 <li><i>Permit</i> - Permit only clients from the <a href="basic-wfilter.asp" class="new_window">list</a> on that interface.</li>
1454 </ul>
1455 </li>
1456 </ul>
1457 <br>
1458 <ul>
1459 <li><b>Other relevant notes/hints:</b>
1460 <ul>
1461 <li>When creating/defining a new wireless VIF, its 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>
1462 <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>
1463 <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>
1464 <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>
1465 <li>Wireless clients will not be able to communicate with each other if setting <b>AP Isolation</b> is enabled.</li>
1466 </ul>
1467 </li>
1468 </ul>
1469 </div>
1470
1471<!-- overview-tab -->
1472 </div>
1473
1474<!-- / / / -->
1475
1476 <div class="section" id="wlif-section">
1477 <script>
1478 for (var i = 1; i < tabs.length; ++i) {
1479 var t = tabs[i][0];
1480 var uidx = wl_ifidxx(t);
1481 var u = t;
1482
1483 W('<div id="'+t+'-tab-disabled">VIF '+tabs[i][1]+' is not defined.<\/div>');
1484
1485 W('<div id="'+t+'-tab-enabled">');
1486
1487/* common to all VIFs */
1488 W('<input type="hidden" id="_wl'+u+'_radio" name="wl'+u+'_radio">');
1489 W('<input type="hidden" id="_wl'+u+'_ap_isolate" name="wl'+u+'_ap_isolate">');
1490 W('<input type="hidden" id="_wl'+u+'_mode" name="wl'+u+'_mode">');
1491 W('<input type="hidden" id="_wl'+u+'_closed" name="wl'+u+'_closed">');
1492 W('<input type="hidden" id="_wl'+u+'_key" name="wl'+u+'_key">');
1493 W('<input type="hidden" id="_wl'+u+'_akm" name="wl'+u+'_akm">');
1494 W('<input type="hidden" id="_wl'+u+'_auth_mode" name="wl'+u+'_auth_mode">');
1495 W('<input type="hidden" id="_wl'+u+'_wep" name="wl'+u+'_wep">');
1496 W('<input type="hidden" id="_wl'+u+'_auth" name="wl'+u+'_auth">');
1497 W('<input type="hidden" id="_wl'+u+'_bss_enabled" name="wl'+u+'_bss_enabled">');
1498 W('<input type="hidden" id="_wl'+u+'_ifname" name="wl'+u+'_ifname">');
1499 W('<input type="hidden" id="_wl'+u+'_macmode" name="wl'+u+'_macmode">');
1500 W('<input type="hidden" id="_wl'+u+'_maclist" name="wl'+u+'_maclist">');
1501
1502/* only if primary VIF */
1503 if (u.toString().indexOf('.') < 0) {
1504 W('<input type="hidden" id="_wl'+u+'_nband" name="wl'+u+'_nband">');
1505 W('<input type="hidden" id="_wl'+u+'_wds_enable" name="wl'+u+'_wds_enable">');
1506 W('<input type="hidden" id="_wl'+u+'_wds" name="wl'+u+'_wds">');
1507 W('<input type="hidden" id="_wl'+u+'_lazywds" name="wl'+u+'_lazywds">');
1508 W('<input type="hidden" id="_wl'+u+'_gmode" name="wl'+u+'_gmode">');
1509
1510 W('<input type="hidden" id="_wl'+u+'_nmode" name="wl'+u+'_nmode">');
1511 W('<input type="hidden" id="_wl'+u+'_nmcsidx" name="wl'+u+'_nmcsidx">');
1512 W('<input type="hidden" id="_wl'+u+'_nreqd" name="wl'+u+'_nreqd">');
1513 W('<input type="hidden" id="_wl'+u+'_nctrlsb" name="wl'+u+'_nctrlsb">');
1514 W('<input type="hidden" id="_wl'+u+'_nbw" name="wl'+u+'_nbw">');
1515/* BCMWL6-BEGIN */
1516 W('<input type="hidden" id="_wl'+u+'_bss_opmode_cap_reqd" name="wl'+u+'_bss_opmode_cap_reqd">');
1517/* BCMWL6-END */
1518 W('<input type="hidden" id="_wl'+u+'_vifs" name="wl'+u+'_vifs">');
1519 }
1520/* common to all VIFs */
1521 var f = [];
1522 f.push (
1523 { title: 'Enable Interface', name: 'f_wl'+u+'_radio', type: 'checkbox', value: (eval('nvram["wl'+u+'_radio"]') == '1') && (eval('nvram["wl'+u+'_net_mode"]') != 'disabled') },
1524 { title: 'AP Isolation', name: 'f_wl'+u+'_ap_isolate', type: 'checkbox', value: (eval('nvram["wl'+u+'_ap_isolate"]') == '1') },
1525 { title: 'MAC Address', text: '<a href="advanced-mac.asp">'+(eval('nvram["wl'+u+'_hwaddr"]') || mac_null)+'<\/a>'+' <b id="wl'+u+'_hwaddr_msg" style="display:none"><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>' },
1526 { title: 'Wireless Mode', name: 'f_wl'+u+'_mode', type: 'select', options: wl_modes_available, value: ((eval('nvram["wl'+u+'_mode"]') == 'ap') && (eval('nvram["wl'+u+'_wds_enable"]') == '1')) ? 'apwds' : eval('nvram["wl'+u+'_mode"]'), suffix: ' <b id="wl'+u+'_mode_msg" style="display:none"><small>(note: you might wish to cross-check settings later on <a href="basic-network.asp">Basic/Network<\/a>)<\/small><\/b>' }
1527 );
1528
1529/* only if primary VIF */
1530 if (u.toString().indexOf('.') < 0) {
1531 f.push (
1532 { title: 'Radio Band', name: 'f_wl'+u+'_nband', type: 'select', options: bands[uidx], value: eval('nvram["wl'+u+'_nband"]') || '0' == '0' ? bands[uidx][0][0] : eval('nvram["wl'+u+'_nband"]') },
1533 { title: 'Wireless Network Mode', name: 'wl'+u+'_net_mode', type: 'select', value: (eval('nvram["wl'+u+'_net_mode"]') == 'disabled') ? 'mixed' : eval('nvram["wl'+u+'_net_mode"]'), options: [], prefix: '<span id="__wl'+u+'_net_mode">', suffix: '<\/span>' }
1534 );
1535 }
1536
1537 if (typeof(eval('nvram["wl'+u+'_closed"]')) == 'undefined')
1538 nvram['wl'+u+'_closed'] = '0';
1539
1540 f.push (
1541// { title: 'SSID', name: 'wl'+u+'_ssid', type: 'text', maxlen: 32, size: 34, value: eval('nvram["wl'+u+'_ssid"]') },
1542 { title: 'SSID', name: 'wl'+u+'_ssid', type: 'text', maxlen: 32, size: 34, value: eval('nvram["wl'+u+'_ssid"]'), prefix: '<span id="__wl'+u+'_ssid">', suffix: '<\/span> <input type="button" id="_f_wl'+u+'_ssidscan" value="Scan" onclick="scanButton('+u+', \'ssid\')"> <img src="spin.gif" alt="" id="spinSsid'+u+'" style="display:none;"> <select id="ssidList'+u+'" style="display:none" onchange="selectSsid(this, '+u+')"> <input type="hidden" id="_wl'+u+'_ssid" name="dummy_wl'+u+'_ssid" value=""> </select>' },
1543 { title: 'Broadcast', indent: 2, name: 'f_wl'+u+'_bcast', type: 'checkbox', value: (eval('nvram["wl'+u+'_closed"]') == '0') }
1544 );
1545
1546/* only if primary VIF */
1547 if (u.toString().indexOf('.') < 0) {
1548 f.push (
1549 { 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" alt="" id="spin'+u+'">', value: eval('nvram["wl'+u+'_channel"]') },
1550 { title: 'Channel Width', name: 'wl'+u+'_nbw_cap', type: 'select', options: [], value: eval('nvram["wl'+u+'_nbw_cap"]'), prefix: '<span id="__wl'+u+'_nbw_cap">', suffix: '<\/span>' },
1551 { title: 'Control Sideband', name: 'f_wl'+u+'_nctrlsb', type: 'select', options: [['lower','Lower'],['upper','Upper']], value: eval('nvram["wl'+u+'_nctrlsb"]') == 'none' ? 'lower' : eval('nvram["wl'+u+'_nctrlsb"]') }
1552 );
1553 }
1554
1555 if (typeof(eval('nvram["wl'+u+'_crypto"]')) == 'undefined')
1556 nvram['wl'+u+'_crypto'] = 'aes';
1557
1558 f.push (
1559 null,
1560 { title: '<a href="basic-wfilter.asp" class="new_window">Wireless Filter<\/a>', name: 'f_wl'+u+'_macmode', type: 'select', options: [['disabled','Disable filter on that interface'],['deny','Block clients from the list on that interface'],['allow','Permit only clients from the list on that interface']], value: nvram['wl'+u+'_macmode'] },
1561 null,
1562 { title: 'Security', name: 'wl'+u+'_security_mode', type: 'select', 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']], value: eval('nvram["wl'+u+'_security_mode"]') },
1563 { title: 'Encryption', indent: 2, name: 'wl'+u+'_crypto', type: 'select', options: [['tkip','TKIP'],['aes','AES'],['tkip+aes','TKIP / AES']], value: eval('nvram["wl'+u+'_crypto"]') },
1564 { title: 'Shared Key', indent: 2, name: 'wl'+u+'_wpa_psk', type: 'password', maxlen: 64, size: 66, peekaboo: 1,
1565 suffix: ' <input type="button" id="_f_wl'+u+'_psk_random1" value="Random" onclick="random_psk(\'_wl'+u+'_wpa_psk\')">', value: eval('nvram["wl'+u+'_wpa_psk"]') },
1566 { title: 'Shared Key', indent: 2, name: 'wl'+u+'_radius_key', type: 'password', maxlen: 80, size: 32, peekaboo: 1, suffix: ' <input type="button" id="_f_wl'+u+'_psk_random2" value="Random" onclick="random_psk(\'_wl'+u+'_radius_key\')">', value: eval('nvram["wl'+u+'_radius_key"]') },
1567 { title: 'Group Key Renewal', indent: 2, name: 'wl'+u+'_wpa_gtk_rekey', type: 'text', maxlen: 7, size: 9, suffix: ' <small>seconds<\/small>', value: eval('nvram["wl'+u+'_wpa_gtk_rekey"]') || '3600' },
1568 { title: 'Radius Server', indent: 2, multi: [
1569 { name: 'wl'+u+'_radius_ipaddr', type: 'text', maxlen: 15, size: 17, value: eval('nvram["wl'+u+'_radius_ipaddr"]') },
1570 { name: 'wl'+u+'_radius_port', type: 'text', maxlen: 5, size: 7, prefix: ' : ', value: eval('nvram["wl'+u+'_radius_port"]') || '1812' } ] },
1571 { title: 'Encryption', indent: 2, name: 'wl'+u+'_wep_bit', type: 'select', options: [['128','128-bits'],['64','64-bits']], value: eval('nvram["wl'+u+'_wep_bit"]') },
1572 { title: 'Passphrase', indent: 2, name: 'wl'+u+'_passphrase', type: 'text', maxlen: 16, size: 20, 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+')">', value: eval('nvram["wl'+u+'_passphrase"]') }
1573 );
1574
1575 if (typeof(eval('nvram["wl'+u+'_key"]')) == 'undefined')
1576 nvram['wl'+u+'_key'] = '1';
1577/* REMOVE-BEGIN
1578 eval('nvram["wl'+u+'_key"] = 1');
1579REMOVE-END */
1580
1581 for (var j = 1; j <= 4; ++j) {
1582 f.push(
1583 { title: ('Key '+j), indent: 2, name: ('wl'+u+'_key'+j), type: 'text', maxlen: 26, size: 34, 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>' : '>'), value: nvram['wl'+u+'_key'+j] });
1584 }
1585
1586 f.push(null, { title: 'WDS', name: 'f_wl'+u+'_lazywds', type: 'select', options: [['0','Link With...'],['1','Automatic']], value: nvram['wl'+u+'_lazywds'] } );
1587/* REMOVE-BEGIN
1588 alert('nvram["wl'+u+'_wds"]='+eval('nvram["wl'+u+'_wds"]'));
1589REMOVE-END */
1590 var wds = eval('nvram["wl'+u+'_wds"]');
1591 if (typeof(wds) == 'undefined')
1592 nvram['wl'+u+'_wds'] = '';
1593
1594 wds = eval('nvram["wl'+u+'_wds"]').split(/\s+/);
1595/* REMOVE-BEGIN
1596 wds = (nvram['wl'+u+'_wds']).split(/\s+/);
1597REMOVE-END */
1598 for (var k = 0; k < 10; k += 2) {
1599 f.push({ title: (k ? '' : 'MAC Address'), indent: 2, multi: [
1600 { name: 'f_wl'+u+'_wds_'+k, type: 'text', maxlen: 17, size: 20, value: wds[k] || mac_null },
1601 { name: 'f_wl'+u+'_wds_'+(k + 1), type: 'text', maxlen: 17, size: 20, value: wds[k + 1] || mac_null } ] } );
1602 }
1603
1604 createFieldTable('', f);
1605 W('<\/div>');
1606 }
1607 </script>
1608
1609<!-- section -->
1610 </div>
1611
1612<!-- sesdiv_vifs -->
1613</div>
1614
1615<!-- / / / -->
1616
1617<div id="footer">
1618 <span id="footer-msg"></span>
1619 <input type="button" value="Save" id="save-button" onclick="save()">
1620 <input type="button" value="Cancel" id="cancel-button" onclick="cancel()">
1621</div>
1622
1623</td></tr>
1624</table>
1625</form>
1626<script>
1627 for (var uidx = 0; uidx < wl_ifaces.length; ++uidx) {
1628 if (wl_sunit(uidx) < 0) {
1629 refreshNetModes(uidx);
1630 refreshChannels(uidx);
1631 refreshBandWidth(uidx);
1632 }
1633 }
1634 verifyFields(null, 1);
1635</script>
1636</body>
1637</html>
1638