cosmetics
[tomato.git] / release / src / router / www / qos-detailed.asp
blobc9b973be411790a0f2dec5250cec439aee17ab4e
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/Connection Details 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 Details</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 .co7 {
27 width: 20px;
29 #grid .co8 {
30 text-align: right;
32 #grid .co9 {
33 text-align: right;
35 </style>
37 <script type='text/javascript' src='debug.js'></script>
38 <script type='text/javascript' src='protocols.js'></script>
39 <script type='text/javascript' src='interfaces.js'></script>
41 <script type='text/javascript'>
43 // <% nvram('qos_classnames,lan_ipaddr,lan1_ipaddr,lan2_ipaddr,lan3_ipaddr,lan_netmask,lan1_netmask,lan2_netmask,lan3_netmask,t_hidelr'); %>
45 var Unclassified = ['Unclassified'];
46 var classNames = nvram.qos_classnames.split(' ');
47 var abc = Unclassified.concat(classNames);
49 var colors = ['F08080','E6E6FA','0066CC','8FBC8F','FAFAD2','ADD8E6','9ACD32','E0FFFF','90EE90','FF9933','FFF0F5'];
50 var filterip = [];
51 var filteripe = [];
53 if ((viewClass = '<% cgi_get("class"); %>') == '') {
54 viewClass = -1;
56 else if ((isNaN(viewClass *= 1)) || (viewClass < 0) || (viewClass > 10)) {
57 viewClass = 0;
60 var queue = [];
61 var xob = null;
62 var cache = [];
63 var lock = 0;
65 function resolve()
67 if ((queue.length == 0) || (xob)) return;
69 xob = new XmlHttp();
70 xob.onCompleted = function(text, xml) {
71 eval(text);
72 for (var i = 0; i < resolve_data.length; ++i) {
73 var r = resolve_data[i];
74 if (r[1] == '') r[1] = r[0];
75 cache[r[0]] = r[1];
76 if (lock == 0) grid.setName(r[0], r[1]);
78 if (queue.length == 0) {
79 if ((lock == 0) && (resolveCB) && (grid.sortColumn == 4)) grid.resort();
81 else setTimeout(resolve, 500);
82 xob = null;
84 xob.onError = function(ex) {
85 xob = null;
88 xob.post('resolve.cgi', 'ip=' + queue.splice(0, 20).join(','));
91 var resolveCB = 0;
92 var bcastCB = 0;
93 var mcastCB = 0;
95 function resolveChanged()
97 var b;
99 b = E('_f_autoresolve').checked ? 1 : 0;
100 if (b != resolveCB) {
101 resolveCB = b;
102 cookie.set('qos_resolve', b);
104 if (b) grid.resolveAll();
107 var grid = new TomatoGrid();
109 grid.dataToView = function(data) {
110 var s, v = [];
111 for (var col = 0; col < data.length; ++col) {
112 switch (col) {
113 case 5: // Class
114 s = abc[data[col]] || ('' + data[col]);
115 break;
116 case 6: // Rule #
117 s = (data[col] * 1 > 0) ? ('' + data[col]) : '';
118 break;
119 case 7: // Bytes out
120 case 8: // Bytes in
121 s = scaleSize(data[col] * 1);
122 break;
123 default:
124 s = '' + data[col];
125 break;
127 v.push(s);
129 return v;
132 grid.sortCompare = function(a, b) {
133 var obj = TGO(a);
134 var col = obj.sortColumn;
135 var da = a.getRowData();
136 var db = b.getRowData();
137 var r;
139 switch (col) {
140 case 0: // Proto
141 case 2: // S port
142 case 4: // D port
143 case 6: // Rule #
144 case 7: // Bytes out
145 case 8: // Bytes in
146 r = cmpInt(da[col], db[col]);
147 break;
148 case 5: // Class
149 r = cmpInt(da[col] ? da[col] : 10000, db[col] ? db[col] : 10000);
150 break;
151 case 1:
152 case 3:
153 var a = fixIP(da[col]);
154 var b = fixIP(db[col]);
155 if ((a != null) && (b != null)) {
156 r = aton(a) - aton(b);
157 break;
159 default:
160 r = cmpText(da[col], db[col]);
161 break;
163 return obj.sortAscending ? r : -r;
166 grid.onClick = function(cell) {
167 var row = PR(cell);
168 var ip = row.getRowData()[3];
169 if (this.lastClicked != row) {
170 this.lastClicked = row;
171 if (ip.indexOf('<') == -1) {
172 queue.push(ip);
173 row.style.cursor = 'wait';
174 resolve();
177 else {
178 this.resolveAll();
182 grid.resolveAll = function()
184 var i, ip, row, q, cols, j;
186 q = [];
187 cols = [1, 3];
188 for (i = 1; i < this.tb.rows.length; ++i) {
189 row = this.tb.rows[i];
190 for (j = cols.length-1; j >= 0; j--) {
191 ip = row.getRowData()[cols[j]];
192 if (ip.indexOf('<') == -1) {
193 if (!q[ip]) {
194 q[ip] = 1;
195 queue.push(ip);
197 row.style.cursor = 'wait';
201 q = null;
202 resolve();
205 grid.setName = function(ip, name) {
206 var i, row, data, cols, j;
208 cols = [1, 3];
209 for (i = this.tb.rows.length - 1; i > 0; --i) {
210 row = this.tb.rows[i];
211 data = row.getRowData();
212 for (j = cols.length-1; j >= 0; j--) {
213 if (data[cols[j]] == ip) {
214 data[cols[j]] = name + ((ip.indexOf(':') != -1) ? '<br>' : ' ') + '<small>(' + ip + ')</small>';
215 row.setRowData(data);
216 row.cells[cols[j]].innerHTML = data[cols[j]];
217 row.style.cursor = 'default';
223 grid.setup = function() {
224 this.init('grid', 'sort');
225 this.headerSet(['Proto', 'Source', 'S Port', 'Destination', 'D Port', 'Class', 'Rule', 'Bytes Out', 'Bytes In']);
228 var ref = new TomatoRefresh('update.cgi', '', 0, 'qos_detailed');
230 var numconntotal = 0;
231 var numconnshown = 0;
233 ref.refresh = function(text)
235 var i, b, d, cols, j;
237 ++lock;
239 numconntotal = 0;
240 numconnshown = 0;
242 try {
243 ctdump = [];
244 eval(text);
246 catch (ex) {
247 ctdump = [];
250 grid.lastClicked = null;
251 grid.removeAllData();
253 var c = [];
254 var q = [];
255 var cursor;
256 var ip;
258 var fskip;
260 cols = [2, 3];
262 for (i = 0; i < ctdump.length; ++i) {
263 fskip=0;
264 numconntotal++;
265 b = ctdump[i];
267 if (E('_f_excludegw').checked) {
268 if ((b[2] == nvram.lan_ipaddr) || (b[3] == nvram.lan_ipaddr) ||
269 (b[2] == nvram.lan1_ipaddr) || (b[3] == nvram.lan1_ipaddr) ||
270 (b[2] == nvram.lan2_ipaddr) || (b[3] == nvram.lan2_ipaddr) ||
271 (b[2] == nvram.lan3_ipaddr) || (b[3] == nvram.lan3_ipaddr) ||
272 (b[2] == '127.0.0.1') || (b[3] == '127.0.0.1')) {
273 continue;
277 if (E('_f_excludebcast').checked) {
278 if ((b[3] == getBroadcastAddress(getNetworkAddress(nvram.lan_ipaddr,nvram.lan_netmask),nvram.lan_netmask)) ||
279 (b[3] == getBroadcastAddress(getNetworkAddress(nvram.lan1_ipaddr,nvram.lan1_netmask),nvram.lan1_netmask)) ||
280 (b[3] == getBroadcastAddress(getNetworkAddress(nvram.lan2_ipaddr,nvram.lan2_netmask),nvram.lan2_netmask)) ||
281 (b[3] == getBroadcastAddress(getNetworkAddress(nvram.lan3_ipaddr,nvram.lan3_netmask),nvram.lan3_netmask)) ||
282 (b[3] == '255.255.255.255') || (b[3] == '0.0.0.0')) {
283 continue;
287 if (E('_f_excludemcast').checked) {
288 var mmin = 3758096384; // aton('224.0.0.0')
289 var mmax = 4026531839; // aton('239.255.255.255')
290 if (((aton(b[2]) >= mmin) && (aton(b[2]) <= mmax)) ||
291 ((aton(b[3]) >= mmin) && (aton(b[3]) <= mmax))) {
292 continue;
296 if (filteripe.length>0) {
297 fskip = 0;
298 for (x = 0; x < filteripe.length; ++x) {
299 if ((b[2] == filteripe[x]) || (b[3] == filteripe[x])) {
300 fskip=1;
301 break;
304 if (fskip == 1) continue;
307 if (filterip.length>0) {
308 fskip = 1;
309 for (x = 0; x < filterip.length; ++x) {
310 if ((b[2] == filterip[x]) || (b[3] == filterip[x])) {
311 fskip=0;
312 break;
315 if (fskip == 1) continue;
318 for (j = cols.length-1; j >= 0; j--) {
319 ip = b[cols[j]];
320 if (cache[ip] != null) {
321 c[ip] = cache[ip];
322 b[cols[j]] = cache[ip] + ((ip.indexOf(':') != -1) ? '<br>' : ' ') + '<small>(' + ip + ')</small>';
323 cursor = 'default';
325 else {
326 if (resolveCB) {
327 if (!q[ip]) {
328 q[ip] = 1;
329 queue.push(ip);
331 cursor = 'wait';
333 else cursor = null;
337 numconnshown++;
338 d = [protocols[b[0]] || b[0], b[2], b[4], b[3], b[5], b[8], b[9], b[6], b[7]];
339 var row = grid.insertData(-1, d);
340 if (cursor) row.style.cursor = cursor;
342 cache = c;
343 c = null;
344 q = null;
346 grid.resort();
347 setTimeout(function() { E('loading').style.visibility = 'hidden'; }, 100);
349 --lock;
351 if (resolveCB) resolve();
352 if (numconnshown != numconntotal)
353 E('numtotalconn').innerHTML='<small><i>(showing ' + numconnshown + ' out of ' + numconntotal + ' connections)</i></small>';
354 else
355 E('numtotalconn').innerHTML='<small><i>(' + numconntotal + ' connections)</i></small>';
358 function init()
360 var c;
362 if (((c = cookie.get('qos_resolve')) != null) && (c == '1')) {
363 E('_f_autoresolve').checked = resolveCB = 1;
366 if (((c = cookie.get('qos_bcast')) != null) && (c == '1')) {
367 E('_f_excludebcast').checked = bcastCB = 1;
370 if (((c = cookie.get('qos_mcast')) != null) && (c == '1')) {
371 E('_f_excludemcast').checked = mcastCB = 1;
374 if (((c = cookie.get('qos_filters')) != null) && (c == '1')) {
375 E('sesdivfilters').style.display='';
378 if (viewClass != -1) E('stitle').innerHTML = 'View Details: ' + abc[viewClass] + ' <span id=\'numtotalconn\'></span>';
379 grid.setup();
380 ref.postData = 'exec=ctdump&arg0=' + viewClass;
381 ref.initPage(250);
383 if (!ref.running) ref.once = 1;
384 ref.start();
387 function dofilter() {
388 if (E('_f_filter_ip').value.length>6) {
389 filterip = E('_f_filter_ip').value.split(',');
390 } else {
391 filterip = [];
394 if (E('_f_filter_ipe').value.length>6) {
395 filteripe = E('_f_filter_ipe').value.split(',');
396 } else {
397 filteripe = [];
400 if (!ref.running) ref.once = 1;
401 ref.start();
404 function toggleFiltersVisibility(){
405 if(E('sesdivfilters').style.display=='') {
406 E('sesdivfilters').style.display='none';
407 cookie.set('qos_filters', 0);
408 } else {
409 E('sesdivfilters').style.display='';
410 cookie.set('qos_filters', 1);
414 function verifyFields(focused, quiet)
416 var b;
418 b = E('_f_excludebcast').checked ? 1 : 0;
419 if (b != bcastCB) {
420 bcastCB = b;
421 cookie.set('qos_bcast', b);
424 b = E('_f_excludemcast').checked ? 1 : 0;
425 if (b != mcastCB) {
426 mcastCB = b;
427 cookie.set('qos_mcast', b);
430 dofilter();
431 resolveChanged();
432 return 1;
435 </script>
436 </head>
437 <body onload='init()'>
438 <form id='_fom' action='javascript:{}'>
439 <table id='container' cellspacing=0>
440 <tr><td colspan=2 id='header'>
441 <div class='title'>Tomato</div>
442 <div class='version'>Version <% version(); %></div>
443 </td></tr>
444 <tr id='body'><td id='navi'><script type='text/javascript'>navi()</script></td>
445 <td id='content'>
446 <div id='ident'><% ident(); %></div>
449 <!-- / / / -->
452 <div class='section-title' id='stitle' onclick='document.location="qos-graphs.asp"' style='cursor:pointer'>View Details: <span id='numtotalconn'></span></div>
453 <div class='section'>
454 <table id='grid' class='tomato-grid' style="float:left" cellspacing=1></table>
456 <div id='loading'><br><b>Loading...</b></div>
457 </div>
460 <!-- / / / -->
463 <div class='section-title'>Filters: <small><i><a href='javascript:toggleFiltersVisibility();'>(Toggle Visibility)</a></i></small></div>
464 <div class='section' id='sesdivfilters' style='display:none'>
465 <script type='text/javascript'>
466 var c;
467 c = [];
468 c.push({ title: 'Only these IPs', name: 'f_filter_ip', size: 50, maxlen: 255, type: 'text', suffix: ' <small>(Comma separated list)</small>' });
469 c.push({ title: 'Exclude these IPs', name: 'f_filter_ipe', size: 50, maxlen: 255, type: 'text', suffix: ' <small>(Comma separated list)</small>' });
470 c.push({ title: 'Exclude gateway traffic', name: 'f_excludegw', type: 'checkbox', value: ((nvram.t_hidelr) == '1' ? 1 : 0) });
471 c.push({ title: 'Exclude broadcasts', name: 'f_excludebcast', type: 'checkbox' });
472 c.push({ title: 'Exclude multicast', name: 'f_excludemcast', type: 'checkbox' });
473 c.push({ title: 'Auto resolve addresses', name: 'f_autoresolve', type: 'checkbox' });
474 createFieldTable('',c);
475 </script>
476 </div>
479 <!-- / / / -->
482 </td></tr>
483 <tr><td id='footer' colspan=2>
484 <script type='text/javascript'>genStdRefresh(1,5,'ref.toggle()');</script>
485 </td></tr>
486 </table>
487 </form>
488 </body>
489 </html>