1 <!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML
4.0//EN'
>
4 Copyright (C) 2006-2008 Jonathan Zarate
5 http://www.polarcloud.com/tomato/
7 Copyright (C) 2011 Deon 'PrinceAMD' Thomas
8 rate limit & connection limit from Conanxu,
9 adapted by Victek, Shibby, PrinceAMD, Phykris
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(); %>] IP/Range BW Limiter
</title>
19 <link rel='stylesheet' type='text/css' href='tomato.css'
>
20 <link rel='stylesheet' type='text/css' href='color.css'
>
21 <script type='text/javascript' src='tomato.js'
></script>
24 <style type='text/css'
>
42 <script type='text/javascript' src='debug.js'
></script>
44 <script type='text/javascript'
>
45 // <% nvram("new_qoslimit_enable,qos_ibw,qos_obw,new_qoslimit_rules,lan_ipaddr,lan_netmask,qosl_enable,qosl_dlr,qosl_dlc,qosl_ulr,qosl_ulc,qosl_udp,qosl_tcp,limit_br0_prio,limit_br1_enable,limit_br1_dlc,limit_br1_dlr,limit_br1_ulc,limit_br1_ulr,limit_br1_prio,limit_br2_enable,limit_br2_dlc,limit_br2_dlr,limit_br2_ulc,limit_br2_ulr,limit_br2_prio,limit_br3_enable,limit_br3_dlc,limit_br3_dlr,limit_br3_ulc,limit_br3_ulr,limit_br3_prio"); %>
47 var class_prio
= [['0','Highest'],['1','High'],['2','Normal'],['3','Low'],['4','Lowest']];
48 var class_tcp
= [['0','nolimit']];
49 var class_udp
= [['0','nolimit']];
50 for (var i
= 1; i
<= 100; ++i
) {
51 class_tcp
.push([i
*10, i
*10+'']);
52 class_udp
.push([i
, i
+ '/s']);
54 var qosg
= new TomatoGrid();
56 qosg
.setup = function() {
57 this.init('qosg-grid', '', 80, [
58 { type
: 'text', maxlen
: 31 },
59 { type
: 'text', maxlen
: 6 },
60 { type
: 'text', maxlen
: 6 },
61 { type
: 'text', maxlen
: 6 },
62 { type
: 'text', maxlen
: 6 },
63 { type
: 'select', options
: class_prio
},
64 { type
: 'select', options
: class_tcp
},
65 { type
: 'select', options
: class_udp
}]);
66 this.headerSet(['IP | IP Range | MAC Address', 'DLRate', 'DLCeil', 'ULRate', 'ULCeil', 'Priority', 'TCP Limit', 'UDP Limit']);
67 var qoslimitrules
= nvram
.new_qoslimit_rules
.split('>');
68 for (var i
= 0; i
< qoslimitrules
.length
; ++i
) {
69 var t
= qoslimitrules
[i
].split('<');
70 if (t
.length
== 8) this.insertData(-1, t
);
73 this.resetNewEditor();
76 qosg
.dataToView = function(data
) {
77 return [data
[0],data
[1]+'kbps',data
[2]+'kbps',data
[3]+'kbps',data
[4]+'kbps',class_prio
[data
[5]*1][1],class_tcp
[data
[6]*1/10][1],class_udp
[data
[7]*1][1]];
80 qosg
.resetNewEditor = function() {
83 var f
= fields
.getAll(this.newEditor
);
85 if ((c
= cookie
.get('addbwlimit')) != null) {
86 cookie
.set('addbwlimit', '', 0);
94 f
[5].selectedIndex
= '2';
95 f
[6].selectedIndex
= '0';
96 f
[7].selectedIndex
= '0';
106 f
[5].selectedIndex
= '2';
107 f
[6].selectedIndex
= '0';
108 f
[7].selectedIndex
= '0';
112 qosg
.exist = function(f
, v
)
114 var data
= this.getAllData();
115 for (var i
= 0; i
< data
.length
; ++i
) {
116 if (data
[i
][f
] == v
) return true;
121 qosg
.existID = function(id
)
123 return this.exist(0, id
);
126 qosg
.existIP = function(ip
)
128 if (ip
== "0.0.0.0") return true;
129 return this.exist(1, ip
);
132 qosg
.checkRate = function(rate
)
134 var s
= parseInt(rate
, 10);
135 if( isNaN(s
) || s
<= 0 || a
>= 100000 ) return true;
139 qosg
.checkRateCeil = function(rate
, ceil
)
141 var r
= parseInt(rate
, 10);
142 var c
= parseInt(ceil
, 10);
143 if( r
> c
) return true;
147 qosg
.verifyFields = function(row
, quiet
)
150 var f
= fields
.getAll(row
);
154 if (v_ip(f[0], quiet)) {
155 if(this.existIP(f[0].value)) {
156 ferror.set(f[0], 'duplicate IP address', quiet);
161 if(v_macip(f
[0], quiet
, 0, nvram
.lan_ipaddr
, nvram
.lan_netmask
)) {
162 if(this.existIP(f
[0].value
)) {
163 ferror
.set(f
[0], 'duplicate IP or MAC address', quiet
);
168 if( this.checkRate(f
[1].value
)) {
169 ferror
.set(f
[1], 'DLRate must between 1 and 99999', quiet
);
173 if( this.checkRate(f
[2].value
)) {
174 ferror
.set(f
[2], 'DLCeil must between 1 and 99999', quiet
);
178 if( this.checkRateCeil(f
[1].value
, f
[2].value
)) {
179 ferror
.set(f
[2], 'DLCeil must be greater than DLRate', quiet
);
183 if( this.checkRate(f
[3].value
)) {
184 ferror
.set(f
[3], 'ULRate must between 1 and 99999', quiet
);
188 if( this.checkRate(f
[4].value
)) {
189 ferror
.set(f
[4], 'ULCeil must between 1 and 99999', quiet
);
193 if( this.checkRateCeil(f
[3].value
, f
[4].value
)) {
194 ferror
.set(f
[4], 'ULCeil must be greater than ULRate', quiet
);
201 function verifyFields(focused
, quiet
)
203 var a
= !E('_f_new_qoslimit_enable').checked
;
204 var b
= !E('_f_qosl_enable').checked
;
205 var b1
= !E('_f_limit_br1_enable').checked
;
206 var b2
= !E('_f_limit_br2_enable').checked
;
207 var b3
= !E('_f_limit_br3_enable').checked
;
209 E('_qos_ibw').disabled
= a
;
210 E('_qos_obw').disabled
= a
;
211 E('_f_qosl_enable').disabled
= a
;
212 E('_f_limit_br1_enable').disabled
= a
;
213 E('_f_limit_br2_enable').disabled
= a
;
214 E('_f_limit_br3_enable').disabled
= a
;
216 E('_qosl_dlr').disabled
= b
|| a
;
217 E('_qosl_dlc').disabled
= b
|| a
;
218 E('_qosl_ulr').disabled
= b
|| a
;
219 E('_qosl_ulc').disabled
= b
|| a
;
220 E('_qosl_tcp').disabled
= b
|| a
;
221 E('_qosl_udp').disabled
= b
|| a
;
222 E('_limit_br0_prio').disabled
= b
|| a
;
224 elem
.display(PR('_qos_ibw'), PR('_qos_obw'), !a
);
225 elem
.display(PR('_qosl_dlr'), PR('_qosl_dlc'), PR('_qosl_ulr'), PR('_qosl_ulc'), PR('_qosl_tcp'), PR('_qosl_udp'), PR('_limit_br0_prio'), !a
&& !b
);
227 E('_limit_br1_dlr').disabled
= b1
|| a
;
228 E('_limit_br1_dlc').disabled
= b1
|| a
;
229 E('_limit_br1_ulr').disabled
= b1
|| a
;
230 E('_limit_br1_ulc').disabled
= b1
|| a
;
231 E('_limit_br1_prio').disabled
= b1
|| a
;
232 elem
.display(PR('_limit_br1_dlr'), PR('_limit_br1_dlc'), PR('_limit_br1_ulr'), PR('_limit_br1_ulc'), PR('_limit_br1_prio'), !a
&& !b1
);
234 E('_limit_br2_dlr').disabled
= b2
|| a
;
235 E('_limit_br2_dlc').disabled
= b2
|| a
;
236 E('_limit_br2_ulr').disabled
= b2
|| a
;
237 E('_limit_br2_ulc').disabled
= b2
|| a
;
238 E('_limit_br2_prio').disabled
= b2
|| a
;
239 elem
.display(PR('_limit_br2_dlr'), PR('_limit_br2_dlc'), PR('_limit_br2_ulr'), PR('_limit_br2_ulc'), PR('_limit_br2_prio'), !a
&& !b2
);
241 E('_limit_br3_dlr').disabled
= b3
|| a
;
242 E('_limit_br3_dlc').disabled
= b3
|| a
;
243 E('_limit_br3_ulr').disabled
= b3
|| a
;
244 E('_limit_br3_ulc').disabled
= b3
|| a
;
245 E('_limit_br3_prio').disabled
= b3
|| a
;
246 elem
.display(PR('_limit_br3_dlr'), PR('_limit_br3_dlc'), PR('_limit_br3_ulr'), PR('_limit_br3_ulc'), PR('_limit_br3_prio'), !a
&& !b3
);
253 if (qosg
.isEditing()) return;
255 var data
= qosg
.getAllData();
256 var qoslimitrules
= '';
259 if (data
.length
!= 0) qoslimitrules
+= data
[0].join('<');
260 for (i
= 1; i
< data
.length
; ++i
) {
261 qoslimitrules
+= '>' + data
[i
].join('<');
265 fom
.new_qoslimit_enable
.value
= E('_f_new_qoslimit_enable').checked
? 1 : 0;
266 fom
.qosl_enable
.value
= E('_f_qosl_enable').checked
? 1 : 0;
267 fom
.limit_br1_enable
.value
= E('_f_limit_br1_enable').checked
? 1 : 0;
268 fom
.limit_br2_enable
.value
= E('_f_limit_br2_enable').checked
? 1 : 0;
269 fom
.limit_br3_enable
.value
= E('_f_limit_br3_enable').checked
? 1 : 0;
270 fom
.new_qoslimit_rules
.value
= qoslimitrules
;
280 <body onload='init()'
>
281 <form id='_fom' method='post' action='tomato.cgi'
>
282 <table id='container' cellspacing=
0>
283 <tr><td colspan=
2 id='header'
>
284 <div class='title'
>Tomato
</div>
285 <div class='version'
>Version <%
version(); %></div>
287 <tr id='body'
><td id='navi'
><script type='text/javascript'
>navi()</script></td>
289 <div id='ident'
><%
ident(); %></div>
293 <input type='hidden' name='_nextpage' value='bwlimit.asp'
>
294 <input type='hidden' name='_nextwait' value='
10'
>
295 <input type='hidden' name='_service' value='qoslimit-restart'
>
297 <input type='hidden' name='new_qoslimit_enable'
>
298 <input type='hidden' name='new_qoslimit_rules'
>
299 <input type='hidden' name='qosl_enable'
>
300 <input type='hidden' name='limit_br1_enable'
>
301 <input type='hidden' name='limit_br2_enable'
>
302 <input type='hidden' name='limit_br3_enable'
>
307 <div class='section-title'
>Bandwidth Limiter for LAN (br0)
</div>
308 <div class='section'
>
309 <script type='text/javascript'
>
310 createFieldTable('', [
311 { title
: 'Enable Limiter', name
: 'f_new_qoslimit_enable', type
: 'checkbox', value
: nvram
.new_qoslimit_enable
!= '0' },
312 { title
: 'Max Available Download <br><small>(same as used in QoS)</small>', indent
: 2, name
: 'qos_ibw', type
: 'text', maxlen
: 6, size
: 8, suffix
: ' <small>kbit/s</small>', value
: nvram
.qos_ibw
},
313 { title
: 'Max Available Upload <br><small>(same as used in QoS)</small>', indent
: 2, name
: 'qos_obw', type
: 'text', maxlen
: 6, size
: 8, suffix
: ' <small>kbit/s</small>', value
: nvram
.qos_obw
}
317 <table class='tomato-grid' id='qosg-grid'
></table>
320 <div class='section-title'
>Default Class for unlisted MAC / IPs in LAN (br0)
</div>
321 <div class='section'
>
322 <script type='text/javascript'
>
323 createFieldTable('', [
324 { title
: 'Enable', name
: 'f_qosl_enable', type
: 'checkbox', value
: nvram
.qosl_enable
== '1'},
325 { title
: 'Download rate', indent
: 2, name
: 'qosl_dlr', type
: 'text', maxlen
: 6, size
: 8, suffix
: ' <small>kbit/s</small>', value
: nvram
.qosl_dlr
},
326 { title
: 'Download ceil', indent
: 2, name
: 'qosl_dlc', type
: 'text', maxlen
: 6, size
: 8, suffix
: ' <small>kbit/s</small>', value
: nvram
.qosl_dlc
},
327 { title
: 'Upload rate', indent
: 2, name
: 'qosl_ulr', type
: 'text', maxlen
: 6, size
: 8, suffix
: ' <small>kbit/s</small>', value
: nvram
.qosl_ulr
},
328 { title
: 'Upload ceil', indent
: 2, name
: 'qosl_ulc', type
: 'text', maxlen
: 6, size
: 8, suffix
: ' <small>kbit/s</small>', value
: nvram
.qosl_ulc
},
329 { title
: 'Priority', indent
: 2, name
: 'limit_br0_prio', type
: 'select', options
:
330 [['0','Highest'],['1','High'],['2','Normal'],['3','Low'],['4','Lowest']], value
: nvram
.limit_br0_prio
},
331 { title
: 'TCP Limit', indent
: 2, name
: 'qosl_tcp', type
: 'select', options
:
342 ['1000', '1000']], value
: nvram
.qosl_tcp
},
343 { title
: 'UDP limit', indent
: 2, name
: 'qosl_udp', type
: 'select', options
:
351 ['100', '100/s']], value
: nvram
.qosl_udp
}
356 <li><b>Default Class
</b> - IP / MAC's non included in the list will take the Default Rate/Ceiling setting
357 <li><b>The bandwidth will be shared by all unlisted hosts in br0
</b>
362 <div class='section-title'
>Default Class for LAN1 (br1)
</div>
363 <div class='section'
>
364 <script type='text/javascript'
>
365 createFieldTable('', [
366 { title
: 'Enable', name
: 'f_limit_br1_enable', type
: 'checkbox', value
: nvram
.limit_br1_enable
== '1'},
367 { title
: 'Download rate', indent
: 2, name
: 'limit_br1_dlr', type
: 'text', maxlen
: 6, size
: 8, suffix
: ' <small>kbit/s</small>', value
: nvram
.limit_br1_dlr
},
368 { title
: 'Download ceil', indent
: 2, name
: 'limit_br1_dlc', type
: 'text', maxlen
: 6, size
: 8, suffix
: ' <small>kbit/s</small>', value
: nvram
.limit_br1_dlc
},
369 { title
: 'Upload rate', indent
: 2, name
: 'limit_br1_ulr', type
: 'text', maxlen
: 6, size
: 8, suffix
: ' <small>kbit/s</small>', value
: nvram
.limit_br1_ulr
},
370 { title
: 'Upload ceil', indent
: 2, name
: 'limit_br1_ulc', type
: 'text', maxlen
: 6, size
: 8, suffix
: ' <small>kbit/s</small>', value
: nvram
.limit_br1_ulc
},
371 { title
: 'Priority', indent
: 2, name
: 'limit_br1_prio', type
: 'select', options
:
372 [['0','Highest'],['1','High'],['2','Normal'],['3','Low'],['4','Lowest']], value
: nvram
.limit_br1_prio
}
377 <li><b>The bandwidth will be shared by all hosts in br1.
</b>
382 <div class='section-title'
>Default Class for LAN2 (br2)
</div>
383 <div class='section'
>
384 <script type='text/javascript'
>
385 createFieldTable('', [
386 { title
: 'Enable', name
: 'f_limit_br2_enable', type
: 'checkbox', value
: nvram
.limit_br2_enable
== '1'},
387 { title
: 'Download rate', indent
: 2, name
: 'limit_br2_dlr', type
: 'text', maxlen
: 6, size
: 8, suffix
: ' <small>kbit/s</small>', value
: nvram
.limit_br2_dlr
},
388 { title
: 'Download ceil', indent
: 2, name
: 'limit_br2_dlc', type
: 'text', maxlen
: 6, size
: 8, suffix
: ' <small>kbit/s</small>', value
: nvram
.limit_br2_dlc
},
389 { title
: 'Upload rate', indent
: 2, name
: 'limit_br2_ulr', type
: 'text', maxlen
: 6, size
: 8, suffix
: ' <small>kbit/s</small>', value
: nvram
.limit_br2_ulr
},
390 { title
: 'Upload ceil', indent
: 2, name
: 'limit_br2_ulc', type
: 'text', maxlen
: 6, size
: 8, suffix
: ' <small>kbit/s</small>', value
: nvram
.limit_br2_ulc
},
391 { title
: 'Priority', indent
: 2, name
: 'limit_br2_prio', type
: 'select', options
:
392 [['0','Highest'],['1','High'],['2','Normal'],['3','Low'],['4','Lowest']], value
: nvram
.limit_br2_prio
}
397 <li><b>The bandwidth will be shared by all hosts in br2.
</b>
402 <div class='section-title'
>Default Class for LAN3 (br3)
</div>
403 <div class='section'
>
404 <script type='text/javascript'
>
405 createFieldTable('', [
406 { title
: 'Enable', name
: 'f_limit_br3_enable', type
: 'checkbox', value
: nvram
.limit_br3_enable
== '1'},
407 { title
: 'Download rate', indent
: 2, name
: 'limit_br3_dlr', type
: 'text', maxlen
: 6, size
: 8, suffix
: ' <small>kbit/s</small>', value
: nvram
.limit_br3_dlr
},
408 { title
: 'Download ceil', indent
: 2, name
: 'limit_br3_dlc', type
: 'text', maxlen
: 6, size
: 8, suffix
: ' <small>kbit/s</small>', value
: nvram
.limit_br3_dlc
},
409 { title
: 'Upload rate', indent
: 2, name
: 'limit_br3_ulr', type
: 'text', maxlen
: 6, size
: 8, suffix
: ' <small>kbit/s</small>', value
: nvram
.limit_br3_ulr
},
410 { title
: 'Upload ceil', indent
: 2, name
: 'limit_br3_ulc', type
: 'text', maxlen
: 6, size
: 8, suffix
: ' <small>kbit/s</small>', value
: nvram
.limit_br3_ulc
},
411 { title
: 'Priority', indent
: 2, name
: 'limit_br3_prio', type
: 'select', options
:
412 [['0','Highest'],['1','High'],['2','Normal'],['3','Low'],['4','Lowest']], value
: nvram
.limit_br3_prio
}
417 <li><b>The bandwidth will be shared by all hosts in br3.
</b>
425 <div class='section-title'
>Notes
</div>
426 <div class='section'
>
427 <i>IP / IP Range / MAC Address field:
</i>
430 <li>Example single IP:
<b>192.168.1.4</b></li>
431 <li>Example IP range:
<b>192.168.1.4-
7</b> (for IPs
192.168.1.4 to
192.168.1.7)
</li>
432 <li>Example IP range:
<b>4-
7</b> (for IPs
192.168.1.4 to
192.168.1.7)
</li>
433 <li><b>All hosts within an IP range will share bandwidth.
</b></li>
434 <li>MAC addresses are colon-delimited, case-insensivite, and require
6 octets (ex.
<b>00:aa:bb:cc:dd:ee
</b>).
</li>
441 <tr><td id='footer' colspan=
2>
442 <span id='footer-msg'
></span>
443 <input type='button' value='Save' id='save-button' onclick='save()'
>
444 <input type='button' value='Cancel' id='cancel-button' onclick='reloadPage();'
>
448 <script type='text/javascript'
>qosg
.setup(); verifyFields(null, 1);</script>