UI cleanup, phase 2 (partially cosmetic)
[tomato.git] / release / src-rt-6.x.4708 / router / www / qos-ctrate.asp
blob616fa196941994c289c464a3e68648adc1cad7ea
1 <!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0//EN'>
2 <!--
3 Tomato GUI
4 Copyright (C) 2006-2010 Jonathan Zarate
5 http://www.polarcloud.com/tomato/
7 Filtering/Extensions on this QoS/Transfer Rates page
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.
13 -->
14 <html>
15 <head>
16 <meta http-equiv='content-type' content='text/html;charset=utf-8'>
17 <meta name='robots' content='noindex,nofollow'>
18 <title>[<% ident(); %>] QoS: View Per-Connection Transfer Rates</title>
19 <link rel='stylesheet' type='text/css' href='tomato.css'>
20 <% css(); %>
21 <script type='text/javascript' src='tomato.js'></script>
23 <!-- / / / -->
25 <style type='text/css'>
26 #grid .co6 {
27 text-align: right;
29 #grid .co7 {
30 text-align: right;
32 </style>
34 <script type='text/javascript' src='debug.js'></script>
35 <script type='text/javascript' src='protocols.js'></script>
36 <script type='text/javascript' src='interfaces.js'></script>
38 <script type='text/javascript'>
39 // <% nvram('lan_ipaddr,lan1_ipaddr,lan2_ipaddr,lan3_ipaddr,lan_netmask,lan1_netmask,lan2_netmask,lan3_netmask,t_hidelr'); %>
40 var filterip = [];
41 var filteripe = [];
43 readDelay = fixInt('<% cgi_get("delay"); %>', 2, 30, 2);
45 var queue = [];
46 var xob = null;
47 var cache = [];
48 var lock = 0;
50 function resolve()
52 if ((queue.length == 0) || (xob)) return;
54 xob = new XmlHttp();
55 xob.onCompleted = function(text, xml) {
56 eval(text);
57 for (var i = 0; i < resolve_data.length; ++i) {
58 var r = resolve_data[i];
59 if (r[1] == '') r[1] = r[0];
60 cache[r[0]] = r[1];
61 if (lock == 0) grid.setName(r[0], r[1]);
63 if (queue.length == 0) {
64 if ((lock == 0) && (resolveCB) && (grid.sortColumn == 4)) grid.resort();
66 else setTimeout(resolve, 500);
67 xob = null;
69 xob.onError = function(ex) {
70 xob = null;
73 xob.post('resolve.cgi', 'ip=' + queue.splice(0, 20).join(','));
76 var resolveCB = 0;
77 var bcastCB = 0;
78 var mcastCB = 0;
80 function resolveChanged()
82 var b;
84 b = E('_f_autoresolve').checked ? 1 : 0;
85 if (b != resolveCB) {
86 resolveCB = b;
87 cookie.set('qos_ctr_resolve', b);
89 if (b) grid.resolveAll();
92 var thres = 0;
94 function thresChanged()
96 var a, b;
98 b = E('_f_excludebythreshold').checked ? fixInt('<% cgi_get("thres"); %>', 100, 10000000, 100) : 0;
99 if (b != thres) {
100 thres = b;
101 cookie.set('qos_ctr_thres', b);
102 ref.postData = 'exec=ctrate&arg0=' + readDelay + '&arg1=' + thres;
103 if (!ref.running) ref.once = 1;
104 E('loading').style.visibility = '';
105 ref.start();
109 var grid = new TomatoGrid();
111 grid.dataToView = function(data) {
112 var s, v = [];
113 for (var col = 0; col < data.length; ++col) {
114 switch (col) {
115 case 5:
116 case 6:
117 s = (data[col] / (readDelay * 1024)).toFixed(1);
118 break;
119 default:
120 s = data[col];
121 break;
123 v.push('' + s);
125 return v;
128 grid.sortCompare = function(a, b) {
129 var obj = TGO(a);
130 var col = obj.sortColumn;
131 var da = a.getRowData();
132 var db = b.getRowData();
133 var r;
135 switch (col) {
136 case 2:
137 case 4:
138 case 5:
139 case 6:
140 r = cmpInt(da[col], db[col]);
141 break;
142 case 1:
143 case 3:
144 var a = fixIP(da[col]);
145 var b = fixIP(db[col]);
146 if ((a != null) && (b != null)) {
147 r = aton(a) - aton(b);
148 break;
150 default:
151 r = cmpText(da[col], db[col]);
152 break;
154 return obj.sortAscending ? r : -r;
157 grid.onClick = function(cell) {
158 var row = PR(cell);
159 var ip = row.getRowData()[3];
160 if (this.lastClicked != row) {
161 this.lastClicked = row;
162 if (ip.indexOf('<') == -1) {
163 queue.push(ip);
164 row.style.cursor = 'wait';
165 resolve();
168 else {
169 this.resolveAll();
173 grid.resolveAll = function()
175 var i, ip, row, q, cols, j;
177 q = [];
178 cols = [1, 3];
179 for (i = 1; i < this.tb.rows.length; ++i) {
180 row = this.tb.rows[i];
181 for (j = cols.length-1; j >= 0; j--) {
182 ip = row.getRowData()[cols[j]];
183 if (ip.indexOf('<') == -1) {
184 if (!q[ip]) {
185 q[ip] = 1;
186 queue.push(ip);
188 row.style.cursor = 'wait';
192 q = null;
193 resolve();
196 grid.setName = function(ip, name) {
197 var i, row, data, cols, j;
199 cols = [1, 3];
200 for (i = this.tb.rows.length - 1; i > 0; --i) {
201 row = this.tb.rows[i];
202 data = row.getRowData();
203 for (j = cols.length-1; j >= 0; j--) {
204 if (data[cols[j]].indexOf(ip) != -1 ) {
205 data[cols[j]] = name + ((ip.indexOf(':') != -1) ? '<br>' : ' ') + '<small>(' + ip + ')</small>';
206 row.setRowData(data);
207 if (E('_f_shortcuts').checked)
208 data[cols[j]] = data[cols[j]] + ' <small><a href="javascript:addExcludeList(\'' + ip + '\')" title="Exclude from List">[Hide]</a></small>';
209 row.cells[cols[j]].innerHTML = data[cols[j]];
210 row.style.cursor = 'default';
216 grid.setup = function() {
217 this.init('grid', 'sort');
218 this.headerSet(['Protocol', 'Source', 'S Port', 'Destination', 'D Port', 'UL Rate', 'DL Rate']);
221 var ref = new TomatoRefresh('update.cgi', '', 0, 'qos_ctrate');
223 var numconntotal = 0;
224 var numconnshown = 0;
226 ref.refresh = function(text)
228 var i, b, d, cols, j;
230 ++lock;
232 numconntotal = 0;
233 numconnshown = 0;
235 try {
236 ctrate = [];
237 eval(text);
239 catch (ex) {
240 ctrate = [];
243 grid.lastClicked = null;
244 grid.removeAllData();
246 var c = [];
247 var q = [];
248 var cursor;
249 var ip;
251 var fskip;
253 cols = [1, 2];
255 for (i = 0; i < ctrate.length; ++i) {
256 fskip=0;
257 numconntotal++;
258 b = ctrate[i];
260 if (E('_f_excludegw').checked) {
261 if ((b[1] == nvram.lan_ipaddr) || (b[2] == nvram.lan_ipaddr) ||
262 (b[1] == nvram.lan1_ipaddr) || (b[2] == nvram.lan1_ipaddr) ||
263 (b[1] == nvram.lan2_ipaddr) || (b[2] == nvram.lan2_ipaddr) ||
264 (b[1] == nvram.lan3_ipaddr) || (b[2] == nvram.lan3_ipaddr) ||
265 (b[1] == '127.0.0.1') || (b[2] == '127.0.0.1') ) {
266 continue;
270 if (E('_f_excludebcast').checked) {
271 if ((b[2] == getBroadcastAddress(getNetworkAddress(nvram.lan_ipaddr,nvram.lan_netmask),nvram.lan_netmask)) ||
272 (b[2] == getBroadcastAddress(getNetworkAddress(nvram.lan1_ipaddr,nvram.lan1_netmask),nvram.lan1_netmask)) ||
273 (b[2] == getBroadcastAddress(getNetworkAddress(nvram.lan2_ipaddr,nvram.lan2_netmask),nvram.lan2_netmask)) ||
274 (b[2] == getBroadcastAddress(getNetworkAddress(nvram.lan3_ipaddr,nvram.lan3_netmask),nvram.lan3_netmask)) ||
275 (b[2] == '255.255.255.255') || (b[2] == '0.0.0.0') ) {
276 continue;
280 if (E('_f_excludemcast').checked) {
281 var mmin = 3758096384; // aton('224.0.0.0') == 3758096384
282 var mmax = 4026531839; // aton('239.255.255.255') == 4026531839
283 if (((aton(b[1]) >= mmin) && (aton(b[1]) <= mmax)) ||
284 ((aton(b[2]) >= mmin) && (aton(b[2]) <= mmax))) {
285 continue;
289 if (filteripe.length>0) {
290 fskip = 0;
291 for (x = 0; x < filteripe.length; ++x) {
292 if ((b[1] == filteripe[x]) || (b[2] == filteripe[x])) {
293 fskip=1;
294 break;
297 if (fskip == 1) continue;
300 if (filterip.length>0) {
301 fskip = 1;
302 for (x = 0; x < filterip.length; ++x) {
303 if ((b[1] == filterip[x]) || (b[2] == filterip[x])) {
304 fskip=0;
305 break;
308 if (fskip == 1) continue;
311 for (j = cols.length-1; j >= 0; j--) {
312 ip = b[cols[j]];
313 if (cache[ip] != null) {
314 c[ip] = cache[ip];
315 b[cols[j]] = cache[ip] + ((ip.indexOf(':') != -1) ? '<br>' : ' ') + '<small>(' + ip + ')</small>';
316 cursor = 'default';
317 } else {
318 if (resolveCB) {
319 if (!q[ip]) {
320 q[ip] = 1;
321 queue.push(ip);
323 cursor = 'wait';
325 else cursor = null;
327 if (E('_f_shortcuts').checked) {
328 if (cache[ip] == null) {
329 b[cols[j]] = b[cols[j]] + ' <small><a href="javascript:addToResolveQueue(\'' + ip + '\')" title="Resolve the hostname of this address">[resolve]</a></small>';
331 b[cols[j]] = b[cols[j]] + ' <small><a href="javascript:addExcludeList(\'' + ip + '\')" title="Filter out this IP">[hide]</a></small>';
335 numconnshown++;
336 d = [protocols[b[0]] || b[0], b[1], b[3], b[2], b[4], b[5], b[6]];
337 var row = grid.insertData(-1, d);
338 if (cursor) row.style.cursor = cursor;
340 cache = c;
341 c = null;
342 q = null;
344 grid.resort();
345 setTimeout(function() { E('loading').style.visibility = 'hidden'; }, 100);
347 --lock;
349 if (resolveCB) resolve();
351 if (numconnshown != numconntotal)
352 E('numtotalconn').innerHTML='<small><i>(showing ' + numconnshown + ' out of ' + numconntotal + ' connections)</i></small>';
353 else
354 E('numtotalconn').innerHTML='<small><i>(' + numconntotal + ' connections)</i></small>';
357 function addExcludeList(address) {
358 if (E('_f_filter_ipe').value.length<6) {
359 E('_f_filter_ipe').value = address;
360 } else {
361 if (E('_f_filter_ipe').value.indexOf(address) < 0) {
362 E('_f_filter_ipe').value = E('_f_filter_ipe').value + ',' + address;
365 dofilter();
368 function addToResolveQueue(ip) {
369 queue.push(ip);
370 resolve();
373 function init()
375 var c;
377 if ((c = cookie.get('qos_filterip')) != null) {
378 cookie.set('qos_filterip', '', 0);
379 if (c.length>6) {
380 E('_f_filter_ip').value = c;
381 filterip = c.split(',');
385 if (((c = cookie.get('qos_ctr_resolve')) != null) && (c == '1')) {
386 E('_f_autoresolve').checked = resolveCB = 1;
389 if (((c = cookie.get('qos_ctr_bcast')) != null) && (c == '1')) {
390 E('_f_excludebcast').checked = bcastCB = 1;
393 if (((c = cookie.get('qos_ctr_mcast')) != null) && (c == '1')) {
394 E('_f_excludemcast').checked = mcastCB = 1;
397 if (((c = cookie.get('qos_ctr_filters_vis')) != null) && (c == '1')) {
398 toggleVisibility("filters");
401 if ((thres = cookie.get('qos_ctr_thres')) == null || isNaN(thres *= 1)) {
402 thres = 0;
405 E('_f_shortcuts').checked = (((c = cookie.get('qos_ctr_shortcuts')) != null) && (c == '1'));
407 E('_f_excludebythreshold').checked = (thres != 0);
408 grid.setup();
409 ref.postData = 'exec=ctrate&arg0=' + readDelay + '&arg1=' + thres;
410 ref.initPage(250);
412 if (!ref.running) ref.once = 1;
413 ref.start();
416 function dofilter() {
417 if (E('_f_filter_ip').value.length>6) {
418 filterip = E('_f_filter_ip').value.split(',');
419 } else {
420 filterip = [];
423 if (E('_f_filter_ipe').value.length>6) {
424 filteripe = E('_f_filter_ipe').value.split(',');
425 } else {
426 filteripe = [];
429 if (!ref.running)
430 ref.start();
433 function toggleVisibility(whichone) {
434 if(E('sesdiv' + whichone).style.display=='') {
435 E('sesdiv' + whichone).style.display='none';
436 E('sesdiv' + whichone + 'showhide').innerHTML='(Click here to show)';
437 cookie.set('qos_ctr_' + whichone + '_vis', 0);
438 } else {
439 E('sesdiv' + whichone).style.display='';
440 E('sesdiv' + whichone + 'showhide').innerHTML='(Click here to hide)';
441 cookie.set('qos_ctr_' + whichone + '_vis', 1);
445 function verifyFields(focused, quiet) {
446 var b;
448 b = E('_f_excludebcast').checked ? 1 : 0;
449 if (b != bcastCB) {
450 bcastCB = b;
451 cookie.set('qos_ctr_bcast', b);
454 b = E('_f_excludemcast').checked ? 1 : 0;
455 if (b != mcastCB) {
456 mcastCB = b;
457 cookie.set('qos_ctr_mcast', b);
460 cookie.set('qos_ctr_shortcuts', (E('_f_shortcuts').checked ? '1' : '0'), 1);
462 thresChanged();
463 resolveChanged();
464 dofilter();
465 return 1;
467 </script>
469 </head>
470 <body onload='init()'>
471 <form id='_fom' action='javascript:{}'>
472 <table id='container' cellspacing=0>
473 <tr><td colspan=2 id='header'>
474 <div class='title'>Tomato</div>
475 <div class='version'>Version <% version(); %></div>
476 </td></tr>
477 <tr id='body'><td id='navi'><script type='text/javascript'>navi()</script></td>
478 <td id='content'>
479 <div id='ident'><% ident(); %></div>
481 <!-- / / / -->
483 <div class='section-title' id='stitle' onclick='document.location="qos-graphs.asp"' style='cursor:pointer'>Transfer Rates: <span id='numtotalconn'></span></div>
484 <div class='section'>
485 <table id='grid' class='tomato-grid' style="float:left" cellspacing=1></table>
487 <div id='loading'><br><b>Loading...</b></div>
488 </div>
490 <!-- / / / -->
492 <div class='section-title'>Filters: <small><i><a href='javascript:toggleVisibility("filters");'><span id='sesdivfiltersshowhide'>(Toggle Visibility)</span></a></i></small></div>
493 <div class='section' id='sesdivfilters' style='display:none'>
494 <script type='text/javascript'>
495 var c;
496 c = [];
497 c.push({ title: 'Show only these IPs', name: 'f_filter_ip', size: 50, maxlen: 255, type: 'text', suffix: ' <small>(comma separated list)</small>' });
498 c.push({ title: 'Exclude these IPs', name: 'f_filter_ipe', size: 50, maxlen: 255, type: 'text', suffix: ' <small>(comma separated list)</small>' });
499 c.push({ title: 'Exclude gateway traffic', name: 'f_excludegw', type: 'checkbox', value: ((nvram.t_hidelr) == '1' ? 1 : 0) });
500 c.push({ title: 'Exclude IPv4 broadcast', name: 'f_excludebcast', type: 'checkbox' });
501 c.push({ title: 'Exclude IPv4 multicast', name: 'f_excludemcast', type: 'checkbox' });
502 c.push({ title: 'Ignore inactive connections', name: 'f_excludebythreshold', type: 'checkbox' });
503 c.push({ title: 'Auto resolve addresses', name: 'f_autoresolve', type: 'checkbox' });
504 c.push({ title: 'Show shortcuts', name: 'f_shortcuts', type: 'checkbox' });
505 createFieldTable('',c);
506 </script>
507 </div>
509 <!-- / / / -->
511 </td></tr>
512 <tr><td id='footer' colspan=2>
513 <script type='text/javascript'>genStdRefresh(1,1,'ref.toggle()');</script>
514 </td></tr>
515 </table>
516 </form>
517 </body>
518 </html>