1 <!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML
4.0//EN'
>
4 Copyright (C) 2006-2010 Jonathan Zarate
5 http://www.polarcloud.com/tomato/
7 For use with Tomato Firmware only.
8 No part of this file may be used without permission.
12 <meta http-equiv='content-type' content='text/html;charset=utf-
8'
>
13 <meta name='robots' content='noindex,nofollow'
>
14 <title>[<%
ident(); %>] Basic: Network
</title>
15 <link rel='stylesheet' type='text/css' href='tomato.css'
>
17 <script type='text/javascript' src='tomato.js'
></script>
21 <style type='text/css'
>
38 vertical-align: middle
;
42 <script type='text/javascript' src='debug.js'
></script>
44 <script type='text/javascript' src='md5.js'
></script>
45 <script type='text/javascript' src='wireless.jsx?_http_id=<%
nv(http_id
); %>'
></script>
46 <script type='text/javascript' src='interfaces.js'
></script>
47 <script type='text/javascript'
>
49 // <% nvram("dhcp_lease,dhcp_num,dhcp_start,dhcpd_startip,dhcpd_endip,l2tp_server_ip,lan_gateway,lan_ipaddr,lan_netmask,lan_proto,mtu_enable,ppp_demand,ppp_idletime,ppp_passwd,ppp_redialperiod,ppp_service,ppp_username,ppp_custom,pptp_server_ip,pptp_dhcp,wl_security_mode,wan_dns,wan_gateway,wan_ipaddr,wan_mtu,wan_netmask,wan_proto,wan_wins,wl_wds_enable,wl_channel,wl_closed,wl_crypto,wl_key,wl_key1,wl_key2,wl_key3,wl_key4,wl_lazywds,wl_mode,wl_net_mode,wl_passphrase,wl_radio,wl_radius_ipaddr,wl_radius_port,wl_ssid,wl_wds,wl_wep_bit,wl_wpa_gtk_rekey,wl_wpa_psk,wl_radius_key,wl_auth,wl_hwaddr,wan_islan,t_features,wl_nbw_cap,wl_nctrlsb,wl_nband,wl_phytype,lan_ifname,lan_stp,lan1_ifname,lan1_ipaddr,lan1_netmask,lan1_proto,lan1_stp,dhcp1_start,dhcp1_num,dhcp1_lease,dhcpd1_startip,dhcpd1_endip,lan2_ifname,lan2_ipaddr,lan2_netmask,lan2_proto,lan2_stp,dhcp2_start,dhcp2_num,dhcp2_lease,dhcpd2_startip,dhcpd2_endip,lan3_ifname,lan3_ipaddr,lan3_netmask,lan3_proto,lan3_stp,dhcp3_start,dhcp3_num,dhcp3_lease,dhcpd3_startip,dhcpd3_endip,ppp_mlppp,modem_ipaddr,cstats_enable"); %>
52 var lg
= new TomatoGrid();
53 lg
.setup = function() {
54 this.init('lan-grid', '', 4, [
55 { type
: 'select', options
: [[0, '0'],[1, '1'],[2, '2'],[3, '3']], prefix
: '<div class="centered">', suffix
: '</div>' },
56 { type
: 'checkbox', prefix
: '<div class="centered">', suffix
: '</div>' },
57 { type
: 'text', maxlen
: 15, size
: 17 },
58 { type
: 'text', maxlen
: 15, size
: 17 },
59 { type
: 'checkbox', prefix
: '<div class="centered">', suffix
: '</div>' },
60 { multi
: [ { type
: 'text', maxlen
: 15, size
: 17}, { type
: 'text', maxlen
: 15, size
: 17 } ] },
61 { type
: 'text', maxlen
: 6, size
: 8 }] );
62 this.headerSet(['Bridge', 'STP', 'IP Address', 'Netmask', 'DHCP', 'IP Range <i>(first/last)</i>', 'Lease Time <i>(mins)</i>']);
65 for (var i
= 0 ; i
<= MAX_BRIDGE_ID
; i
++) {
66 var j
= (i
== 0) ? '' : i
.toString();
67 if (nvram
['lan' + j
+ '_ifname'].length
> 0) {
68 if ((!fixIP(nvram
['dhcpd' + j
+ '_startip'])) || (!fixIP(nvram
['dhcpd' + j
+ '_endip']))) {
69 if ((fixIP(nvram
['lan' + j
+ '_ipaddr'])) && (fixIP(nvram
['lan' + j
+ '_netmask'])) && (nvram
['dhcp' + j
+ '_start'] != '')) {
70 var n
= getNetworkAddress(nvram
['lan' + j
+ '_ipaddr'], nvram
['lan' + j
+ '_netmask']);
71 nvram
['dhcpd' + j
+ '_startip'] = getAddress(('0.0.0.' + nvram
['dhcp' + j
+ '_start'] * 1), n
);
72 nvram
['dhcpd' + j
+ '_endip'] = getAddress(('0.0.0.' + ((nvram
['dhcp' + j
+ '_start'] * 1) + (nvram
['dhcp' + j
+ '_num'] *1) - 1)), n
);
77 nvram
['lan' + j
+ '_stp'],
78 nvram
['lan' + j
+ '_ipaddr'],
79 nvram
['lan' + j
+ '_netmask'],
80 (nvram
['lan' + j
+ '_proto'] == 'dhcp') ? '1' : '0',
81 nvram
['dhcpd' + j
+ '_startip'],
82 nvram
['dhcpd' + j
+ '_endip'],
83 (nvram
['lan' + j
+ '_proto'] == 'dhcp') ? (((nvram
['dhcp' + j
+ '_lease'])*1 == 0) ? '1440' : (nvram
['dhcp' + j
+ '_lease']).toString()) : ''
90 elem
.removeClass(lg
.header
.cells
[lg
.sortColumn
], 'sortasc', 'sortdes');
95 lg
.dataToView = function(data
) {
96 return ['br' + data
[0],
97 (data
[1].toString() == '1') ? '<small><i>Enabled</i></small>' : '<small><i>Disabled</i></small>',
100 (data
[4].toString() == '1') ? '<small><i>Enabled</i></small>' : '<small><i>Disabled</i></small>',
101 (data
[5].toString() + ((numberOfBitsOnNetMask(data
[3])>=24) ? (' - ' + data
[6].split('.').splice(3, 1).toString()) : ('<br>' + data
[6].toString()) )),
102 (((data
[7] != null) && (data
[7] != '')) ? data
[7] : '') ];
105 lg
.dataToFieldValues = function (data
) {
107 (data
[1] != 0) ? 'checked' : '',
110 (data
[4].toString() == '1') ? 'checked' : '',
113 data
[7].toString() ];
116 lg
.fieldValuesToData = function(row
) {
117 var f
= fields
.getAll(row
);
119 f
[1].checked
? 1 : 0,
122 f
[4].checked
? 1 : 0,
128 lg
.resetNewEditor = function() {
129 var f
= fields
.getAll(this.newEditor
);
130 f
[0].selectedIndex
=0;
131 var t
= MAX_BRIDGE_ID
;
132 while((this.countBridge(f
[0].selectedIndex
) > 0) && (t
> 0)) {
133 f
[0].selectedIndex
= (f
[0].selectedIndex
%(MAX_BRIDGE_ID
))+1;
136 for(var j
=0; j
<= MAX_BRIDGE_ID
; j
++) {
137 f
[0].options
[j
].disabled
= (this.countBridge(j
) > 0);
150 ferror
.clearAll(fields
.getAll(this.newEditor
));
153 lg
.onCancel = function() {
156 this.disableNewEditor(false);
158 this.resetNewEditor();
161 lg
.onAdd = function() {
167 if (!this.verifyFields(this.newEditor
, false)) return;
169 data
= this.fieldValuesToData(this.newEditor
);
170 this.insertData(-1, data
);
172 this.disableNewEditor(false);
173 this.resetNewEditor();
178 lg
.onOK = function() {
181 if (!this.verifyFields(this.editor
, false)) return;
183 data
= this.fieldValuesToData(this.editor
);
184 view
= this.dataToView(data
);
186 this.source
.setRowData(data
);
187 for (i
= 0; i
< this.source
.cells
.length
; ++i
) {
188 this.source
.cells
[i
].innerHTML
= view
[i
];
193 this.disableNewEditor(false);
196 this.resetNewEditor();
199 lg
.onDelete = function() {
201 elem
.remove(this.source
);
203 this.disableNewEditor(false);
205 this.resetNewEditor();
208 lg
.countElem = function(f
, v
) {
209 var data
= this.getAllData();
211 for (var i
= 0; i
< data
.length
; ++i
) {
212 total
+= (data
[i
][f
] == v
) ? 1 : 0;
217 lg
.countBridge = function (v
) {
218 return this.countElem(0,v
);
221 lg
.countOverlappingNetworks = function (ip
) {
222 var data
= this.getAllData();
224 for (var i
= 0; i
< data
.length
; ++i
) {
225 var net
= getNetworkAddress(data
[i
][2], data
[i
][3]);
226 var brd
= getBroadcastAddress(net
, data
[i
][3]);
227 total
+= ((aton(ip
) <= aton(brd
)) && (aton(ip
) >= aton(net
))) ? 1 : 0;
232 lg
.verifyFields = function(row
, quiet
) {
236 f
= fields
.getAll(row
);
238 for(var j
=0; j
<= MAX_BRIDGE_ID
; j
++) {
239 f
[0].options
[j
].disabled
= (this.countBridge(j
) > 0);
242 if(this.countBridge(f
[0].selectedIndex
) > 0) {
243 ferror
.set(f
[0], 'Cannot add another entry for bridge br' + f
[0].selectedIndex
, quiet
);
249 if(!v_ip(f
[2], quiet
|| !ok
))
251 // if we have a properly defined IP address - 0.0.0.0 is NOT a valid IP address for our intents/purposes!
252 if ((f
[2].value
!= '') && (f
[2].value
!= '0.0.0.0')) {
253 // allow DHCP to be enabled
256 if(!v_netmask(f
[3], quiet
|| !ok
)) {
260 // should be 22 bits or smaller network
261 if ((numberOfBitsOnNetMask(f
[3].value
) < 22) && (nvram
.cstats_enable
== '1' )) {
262 if (!confirm("Netmask should have at least 22 bits (255.255.252.0). You may continue anyway but remember - you were warned!")) return;
267 if(f
[2].value
== getNetworkAddress(f
[2].value
, f
[3].value
)) {
268 var s
= 'Invalid IP address or subnet mask (the address of the network cannot be used)';
269 ferror
.set(f
[2], s
, quiet
);
270 ferror
.set(f
[3], s
, quiet
);
273 if(f
[2].value
== getBroadcastAddress(getNetworkAddress(f
[2].value
, f
[3].value
), f
[3].value
)) {
274 var s
= 'Invalid IP address or subnet mask (the broadcast address cannot be used)';
275 ferror
.set(f
[2], s
, quiet
);
276 ferror
.set(f
[3], s
, quiet
);
279 if (this.countOverlappingNetworks(f
[2].value
) > 0) {
280 var s
= 'Invalid IP address or subnet mask (conflicts/overlaps with another LAN bridge)';
281 ferror
.set(f
[2], s
, quiet
);
282 ferror
.set(f
[3], s
, quiet
);
293 if( (f
[4].checked
) && (v_ip(f
[2], 1)) && (v_netmask(f
[3],1)) ) {
297 // first/last IP still unset?
298 if (f
[5].value
== '') {
300 var m
= aton(f
[2].value
) & aton(f
[3].value
);
301 var o
= (m
) ^ (~ aton(f
[3].value
))
309 } while (((l
= fixIP(ntoa(m
), 1)) == null) || (l
== f
[2].value
) );
312 if (f
[6].value
== '') {
314 var m
= aton(f
[2].value
) & aton(f
[3].value
);
315 var o
= (m
) ^ (~ aton(f
[3].value
));
323 } while (((l
= fixIP(ntoa(o
), 1)) == null) || (l
== f
[2].value
) );
327 if ((getNetworkAddress(f
[5].value
, f
[3].value
) != getNetworkAddress(f
[2].value
, f
[3].value
)) ||
328 (f
[5].value
== getBroadcastAddress(getNetworkAddress(f
[2].value
, f
[3].value
), f
[3].value
)) ||
329 (f
[5].value
== getNetworkAddress(f
[2].value
, f
[3].value
)) ||
330 (f
[2].value
== f
[5].value
)) {
331 ferror
.set(f
[5], 'Invalid first IP address or subnet mask', quiet
|| !ok
);
337 if ((getNetworkAddress(f
[6].value
, f
[3].value
) != getNetworkAddress(f
[2].value
, f
[3].value
)) ||
338 (f
[6].value
== getBroadcastAddress(getNetworkAddress(f
[2].value
, f
[3].value
), f
[3].value
)) ||
339 (f
[6].value
== getNetworkAddress(f
[2].value
, f
[3].value
)) ||
340 (f
[2].value
== f
[6].value
)) {
341 ferror
.set(f
[6], 'Invalid last IP address or subnet mask', quiet
|| !ok
);
346 // validate range, swap first/last IP if needed
347 if (aton(f
[6].value
) < aton(f
[5].value
)) {
349 f
[5].value
= f
[6].value
;
353 if (parseInt(f
[7].value
*1) == 0)
354 f
[7].value
= 1440; // from nvram/defaults.c
355 if(!v_mins(f
[7], quiet
|| !ok
, 1, 10080))
369 W('<style type=\'text/css\'>');
370 for (var u
= 0; u
< wl_ifaces
.length
; ++u
) {
371 W('#spin'+wl_unit(u
)+', ');
374 W(' visibility: hidden;');
375 W(' vertical-align: middle;');
381 var nphy
= features('11n');
384 if ((!fixIP(nvram
.dhcpd_startip
)) || (!fixIP(nvram
.dhcpd_endip
))) {
385 var x
= nvram
.lan_ipaddr
.split('.').splice(0, 3).join('.') + '.';
386 nvram
.dhcpd_startip
= x
+ nvram
.dhcp_start
;
387 nvram
.dhcpd_endip
= x
+ ((nvram
.dhcp_start
* 1) + (nvram
.dhcp_num
* 1) - 1);
393 var nm_loaded
= [], ch_loaded
= [], max_channel
= [];
395 for (var uidx
= 0; uidx
< wl_ifaces
.length
; ++uidx
) {
396 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
397 if (wl_sunit(uidx
)<0) {
400 for (var i
= 0; i
< wl_bands
[uidx
].length
; ++i
) {
401 b
.push([wl_bands
[uidx
][i
] + '', (wl_bands
[uidx
][i
] == '1') ? '5 GHz' : '2.4 GHz']);
411 refresher
.push(null);
415 function selectedBand(uidx
)
417 if (bands
[uidx
].length
> 1) {
418 var e
= E('_f_wl'+u
+'_nband');
419 return (e
.value
+ '' == '' ? eval('nvram.wl'+u
+'_nband') : e
.value
);
420 } else if (bands
[uidx
].length
> 0) {
421 return bands
[uidx
][0][0] || '0';
427 function refreshNetModes(uidx
)
431 if (uidx
>= wl_ifaces
.length
) return;
432 var u
= wl_unit(uidx
);
434 var m
= [['mixed','Auto']];
435 if (selectedBand(uidx
) == '1') {
436 m
.push(['a-only','A Only']);
438 m
.push(['n-only','N Only']);
442 m
.push(['b-only','B Only']);
443 m
.push(['g-only','G Only']);
445 m
.push(['bg-mixed','B/G Mixed']);
446 m
.push(['n-only','N Only']);
450 e
= E('_wl'+u
+'_net_mode');
452 val
= (!nm_loaded
[uidx
] || (e
.value
+ '' == '')) ? eval('nvram.wl'+u
+'_net_mode') : e
.value
;
453 if (val
== 'disabled') val
= 'mixed';
454 for (i
= 0; i
< m
.length
; ++i
)
455 buf
+= '<option value="' + m
[i
][0] + '"' + ((m
[i
][0] == val
) ? ' selected' : '') + '>' + m
[i
][1] + '</option>';
457 e
= E('__wl'+u
+'_net_mode');
458 buf
= '<select name="wl'+u
+'_net_mode" onchange="verifyFields(this, 1)" id = "_wl'+u
+'_net_mode">' + buf
+ '</select>';
459 elem
.setInnerHTML(e
, buf
);
463 function refreshChannels(uidx
)
465 if (refresher
[uidx
] != null) return;
466 if (u
>= wl_ifaces
.length
) return;
467 var u
= wl_unit(uidx
);
469 refresher
[uidx
] = new XmlHttp();
470 refresher
[uidx
].onCompleted = function(text
, xml
) {
474 var wl_channels
= [];
478 max_channel
[uidx
] = 0;
479 for (i
= 0; i
< wl_channels
.length
; ++i
) {
480 ghz
[uidx
].push([wl_channels
[i
][0] + '',
481 (wl_channels
[i
][0]) ? ((wl_channels
[i
][1]) ? wl_channels
[i
][0] + ' - ' + (wl_channels
[i
][1] / 1000.0).toFixed(3) + ' GHz' : wl_channels
[i
][0] + '') : 'Auto']);
482 max_channel
[uidx
] = wl_channels
[i
][0] * 1;
485 e
= E('_wl'+u
+'_channel');
487 val
= (!ch_loaded
[uidx
] || (e
.value
+ '' == '')) ? eval('nvram.wl'+u
+'_channel') : e
.value
;
488 for (i
= 0; i
< ghz
[uidx
].length
; ++i
)
489 buf
+= '<option value="' + ghz
[uidx
][i
][0] + '"' + ((ghz
[uidx
][i
][0] == val
) ? ' selected' : '') + '>' + ghz
[uidx
][i
][1] + '</option>';
491 e
= E('__wl'+u
+'_channel');
492 buf
= '<select name="wl'+u
+'_channel" onchange="verifyFields(this, 1)" id = "_wl'+u
+'_channel">' + buf
+ '</select>';
493 elem
.setInnerHTML(e
, buf
);
496 refresher
[uidx
] = null;
497 verifyFields(null, 1);
501 refresher
[uidx
] = null;
506 e
= E('_f_wl'+u
+'_nctrlsb');
507 sb
= (e
.value
+ '' == '' ? eval('nvram.wl'+u
+'_nctrlsb') : e
.value
);
508 e
= E('_wl'+u
+'_nbw_cap');
509 bw
= (e
.value
+ '' == '' ? eval('nvram.wl'+u
+'_nbw_cap') : e
.value
) == '0' ? '20' : '40';
511 refresher
[uidx
].onError = function(ex
) { alert(ex
); refresher
[uidx
] = null; reloadPage(); }
512 refresher
[uidx
].post('update.cgi', 'exec=wlchannels&arg0=' + u
+ '&arg1=' + (nphy
? '1' : '0') +
513 '&arg2=' + bw
+ '&arg3=' + selectedBand(uidx
) + '&arg4=' + sb
);
516 function spin(x
, unit
)
518 for (var u
= 0; u
< wl_ifaces
.length
; ++u
) {
519 E('_f_wl'+wl_unit(u
)+'_scan').disabled
= x
;
521 var e
= E('_f_wl'+unit
+'_scan');
522 if (x
) e
.value
= 'Scan ' + (wscan
.tries
+ 1);
523 else e
.value
= 'Scan';
524 E('spin'+unit
).style
.visibility
= x
? 'visible' : 'hidden';
531 var unit
= wscan
.unit
;
532 var uidx
= wl_uidx(unit
);
535 xob
.onCompleted = function(text
, xml
) {
542 for (i
= 0; i
< wlscandata
.length
; ++i
) {
543 var data
= wlscandata
[i
];
547 if (!wscan
.inuse
[ch
]) {
555 if (!wscan
.seen
[mac
]) {
557 ++wscan
.inuse
[ch
].count
;
560 if (data
[4] > wscan
.inuse
[ch
].rssi
) {
561 wscan
.inuse
[ch
].rssi
= data
[4];
562 wscan
.inuse
[ch
].ssid
= data
[1];
565 var e
= E('_wl'+unit
+'_channel');
566 for (i
= 1; i
< ghz
[uidx
].length
; ++i
) {
567 var s
= ghz
[uidx
][i
][1];
568 var u
= wscan
.inuse
[ghz
[uidx
][i
][0]];
569 if (u
) s
+= ' (' + u
.count
+ ' AP' + (u
.count
== 1 ? '' : 's') + ' / strongest: "' + escapeHTML(ellipsis(u
.ssid
, 15)) + '" ' + u
.rssi
+ ' dBm)';
570 e
.options
[i
].innerHTML
= s
;
572 e
.style
.width
= '400px';
576 if (wscan
.tries
< 4) {
578 setTimeout(scan
, 1000);
586 xob
.onError = function(x
) {
587 alert('error: ' + x
);
593 xob
.post('update.cgi', 'exec=wlscan&arg0='+unit
);
596 function scanButton(u
)
610 function joinAddr(a
) {
614 for (i
= 0; i
< a
.length
; ++i
) {
616 if ((s
!= '00:00:00:00:00:00') && (s
!= '0.0.0.0')) r
.push(s
);
621 function random_x(max
)
623 var c
= '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
625 while (max
-- > 0) s
+= c
.substr(Math
.floor(c
.length
* Math
.random()), 1);
629 function random_psk(id
)
632 e
.value
= random_x(63);
633 verifyFields(null, 1);
636 function random_wep(u
)
638 E('_wl'+u
+'_passphrase').value
= random_x(16);
642 function v_wep(e
, quiet
)
646 if (((s
.length
== 5) || (s
.length
== 13)) && (s
.length
== (e
.maxLength
>> 1))) {
650 s
= s
.toUpperCase().replace(/[^0-9A-F]/g, '');
651 if (s
.length
!= e
.maxLength
) {
652 ferror
.set(e
, 'Invalid WEP key. Expecting ' + e
.maxLength
+ ' hex or ' + (e
.maxLength
>> 1) + ' ASCII characters.', quiet
);
662 // compatible w/ Linksys' and Netgear's (key 1) method for 128-bits
663 function generate_wep(u
)
665 function _wepgen(pass
, i
)
667 while (pass
.length
< 64) pass
+= pass
;
668 return hex_md5(pass
.substr(0, 64)).substr(i
, (E('_wl'+u
+'_wep_bit').value
== 128) ? 26 : 10);
671 var e
= E('_wl'+u
+'_passphrase');
673 if (!v_length(e
, false, 3)) return;
674 E('_wl'+u
+'_key1').value
= _wepgen(pass
, 0);
676 E('_wl'+u
+'_key2').value
= _wepgen(pass
, 2);
678 E('_wl'+u
+'_key3').value
= _wepgen(pass
, 4);
680 E('_wl'+u
+'_key4').value
= _wepgen(pass
, 6);
681 verifyFields(null, 1);
684 function verifyFields(focused
, quiet
)
692 for (uidx
= 0; uidx
< wl_ifaces
.length
; ++uidx
) {
693 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
694 if (wl_sunit(uidx
)<0) {
696 if (focused
== E('_f_wl'+u
+'_nband')) {
697 refreshNetModes(uidx
);
698 refreshChannels(uidx
);
700 else if (focused
== E('_f_wl'+u
+'_nctrlsb') || focused
== E('_wl'+u
+'_nbw_cap')) {
701 refreshChannels(uidx
);
706 // --- visibility ---
722 _ppp_redialperiod
: 1,
745 for (uidx
= 0; uidx
< wl_ifaces
.length
; ++uidx
) {
746 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
747 if (wl_sunit(uidx
)<0) {
751 _f_wl_nband
: (bands
[uidx
].length
> 1) ? 1 : 0,
756 _wl_nbw_cap
: nphy
? 1 : 0,
757 _f_wl_nctrlsb
: nphy
? 1 : 0,
760 _wl_security_mode
: 1,
763 _f_wl_psk_random1
: 1,
764 _f_wl_psk_random2
: 1,
765 _wl_wpa_gtk_rekey
: 1,
767 _wl_radius_ipaddr
: 1,
785 var wan
= E('_wan_proto').value
;
787 for (uidx
= 0; uidx
< wl_ifaces
.length
; ++uidx
) {
788 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
789 if (wl_sunit(uidx
)<0) {
790 wmode
= E('_f_wl'+wl_unit(uidx
)+'_mode').value
;
792 if (wmode
== 'wet') {
796 vis
._f_dhcpd_enable
= 0;
801 if ((wan
== 'disabled') || (wmode
== 'sta') || (wmode
== 'wet')) {
802 vis
._f_wan_islan
= 1;
809 vis
._ppp_username
= 0;
810 vis
._ppp_service
= 0;
812 vis
._l2tp_server_ip
= 0;
814 vis
._wan_netmask
= 0;
815 vis
._wan_gateway
= 0;
816 vis
._pptp_server_ip
= 0;
817 vis
._f_pptp_dhcp
= 0;
821 vis
._f_ppp_mlppp
= 0;
822 vis
._modem_ipaddr
= 0;
825 vis
._l2tp_server_ip
= 0;
827 vis
._ppp_service
= 0;
828 vis
._ppp_username
= 0;
830 vis
._pptp_server_ip
= 0;
831 vis
._f_pptp_dhcp
= 0;
832 vis
._wan_gateway
= 0;
834 vis
._wan_netmask
= 0;
835 vis
._f_ppp_mlppp
= 0;
836 vis
._modem_ipaddr
= 1;
838 vis
._lan_gateway
= 0;
841 vis
._l2tp_server_ip
= 0;
842 vis
._pptp_server_ip
= 0;
843 vis
._f_pptp_dhcp
= 0;
844 vis
._wan_gateway
= 0;
846 vis
._wan_netmask
= 0;
847 vis
._modem_ipaddr
= 1;
849 vis
._lan_gateway
= 0;
852 vis
._l2tp_server_ip
= 0;
854 vis
._ppp_service
= 0;
855 vis
._ppp_username
= 0;
857 vis
._pptp_server_ip
= 0;
858 vis
._f_pptp_dhcp
= 0;
859 vis
._f_ppp_mlppp
= 0;
860 vis
._modem_ipaddr
= 1;
862 vis
._lan_gateway
= 0;
865 vis
._l2tp_server_ip
= 0;
866 vis
._ppp_service
= 0;
867 vis
._wan_gateway
= (!E('_f_pptp_dhcp').checked
);
868 vis
._wan_ipaddr
= (!E('_f_pptp_dhcp').checked
);
869 vis
._modem_ipaddr
= 0;
871 vis
._lan_gateway
= 0;
874 vis
._pptp_server_ip
= 0;
875 vis
._ppp_service
= 0;
876 vis
._wan_gateway
= (!E('_f_pptp_dhcp').checked
);
877 vis
._wan_ipaddr
= (!E('_f_pptp_dhcp').checked
);
878 vis
._modem_ipaddr
= 0;
880 vis
._lan_gateway
= 0;
884 vis
._ppp_idletime
= (E('_ppp_demand').value
== 1) && vis
._ppp_demand
885 vis
._ppp_redialperiod
= !vis
._ppp_idletime
&& vis
._ppp_demand
;
887 if (vis
._mtu_enable
) {
888 if (E('_mtu_enable').value
== 0) {
891 switch (E('_wan_proto').value
) {
907 if (!E('_f_dhcpd_enable').checked
) vis
._dhcp_lease
= 0;
910 for (uidx
= 0; uidx
< wl_ifaces
.length
; ++uidx
) {
911 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
912 if (wl_sunit(uidx
)<0) {
914 wmode
= E('_f_wl'+u
+'_mode').value
;
916 if (!E('_f_wl'+u
+'_radio').checked
) {
917 for (a
in wl_vis
[uidx
]) {
920 wl_vis
[uidx
]._f_wl_radio
= 1;
921 wl_vis
[uidx
]._wl_nbw_cap
= nphy
? 2 : 0;
922 wl_vis
[uidx
]._f_wl_nband
= (bands
[uidx
].length
> 1) ? 2 : 0;
931 wl_vis
[uidx
]._f_wl_bcast
= 0;
932 wl_vis
[uidx
]._wl_channel
= 0;
933 wl_vis
[uidx
]._wl_nbw_cap
= 0;
934 vis
._modem_ipaddr
= 0;
936 wl_vis
[uidx
]._f_wl_lazywds
= 0;
937 wl_vis
[uidx
]._f_wl_wds_0
= 0;
941 sm2
= E('_wl'+u
+'_security_mode').value
;
944 wl_vis
[uidx
]._wl_crypto
= 0;
945 wl_vis
[uidx
]._wl_wep_bit
= 0;
946 wl_vis
[uidx
]._wl_wpa_psk
= 0;
947 wl_vis
[uidx
]._wl_radius_key
= 0;
948 wl_vis
[uidx
]._wl_radius_ipaddr
= 0;
949 wl_vis
[uidx
]._wl_wpa_gtk_rekey
= 0;
952 wl_vis
[uidx
]._wl_crypto
= 0;
953 wl_vis
[uidx
]._wl_wpa_psk
= 0;
954 wl_vis
[uidx
]._wl_radius_key
= 0;
955 wl_vis
[uidx
]._wl_radius_ipaddr
= 0;
956 wl_vis
[uidx
]._wl_wpa_gtk_rekey
= 0;
959 wl_vis
[uidx
]._wl_crypto
= 0;
960 wl_vis
[uidx
]._wl_wpa_psk
= 0;
963 wl_vis
[uidx
]._wl_wep_bit
= 0;
964 if (sm2
.indexOf('personal') != -1) {
965 wl_vis
[uidx
]._wl_radius_key
= 0;
966 wl_vis
[uidx
]._wl_radius_ipaddr
= 0;
969 wl_vis
[uidx
]._wl_wpa_psk
= 0;
974 if ((E('_f_wl'+u
+'_lazywds').value
== 1) && (wl_vis
[uidx
]._f_wl_wds_0
== 1)) {
975 wl_vis
[uidx
]._f_wl_wds_0
= 2;
978 if (wl_vis
[uidx
]._wl_nbw_cap
!= 0) {
979 switch (E('_wl'+u
+'_net_mode').value
) {
984 wl_vis
[uidx
]._wl_nbw_cap
= 2;
985 if (E('_wl'+u
+'_nbw_cap').value
!= '0') {
986 E('_wl'+u
+'_nbw_cap').value
= 0;
987 refreshChannels(uidx
);
991 // avoid Enterprise-TKIP with 40MHz
992 if ((sm2
== 'wpa_enterprise') && (E('_wl'+u
+'_crypto').value
== 'tkip')) {
993 wl_vis
[uidx
]._wl_nbw_cap
= 2;
994 if (E('_wl'+u
+'_nbw_cap').value
!= '0') {
995 E('_wl'+u
+'_nbw_cap').value
= 0;
996 refreshChannels(uidx
);
1001 wl_vis
[uidx
]._f_wl_nctrlsb
= (E('_wl'+u
+'_nbw_cap').value
== 0) ? 0 : wl_vis
[uidx
]._wl_nbw_cap
;
1005 Special case - 2.4GHz band, currently running in B/G-only mode,
1006 with N/Auto and 40MHz selected in the GUI.
1007 Channel list is not filtered in this case by the wl driver,
1008 and includes all channels available with 20MHz channel width.
1010 b
= selectedBand(uidx
);
1011 if (wl_vis
[uidx
]._wl_channel
== 1 && wl_vis
[uidx
]._f_wl_nctrlsb
!= 0 &&
1012 ((b
== '2') || (wl_vis
[uidx
]._f_wl_nband
== 0 && b
== '0'))) {
1013 switch (eval('nvram.wl'+u
+'_net_mode')) {
1017 i
= E('_wl'+u
+'_channel').value
* 1;
1018 if (i
> 0 && i
< 5) {
1019 E('_f_wl'+u
+'_nctrlsb').value
= 'lower';
1020 wl_vis
[uidx
]._f_wl_nctrlsb
= 2;
1022 else if (i
> max_channel
[uidx
] - 4) {
1023 E('_f_wl'+u
+'_nctrlsb').value
= 'upper';
1024 wl_vis
[uidx
]._f_wl_nctrlsb
= 2;
1030 wl_vis
[uidx
]._f_wl_scan
= wl_vis
[uidx
]._wl_channel
;
1031 wl_vis
[uidx
]._f_wl_psk_random1
= wl_vis
[uidx
]._wl_wpa_psk
;
1032 wl_vis
[uidx
]._f_wl_psk_random2
= wl_vis
[uidx
]._wl_radius_key
;
1033 wl_vis
[uidx
]._wl_radius_port
= wl_vis
[uidx
]._wl_radius_ipaddr
;
1034 wl_vis
[uidx
]._wl_key1
= wl_vis
[uidx
]._wl_key2
= wl_vis
[uidx
]._wl_key3
= wl_vis
[uidx
]._wl_key4
= wl_vis
[uidx
]._f_wl_wep_gen
= wl_vis
[uidx
]._f_wl_wep_random
= wl_vis
[uidx
]._wl_passphrase
= wl_vis
[uidx
]._wl_wep_bit
;
1036 for (i
= 1; i
< 10; ++i
) {
1037 wl_vis
[uidx
]['_f_wl_wds_' + i
] = wl_vis
[uidx
]._f_wl_wds_0
;
1040 } // for each wl_iface
1042 vis
._ppp_passwd
= vis
._ppp_username
;
1044 vis
._dhcpd_startip
= vis
._dhcpd_endip
= vis
._wan_wins
= vis
._dhcp_lease
;
1053 b
.disabled
= (c
!= 1);
1054 PR(b
).style
.display
= c
? '' : 'none';
1057 for (uidx
= 0; uidx
< wl_ifaces
.length
; ++uidx
) {
1058 if(wl_ifaces
[uidx
][0].indexOf('.') < 0) {
1059 for (a
in wl_vis
[uidx
]) {
1061 if (a
.substr(0, 6) == '_f_wl_') i
= 5;
1062 b
= E(a
.substr(0, i
) + wl_unit(uidx
) + a
.substr(i
, a
.length
));
1063 c
= wl_vis
[uidx
][a
];
1064 b
.disabled
= (c
!= 1);
1065 PR(b
).style
.display
= c
? '' : 'none';
1072 ferror
.clear('_wan_proto');
1075 for (uidx
= 0; uidx
< wl_ifaces
.length
; ++uidx
) {
1076 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1077 if (wl_sunit(uidx
)<0) {
1079 wmode
= E('_f_wl'+u
+'_mode').value
;
1080 sm2
= E('_wl'+u
+'_security_mode').value
;
1083 if ((wl_vis[uidx]._f_wl_mode == 1) && (wmode != 'ap') && (sm2.substr(0, 4) == 'wpa2')) {
1084 ferror.set('_wl'+u+'_security_mode', 'WPA2 is supported only in AP mode.', quiet || !ok);
1087 else ferror.clear('_wl'+u+'_security_mode');
1090 // --- N standard does not support WPA+TKIP ---
1091 a
= E('_wl'+u
+'_crypto');
1092 switch (E('_wl'+u
+'_net_mode').value
) {
1095 if (nphy
&& (a
.value
== 'tkip') && (sm2
.indexOf('wpa') != -1)) {
1096 ferror
.set(a
, 'TKIP encryption is not supported with WPA / WPA2 in N mode.', quiet
|| !ok
);
1099 else ferror
.clear(a
);
1103 a
= E('_wl'+u
+'_net_mode');
1105 b
= E('_f_wl'+u
+'_mode');
1107 if ((wmode
== 'sta') || (wmode
== 'wet')) {
1110 ferror
.set(b
, 'Only one wireless interface can be configured in client mode.', quiet
|| !ok
);
1113 else if (a
.value
== 'n-only') {
1114 ferror
.set(a
, 'N-only is not supported in wireless client modes, use Auto.', quiet
|| !ok
);
1119 a
= E('_wl'+u
+'_wpa_psk');
1121 if (wl_vis
[uidx
]._wl_wpa_psk
== 1) {
1122 if ((a
.value
.length
< 8) || ((a
.value
.length
== 64) && (a
.value
.search(/[^0-9A-Fa-f]/) != -1))) {
1123 ferror
.set('_wl'+u
+'_wpa_psk', 'Invalid pre-shared key. Please enter at least 8 characters or 64 hexadecimal digits.', quiet
|| !ok
);
1129 if (((wmode
== 'wds') || (wmode
== 'apwds')) && (wl_vis
[uidx
]._wl_channel
== 1) && (E('_wl'+u
+'_channel').value
== '0')) {
1130 ferror
.set('_wl'+u
+'_channel', 'Fixed wireless channel required in WDS mode.', quiet
|| !ok
);
1133 else ferror
.clear('_wl'+u
+'_channel');
1135 if (E('_f_wl'+u
+'_mode').value
== 'sta') {
1136 if ((wan
== 'disabled') && (E('_f_wl'+u
+'_radio').checked
)) {
1137 ferror
.set('_wan_proto', 'Wireless Client mode requires a valid WAN setting (usually DHCP).', quiet
|| !ok
);
1144 // domain name or IP address
1145 a
= ['_l2tp_server_ip', '_pptp_server_ip'];
1146 for (i
= a
.length
- 1; i
>= 0; --i
)
1147 if ((vis
[a
[i
]]) && ((!v_length(a
[i
], 1, 1)) || ((!v_ip(a
[i
], 1)) && (!v_domain(a
[i
], 1))))) {
1148 if (!quiet
&& ok
) ferror
.show(a
[i
]);
1154 a
= ['_wan_gateway','_wan_ipaddr','_lan_ipaddr', '_dhcpd_startip', '_dhcpd_endip'];
1157 a
= ['_wan_gateway','_wan_ipaddr'];
1159 for (i
= a
.length
- 1; i
>= 0; --i
)
1160 if ((vis
[a
[i
]]) && (!v_ip(a
[i
], quiet
|| !ok
))) ok
= 0;
1162 // IP address, blank -> 0.0.0.0
1163 a
= ['_f_dns_1', '_f_dns_2', '_f_dns_3','_wan_wins','_lan_gateway', '_modem_ipaddr'];
1164 for (i
= a
.length
- 1; i
>= 0; --i
)
1165 if ((vis
[a
[i
]]) && (!v_dns(a
[i
], quiet
|| !ok
))) ok
= 0;
1169 a
= ['_wan_netmask','_lan_netmask'];
1172 a
= ['_wan_netmask'];
1174 for (i
= a
.length
- 1; i
>= 0; --i
)
1175 if ((vis
[a
[i
]]) && (!v_netmask(a
[i
], quiet
|| !ok
))) ok
= 0;
1179 a
= [['_ppp_idletime', 3, 1440],['_ppp_redialperiod', 1, 86400],['_f_wan_mtu', 576, 1500],
1180 ['_dhcp_lease', 1, 10080]];
1183 a
= [['_ppp_idletime', 3, 1440],['_ppp_redialperiod', 1, 86400],['_f_wan_mtu', 576, 1500]];
1185 for (i
= a
.length
- 1; i
>= 0; --i
) {
1187 if ((vis
[v
[0]]) && (!v_range(v
[0], quiet
|| !ok
, v
[1], v
[2]))) ok
= 0;
1190 for (uidx
= 0; uidx
< wl_ifaces
.length
; ++uidx
) {
1191 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1192 if (wl_sunit(uidx
)<0) {
1196 a
= ['_radius_ipaddr'];
1197 for (i
= a
.length
- 1; i
>= 0; --i
) {
1198 if ((wl_vis
[uidx
]['_wl'+a
[i
]]) && (!v_ip('_wl'+u
+a
[i
], quiet
|| !ok
))) ok
= 0;
1202 a
= [['_wpa_gtk_rekey', 60, 7200], ['_radius_port', 1, 65535]];
1203 for (i
= a
.length
- 1; i
>= 0; --i
) {
1205 if ((wl_vis
[uidx
]['_wl'+v
[0]]) && (!v_range('_wl'+u
+v
[0], quiet
|| !ok
, v
[1], v
[2]))) ok
= 0;
1209 a
= [['_ssid', 1], ['_radius_key', 1]];
1210 for (i
= a
.length
- 1; i
>= 0; --i
) {
1212 if ((wl_vis
[uidx
]['_wl'+v
[0]]) && (!v_length('_wl'+u
+v
[0], quiet
|| !ok
, v
[1], E('_wl'+u
+v
[0]).maxlength
))) ok
= 0;
1215 if (wl_vis
[uidx
]._wl_key1
) {
1216 a
= (E('_wl'+u
+'_wep_bit').value
== 128) ? 26 : 10;
1217 for (i
= 1; i
<= 4; ++i
) {
1218 b
= E('_wl'+u
+'_key' + i
);
1220 if ((b
.value
.length
> 0) || (E('_f_wl'+u
+'_wepidx_' + i
).checked
)) {
1221 if (!v_wep(b
, quiet
|| !ok
)) ok
= 0;
1223 else ferror
.clear(b
);
1227 ferror
.clear('_f_wl'+u
+'_wds_0');
1228 if (wl_vis
[uidx
]._f_wl_wds_0
== 1) {
1230 for (i
= 0; i
< 10; ++i
) {
1231 a
= E('_f_wl'+u
+'_wds_' + i
);
1232 if (!v_macz(a
, quiet
|| !ok
)) ok
= 0;
1233 else if (!isMAC0(a
.value
)) b
= 1;
1236 ferror
.set('_f_wl'+u
+'_wds_0', 'WDS MAC address required.', quiet
|| !ok
);
1244 a
= E('_dhcpd_startip');
1245 b
= E('_dhcpd_endip');
1249 if ((vis
._dhcp_lease
) && (!a
._error_msg
) && (!b
._error_msg
)) {
1250 c
= aton(E('_lan_netmask').value
);
1251 d
= aton(E('_lan_ipaddr').value
) & c
;
1252 e
= 'Invalid IP address or subnet mask';
1253 if ((aton(a
.value
) & c
) != d
) {
1254 ferror
.set(a
, e
, quiet
|| !ok
);
1257 if ((aton(b
.value
) & c
) != d
) {
1258 ferror
.set(b
, e
, quiet
|| !ok
);
1263 if ((vis
._dhcp_lease
) && (!a
._error_msg
) && (!b
._error_msg
)) {
1264 if (aton(a
.value
) > aton(b
.value
)) {
1270 elem
.setInnerHTML('dhcp_count', '(' + ((aton(b
.value
) - aton(a
.value
)) + 1) + ')');
1274 /* TODO: same validation for builds with VLAN-GUI enabled */
1276 ferror
.clear('_modem_ipaddr');
1277 a
= E('_modem_ipaddr');
1278 b
= E('_lan_ipaddr');
1279 c
= E('_lan_netmask');
1280 if ( vis
['_modem_ipaddr'] && !(a
._error_msg
|| b
._error_msg
|| c
._error_msg
) && a
.value
!= "0.0.0.0" ) {
1282 if ( (aton(a
.value
) & c
) == (aton(b
.value
) & c
) ) {
1283 ferror
.set('_modem_ipaddr', 'Modem IP address may not be within your local address space.', quiet
);
1292 function earlyInit()
1294 verifyFields(null, 1);
1300 if (lg
.isEditing()) return;
1301 lg
.resetNewEditor();
1306 var u
, uidx
, wmode
, sm2
, wradio
;
1308 if (!verifyFields(null, false)) return;
1310 var fom
= E('_fom');
1312 fom
.wan_mtu
.value
= fom
.f_wan_mtu
.value
;
1313 fom
.wan_mtu
.disabled
= fom
.f_wan_mtu
.disabled
;
1316 fom
.lan_proto
.value
= fom
.f_dhcpd_enable
.checked
? 'dhcp' : 'static';
1319 for (uidx
= 0; uidx
< wl_ifaces
.length
; ++uidx
) {
1320 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1321 if (wl_sunit(uidx
)<0) {
1323 wmode
= E('_f_wl'+u
+'_mode').value
;
1324 sm2
= E('_wl'+u
+'_security_mode').value
;
1325 wradio
= E('_f_wl'+u
+'_radio').checked
;
1327 E('_wl'+u
+'_nband').value
= selectedBand(uidx
);
1329 if (wmode
== 'apwds') E('_wl'+u
+'_mode').value
= 'ap';
1330 else E('_wl'+u
+'_mode').value
= wmode
;
1332 if (wmode
== 'wet') {
1333 fom
.wan_proto
.value
= 'disabled';
1334 fom
.wan_proto
.disabled
= 0;
1336 fom
.lan_proto
.value
= 'static';
1340 // TODO - what's required ? integrate with tomatogrid?
1346 for (i
= 0; i
< 10; ++i
) a
.push(E('_f_wl'+u
+'_wds_' + i
).value
);
1347 E('_wl'+u
+'_wds').value
= joinAddr(a
);
1349 if (wmode
.indexOf('wds') != -1) {
1350 E('_wl'+u
+'_wds_enable').value
= 1;
1351 E('_wl'+u
+'_lazywds').value
= E('_f_wl'+u
+'_lazywds').value
;
1352 if (E('_wl'+u
+'_lazywds').value
== 1) E('_wl'+u
+'_wds').value
= '';
1355 E('_wl'+u
+'_wds_enable').value
= 0;
1356 E('_wl'+u
+'_wds').value
= '';
1357 E('_wl'+u
+'_lazywds').value
= 0;
1360 E('_wl'+u
+'_radio').value
= wradio
? 1 : 0;
1361 E('_wl'+u
+'_auth').value
= eval('nvram.wl'+u
+'_auth');
1363 e
= E('_wl'+u
+'_akm');
1373 if (sm2
.indexOf('personal') != -1) {
1374 if (sm2
.indexOf('wpa2_') == -1) c
.push('psk');
1375 if (sm2
.indexOf('wpa_') == -1) c
.push('psk2');
1378 if (sm2
.indexOf('wpa2_') == -1) c
.push('wpa');
1379 if (sm2
.indexOf('wpa_') == -1) c
.push('wpa2');
1385 E('_wl'+u
+'_auth_mode').value
= (sm2
== 'radius') ? 'radius' : 'none';
1386 E('_wl'+u
+'_wep').value
= ((sm2
== 'radius') || (sm2
== 'wep')) ? 'enabled': 'disabled';
1388 if (sm2
.indexOf('wpa') != -1) E('_wl'+u
+'_auth').value
= 0;
1390 E('_wl'+u
+'_nreqd').value
= 0;
1391 E('_wl'+u
+'_gmode').value
= 1;
1392 E('_wl'+u
+'_nmode').value
= 0;
1393 E('_wl'+u
+'_nmcsidx').value
= -2; // Legacy Rate
1394 E('_wl'+u
+'_nbw').value
= 0;
1395 switch (E('_wl'+u
+'_net_mode').value
) {
1397 E('_wl'+u
+'_gmode').value
= 0;
1400 E('_wl'+u
+'_gmode').value
= 4;
1405 E('_wl'+u
+'_nmcsidx').value
= -1; // Auto
1408 if (selectedBand(uidx
) == '1') { // 5 GHz
1409 E('_wl'+u
+'_nmode').value
= -1;
1410 E('_wl'+u
+'_nmcsidx').value
= -1;
1412 E('_wl'+u
+'_nmode').value
= 1;
1413 E('_wl'+u
+'_nmcsidx').value
= 32;
1415 E('_wl'+u
+'_nreqd').value
= 1;
1418 E('_wl'+u
+'_nmode').value
= -1;
1419 E('_wl'+u
+'_nmcsidx').value
= -1;
1423 E('_wl'+u
+'_nctrlsb').value
= eval('nvram.wl'+u
+'_nctrlsb');
1424 if (E('_wl'+u
+'_nmode').value
!= 0) {
1425 E('_wl'+u
+'_nctrlsb').value
= E('_f_wl'+u
+'_nctrlsb').value
;
1426 E('_wl'+u
+'_nbw').value
= (E('_wl'+u
+'_nbw_cap').value
== 0) ? 20 : 40;
1429 E('_wl'+u
+'_closed').value
= E('_f_wl'+u
+'_bcast').checked
? 0 : 1;
1431 a
= fields
.radio
.selected(eval('fom.f_wl'+u
+'_wepidx'));
1432 if (a
) E('_wl'+u
+'_key').value
= a
.value
;
1436 fom
.wan_islan
.value
= fom
.f_wan_islan
.checked
? 1 : 0;
1437 fom
.pptp_dhcp
.value
= fom
.f_pptp_dhcp
.checked
? 1 : 0;
1439 fom
.wan_dns
.value
= joinAddr([fom
.f_dns_1
.value
, fom
.f_dns_2
.value
, fom
.f_dns_3
.value
]);
1442 // initialize/wipe out relevant fields
1443 for (var i
= 0 ; i
<= MAX_BRIDGE_ID
; i
++) {
1444 var j
= (i
== 0) ? '' : i
.toString();
1445 fom
['lan' + j
+ '_ifname'].value
= '';
1446 fom
['lan' + j
+ '_ipaddr'].value
= '';
1447 fom
['lan' + j
+ '_netmask'].value
= '';
1448 fom
['lan' + j
+ '_proto'].value
= '';
1449 fom
['lan' + j
+ '_stp'].value
= '';
1450 fom
['dhcp' + j
+ '_start'].value
= '';
1451 fom
['dhcp' + j
+ '_num'].value
= '';
1452 fom
['dhcp' + j
+ '_lease'].value
= '';
1453 fom
['dhcpd' + j
+ '_startip'].value
= '';
1454 fom
['dhcpd' + j
+ '_endip'].value
= '';
1457 var d
= lg
.getAllData();
1458 for (var i
= 0; i
< d
.length
; ++i
) {
1460 if (lg
.countOverlappingNetworks(d
[i
][2]) > 1) {
1461 var s
= 'Cannot proceed: two or more LAN bridges have conflicting IP addresses or overlapping subnets';
1463 var e
= E('footer-msg');
1465 e
.style
.visibility
= 'visible';
1469 e
.style
.visibility
= 'hidden';
1474 var j
= (parseInt(d
[i
][0]) == 0) ? '' : d
[i
][0].toString();
1475 fom
['lan' + j
+ '_ifname'].value
= 'br' + d
[i
][0];
1476 fom
['lan' + j
+ '_stp'].value
= d
[i
][1];
1477 fom
['lan' + j
+ '_ipaddr'].value
= d
[i
][2];
1478 fom
['lan' + j
+ '_netmask'].value
= d
[i
][3];
1479 fom
['lan' + j
+ '_proto'].value
= (d
[i
][4] != '0') ? 'dhcp' : 'static';
1480 fom
['dhcp' + j
+ '_start'].value
= (d
[i
][4] != '0') ? (d
[i
][5]).split('.').splice(3, 1) : '';
1481 fom
['dhcp' + j
+ '_num'].value
= (d
[i
][4] != '0') ? d
[i
][6].split('.').splice(3, 1) - (d
[i
][5]).split('.').splice(3, 1) + 1 : ''; // presuming /24 subnet (legacy)
1482 fom
['dhcp' + j
+ '_lease'].value
= (d
[i
][4] != '0') ? d
[i
][7] : '';
1483 fom
['dhcpd' + j
+ '_startip'].value
= (d
[i
][4] != '0') ? d
[i
][5] : '';
1484 fom
['dhcpd' + j
+ '_endip'].value
= (d
[i
][4] != '0') ? d
[i
][6] : '';
1487 alert('lan' + j
+ '_ifname=' + fom
['lan' + j
+ '_ifname'].value
+ '\n' +
1488 'lan' + j
+ '_stp=' + fom
['lan' + j
+ '_stp'].value
+ '\n' +
1489 'lan' + j
+ '_ipaddr=' + fom
['lan' + j
+ '_ipaddr'].value
+ '\n' +
1490 'lan' + j
+ '_netmask=' + fom
['lan' + j
+ '_netmask'].value
+ '\n' +
1491 'lan' + j
+ '_proto=' + fom
['lan' + j
+ '_proto'].value
+ '\n' +
1492 'dhcp' + j
+ '_start=' + fom
['dhcp' + j
+ '_start'].value
+ '\n' +
1493 'dhcp' + j
+ '_num=' + fom
['dhcp' + j
+ '_num'].value
+ '\n' +
1494 'dhcp' + j
+ '_lease=' + fom
['dhcp' + j
+ '_lease'].value
+ '\n' +
1495 'dhcpd' + j
+ '_startip=' + fom
['dhcpd' + j
+ '_startip'].value
+ '\n' +
1496 'dhcpd' + j
+ '_endip=' + fom
['dhcpd' + j
+ '_endip'].value
);
1500 var e
= E('footer-msg');
1501 var t
= fixIP(fom
['lan_ipaddr'].value
);
1502 if ((fom
['lan_ifname'].value
!= 'br0') || (fom
['lan_ipaddr'].value
== '0.0.0.0') || (!t
)) {
1503 e
.innerHTML
= 'Bridge br0 must be always defined and have a valid IP address set.';
1504 e
.style
.visibility
= 'visible';
1508 e
.style
.visibility
= 'hidden';
1515 // if ((nvram.lan_ipaddr != fom.lan_ipaddr.value) || (nvram.lan1_ipaddr != fom.lan1_ipaddr.value) ||
1516 // (nvram.lan2_ipaddr != fom.lan2_ipaddr.value) || (nvram.lan3_ipaddr != fom.lan3_ipaddr.value)){
1519 fom
.ppp_mlppp
.value
= fom
.f_ppp_mlppp
.checked
? 1 : 0;
1521 if (nvram
.lan_ipaddr
!= fom
.lan_ipaddr
.value
) {
1522 fom
._moveip
.value
= 1;
1526 form
.submit(fom
, 1);
1532 for (var uidx
= 0; uidx
< wl_ifaces
.length
; ++uidx
) {
1533 // if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1534 if (wl_sunit(uidx
)<0) {
1535 refreshNetModes(uidx
);
1536 refreshChannels(uidx
);
1543 <body onload='init()'
>
1544 <form id='_fom' method='post' action='tomato.cgi'
>
1545 <table id='container' cellspacing=
0>
1546 <tr><td colspan=
2 id='header'
>
1547 <div class='title'
>Tomato
</div>
1548 <div class='version'
>Version <%
version(); %></div>
1550 <tr id='body'
><td id='navi'
><script type='text/javascript'
>navi()</script></td>
1552 <div id='ident'
><%
ident(); %></div>
1556 <input type='hidden' name='_nextpage' value='basic-network.asp'
>
1557 <input type='hidden' name='_nextwait' value='
10'
>
1558 <input type='hidden' name='_service' value='*'
>
1559 <input type='hidden' name='_moveip' value='
0'
>
1561 <input type='hidden' name='wan_mtu'
>
1562 <input type='hidden' name='wan_islan'
>
1563 <input type='hidden' name='pptp_dhcp'
>
1564 <!-- NOVLAN-BEGIN -->
1565 <input type='hidden' name='lan_proto'
>
1567 <input type='hidden' name='wan_dns'
>
1568 <input type='hidden' name='ppp_mlppp'
>
1571 <script type='text/javascript'
>
1573 for (var i
= 0 ; i
<= MAX_BRIDGE_ID
; i
++) {
1574 var j
= (i
== 0) ? '' : i
.toString();
1575 W('<input type=\'hidden\' id=\'lan' + j
+ '_ifname\' name=\'lan' + j
+ '_ifname\'>');
1576 W('<input type=\'hidden\' id=\'lan' + j
+ '_ipaddr\' name=\'lan' + j
+ '_ipaddr\'>');
1577 W('<input type=\'hidden\' id=\'lan' + j
+ '_netmask\' name=\'lan' + j
+ '_netmask\'>');
1578 W('<input type=\'hidden\' id=\'lan' + j
+ '_proto\' name=\'lan' + j
+ '_proto\'>');
1579 W('<input type=\'hidden\' id=\'lan' + j
+ '_stp\' name=\'lan' + j
+ '_stp\'>');
1580 W('<input type=\'hidden\' id=\'dhcp' + j
+ '_start\' name=\'dhcp' + j
+ '_start\'>');
1581 W('<input type=\'hidden\' id=\'dhcp' + j
+ '_num\' name=\'dhcp' + j
+ '_num\'>');
1582 W('<input type=\'hidden\' id=\'dhcp' + j
+ '_lease\' name=\'dhcp' + j
+ '_lease\'>');
1583 W('<input type=\'hidden\' id=\'dhcpd' + j
+ '_startip\' name=\'dhcpd' + j
+ '_startip\'>');
1584 W('<input type=\'hidden\' id=\'dhcpd' + j
+ '_endip\' name=\'dhcpd' + j
+ '_endip\'>');
1589 <div class='section-title'
>WAN / Internet
</div>
1590 <div class='section'
>
1591 <script type='text/javascript'
>
1592 createFieldTable('', [
1593 { title
: 'Type', name
: 'wan_proto', type
: 'select', options
: [['dhcp','DHCP'],['pppoe','PPPoE'],['static','Static'],['pptp','PPTP'],['l2tp','L2TP'],['disabled','Disabled']],
1594 value
: nvram
.wan_proto
},
1595 { title
: 'Username', name
: 'ppp_username', type
: 'text', maxlen
: 60, size
: 64, value
: nvram
.ppp_username
},
1596 { title
: 'Password', name
: 'ppp_passwd', type
: 'password', maxlen
: 60, size
: 64, peekaboo
: 1, value
: nvram
.ppp_passwd
},
1597 { title
: 'Service Name', name
: 'ppp_service', type
: 'text', maxlen
: 50, size
: 64, value
: nvram
.ppp_service
},
1598 { title
: 'L2TP Server', name
: 'l2tp_server_ip', type
: 'text', maxlen
: 128, size
: 64, value
: nvram
.l2tp_server_ip
},
1599 { title
: 'Use DHCP', name
: 'f_pptp_dhcp', type
: 'checkbox', value
: (nvram
.pptp_dhcp
== 1) },
1600 { title
: 'IP Address', name
: 'wan_ipaddr', type
: 'text', maxlen
: 15, size
: 17, value
: nvram
.wan_ipaddr
},
1601 { title
: 'Subnet Mask', name
: 'wan_netmask', type
: 'text', maxlen
: 15, size
: 17, value
: nvram
.wan_netmask
},
1602 { title
: 'Gateway', name
: 'wan_gateway', type
: 'text', maxlen
: 15, size
: 17, value
: nvram
.wan_gateway
},
1603 { title
: 'PPTP Gateway', name
: 'pptp_server_ip', type
: 'text', maxlen
: 128, size
: 64, value
: nvram
.pptp_server_ip
},
1604 { title
: 'Options', name
: 'ppp_custom', type
: 'text', maxlen
: 256, size
: 64, value
: nvram
.ppp_custom
},
1605 { title
: 'Connect Mode', name
: 'ppp_demand', type
: 'select', options
: [['1', 'Connect On Demand'],['0', 'Keep Alive']],
1606 value
: nvram
.ppp_demand
},
1607 { title
: 'Max Idle Time', indent
: 2, name
: 'ppp_idletime', type
: 'text', maxlen
: 5, size
: 7, suffix
: ' <i>(minutes)</i>',
1608 value
: nvram
.ppp_idletime
},
1609 { title
: 'Check Interval', indent
: 2, name
: 'ppp_redialperiod', type
: 'text', maxlen
: 5, size
: 7, suffix
: ' <i>(seconds)</i>',
1610 value
: nvram
.ppp_redialperiod
},
1611 { title
: 'MTU', multi
: [
1612 { name
: 'mtu_enable', type
: 'select', options
: [['0', 'Default'],['1','Manual']], value
: nvram
.mtu_enable
},
1613 { name
: 'f_wan_mtu', type
: 'text', maxlen
: 4, size
: 6, value
: nvram
.wan_mtu
} ] },
1614 { title
: 'Single Line MLPPP', name
: 'f_ppp_mlppp', type
: 'checkbox', value
: (nvram
.ppp_mlppp
== 1) },
1615 { title
: 'Route Modem IP', name
: 'modem_ipaddr', type
: 'text', maxlen
: 15, size
: 17, suffix
: ' <i>(must be in different subnet to router, 0.0.0.0 to disable)</i>', value
: nvram
.modem_ipaddr
},
1618 { title
: 'Use WAN port for LAN', name
: 'f_wan_islan', type
: 'checkbox', value
: (nvram
.wan_islan
== 1) }
1621 { title
: 'Bridge WAN port to primary LAN (br0)', name
: 'f_wan_islan', type
: 'checkbox', value
: (nvram
.wan_islan
== 1) }
1627 <div class='section-title'
>LAN
</div>
1628 <div class='section'
>
1630 <table class='tomato-grid' cellspacing=
1 id='lan-grid'
></table>
1632 <script type='text/javascript'
>lg
.setup();</script>
1635 <script type='text/javascript'
>
1636 dns
= nvram
.wan_dns
.split(/\s+/);
1638 //ipp = nvram.lan_ipaddr.split('.').splice(0, 3).join('.');
1640 createFieldTable('', [
1642 { title
: 'Router IP Address', name
: 'lan_ipaddr', type
: 'text', maxlen
: 15, size
: 17, value
: nvram
.lan_ipaddr
},
1643 { title
: 'Subnet Mask', name
: 'lan_netmask', type
: 'text', maxlen
: 15, size
: 17, value
: nvram
.lan_netmask
},
1645 { title
: 'Default Gateway', name
: 'lan_gateway', type
: 'text', maxlen
: 15, size
: 17, value
: nvram
.lan_gateway
},
1646 { 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' },
1647 { title
: '', name
: 'f_dns_2', type
: 'text', maxlen
: 21, size
: 25, value
: dns
[1] || '0.0.0.0' },
1648 { title
: '', name
: 'f_dns_3', type
: 'text', maxlen
: 21, size
: 25, value
: dns
[2] || '0.0.0.0' },
1650 { title
: 'DHCP Server', name
: 'f_dhcpd_enable', type
: 'checkbox', value
: (nvram
.lan_proto
== 'dhcp') },
1651 { title
: 'IP Address Range', indent
: 2, multi
: [
1652 { name
: 'dhcpd_startip', type
: 'text', maxlen
: 15, size
: 17, value
: nvram
.dhcpd_startip
, suffix
: ' - ' },
1653 { name
: 'dhcpd_endip', type
: 'text', maxlen
: 15, size
: 17, value
: nvram
.dhcpd_endip
, suffix
: ' <i id="dhcp_count"></i>' }
1656 { title
: 'Lease Time', indent
: 2, name
: 'dhcp_lease', type
: 'text', maxlen
: 6, size
: 8, suffix
: ' <i>(minutes)</i>',
1657 value
: (nvram
.dhcp_lease
> 0) ? nvram
.dhcp_lease
: 1440 },
1658 { title
: 'WINS', indent
: 2, name
: 'wan_wins', type
: 'text', maxlen
: 15, size
: 17, value
: nvram
.wan_wins
}
1661 { title
: 'WINS <i>(for DHCP)</i>', name
: 'wan_wins', type
: 'text', maxlen
: 15, size
: 17, value
: nvram
.wan_wins
}
1667 <script type='text/javascript'
>
1669 for (var uidx
= 0; uidx
< wl_ifaces
.length
; ++uidx
) {
1670 //if(wl_ifaces[uidx][0].indexOf('.') < 0) {
1671 if (wl_sunit(uidx
)<0) {
1672 var u
= wl_unit(uidx
);
1674 W('<input type=\'hidden\' id=\'_wl'+u
+'_mode\' name=\'wl'+u
+'_mode\'>');
1675 W('<input type=\'hidden\' id=\'_wl'+u
+'_nband\' name=\'wl'+u
+'_nband\'>');
1676 W('<input type=\'hidden\' id=\'_wl'+u
+'_wds_enable\' name=\'wl'+u
+'_wds_enable\'>');
1677 W('<input type=\'hidden\' id=\'_wl'+u
+'_wds\' name=\'wl'+u
+'_wds\'>');
1678 W('<input type=\'hidden\' id=\'_wl'+u
+'_radio\' name=\'wl'+u
+'_radio\'>');
1679 W('<input type=\'hidden\' id=\'_wl'+u
+'_closed\' name=\'wl'+u
+'_closed\'>');
1680 W('<input type=\'hidden\' id=\'_wl'+u
+'_key\' name=\'wl'+u
+'_key\'>');
1681 W('<input type=\'hidden\' id=\'_wl'+u
+'_gmode\' name=\'wl'+u
+'_gmode\'>');
1682 W('<input type=\'hidden\' id=\'_wl'+u
+'_akm\' name=\'wl'+u
+'_akm\'>');
1683 W('<input type=\'hidden\' id=\'_wl'+u
+'_auth\' name=\'wl'+u
+'_auth\'>');
1684 W('<input type=\'hidden\' id=\'_wl'+u
+'_auth_mode\' name=\'wl'+u
+'_auth_mode\'>');
1685 W('<input type=\'hidden\' id=\'_wl'+u
+'_wep\' name=\'wl'+u
+'_wep\'>');
1686 W('<input type=\'hidden\' id=\'_wl'+u
+'_lazywds\' name=\'wl'+u
+'_lazywds\'>');
1687 W('<input type=\'hidden\' id=\'_wl'+u
+'_nmode\' name=\'wl'+u
+'_nmode\'>');
1688 W('<input type=\'hidden\' id=\'_wl'+u
+'_nmcsidx\' name=\'wl'+u
+'_nmcsidx\'>');
1689 W('<input type=\'hidden\' id=\'_wl'+u
+'_nreqd\' name=\'wl'+u
+'_nreqd\'>');
1690 W('<input type=\'hidden\' id=\'_wl'+u
+'_nctrlsb\' name=\'wl'+u
+'_nctrlsb\'>');
1691 W('<input type=\'hidden\' id=\'_wl'+u
+'_nbw\' name=\'wl'+u
+'_nbw\'>');
1693 W('<div class=\'section-title\'>Wireless');
1694 // if (wl_ifaces.length > 1)
1695 W(' (' + wl_display_ifname(uidx
) + ')');
1698 W('<div class=\'section\'>');
1701 { title
: 'Enable Wireless', name
: 'f_wl'+u
+'_radio', type
: 'checkbox',
1702 value
: (eval('nvram.wl'+u
+'_radio') == '1') && (eval('nvram.wl'+u
+'_net_mode') != 'disabled') },
1703 { title
: 'MAC Address', text
: '<a href="advanced-mac.asp">' + eval('nvram.wl'+u
+'_hwaddr') + '</a>' },
1704 { title
: 'Wireless Mode', name
: 'f_wl'+u
+'_mode', type
: 'select',
1705 options
: [['ap', 'Access Point'],['apwds', 'Access Point + WDS'],['sta', 'Wireless Client'],['wet', 'Wireless Ethernet Bridge'],['wds', 'WDS']],
1706 value
: ((eval('nvram.wl'+u
+'_mode') == 'ap') && (eval('nvram.wl'+u
+'_wds_enable') == '1')) ? 'apwds' : eval('nvram.wl'+u
+'_mode') },
1707 { title
: 'Radio Band', name
: 'f_wl'+u
+'_nband', type
: 'select', options
: bands
[uidx
],
1708 value
: eval('nvram.wl'+u
+'_nband') || '0' == '0' ? bands
[uidx
][0][0] : eval('nvram.wl'+u
+'_nband') },
1709 { title
: 'Wireless Network Mode', name
: 'wl'+u
+'_net_mode', type
: 'select',
1710 value
: (eval('nvram.wl'+u
+'_net_mode') == 'disabled') ? 'mixed' : eval('nvram.wl'+u
+'_net_mode'),
1711 options
: [], prefix
: '<span id="__wl'+u
+'_net_mode">', suffix
: '</span>' },
1712 { title
: 'SSID', name
: 'wl'+u
+'_ssid', type
: 'text', maxlen
: 32, size
: 34, value
: eval('nvram.wl'+u
+'_ssid') },
1713 { title
: 'Broadcast', indent
: 2, name
: 'f_wl'+u
+'_bcast', type
: 'checkbox', value
: (eval('nvram.wl'+u
+'_closed') == '0') },
1714 { title
: 'Channel', name
: 'wl'+u
+'_channel', type
: 'select', options
: ghz
[uidx
], prefix
: '<span id="__wl'+u
+'_channel">', suffix
: '</span> <input type="button" id="_f_wl'+u
+'_scan" value="Scan" onclick="scanButton('+u
+')"> <img src="spin.gif" id="spin'+u
+'">',
1715 value
: eval('nvram.wl'+u
+'_channel') },
1716 { title
: 'Channel Width', name
: 'wl'+u
+'_nbw_cap', type
: 'select', options
: [['0','20 MHz'],['1','40 MHz']],
1717 value
: eval('nvram.wl'+u
+'_nbw_cap') },
1718 { title
: 'Control Sideband', name
: 'f_wl'+u
+'_nctrlsb', type
: 'select', options
: [['lower','Lower'],['upper','Upper']],
1719 value
: eval('nvram.wl'+u
+'_nctrlsb') == 'none' ? 'lower' : eval('nvram.wl'+u
+'_nctrlsb') },
1721 { title
: 'Security', name
: 'wl'+u
+'_security_mode', type
: 'select',
1722 options
: [['disabled','Disabled'],['wep','WEP'],['wpa_personal','WPA Personal'],['wpa_enterprise','WPA Enterprise'],['wpa2_personal','WPA2 Personal'],['wpa2_enterprise','WPA2 Enterprise'],['wpaX_personal','WPA / WPA2 Personal'],['wpaX_enterprise','WPA / WPA2 Enterprise'],['radius','Radius']],
1723 value
: eval('nvram.wl'+u
+'_security_mode') },
1724 { title
: 'Encryption', indent
: 2, name
: 'wl'+u
+'_crypto', type
: 'select',
1725 options
: [['tkip','TKIP'],['aes','AES'],['tkip+aes','TKIP / AES']], value
: eval('nvram.wl'+u
+'_crypto') },
1726 { title
: 'Shared Key', indent
: 2, name
: 'wl'+u
+'_wpa_psk', type
: 'password', maxlen
: 64, size
: 66, peekaboo
: 1,
1727 suffix
: ' <input type="button" id="_f_wl'+u
+'_psk_random1" value="Random" onclick="random_psk(\'_wl'+u
+'_wpa_psk\')">',
1728 value
: eval('nvram.wl'+u
+'_wpa_psk') },
1729 { title
: 'Shared Key', indent
: 2, name
: 'wl'+u
+'_radius_key', type
: 'password', maxlen
: 80, size
: 32, peekaboo
: 1,
1730 suffix
: ' <input type="button" id="_f_wl'+u
+'_psk_random2" value="Random" onclick="random_psk(\'_wl'+u
+'_radius_key\')">',
1731 value
: eval('nvram.wl'+u
+'_radius_key') },
1732 { title
: 'Group Key Renewal', indent
: 2, name
: 'wl'+u
+'_wpa_gtk_rekey', type
: 'text', maxlen
: 4, size
: 6, suffix
: ' <i>(seconds)</i>',
1733 value
: eval('nvram.wl'+u
+'_wpa_gtk_rekey') },
1734 { title
: 'Radius Server', indent
: 2, multi
: [
1735 { name
: 'wl'+u
+'_radius_ipaddr', type
: 'text', maxlen
: 15, size
: 17, value
: eval('nvram.wl'+u
+'_radius_ipaddr') },
1736 { name
: 'wl'+u
+'_radius_port', type
: 'text', maxlen
: 5, size
: 7, prefix
: ' : ', value
: eval('nvram.wl'+u
+'_radius_port') } ] },
1737 { title
: 'Encryption', indent
: 2, name
: 'wl'+u
+'_wep_bit', type
: 'select', options
: [['128','128-bits'],['64','64-bits']],
1738 value
: eval('nvram.wl'+u
+'_wep_bit') },
1739 { title
: 'Passphrase', indent
: 2, name
: 'wl'+u
+'_passphrase', type
: 'text', maxlen
: 16, size
: 20,
1740 suffix
: ' <input type="button" id="_f_wl'+u
+'_wep_gen" value="Generate" onclick="generate_wep('+u
+')"> <input type="button" id="_f_wl'+u
+'_wep_random" value="Random" onclick="random_wep('+u
+')">',
1741 value
: eval('nvram.wl'+u
+'_passphrase') }
1744 for (i
= 1; i
<= 4; ++i
) {
1746 { title
: ('Key ' + i
), indent
: 2, name
: ('wl'+u
+'_key' + i
), type
: 'text', maxlen
: 26, size
: 34,
1747 suffix
: '<input type="radio" onchange="verifyFields(this,1)" onclick="verifyFields(this,1)" name="f_wl'+u
+'_wepidx" id="_f_wl'+u
+'_wepidx_' + i
+ '" value="' + i
+ '"' + ((eval('nvram.wl'+u
+'_key') == i
) ? ' checked>' : '>'),
1748 value
: nvram
['wl'+u
+'_key' + i
] });
1752 { title
: 'WDS', name
: 'f_wl'+u
+'_lazywds', type
: 'select',
1753 options
: [['0','Link With...'],['1','Automatic']], value
: nvram
['wl'+u
+'_lazywds'] } );
1754 wds
= eval('nvram.wl'+u
+'_wds').split(/\s+/);
1755 for (i
= 0; i
< 10; i
+= 2) {
1756 f
.push({ title
: (i
? '' : 'MAC Address'), indent
: 2, multi
: [
1757 { name
: 'f_wl'+u
+'_wds_' + i
, type
: 'text', maxlen
: 17, size
: 20, value
: wds
[i
] || '00:00:00:00:00:00' },
1758 { name
: 'f_wl'+u
+'_wds_' + (i
+ 1), type
: 'text', maxlen
: 17, size
: 20, value
: wds
[i
+ 1] || '00:00:00:00:00:00' } ] } );
1761 createFieldTable('', f
);
1771 <tr><td id='footer' colspan=
2>
1772 <span id='footer-msg'
></span>
1773 <input type='button' value='Save' id='save-button' onclick='save()'
>
1774 <input type='button' value='Cancel' id='cancel-button' onclick='reloadPage();'
>
1778 <script type='text/javascript'
>earlyInit()</script>
1779 <div style='height:
100px'
></div>