1 <!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML
4.0//EN'
>
4 Copyright (C) 2006-2010 Jonathan Zarate
5 http://www.polarcloud.com/tomato/
8 Copyright (C) 2011 Augusto Bott
9 http://code.google.com/p/tomato-sdhc-vlan/
11 For use with Tomato Firmware only.
12 No part of this file may be used without permission.
16 <meta http-equiv='content-type' content='text/html;charset=utf-
8'
>
17 <meta name='robots' content='noindex,nofollow'
>
18 <title>[<%
ident(); %>] Basic: Network
</title>
19 <link rel='stylesheet' type='text/css' href='tomato.css'
>
21 <script type='text/javascript' src='tomato.js'
></script>
25 <style type='text/css'
>
42 vertical-align: middle
;
46 <script type='text/javascript' src='debug.js'
></script>
48 <script type='text/javascript' src='md5.js'
></script>
49 <script type='text/javascript' src='wireless.jsx?_http_id=<%
nv(http_id
); %>'
></script>
50 <script type='text/javascript' src='interfaces.js'
></script>
51 <script type='text/javascript'
>
53 // <% nvram("dhcp_lease,dhcp_num,dhcp_start,dhcpd_startip,dhcpd_endip,l2tp_server_ip,lan_gateway,lan_ipaddr,lan_netmask,lan_proto,mtu_enable,ppp_demand,ppp_idletime,ppp_passwd,ppp_redialperiod,ppp_service,ppp_username,ppp_custom,pptp_server_ip,pptp_dhcp,wl_security_mode,wan_dns,wan_gateway,wan_ipaddr,wan_mtu,wan_netmask,wan_proto,wan_wins,wl_wds_enable,wl_channel,wl_closed,wl_crypto,wl_key,wl_key1,wl_key2,wl_key3,wl_key4,wl_lazywds,wl_mode,wl_net_mode,wl_passphrase,wl_radio,wl_radius_ipaddr,wl_radius_port,wl_ssid,wl_wds,wl_wep_bit,wl_wpa_gtk_rekey,wl_wpa_psk,wl_radius_key,wl_auth,wl_hwaddr,wan_islan,t_features,wl_nbw_cap,wl_nctrlsb,wl_nband,wl_phytype,lan_ifname,lan_stp,lan1_ifname,lan1_ipaddr,lan1_netmask,lan1_proto,lan1_stp,dhcp1_start,dhcp1_num,dhcp1_lease,dhcpd1_startip,dhcpd1_endip,lan2_ifname,lan2_ipaddr,lan2_netmask,lan2_proto,lan2_stp,dhcp2_start,dhcp2_num,dhcp2_lease,dhcpd2_startip,dhcpd2_endip,lan3_ifname,lan3_ipaddr,lan3_netmask,lan3_proto,lan3_stp,dhcp3_start,dhcp3_num,dhcp3_lease,dhcpd3_startip,dhcpd3_endip,ppp_mlppp,modem_ipaddr"); %>
56 var lg
= new TomatoGrid();
57 lg
.setup = function() {
58 this.init('lan-grid', '', 4, [
59 { type
: 'select', options
: [[0, '0'],[1, '1'],[2, '2'],[3, '3']], prefix
: '<div class="centered">', suffix
: '</div>' },
60 { type
: 'checkbox', prefix
: '<div class="centered">', suffix
: '</div>' },
61 { type
: 'text', maxlen
: 15, size
: 17 },
62 { type
: 'text', maxlen
: 15, size
: 17 },
63 { type
: 'checkbox', prefix
: '<div class="centered">', suffix
: '</div>' },
64 { multi
: [ { type
: 'text', maxlen
: 15, size
: 17}, { type
: 'text', maxlen
: 15, size
: 17 } ] },
65 { type
: 'text', maxlen
: 6, size
: 8 }] );
66 this.headerSet(['Bridge', 'STP', 'IP Address', 'Netmask', 'DHCP', 'IP Range <i>(first/last)</i>', 'Lease Time <i>(mins)</i>']);
69 for (var i
= 0 ; i
<= MAX_BRIDGE_ID
; i
++) {
70 var j
= (i
== 0) ? '' : i
.toString();
71 if (nvram
['lan' + j
+ '_ifname'].length
> 0) {
72 if ((!fixIP(nvram
['dhcpd' + j
+ '_startip'])) || (!fixIP(nvram
['dhcpd' + j
+ '_endip']))) {
73 if ((fixIP(nvram
['lan' + j
+ '_ipaddr'])) && (fixIP(nvram
['lan' + j
+ '_netmask'])) && (nvram
['dhcp' + j
+ '_start'] != '')) {
74 var n
= getNetworkAddress(nvram
['lan' + j
+ '_ipaddr'], nvram
['lan' + j
+ '_netmask']);
75 nvram
['dhcpd' + j
+ '_startip'] = getAddress(('0.0.0.' + nvram
['dhcp' + j
+ '_start'] * 1), n
);
76 nvram
['dhcpd' + j
+ '_endip'] = getAddress(('0.0.0.' + ((nvram
['dhcp' + j
+ '_start'] * 1) + (nvram
['dhcp' + j
+ '_num'] *1) - 1)), n
);
81 nvram
['lan' + j
+ '_stp'],
82 nvram
['lan' + j
+ '_ipaddr'],
83 nvram
['lan' + j
+ '_netmask'],
84 (nvram
['lan' + j
+ '_proto'] == 'dhcp') ? '1' : '0',
85 nvram
['dhcpd' + j
+ '_startip'],
86 nvram
['dhcpd' + j
+ '_endip'],
87 (nvram
['lan' + j
+ '_proto'] == 'dhcp') ? (((nvram
['dhcp' + j
+ '_lease'])*1 == 0) ? '1440' : (nvram
['dhcp' + j
+ '_lease']).toString()) : ''
94 elem
.removeClass(lg
.header
.cells
[lg
.sortColumn
], 'sortasc', 'sortdes');
99 lg
.dataToView = function(data
) {
100 return ['br' + data
[0],
101 (data
[1].toString() == '1') ? '<small><i>Enabled</i></small>' : '<small><i>Disabled</i></small>',
104 (data
[4].toString() == '1') ? '<small><i>Enabled</i></small>' : '<small><i>Disabled</i></small>',
105 (data
[5].toString() + ((numberOfBitsOnNetMask(data
[3])>=24) ? (' - ' + data
[6].split('.').splice(3, 1).toString()) : ('<br>' + data
[6].toString()) )),
106 (((data
[7] != null) && (data
[7] != '')) ? data
[7] : '') ];
109 lg
.dataToFieldValues = function (data
) {
111 (data
[1] != 0) ? 'checked' : '',
114 (data
[4].toString() == '1') ? 'checked' : '',
117 data
[7].toString() ];
120 lg
.fieldValuesToData = function(row
) {
121 var f
= fields
.getAll(row
);
123 f
[1].checked
? 1 : 0,
126 f
[4].checked
? 1 : 0,
132 lg
.resetNewEditor = function() {
133 var f
= fields
.getAll(this.newEditor
);
134 f
[0].selectedIndex
=0;
135 var t
= MAX_BRIDGE_ID
;
136 while((this.countBridge(f
[0].selectedIndex
) > 0) && (t
> 0)) {
137 f
[0].selectedIndex
= (f
[0].selectedIndex
%(MAX_BRIDGE_ID
))+1;
140 for(var j
=0; j
<= MAX_BRIDGE_ID
; j
++) {
141 f
[0].options
[j
].disabled
= (this.countBridge(j
) > 0);
154 ferror
.clearAll(fields
.getAll(this.newEditor
));
157 lg
.onCancel = function() {
160 this.disableNewEditor(false);
162 this.resetNewEditor();
165 lg
.onAdd = function() {
171 if (!this.verifyFields(this.newEditor
, false)) return;
173 data
= this.fieldValuesToData(this.newEditor
);
174 this.insertData(-1, data
);
176 this.disableNewEditor(false);
177 this.resetNewEditor();
182 lg
.onOK = function() {
185 if (!this.verifyFields(this.editor
, false)) return;
187 data
= this.fieldValuesToData(this.editor
);
188 view
= this.dataToView(data
);
190 this.source
.setRowData(data
);
191 for (i
= 0; i
< this.source
.cells
.length
; ++i
) {
192 this.source
.cells
[i
].innerHTML
= view
[i
];
197 this.disableNewEditor(false);
200 this.resetNewEditor();
203 lg
.onDelete = function() {
205 elem
.remove(this.source
);
207 this.disableNewEditor(false);
209 this.resetNewEditor();
212 lg
.countElem = function(f
, v
) {
213 var data
= this.getAllData();
215 for (var i
= 0; i
< data
.length
; ++i
) {
216 total
+= (data
[i
][f
] == v
) ? 1 : 0;
221 lg
.countBridge = function (v
) {
222 return this.countElem(0,v
);
225 lg
.countOverlappingNetworks = function (ip
) {
226 var data
= this.getAllData();
228 for (var i
= 0; i
< data
.length
; ++i
) {
229 var net
= getNetworkAddress(data
[i
][2], data
[i
][3]);
230 var brd
= getBroadcastAddress(net
, data
[i
][3]);
231 total
+= ((aton(ip
) <= aton(brd
)) && (aton(ip
) >= aton(net
))) ? 1 : 0;
236 lg
.verifyFields = function(row
, quiet
) {
240 f
= fields
.getAll(row
);
242 for(var j
=0; j
<= MAX_BRIDGE_ID
; j
++) {
243 f
[0].options
[j
].disabled
= (this.countBridge(j
) > 0);
246 if(this.countBridge(f
[0].selectedIndex
) > 0) {
247 ferror
.set(f
[0], 'Cannot add another entry for bridge br' + f
[0].selectedIndex
, quiet
);
253 if(!v_ip(f
[2], quiet
|| !ok
))
255 // if we have a properly defined IP address - 0.0.0.0 is NOT a valid IP address for our intents/purposes!
256 if ((f
[2].value
!= '') && (f
[2].value
!= '0.0.0.0')) {
257 // allow DHCP to be enabled
260 if(!v_netmask(f
[3], quiet
|| !ok
)) {
263 // must be 22 bits or smaller network
264 if (numberOfBitsOnNetMask(f
[3].value
) < 22) {
265 ferror
.set(f
[3], 'Netmask must have at least 22 bits set (255.255.252.0)', quiet
);
271 if(f
[2].value
== getNetworkAddress(f
[2].value
, f
[3].value
)) {
272 var s
= 'Invalid IP address or subnet mask (the address of the network cannot be used)';
273 ferror
.set(f
[2], s
, quiet
);
274 ferror
.set(f
[3], s
, quiet
);
277 if(f
[2].value
== getBroadcastAddress(getNetworkAddress(f
[2].value
, f
[3].value
), f
[3].value
)) {
278 var s
= 'Invalid IP address or subnet mask (the broadcast address cannot be used)';
279 ferror
.set(f
[2], s
, quiet
);
280 ferror
.set(f
[3], s
, quiet
);
283 if (this.countOverlappingNetworks(f
[2].value
) > 0) {
284 var s
= 'Invalid IP address or subnet mask (conflicts/overlaps with another LAN bridge)';
285 ferror
.set(f
[2], s
, quiet
);
286 ferror
.set(f
[3], s
, quiet
);
297 if( (f
[4].checked
) && (v_ip(f
[2], 1)) && (v_netmask(f
[3],1)) ) {
301 // first/last IP still unset?
302 if (f
[5].value
== '') {
304 var m
= aton(f
[2].value
) & aton(f
[3].value
);
305 var o
= (m
) ^ (~ aton(f
[3].value
))
313 } while (((l
= fixIP(ntoa(m
), 1)) == null) || (l
== f
[2].value
) );
316 if (f
[6].value
== '') {
318 var m
= aton(f
[2].value
) & aton(f
[3].value
);
319 var o
= (m
) ^ (~ aton(f
[3].value
));
327 } while (((l
= fixIP(ntoa(o
), 1)) == null) || (l
== f
[2].value
) );
331 if ((getNetworkAddress(f
[5].value
, f
[3].value
) != getNetworkAddress(f
[2].value
, f
[3].value
)) ||
332 (f
[5].value
== getBroadcastAddress(getNetworkAddress(f
[2].value
, f
[3].value
), f
[3].value
)) ||
333 (f
[5].value
== getNetworkAddress(f
[2].value
, f
[3].value
)) ||
334 (f
[2].value
== f
[5].value
)) {
335 ferror
.set(f
[5], 'Invalid first IP address or subnet mask', quiet
|| !ok
);
341 if ((getNetworkAddress(f
[6].value
, f
[3].value
) != getNetworkAddress(f
[2].value
, f
[3].value
)) ||
342 (f
[6].value
== getBroadcastAddress(getNetworkAddress(f
[2].value
, f
[3].value
), f
[3].value
)) ||
343 (f
[6].value
== getNetworkAddress(f
[2].value
, f
[3].value
)) ||
344 (f
[2].value
== f
[6].value
)) {
345 ferror
.set(f
[6], 'Invalid last IP address or subnet mask', quiet
|| !ok
);
350 // validate range, swap first/last IP if needed
351 if (aton(f
[6].value
) < aton(f
[5].value
)) {
353 f
[5].value
= f
[6].value
;
357 if (parseInt(f
[7].value
*1) == 0)
358 f
[7].value
= 1440; // from nvram/defaults.c
359 if(!v_mins(f
[7], quiet
|| !ok
, 1, 10080))
373 W('<style type=\'text/css\'>');
374 for (var u
= 0; u
< wl_ifaces
.length
; ++u
) {
375 W('#spin'+wl_unit(u
)+', ');
378 W(' visibility: hidden;');
379 W(' vertical-align: middle;');
385 var nphy
= features('11n');
388 if ((!fixIP(nvram
.dhcpd_startip
)) || (!fixIP(nvram
.dhcpd_endip
))) {
389 var x
= nvram
.lan_ipaddr
.split('.').splice(0, 3).join('.') + '.';
390 nvram
.dhcpd_startip
= x
+ nvram
.dhcp_start
;
391 nvram
.dhcpd_endip
= x
+ ((nvram
.dhcp_start
* 1) + (nvram
.dhcp_num
* 1) - 1);
397 var nm_loaded
= [], ch_loaded
= [], max_channel
= [];
399 for (var uidx
= 0; uidx
< wl_ifaces
.length
; ++uidx
) {
400 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
401 if (wl_sunit(uidx
)<0) {
404 for (var i
= 0; i
< wl_bands
[uidx
].length
; ++i
) {
405 b
.push([wl_bands
[uidx
][i
] + '', (wl_bands
[uidx
][i
] == '1') ? '5 GHz' : '2.4 GHz']);
415 refresher
.push(null);
419 function selectedBand(uidx
)
421 if (bands
[uidx
].length
> 1) {
422 var e
= E('_f_wl'+u
+'_nband');
423 return (e
.value
+ '' == '' ? eval('nvram.wl'+u
+'_nband') : e
.value
);
424 } else if (bands
[uidx
].length
> 0) {
425 return bands
[uidx
][0][0] || '0';
431 function refreshNetModes(uidx
)
435 if (uidx
>= wl_ifaces
.length
) return;
436 var u
= wl_unit(uidx
);
438 var m
= [['mixed','Auto']];
439 if (selectedBand(uidx
) == '1') {
440 m
.push(['a-only','A Only']);
442 m
.push(['n-only','N Only']);
446 m
.push(['b-only','B Only']);
447 m
.push(['g-only','G Only']);
449 m
.push(['bg-mixed','B/G Mixed']);
450 m
.push(['n-only','N Only']);
454 e
= E('_wl'+u
+'_net_mode');
456 val
= (!nm_loaded
[uidx
] || (e
.value
+ '' == '')) ? eval('nvram.wl'+u
+'_net_mode') : e
.value
;
457 if (val
== 'disabled') val
= 'mixed';
458 for (i
= 0; i
< m
.length
; ++i
)
459 buf
+= '<option value="' + m
[i
][0] + '"' + ((m
[i
][0] == val
) ? ' selected' : '') + '>' + m
[i
][1] + '</option>';
461 e
= E('__wl'+u
+'_net_mode');
462 buf
= '<select name="wl'+u
+'_net_mode" onchange="verifyFields(this, 1)" id = "_wl'+u
+'_net_mode">' + buf
+ '</select>';
463 elem
.setInnerHTML(e
, buf
);
467 function refreshChannels(uidx
)
469 if (refresher
[uidx
] != null) return;
470 if (u
>= wl_ifaces
.length
) return;
471 var u
= wl_unit(uidx
);
473 refresher
[uidx
] = new XmlHttp();
474 refresher
[uidx
].onCompleted = function(text
, xml
) {
478 var wl_channels
= [];
482 max_channel
[uidx
] = 0;
483 for (i
= 0; i
< wl_channels
.length
; ++i
) {
484 ghz
[uidx
].push([wl_channels
[i
][0] + '',
485 (wl_channels
[i
][0]) ? ((wl_channels
[i
][1]) ? wl_channels
[i
][0] + ' - ' + (wl_channels
[i
][1] / 1000.0).toFixed(3) + ' GHz' : wl_channels
[i
][0] + '') : 'Auto']);
486 max_channel
[uidx
] = wl_channels
[i
][0] * 1;
489 e
= E('_wl'+u
+'_channel');
491 val
= (!ch_loaded
[uidx
] || (e
.value
+ '' == '')) ? eval('nvram.wl'+u
+'_channel') : e
.value
;
492 for (i
= 0; i
< ghz
[uidx
].length
; ++i
)
493 buf
+= '<option value="' + ghz
[uidx
][i
][0] + '"' + ((ghz
[uidx
][i
][0] == val
) ? ' selected' : '') + '>' + ghz
[uidx
][i
][1] + '</option>';
495 e
= E('__wl'+u
+'_channel');
496 buf
= '<select name="wl'+u
+'_channel" onchange="verifyFields(this, 1)" id = "_wl'+u
+'_channel">' + buf
+ '</select>';
497 elem
.setInnerHTML(e
, buf
);
500 refresher
[uidx
] = null;
501 verifyFields(null, 1);
505 refresher
[uidx
] = null;
510 e
= E('_f_wl'+u
+'_nctrlsb');
511 sb
= (e
.value
+ '' == '' ? eval('nvram.wl'+u
+'_nctrlsb') : e
.value
);
512 e
= E('_wl'+u
+'_nbw_cap');
513 bw
= (e
.value
+ '' == '' ? eval('nvram.wl'+u
+'_nbw_cap') : e
.value
) == '0' ? '20' : '40';
515 refresher
[uidx
].onError = function(ex
) { alert(ex
); refresher
[uidx
] = null; reloadPage(); }
516 refresher
[uidx
].post('update.cgi', 'exec=wlchannels&arg0=' + u
+ '&arg1=' + (nphy
? '1' : '0') +
517 '&arg2=' + bw
+ '&arg3=' + selectedBand(uidx
) + '&arg4=' + sb
);
520 function spin(x
, unit
)
522 for (var u
= 0; u
< wl_ifaces
.length
; ++u
) {
523 E('_f_wl'+wl_unit(u
)+'_scan').disabled
= x
;
525 var e
= E('_f_wl'+unit
+'_scan');
526 if (x
) e
.value
= 'Scan ' + (wscan
.tries
+ 1);
527 else e
.value
= 'Scan';
528 E('spin'+unit
).style
.visibility
= x
? 'visible' : 'hidden';
535 var unit
= wscan
.unit
;
536 var uidx
= wl_uidx(unit
);
539 xob
.onCompleted = function(text
, xml
) {
546 for (i
= 0; i
< wlscandata
.length
; ++i
) {
547 var data
= wlscandata
[i
];
551 if (!wscan
.inuse
[ch
]) {
559 if (!wscan
.seen
[mac
]) {
561 ++wscan
.inuse
[ch
].count
;
564 if (data
[4] > wscan
.inuse
[ch
].rssi
) {
565 wscan
.inuse
[ch
].rssi
= data
[4];
566 wscan
.inuse
[ch
].ssid
= data
[1];
569 var e
= E('_wl'+unit
+'_channel');
570 for (i
= 1; i
< ghz
[uidx
].length
; ++i
) {
571 var s
= ghz
[uidx
][i
][1];
572 var u
= wscan
.inuse
[ghz
[uidx
][i
][0]];
573 if (u
) s
+= ' (' + u
.count
+ ' AP' + (u
.count
== 1 ? '' : 's') + ' / strongest: "' + escapeHTML(ellipsis(u
.ssid
, 15)) + '" ' + u
.rssi
+ ' dBm)';
574 e
.options
[i
].innerHTML
= s
;
576 e
.style
.width
= '400px';
580 if (wscan
.tries
< 4) {
582 setTimeout(scan
, 1000);
590 xob
.onError = function(x
) {
591 alert('error: ' + x
);
597 xob
.post('update.cgi', 'exec=wlscan&arg0='+unit
);
600 function scanButton(u
)
614 function joinAddr(a
) {
618 for (i
= 0; i
< a
.length
; ++i
) {
620 if ((s
!= '00:00:00:00:00:00') && (s
!= '0.0.0.0')) r
.push(s
);
625 function random_x(max
)
627 var c
= '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
629 while (max
-- > 0) s
+= c
.substr(Math
.floor(c
.length
* Math
.random()), 1);
633 function random_psk(id
)
636 e
.value
= random_x(63);
637 verifyFields(null, 1);
640 function random_wep(u
)
642 E('_wl'+u
+'_passphrase').value
= random_x(16);
646 function v_wep(e
, quiet
)
650 if (((s
.length
== 5) || (s
.length
== 13)) && (s
.length
== (e
.maxLength
>> 1))) {
654 s
= s
.toUpperCase().replace(/[^0-9A-F]/g, '');
655 if (s
.length
!= e
.maxLength
) {
656 ferror
.set(e
, 'Invalid WEP key. Expecting ' + e
.maxLength
+ ' hex or ' + (e
.maxLength
>> 1) + ' ASCII characters.', quiet
);
666 // compatible w/ Linksys' and Netgear's (key 1) method for 128-bits
667 function generate_wep(u
)
669 function _wepgen(pass
, i
)
671 while (pass
.length
< 64) pass
+= pass
;
672 return hex_md5(pass
.substr(0, 64)).substr(i
, (E('_wl'+u
+'_wep_bit').value
== 128) ? 26 : 10);
675 var e
= E('_wl'+u
+'_passphrase');
677 if (!v_length(e
, false, 3)) return;
678 E('_wl'+u
+'_key1').value
= _wepgen(pass
, 0);
680 E('_wl'+u
+'_key2').value
= _wepgen(pass
, 2);
682 E('_wl'+u
+'_key3').value
= _wepgen(pass
, 4);
684 E('_wl'+u
+'_key4').value
= _wepgen(pass
, 6);
685 verifyFields(null, 1);
688 function verifyFields(focused
, quiet
)
696 for (uidx
= 0; uidx
< wl_ifaces
.length
; ++uidx
) {
697 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
698 if (wl_sunit(uidx
)<0) {
700 if (focused
== E('_f_wl'+u
+'_nband')) {
701 refreshNetModes(uidx
);
702 refreshChannels(uidx
);
704 else if (focused
== E('_f_wl'+u
+'_nctrlsb') || focused
== E('_wl'+u
+'_nbw_cap')) {
705 refreshChannels(uidx
);
710 // --- visibility ---
726 _ppp_redialperiod
: 1,
749 for (uidx
= 0; uidx
< wl_ifaces
.length
; ++uidx
) {
750 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
751 if (wl_sunit(uidx
)<0) {
755 _f_wl_nband
: (bands
[uidx
].length
> 1) ? 1 : 0,
760 _wl_nbw_cap
: nphy
? 1 : 0,
761 _f_wl_nctrlsb
: nphy
? 1 : 0,
764 _wl_security_mode
: 1,
767 _f_wl_psk_random1
: 1,
768 _f_wl_psk_random2
: 1,
769 _wl_wpa_gtk_rekey
: 1,
771 _wl_radius_ipaddr
: 1,
789 var wan
= E('_wan_proto').value
;
791 for (uidx
= 0; uidx
< wl_ifaces
.length
; ++uidx
) {
792 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
793 if (wl_sunit(uidx
)<0) {
794 wmode
= E('_f_wl'+wl_unit(uidx
)+'_mode').value
;
796 if (wmode
== 'wet') {
800 vis
._f_dhcpd_enable
= 0;
805 if ((wan
== 'disabled') || (wmode
== 'sta') || (wmode
== 'wet')) {
806 vis
._f_wan_islan
= 1;
813 vis
._ppp_username
= 0;
814 vis
._ppp_service
= 0;
816 vis
._l2tp_server_ip
= 0;
818 vis
._wan_netmask
= 0;
819 vis
._wan_gateway
= 0;
820 vis
._pptp_server_ip
= 0;
821 vis
._f_pptp_dhcp
= 0;
825 vis
._f_ppp_mlppp
= 0;
826 vis
._modem_ipaddr
= 0;
829 vis
._l2tp_server_ip
= 0;
831 vis
._ppp_service
= 0;
832 vis
._ppp_username
= 0;
834 vis
._pptp_server_ip
= 0;
835 vis
._f_pptp_dhcp
= 0;
836 vis
._wan_gateway
= 0;
838 vis
._wan_netmask
= 0;
839 vis
._f_ppp_mlppp
= 0;
840 vis
._modem_ipaddr
= 1;
842 vis
._lan_gateway
= 0;
845 vis
._l2tp_server_ip
= 0;
846 vis
._pptp_server_ip
= 0;
847 vis
._f_pptp_dhcp
= 0;
848 vis
._wan_gateway
= 0;
850 vis
._wan_netmask
= 0;
851 vis
._modem_ipaddr
= 1;
853 vis
._lan_gateway
= 0;
856 vis
._l2tp_server_ip
= 0;
858 vis
._ppp_service
= 0;
859 vis
._ppp_username
= 0;
861 vis
._pptp_server_ip
= 0;
862 vis
._f_pptp_dhcp
= 0;
863 vis
._f_ppp_mlppp
= 0;
864 vis
._modem_ipaddr
= 0;
866 vis
._lan_gateway
= 0;
869 vis
._l2tp_server_ip
= 0;
870 vis
._ppp_service
= 0;
871 vis
._wan_gateway
= (!E('_f_pptp_dhcp').checked
);
872 vis
._wan_ipaddr
= (!E('_f_pptp_dhcp').checked
);
873 vis
._modem_ipaddr
= 0;
875 vis
._lan_gateway
= 0;
878 vis
._pptp_server_ip
= 0;
879 vis
._ppp_service
= 0;
880 vis
._wan_gateway
= (!E('_f_pptp_dhcp').checked
);
881 vis
._wan_ipaddr
= (!E('_f_pptp_dhcp').checked
);
882 vis
._modem_ipaddr
= 0;
884 vis
._lan_gateway
= 0;
888 vis
._ppp_idletime
= (E('_ppp_demand').value
== 1) && vis
._ppp_demand
889 vis
._ppp_redialperiod
= !vis
._ppp_idletime
&& vis
._ppp_demand
;
891 if (vis
._mtu_enable
) {
892 if (E('_mtu_enable').value
== 0) {
895 switch (E('_wan_proto').value
) {
911 if (!E('_f_dhcpd_enable').checked
) vis
._dhcp_lease
= 0;
914 for (uidx
= 0; uidx
< wl_ifaces
.length
; ++uidx
) {
915 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
916 if (wl_sunit(uidx
)<0) {
918 wmode
= E('_f_wl'+u
+'_mode').value
;
920 if (!E('_f_wl'+u
+'_radio').checked
) {
921 for (a
in wl_vis
[uidx
]) {
924 wl_vis
[uidx
]._f_wl_radio
= 1;
925 wl_vis
[uidx
]._wl_nbw_cap
= nphy
? 2 : 0;
926 wl_vis
[uidx
]._f_wl_nband
= (bands
[uidx
].length
> 1) ? 2 : 0;
935 wl_vis
[uidx
]._f_wl_bcast
= 0;
936 wl_vis
[uidx
]._wl_channel
= 0;
937 wl_vis
[uidx
]._wl_nbw_cap
= 0;
939 wl_vis
[uidx
]._f_wl_lazywds
= 0;
940 wl_vis
[uidx
]._f_wl_wds_0
= 0;
944 sm2
= E('_wl'+u
+'_security_mode').value
;
947 wl_vis
[uidx
]._wl_crypto
= 0;
948 wl_vis
[uidx
]._wl_wep_bit
= 0;
949 wl_vis
[uidx
]._wl_wpa_psk
= 0;
950 wl_vis
[uidx
]._wl_radius_key
= 0;
951 wl_vis
[uidx
]._wl_radius_ipaddr
= 0;
952 wl_vis
[uidx
]._wl_wpa_gtk_rekey
= 0;
955 wl_vis
[uidx
]._wl_crypto
= 0;
956 wl_vis
[uidx
]._wl_wpa_psk
= 0;
957 wl_vis
[uidx
]._wl_radius_key
= 0;
958 wl_vis
[uidx
]._wl_radius_ipaddr
= 0;
959 wl_vis
[uidx
]._wl_wpa_gtk_rekey
= 0;
962 wl_vis
[uidx
]._wl_crypto
= 0;
963 wl_vis
[uidx
]._wl_wpa_psk
= 0;
966 wl_vis
[uidx
]._wl_wep_bit
= 0;
967 if (sm2
.indexOf('personal') != -1) {
968 wl_vis
[uidx
]._wl_radius_key
= 0;
969 wl_vis
[uidx
]._wl_radius_ipaddr
= 0;
972 wl_vis
[uidx
]._wl_wpa_psk
= 0;
977 if ((E('_f_wl'+u
+'_lazywds').value
== 1) && (wl_vis
[uidx
]._f_wl_wds_0
== 1)) {
978 wl_vis
[uidx
]._f_wl_wds_0
= 2;
981 if (wl_vis
[uidx
]._wl_nbw_cap
!= 0) {
982 switch (E('_wl'+u
+'_net_mode').value
) {
987 wl_vis
[uidx
]._wl_nbw_cap
= 2;
988 if (E('_wl'+u
+'_nbw_cap').value
!= '0') {
989 E('_wl'+u
+'_nbw_cap').value
= 0;
990 refreshChannels(uidx
);
994 // avoid Enterprise-TKIP with 40MHz
995 if ((sm2
== 'wpa_enterprise') && (E('_wl'+u
+'_crypto').value
== 'tkip')) {
996 wl_vis
[uidx
]._wl_nbw_cap
= 2;
997 if (E('_wl'+u
+'_nbw_cap').value
!= '0') {
998 E('_wl'+u
+'_nbw_cap').value
= 0;
999 refreshChannels(uidx
);
1004 wl_vis
[uidx
]._f_wl_nctrlsb
= (E('_wl'+u
+'_nbw_cap').value
== 0) ? 0 : wl_vis
[uidx
]._wl_nbw_cap
;
1008 Special case - 2.4GHz band, currently running in B/G-only mode,
1009 with N/Auto and 40MHz selected in the GUI.
1010 Channel list is not filtered in this case by the wl driver,
1011 and includes all channels available with 20MHz channel width.
1013 b
= selectedBand(uidx
);
1014 if (wl_vis
[uidx
]._wl_channel
== 1 && wl_vis
[uidx
]._f_wl_nctrlsb
!= 0 &&
1015 ((b
== '2') || (wl_vis
[uidx
]._f_wl_nband
== 0 && b
== '0'))) {
1016 switch (eval('nvram.wl'+u
+'_net_mode')) {
1020 i
= E('_wl'+u
+'_channel').value
* 1;
1021 if (i
> 0 && i
< 5) {
1022 E('_f_wl'+u
+'_nctrlsb').value
= 'lower';
1023 wl_vis
[uidx
]._f_wl_nctrlsb
= 2;
1025 else if (i
> max_channel
[uidx
] - 4) {
1026 E('_f_wl'+u
+'_nctrlsb').value
= 'upper';
1027 wl_vis
[uidx
]._f_wl_nctrlsb
= 2;
1033 wl_vis
[uidx
]._f_wl_scan
= wl_vis
[uidx
]._wl_channel
;
1034 wl_vis
[uidx
]._f_wl_psk_random1
= wl_vis
[uidx
]._wl_wpa_psk
;
1035 wl_vis
[uidx
]._f_wl_psk_random2
= wl_vis
[uidx
]._wl_radius_key
;
1036 wl_vis
[uidx
]._wl_radius_port
= wl_vis
[uidx
]._wl_radius_ipaddr
;
1037 wl_vis
[uidx
]._wl_key1
= wl_vis
[uidx
]._wl_key2
= wl_vis
[uidx
]._wl_key3
= wl_vis
[uidx
]._wl_key4
= wl_vis
[uidx
]._f_wl_wep_gen
= wl_vis
[uidx
]._f_wl_wep_random
= wl_vis
[uidx
]._wl_passphrase
= wl_vis
[uidx
]._wl_wep_bit
;
1039 for (i
= 1; i
< 10; ++i
) {
1040 wl_vis
[uidx
]['_f_wl_wds_' + i
] = wl_vis
[uidx
]._f_wl_wds_0
;
1043 } // for each wl_iface
1045 vis
._ppp_passwd
= vis
._ppp_username
;
1047 vis
._dhcpd_startip
= vis
._dhcpd_endip
= vis
._wan_wins
= vis
._dhcp_lease
;
1056 b
.disabled
= (c
!= 1);
1057 PR(b
).style
.display
= c
? '' : 'none';
1060 for (uidx
= 0; uidx
< wl_ifaces
.length
; ++uidx
) {
1061 if(wl_ifaces
[uidx
][0].indexOf('.') < 0) {
1062 for (a
in wl_vis
[uidx
]) {
1064 if (a
.substr(0, 6) == '_f_wl_') i
= 5;
1065 b
= E(a
.substr(0, i
) + wl_unit(uidx
) + a
.substr(i
, a
.length
));
1066 c
= wl_vis
[uidx
][a
];
1067 b
.disabled
= (c
!= 1);
1068 PR(b
).style
.display
= c
? '' : 'none';
1075 ferror
.clear('_wan_proto');
1078 for (uidx
= 0; uidx
< wl_ifaces
.length
; ++uidx
) {
1079 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1080 if (wl_sunit(uidx
)<0) {
1082 wmode
= E('_f_wl'+u
+'_mode').value
;
1083 sm2
= E('_wl'+u
+'_security_mode').value
;
1086 if ((wl_vis[uidx]._f_wl_mode == 1) && (wmode != 'ap') && (sm2.substr(0, 4) == 'wpa2')) {
1087 ferror.set('_wl'+u+'_security_mode', 'WPA2 is supported only in AP mode.', quiet || !ok);
1090 else ferror.clear('_wl'+u+'_security_mode');
1093 // --- N standard does not support WPA+TKIP ---
1094 a
= E('_wl'+u
+'_crypto');
1095 switch (E('_wl'+u
+'_net_mode').value
) {
1098 if (nphy
&& (a
.value
== 'tkip') && (sm2
.indexOf('wpa') != -1)) {
1099 ferror
.set(a
, 'TKIP encryption is not supported with WPA / WPA2 in N mode.', quiet
|| !ok
);
1102 else ferror
.clear(a
);
1106 a
= E('_wl'+u
+'_net_mode');
1108 b
= E('_f_wl'+u
+'_mode');
1110 if ((wmode
== 'sta') || (wmode
== 'wet')) {
1113 ferror
.set(b
, 'Only one wireless interface can be configured in client mode.', quiet
|| !ok
);
1116 else if (a
.value
== 'n-only') {
1117 ferror
.set(a
, 'N-only is not supported in wireless client modes, use Auto.', quiet
|| !ok
);
1122 a
= E('_wl'+u
+'_wpa_psk');
1124 if (wl_vis
[uidx
]._wl_wpa_psk
== 1) {
1125 if ((a
.value
.length
< 8) || ((a
.value
.length
== 64) && (a
.value
.search(/[^0-9A-Fa-f]/) != -1))) {
1126 ferror
.set('_wl'+u
+'_wpa_psk', 'Invalid pre-shared key. Please enter at least 8 characters or 64 hexadecimal digits.', quiet
|| !ok
);
1132 if (((wmode
== 'wds') || (wmode
== 'apwds')) && (wl_vis
[uidx
]._wl_channel
== 1) && (E('_wl'+u
+'_channel').value
== '0')) {
1133 ferror
.set('_wl'+u
+'_channel', 'Fixed wireless channel required in WDS mode.', quiet
|| !ok
);
1136 else ferror
.clear('_wl'+u
+'_channel');
1138 if (E('_f_wl'+u
+'_mode').value
== 'sta') {
1139 if ((wan
== 'disabled') && (E('_f_wl'+u
+'_radio').checked
)) {
1140 ferror
.set('_wan_proto', 'Wireless Client mode requires a valid WAN setting (usually DHCP).', quiet
|| !ok
);
1147 // domain name or IP address
1148 a
= ['_l2tp_server_ip', '_pptp_server_ip'];
1149 for (i
= a
.length
- 1; i
>= 0; --i
)
1150 if ((vis
[a
[i
]]) && ((!v_length(a
[i
], 1, 1)) || ((!v_ip(a
[i
], 1)) && (!v_domain(a
[i
], 1))))) {
1151 if (!quiet
&& ok
) ferror
.show(a
[i
]);
1157 a
= ['_wan_gateway','_wan_ipaddr','_lan_ipaddr', '_dhcpd_startip', '_dhcpd_endip'];
1160 a
= ['_wan_gateway','_wan_ipaddr'];
1162 for (i
= a
.length
- 1; i
>= 0; --i
)
1163 if ((vis
[a
[i
]]) && (!v_ip(a
[i
], quiet
|| !ok
))) ok
= 0;
1165 // IP address, blank -> 0.0.0.0
1166 a
= ['_f_dns_1', '_f_dns_2', '_f_dns_3','_wan_wins','_lan_gateway', '_modem_ipaddr'];
1167 for (i
= a
.length
- 1; i
>= 0; --i
)
1168 if ((vis
[a
[i
]]) && (!v_dns(a
[i
], quiet
|| !ok
))) ok
= 0;
1172 a
= ['_wan_netmask','_lan_netmask'];
1175 a
= ['_wan_netmask'];
1177 for (i
= a
.length
- 1; i
>= 0; --i
)
1178 if ((vis
[a
[i
]]) && (!v_netmask(a
[i
], quiet
|| !ok
))) ok
= 0;
1182 a
= [['_ppp_idletime', 3, 1440],['_ppp_redialperiod', 1, 86400],['_f_wan_mtu', 576, 1500],
1183 ['_dhcp_lease', 1, 10080]];
1186 a
= [['_ppp_idletime', 3, 1440],['_ppp_redialperiod', 1, 86400],['_f_wan_mtu', 576, 1500]];
1188 for (i
= a
.length
- 1; i
>= 0; --i
) {
1190 if ((vis
[v
[0]]) && (!v_range(v
[0], quiet
|| !ok
, v
[1], v
[2]))) ok
= 0;
1193 for (uidx
= 0; uidx
< wl_ifaces
.length
; ++uidx
) {
1194 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1195 if (wl_sunit(uidx
)<0) {
1199 a
= ['_radius_ipaddr'];
1200 for (i
= a
.length
- 1; i
>= 0; --i
) {
1201 if ((wl_vis
[uidx
]['_wl'+a
[i
]]) && (!v_ip('_wl'+u
+a
[i
], quiet
|| !ok
))) ok
= 0;
1205 a
= [['_wpa_gtk_rekey', 60, 7200], ['_radius_port', 1, 65535]];
1206 for (i
= a
.length
- 1; i
>= 0; --i
) {
1208 if ((wl_vis
[uidx
]['_wl'+v
[0]]) && (!v_range('_wl'+u
+v
[0], quiet
|| !ok
, v
[1], v
[2]))) ok
= 0;
1212 a
= [['_ssid', 1], ['_radius_key', 1]];
1213 for (i
= a
.length
- 1; i
>= 0; --i
) {
1215 if ((wl_vis
[uidx
]['_wl'+v
[0]]) && (!v_length('_wl'+u
+v
[0], quiet
|| !ok
, v
[1], E('_wl'+u
+v
[0]).maxlength
))) ok
= 0;
1218 if (wl_vis
[uidx
]._wl_key1
) {
1219 a
= (E('_wl'+u
+'_wep_bit').value
== 128) ? 26 : 10;
1220 for (i
= 1; i
<= 4; ++i
) {
1221 b
= E('_wl'+u
+'_key' + i
);
1223 if ((b
.value
.length
> 0) || (E('_f_wl'+u
+'_wepidx_' + i
).checked
)) {
1224 if (!v_wep(b
, quiet
|| !ok
)) ok
= 0;
1226 else ferror
.clear(b
);
1230 ferror
.clear('_f_wl'+u
+'_wds_0');
1231 if (wl_vis
[uidx
]._f_wl_wds_0
== 1) {
1233 for (i
= 0; i
< 10; ++i
) {
1234 a
= E('_f_wl'+u
+'_wds_' + i
);
1235 if (!v_macz(a
, quiet
|| !ok
)) ok
= 0;
1236 else if (!isMAC0(a
.value
)) b
= 1;
1239 ferror
.set('_f_wl'+u
+'_wds_0', 'WDS MAC address required.', quiet
|| !ok
);
1247 a
= E('_dhcpd_startip');
1248 b
= E('_dhcpd_endip');
1252 if ((vis
._dhcp_lease
) && (!a
._error_msg
) && (!b
._error_msg
)) {
1253 c
= aton(E('_lan_netmask').value
);
1254 d
= aton(E('_lan_ipaddr').value
) & c
;
1255 e
= 'Invalid IP address or subnet mask';
1256 if ((aton(a
.value
) & c
) != d
) {
1257 ferror
.set(a
, e
, quiet
|| !ok
);
1260 if ((aton(b
.value
) & c
) != d
) {
1261 ferror
.set(b
, e
, quiet
|| !ok
);
1266 if ((vis
._dhcp_lease
) && (!a
._error_msg
) && (!b
._error_msg
)) {
1267 if (aton(a
.value
) > aton(b
.value
)) {
1273 elem
.setInnerHTML('dhcp_count', '(' + ((aton(b
.value
) - aton(a
.value
)) + 1) + ')');
1277 /* TODO: same validation for builds with VLAN-GUI enabled */
1279 ferror
.clear('_modem_ipaddr');
1280 a
= E('_modem_ipaddr');
1281 b
= E('_lan_ipaddr');
1282 c
= E('_lan_netmask');
1283 if ( vis
['_modem_ipaddr'] && !(a
._error_msg
|| b
._error_msg
|| c
._error_msg
) && a
.value
!= "0.0.0.0" ) {
1285 if ( (aton(a
.value
) & c
) == (aton(b
.value
) & c
) ) {
1286 ferror
.set('_modem_ipaddr', 'Modem IP address may not be within your local address space.', quiet
);
1295 function earlyInit()
1297 verifyFields(null, 1);
1303 if (lg
.isEditing()) return;
1304 lg
.resetNewEditor();
1309 var u
, uidx
, wmode
, sm2
, wradio
;
1311 if (!verifyFields(null, false)) return;
1313 var fom
= E('_fom');
1315 fom
.wan_mtu
.value
= fom
.f_wan_mtu
.value
;
1316 fom
.wan_mtu
.disabled
= fom
.f_wan_mtu
.disabled
;
1319 fom
.lan_proto
.value
= fom
.f_dhcpd_enable
.checked
? 'dhcp' : 'static';
1322 for (uidx
= 0; uidx
< wl_ifaces
.length
; ++uidx
) {
1323 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1324 if (wl_sunit(uidx
)<0) {
1326 wmode
= E('_f_wl'+u
+'_mode').value
;
1327 sm2
= E('_wl'+u
+'_security_mode').value
;
1328 wradio
= E('_f_wl'+u
+'_radio').checked
;
1330 E('_wl'+u
+'_nband').value
= selectedBand(uidx
);
1332 if (wmode
== 'apwds') E('_wl'+u
+'_mode').value
= 'ap';
1333 else E('_wl'+u
+'_mode').value
= wmode
;
1335 if (wmode
== 'wet') {
1336 fom
.wan_proto
.value
= 'disabled';
1337 fom
.wan_proto
.disabled
= 0;
1339 fom
.lan_proto
.value
= 'static';
1343 // TODO - what's required ? integrate with tomatogrid?
1349 for (i
= 0; i
< 10; ++i
) a
.push(E('_f_wl'+u
+'_wds_' + i
).value
);
1350 E('_wl'+u
+'_wds').value
= joinAddr(a
);
1352 if (wmode
.indexOf('wds') != -1) {
1353 E('_wl'+u
+'_wds_enable').value
= 1;
1354 E('_wl'+u
+'_lazywds').value
= E('_f_wl'+u
+'_lazywds').value
;
1355 if (E('_wl'+u
+'_lazywds').value
== 1) E('_wl'+u
+'_wds').value
= '';
1358 E('_wl'+u
+'_wds_enable').value
= 0;
1359 E('_wl'+u
+'_wds').value
= '';
1360 E('_wl'+u
+'_lazywds').value
= 0;
1363 E('_wl'+u
+'_radio').value
= wradio
? 1 : 0;
1364 E('_wl'+u
+'_auth').value
= eval('nvram.wl'+u
+'_auth');
1366 e
= E('_wl'+u
+'_akm');
1376 if (sm2
.indexOf('personal') != -1) {
1377 if (sm2
.indexOf('wpa2_') == -1) c
.push('psk');
1378 if (sm2
.indexOf('wpa_') == -1) c
.push('psk2');
1381 if (sm2
.indexOf('wpa2_') == -1) c
.push('wpa');
1382 if (sm2
.indexOf('wpa_') == -1) c
.push('wpa2');
1388 E('_wl'+u
+'_auth_mode').value
= (sm2
== 'radius') ? 'radius' : 'none';
1389 E('_wl'+u
+'_wep').value
= ((sm2
== 'radius') || (sm2
== 'wep')) ? 'enabled': 'disabled';
1391 if (sm2
.indexOf('wpa') != -1) E('_wl'+u
+'_auth').value
= 0;
1393 E('_wl'+u
+'_nreqd').value
= 0;
1394 E('_wl'+u
+'_gmode').value
= 1;
1395 E('_wl'+u
+'_nmode').value
= 0;
1396 E('_wl'+u
+'_nmcsidx').value
= -2; // Legacy Rate
1397 E('_wl'+u
+'_nbw').value
= 0;
1398 switch (E('_wl'+u
+'_net_mode').value
) {
1400 E('_wl'+u
+'_gmode').value
= 0;
1403 E('_wl'+u
+'_gmode').value
= 4;
1408 E('_wl'+u
+'_nmcsidx').value
= -1; // Auto
1411 if (selectedBand(uidx
) == '1') { // 5 GHz
1412 E('_wl'+u
+'_nmode').value
= -1;
1413 E('_wl'+u
+'_nmcsidx').value
= -1;
1415 E('_wl'+u
+'_nmode').value
= 1;
1416 E('_wl'+u
+'_nmcsidx').value
= 32;
1418 E('_wl'+u
+'_nreqd').value
= 1;
1421 E('_wl'+u
+'_nmode').value
= -1;
1422 E('_wl'+u
+'_nmcsidx').value
= -1;
1426 E('_wl'+u
+'_nctrlsb').value
= eval('nvram.wl'+u
+'_nctrlsb');
1427 if (E('_wl'+u
+'_nmode').value
!= 0) {
1428 E('_wl'+u
+'_nctrlsb').value
= E('_f_wl'+u
+'_nctrlsb').value
;
1429 E('_wl'+u
+'_nbw').value
= (E('_wl'+u
+'_nbw_cap').value
== 0) ? 20 : 40;
1432 E('_wl'+u
+'_closed').value
= E('_f_wl'+u
+'_bcast').checked
? 0 : 1;
1434 a
= fields
.radio
.selected(eval('fom.f_wl'+u
+'_wepidx'));
1435 if (a
) E('_wl'+u
+'_key').value
= a
.value
;
1439 fom
.wan_islan
.value
= fom
.f_wan_islan
.checked
? 1 : 0;
1440 fom
.pptp_dhcp
.value
= fom
.f_pptp_dhcp
.checked
? 1 : 0;
1442 fom
.wan_dns
.value
= joinAddr([fom
.f_dns_1
.value
, fom
.f_dns_2
.value
, fom
.f_dns_3
.value
]);
1445 // initialize/wipe out relevant fields
1446 for (var i
= 0 ; i
<= MAX_BRIDGE_ID
; i
++) {
1447 var j
= (i
== 0) ? '' : i
.toString();
1448 fom
['lan' + j
+ '_ifname'].value
= '';
1449 fom
['lan' + j
+ '_ipaddr'].value
= '';
1450 fom
['lan' + j
+ '_netmask'].value
= '';
1451 fom
['lan' + j
+ '_proto'].value
= '';
1452 fom
['lan' + j
+ '_stp'].value
= '';
1453 fom
['dhcp' + j
+ '_start'].value
= '';
1454 fom
['dhcp' + j
+ '_num'].value
= '';
1455 fom
['dhcp' + j
+ '_lease'].value
= '';
1456 fom
['dhcpd' + j
+ '_startip'].value
= '';
1457 fom
['dhcpd' + j
+ '_endip'].value
= '';
1460 var d
= lg
.getAllData();
1461 for (var i
= 0; i
< d
.length
; ++i
) {
1463 if (lg
.countOverlappingNetworks(d
[i
][2]) > 1) {
1464 var s
= 'Cannot proceed: two or more LAN bridges have conflicting IP addresses or overlapping subnets';
1466 var e
= E('footer-msg');
1468 e
.style
.visibility
= 'visible';
1472 e
.style
.visibility
= 'hidden';
1477 var j
= (parseInt(d
[i
][0]) == 0) ? '' : d
[i
][0].toString();
1478 fom
['lan' + j
+ '_ifname'].value
= 'br' + d
[i
][0];
1479 fom
['lan' + j
+ '_stp'].value
= d
[i
][1];
1480 fom
['lan' + j
+ '_ipaddr'].value
= d
[i
][2];
1481 fom
['lan' + j
+ '_netmask'].value
= d
[i
][3];
1482 fom
['lan' + j
+ '_proto'].value
= (d
[i
][4] != '0') ? 'dhcp' : 'static';
1483 fom
['dhcp' + j
+ '_start'].value
= (d
[i
][4] != '0') ? (d
[i
][5]).split('.').splice(3, 1) : '';
1484 fom
['dhcp' + j
+ '_num'].value
= (d
[i
][4] != '0') ? d
[i
][6].split('.').splice(3, 1) - (d
[i
][5]).split('.').splice(3, 1) + 1 : ''; // presuming /24 subnet (legacy)
1485 fom
['dhcp' + j
+ '_lease'].value
= (d
[i
][4] != '0') ? d
[i
][7] : '';
1486 fom
['dhcpd' + j
+ '_startip'].value
= (d
[i
][4] != '0') ? d
[i
][5] : '';
1487 fom
['dhcpd' + j
+ '_endip'].value
= (d
[i
][4] != '0') ? d
[i
][6] : '';
1490 alert('lan' + j
+ '_ifname=' + fom
['lan' + j
+ '_ifname'].value
+ '\n' +
1491 'lan' + j
+ '_stp=' + fom
['lan' + j
+ '_stp'].value
+ '\n' +
1492 'lan' + j
+ '_ipaddr=' + fom
['lan' + j
+ '_ipaddr'].value
+ '\n' +
1493 'lan' + j
+ '_netmask=' + fom
['lan' + j
+ '_netmask'].value
+ '\n' +
1494 'lan' + j
+ '_proto=' + fom
['lan' + j
+ '_proto'].value
+ '\n' +
1495 'dhcp' + j
+ '_start=' + fom
['dhcp' + j
+ '_start'].value
+ '\n' +
1496 'dhcp' + j
+ '_num=' + fom
['dhcp' + j
+ '_num'].value
+ '\n' +
1497 'dhcp' + j
+ '_lease=' + fom
['dhcp' + j
+ '_lease'].value
+ '\n' +
1498 'dhcpd' + j
+ '_startip=' + fom
['dhcpd' + j
+ '_startip'].value
+ '\n' +
1499 'dhcpd' + j
+ '_endip=' + fom
['dhcpd' + j
+ '_endip'].value
);
1503 var e
= E('footer-msg');
1504 var t
= fixIP(fom
['lan_ipaddr'].value
);
1505 if ((fom
['lan_ifname'].value
!= 'br0') || (fom
['lan_ipaddr'].value
== '0.0.0.0') || (!t
)) {
1506 e
.innerHTML
= 'Bridge br0 must be always defined and have a valid IP address set.';
1507 e
.style
.visibility
= 'visible';
1511 e
.style
.visibility
= 'hidden';
1518 // if ((nvram.lan_ipaddr != fom.lan_ipaddr.value) || (nvram.lan1_ipaddr != fom.lan1_ipaddr.value) ||
1519 // (nvram.lan2_ipaddr != fom.lan2_ipaddr.value) || (nvram.lan3_ipaddr != fom.lan3_ipaddr.value)){
1522 fom
.ppp_mlppp
.value
= fom
.f_ppp_mlppp
.checked
? 1 : 0;
1524 if (nvram
.lan_ipaddr
!= fom
.lan_ipaddr
.value
) {
1525 fom
._moveip
.value
= 1;
1529 form
.submit(fom
, 1);
1535 for (var uidx
= 0; uidx
< wl_ifaces
.length
; ++uidx
) {
1536 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1537 if (wl_sunit(uidx
)<0) {
1538 refreshNetModes(uidx
);
1539 refreshChannels(uidx
);
1546 <body onload='init()'
>
1547 <form id='_fom' method='post' action='tomato.cgi'
>
1548 <table id='container' cellspacing=
0>
1549 <tr><td colspan=
2 id='header'
>
1550 <div class='title'
>Tomato
</div>
1551 <div class='version'
>Version <%
version(); %></div>
1553 <tr id='body'
><td id='navi'
><script type='text/javascript'
>navi()</script></td>
1555 <div id='ident'
><%
ident(); %></div>
1559 <input type='hidden' name='_nextpage' value='basic-network.asp'
>
1560 <input type='hidden' name='_nextwait' value='
10'
>
1561 <input type='hidden' name='_service' value='*'
>
1562 <input type='hidden' name='_moveip' value='
0'
>
1564 <input type='hidden' name='wan_mtu'
>
1565 <input type='hidden' name='wan_islan'
>
1566 <input type='hidden' name='pptp_dhcp'
>
1567 <!-- NOVLAN-BEGIN -->
1568 <input type='hidden' name='lan_proto'
>
1570 <input type='hidden' name='wan_dns'
>
1571 <input type='hidden' name='ppp_mlppp'
>
1574 <script type='text/javascript'
>
1576 for (var i
= 0 ; i
<= MAX_BRIDGE_ID
; i
++) {
1577 var j
= (i
== 0) ? '' : i
.toString();
1578 W('<input type=\'hidden\' id=\'lan' + j
+ '_ifname\' name=\'lan' + j
+ '_ifname\'>');
1579 W('<input type=\'hidden\' id=\'lan' + j
+ '_ipaddr\' name=\'lan' + j
+ '_ipaddr\'>');
1580 W('<input type=\'hidden\' id=\'lan' + j
+ '_netmask\' name=\'lan' + j
+ '_netmask\'>');
1581 W('<input type=\'hidden\' id=\'lan' + j
+ '_proto\' name=\'lan' + j
+ '_proto\'>');
1582 W('<input type=\'hidden\' id=\'lan' + j
+ '_stp\' name=\'lan' + j
+ '_stp\'>');
1583 W('<input type=\'hidden\' id=\'dhcp' + j
+ '_start\' name=\'dhcp' + j
+ '_start\'>');
1584 W('<input type=\'hidden\' id=\'dhcp' + j
+ '_num\' name=\'dhcp' + j
+ '_num\'>');
1585 W('<input type=\'hidden\' id=\'dhcp' + j
+ '_lease\' name=\'dhcp' + j
+ '_lease\'>');
1586 W('<input type=\'hidden\' id=\'dhcpd' + j
+ '_startip\' name=\'dhcpd' + j
+ '_startip\'>');
1587 W('<input type=\'hidden\' id=\'dhcpd' + j
+ '_endip\' name=\'dhcpd' + j
+ '_endip\'>');
1592 <div class='section-title'
>WAN / Internet
</div>
1593 <div class='section'
>
1594 <script type='text/javascript'
>
1595 createFieldTable('', [
1596 { title
: 'Type', name
: 'wan_proto', type
: 'select', options
: [['dhcp','DHCP'],['pppoe','PPPoE'],['static','Static'],['pptp','PPTP'],['l2tp','L2TP'],['disabled','Disabled']],
1597 value
: nvram
.wan_proto
},
1598 { title
: 'Username', name
: 'ppp_username', type
: 'text', maxlen
: 60, size
: 64, value
: nvram
.ppp_username
},
1599 { title
: 'Password', name
: 'ppp_passwd', type
: 'password', maxlen
: 60, size
: 64, peekaboo
: 1, value
: nvram
.ppp_passwd
},
1600 { title
: 'Service Name', name
: 'ppp_service', type
: 'text', maxlen
: 50, size
: 64, value
: nvram
.ppp_service
},
1601 { title
: 'L2TP Server', name
: 'l2tp_server_ip', type
: 'text', maxlen
: 128, size
: 64, value
: nvram
.l2tp_server_ip
},
1602 { title
: 'Use DHCP', name
: 'f_pptp_dhcp', type
: 'checkbox', value
: (nvram
.pptp_dhcp
== 1) },
1603 { title
: 'IP Address', name
: 'wan_ipaddr', type
: 'text', maxlen
: 15, size
: 17, value
: nvram
.wan_ipaddr
},
1604 { title
: 'Subnet Mask', name
: 'wan_netmask', type
: 'text', maxlen
: 15, size
: 17, value
: nvram
.wan_netmask
},
1605 { title
: 'Gateway', name
: 'wan_gateway', type
: 'text', maxlen
: 15, size
: 17, value
: nvram
.wan_gateway
},
1606 { title
: 'PPTP Gateway', name
: 'pptp_server_ip', type
: 'text', maxlen
: 128, size
: 64, value
: nvram
.pptp_server_ip
},
1607 { title
: 'Options', name
: 'ppp_custom', type
: 'text', maxlen
: 256, size
: 64, value
: nvram
.ppp_custom
},
1608 { title
: 'Connect Mode', name
: 'ppp_demand', type
: 'select', options
: [['1', 'Connect On Demand'],['0', 'Keep Alive']],
1609 value
: nvram
.ppp_demand
},
1610 { title
: 'Max Idle Time', indent
: 2, name
: 'ppp_idletime', type
: 'text', maxlen
: 5, size
: 7, suffix
: ' <i>(minutes)</i>',
1611 value
: nvram
.ppp_idletime
},
1612 { title
: 'Check Interval', indent
: 2, name
: 'ppp_redialperiod', type
: 'text', maxlen
: 5, size
: 7, suffix
: ' <i>(seconds)</i>',
1613 value
: nvram
.ppp_redialperiod
},
1614 { title
: 'MTU', multi
: [
1615 { name
: 'mtu_enable', type
: 'select', options
: [['0', 'Default'],['1','Manual']], value
: nvram
.mtu_enable
},
1616 { name
: 'f_wan_mtu', type
: 'text', maxlen
: 4, size
: 6, value
: nvram
.wan_mtu
} ] },
1617 { title
: 'Single Line MLPPP', name
: 'f_ppp_mlppp', type
: 'checkbox', value
: (nvram
.ppp_mlppp
== 1) },
1618 { title
: 'Route Modem IP', name
: 'modem_ipaddr', type
: 'text', maxlen
: 15, size
: 17, suffix
: ' <i>(must be in different subnet to router)</i>', value
: nvram
.modem_ipaddr
},
1620 { title
: 'Use WAN port for LAN', name
: 'f_wan_islan', type
: 'checkbox', value
: (nvram
.wan_islan
== 1) }
1623 { title
: 'Bridge WAN port to primary LAN (br0)', name
: 'f_wan_islan', type
: 'checkbox', value
: (nvram
.wan_islan
== 1) }
1629 <div class='section-title'
>LAN
</div>
1630 <div class='section'
>
1632 <table class='tomato-grid' cellspacing=
1 id='lan-grid'
></table>
1634 <script type='text/javascript'
>lg
.setup();</script>
1637 <script type='text/javascript'
>
1638 dns
= nvram
.wan_dns
.split(/\s+/);
1640 //ipp = nvram.lan_ipaddr.split('.').splice(0, 3).join('.');
1642 createFieldTable('', [
1644 { title
: 'Router IP Address', name
: 'lan_ipaddr', type
: 'text', maxlen
: 15, size
: 17, value
: nvram
.lan_ipaddr
},
1645 { title
: 'Subnet Mask', name
: 'lan_netmask', type
: 'text', maxlen
: 15, size
: 17, value
: nvram
.lan_netmask
},
1647 { title
: 'Default Gateway', name
: 'lan_gateway', type
: 'text', maxlen
: 15, size
: 17, value
: nvram
.lan_gateway
},
1648 { title
: 'Static DNS', suffix
: ' <i>(IP:port)</i>', name
: 'f_dns_1', type
: 'text', maxlen
: 21, size
: 25, value
: dns
[0] || '0.0.0.0' },
1649 { title
: '', name
: 'f_dns_2', type
: 'text', maxlen
: 21, size
: 25, value
: dns
[1] || '0.0.0.0' },
1650 { title
: '', name
: 'f_dns_3', type
: 'text', maxlen
: 21, size
: 25, value
: dns
[2] || '0.0.0.0' },
1652 { title
: 'DHCP Server', name
: 'f_dhcpd_enable', type
: 'checkbox', value
: (nvram
.lan_proto
== 'dhcp') },
1653 { title
: 'IP Address Range', indent
: 2, multi
: [
1654 { name
: 'dhcpd_startip', type
: 'text', maxlen
: 15, size
: 17, value
: nvram
.dhcpd_startip
, suffix
: ' - ' },
1655 { name
: 'dhcpd_endip', type
: 'text', maxlen
: 15, size
: 17, value
: nvram
.dhcpd_endip
, suffix
: ' <i id="dhcp_count"></i>' }
1658 { title
: 'Lease Time', indent
: 2, name
: 'dhcp_lease', type
: 'text', maxlen
: 6, size
: 8, suffix
: ' <i>(minutes)</i>',
1659 value
: (nvram
.dhcp_lease
> 0) ? nvram
.dhcp_lease
: 1440 },
1660 { title
: 'WINS', indent
: 2, name
: 'wan_wins', type
: 'text', maxlen
: 15, size
: 17, value
: nvram
.wan_wins
}
1663 { title
: 'WINS <i>(for DHCP)</i>', name
: 'wan_wins', type
: 'text', maxlen
: 15, size
: 17, value
: nvram
.wan_wins
}
1669 <script type='text/javascript'
>
1671 for (var uidx
= 0; uidx
< wl_ifaces
.length
; ++uidx
) {
1672 //if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1673 if (wl_sunit(uidx
)<0) {
1674 var u
= wl_unit(uidx
);
1676 W('<input type=\'hidden\' id=\'_wl'+u
+'_mode\' name=\'wl'+u
+'_mode\'>');
1677 W('<input type=\'hidden\' id=\'_wl'+u
+'_nband\' name=\'wl'+u
+'_nband\'>');
1678 W('<input type=\'hidden\' id=\'_wl'+u
+'_wds_enable\' name=\'wl'+u
+'_wds_enable\'>');
1679 W('<input type=\'hidden\' id=\'_wl'+u
+'_wds\' name=\'wl'+u
+'_wds\'>');
1680 W('<input type=\'hidden\' id=\'_wl'+u
+'_radio\' name=\'wl'+u
+'_radio\'>');
1681 W('<input type=\'hidden\' id=\'_wl'+u
+'_closed\' name=\'wl'+u
+'_closed\'>');
1682 W('<input type=\'hidden\' id=\'_wl'+u
+'_key\' name=\'wl'+u
+'_key\'>');
1683 W('<input type=\'hidden\' id=\'_wl'+u
+'_gmode\' name=\'wl'+u
+'_gmode\'>');
1684 W('<input type=\'hidden\' id=\'_wl'+u
+'_akm\' name=\'wl'+u
+'_akm\'>');
1685 W('<input type=\'hidden\' id=\'_wl'+u
+'_auth\' name=\'wl'+u
+'_auth\'>');
1686 W('<input type=\'hidden\' id=\'_wl'+u
+'_auth_mode\' name=\'wl'+u
+'_auth_mode\'>');
1687 W('<input type=\'hidden\' id=\'_wl'+u
+'_wep\' name=\'wl'+u
+'_wep\'>');
1688 W('<input type=\'hidden\' id=\'_wl'+u
+'_lazywds\' name=\'wl'+u
+'_lazywds\'>');
1689 W('<input type=\'hidden\' id=\'_wl'+u
+'_nmode\' name=\'wl'+u
+'_nmode\'>');
1690 W('<input type=\'hidden\' id=\'_wl'+u
+'_nmcsidx\' name=\'wl'+u
+'_nmcsidx\'>');
1691 W('<input type=\'hidden\' id=\'_wl'+u
+'_nreqd\' name=\'wl'+u
+'_nreqd\'>');
1692 W('<input type=\'hidden\' id=\'_wl'+u
+'_nctrlsb\' name=\'wl'+u
+'_nctrlsb\'>');
1693 W('<input type=\'hidden\' id=\'_wl'+u
+'_nbw\' name=\'wl'+u
+'_nbw\'>');
1695 W('<div class=\'section-title\'>Wireless');
1696 // if (wl_ifaces.length > 1)
1697 W(' (' + wl_display_ifname(uidx
) + ')');
1700 W('<div class=\'section\'>');
1703 { title
: 'Enable Wireless', name
: 'f_wl'+u
+'_radio', type
: 'checkbox',
1704 value
: (eval('nvram.wl'+u
+'_radio') == '1') && (eval('nvram.wl'+u
+'_net_mode') != 'disabled') },
1705 { title
: 'MAC Address', text
: '<a href="advanced-mac.asp">' + eval('nvram.wl'+u
+'_hwaddr') + '</a>' },
1706 { title
: 'Wireless Mode', name
: 'f_wl'+u
+'_mode', type
: 'select',
1707 options
: [['ap', 'Access Point'],['apwds', 'Access Point + WDS'],['sta', 'Wireless Client'],['wet', 'Wireless Ethernet Bridge'],['wds', 'WDS']],
1708 value
: ((eval('nvram.wl'+u
+'_mode') == 'ap') && (eval('nvram.wl'+u
+'_wds_enable') == '1')) ? 'apwds' : eval('nvram.wl'+u
+'_mode') },
1709 { title
: 'Radio Band', name
: 'f_wl'+u
+'_nband', type
: 'select', options
: bands
[uidx
],
1710 value
: eval('nvram.wl'+u
+'_nband') || '0' == '0' ? bands
[uidx
][0][0] : eval('nvram.wl'+u
+'_nband') },
1711 { title
: 'Wireless Network Mode', name
: 'wl'+u
+'_net_mode', type
: 'select',
1712 value
: (eval('nvram.wl'+u
+'_net_mode') == 'disabled') ? 'mixed' : eval('nvram.wl'+u
+'_net_mode'),
1713 options
: [], prefix
: '<span id="__wl'+u
+'_net_mode">', suffix
: '</span>' },
1714 { title
: 'SSID', name
: 'wl'+u
+'_ssid', type
: 'text', maxlen
: 32, size
: 34, value
: eval('nvram.wl'+u
+'_ssid') },
1715 { title
: 'Broadcast', indent
: 2, name
: 'f_wl'+u
+'_bcast', type
: 'checkbox', value
: (eval('nvram.wl'+u
+'_closed') == '0') },
1716 { 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
+'">',
1717 value
: eval('nvram.wl'+u
+'_channel') },
1718 { title
: 'Channel Width', name
: 'wl'+u
+'_nbw_cap', type
: 'select', options
: [['0','20 MHz'],['1','40 MHz']],
1719 value
: eval('nvram.wl'+u
+'_nbw_cap') },
1720 { title
: 'Control Sideband', name
: 'f_wl'+u
+'_nctrlsb', type
: 'select', options
: [['lower','Lower'],['upper','Upper']],
1721 value
: eval('nvram.wl'+u
+'_nctrlsb') == 'none' ? 'lower' : eval('nvram.wl'+u
+'_nctrlsb') },
1723 { title
: 'Security', name
: 'wl'+u
+'_security_mode', type
: 'select',
1724 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']],
1725 value
: eval('nvram.wl'+u
+'_security_mode') },
1726 { title
: 'Encryption', indent
: 2, name
: 'wl'+u
+'_crypto', type
: 'select',
1727 options
: [['tkip','TKIP'],['aes','AES'],['tkip+aes','TKIP / AES']], value
: eval('nvram.wl'+u
+'_crypto') },
1728 { title
: 'Shared Key', indent
: 2, name
: 'wl'+u
+'_wpa_psk', type
: 'password', maxlen
: 64, size
: 66, peekaboo
: 1,
1729 suffix
: ' <input type="button" id="_f_wl'+u
+'_psk_random1" value="Random" onclick="random_psk(\'_wl'+u
+'_wpa_psk\')">',
1730 value
: eval('nvram.wl'+u
+'_wpa_psk') },
1731 { title
: 'Shared Key', indent
: 2, name
: 'wl'+u
+'_radius_key', type
: 'password', maxlen
: 80, size
: 32, peekaboo
: 1,
1732 suffix
: ' <input type="button" id="_f_wl'+u
+'_psk_random2" value="Random" onclick="random_psk(\'_wl'+u
+'_radius_key\')">',
1733 value
: eval('nvram.wl'+u
+'_radius_key') },
1734 { title
: 'Group Key Renewal', indent
: 2, name
: 'wl'+u
+'_wpa_gtk_rekey', type
: 'text', maxlen
: 4, size
: 6, suffix
: ' <i>(seconds)</i>',
1735 value
: eval('nvram.wl'+u
+'_wpa_gtk_rekey') },
1736 { title
: 'Radius Server', indent
: 2, multi
: [
1737 { name
: 'wl'+u
+'_radius_ipaddr', type
: 'text', maxlen
: 15, size
: 17, value
: eval('nvram.wl'+u
+'_radius_ipaddr') },
1738 { name
: 'wl'+u
+'_radius_port', type
: 'text', maxlen
: 5, size
: 7, prefix
: ' : ', value
: eval('nvram.wl'+u
+'_radius_port') } ] },
1739 { title
: 'Encryption', indent
: 2, name
: 'wl'+u
+'_wep_bit', type
: 'select', options
: [['128','128-bits'],['64','64-bits']],
1740 value
: eval('nvram.wl'+u
+'_wep_bit') },
1741 { title
: 'Passphrase', indent
: 2, name
: 'wl'+u
+'_passphrase', type
: 'text', maxlen
: 16, size
: 20,
1742 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
+')">',
1743 value
: eval('nvram.wl'+u
+'_passphrase') }
1746 for (i
= 1; i
<= 4; ++i
) {
1748 { title
: ('Key ' + i
), indent
: 2, name
: ('wl'+u
+'_key' + i
), type
: 'text', maxlen
: 26, size
: 34,
1749 suffix
: '<input type="radio" onchange="verifyFields(this,1)" onclick="verifyFields(this,1)" name="f_wl'+u
+'_wepidx" id="_f_wl'+u
+'_wepidx_' + i
+ '" value="' + i
+ '"' + ((eval('nvram.wl'+u
+'_key') == i
) ? ' checked>' : '>'),
1750 value
: nvram
['wl'+u
+'_key' + i
] });
1754 { title
: 'WDS', name
: 'f_wl'+u
+'_lazywds', type
: 'select',
1755 options
: [['0','Link With...'],['1','Automatic']], value
: nvram
['wl'+u
+'_lazywds'] } );
1756 wds
= eval('nvram.wl'+u
+'_wds').split(/\s+/);
1757 for (i
= 0; i
< 10; i
+= 2) {
1758 f
.push({ title
: (i
? '' : 'MAC Address'), indent
: 2, multi
: [
1759 { name
: 'f_wl'+u
+'_wds_' + i
, type
: 'text', maxlen
: 17, size
: 20, value
: wds
[i
] || '00:00:00:00:00:00' },
1760 { name
: 'f_wl'+u
+'_wds_' + (i
+ 1), type
: 'text', maxlen
: 17, size
: 20, value
: wds
[i
+ 1] || '00:00:00:00:00:00' } ] } );
1763 createFieldTable('', f
);
1773 <tr><td id='footer' colspan=
2>
1774 <span id='footer-msg'
></span>
1775 <input type='button' value='Save' id='save-button' onclick='save()'
>
1776 <input type='button' value='Cancel' id='cancel-button' onclick='reloadPage();'
>
1780 <script type='text/javascript'
>earlyInit()</script>
1781 <div style='height:
100px'
></div>