Tomato 1.28
[tomato/tomato-null.git] / release / src / router / www / tools-trace.asp
blobafc9e9c83ce29d922a2616f066a1b28f44def251
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 For use with Tomato Firmware only.
8 No part of this file may be used without permission.
9 -->
10 <html>
11 <head>
12 <meta http-equiv='content-type' content='text/html;charset=utf-8'>
13 <meta name='robots' content='noindex,nofollow'>
14 <title>[<% ident(); %>] Tools: Trace</title>
15 <link rel='stylesheet' type='text/css' href='tomato.css'>
16 <link rel='stylesheet' type='text/css' href='color.css'>
17 <script type='text/javascript' src='tomato.js'></script>
19 <!-- / / / -->
20 <style type='text/css'>
21 #ttr-grid .co1, #ttr-grid .co3 {
22 text-align: right;
24 #ttr-grid .co1 {
25 width: 30px;
27 #ttr-grid .co2 {
28 width: 410px;
30 #ttr-grid .co4, #ttr-grid .co5, #ttr-grid .co6 {
31 text-align: right;
32 width: 70px;
34 #ttr-grid .header .co1 {
35 text-align: left;
37 </style>
39 <script type='text/javascript' src='debug.js'></script>
41 <script type='text/javascript'>
42 // <% nvram(''); %> // http_id
44 var tracedata = '';
46 var tg = new TomatoGrid();
47 tg.setup = function() {
48 this.init('ttr-grid');
49 this.headerSet(['Hop', 'Address', 'Min (ms)', 'Max (ms)', 'Avg (ms)', '+/- (ms)']);
51 tg.populate = function() {
52 var seq = 1;
53 var buf = tracedata.split('\n');
54 var i, j, k;
55 var s, f;
56 var addr, emsg, min, max, avg;
57 var time;
58 var last = -1;
60 this.removeAllData();
61 for (i = 0; i < buf.length; ++i) {
62 if (!buf[i].match(/^\s*(\d+)\s+(.+)$/)) continue;
63 if (RegExp.$1 != seq) continue;
65 s = RegExp.$2;
67 if (s.match(/^([\w\.-]+)\s+\(([\d\.]+)\)/)) {
68 addr = RegExp.$1;
69 if (addr != RegExp.$2) addr += ' (' + RegExp.$2 + ')';
71 else addr = '*';
73 min = max = avg = '';
74 change = '';
75 if (time = s.match(/(\d+\.\d+) ms/g)) { // odd: captures 'ms'
76 min = 0xFFFF;
77 avg = max = 0;
78 k = 0;
79 for (j = 0; j < time.length; ++j) {
80 f = parseFloat(time[j]);
81 if (isNaN(f)) continue;
82 if (f < min) min = f;
83 if (f > max) max = f;
84 avg += f;
85 ++k
87 if (k) {
88 avg /= k;
89 if (last >= 0) {
90 change = avg - last;
91 change = change.toFixed(2);
93 last = avg;
94 min = min.toFixed(2);
95 max = max.toFixed(2);
96 avg = avg.toFixed(2);
98 else {
99 min = max = avg = '';
100 last = -1;
103 else last = -1;
105 if (s.match(/ (![<>\w+-]+)/)) emsg = RegExp.$1;
106 else emsg = null;
108 this.insertData(-1, [seq, addr, min, max, avg, change])
109 ++seq;
112 E('debug').value = tracedata;
113 tracedata = '';
114 spin(0);
117 function verifyFields(focused, quiet)
119 var s;
120 var e;
122 e = E('_f_addr');
123 s = e.value.trim();
124 if (!s.match(/^[\w\.-]+$/)) {
125 ferror.set(e, 'Invalid address', quiet);
126 return 0;
128 ferror.clear(e);
130 return v_range('_f_hops', quiet, 2, 40) && v_range('_f_wait', quiet, 2, 10);
133 var tracer = null;
135 function spin(x)
137 E('traceb').disabled = x;
138 E('_f_addr').disabled = x;
139 E('_f_hops').disabled = x;
140 E('_f_wait').disabled = x;
141 E('wait').style.visibility = x ? 'visible' : 'hidden';
142 if (!x) tracer = null;
145 function trace()
147 // Opera 8 sometimes sends 2 clicks
148 if (tracer) return;
150 if (!verifyFields(null, 0)) return;
151 spin(1);
152 E('trace-error').style.visibility = 'hidden';
154 tracer = new XmlHttp();
155 tracer.onCompleted = function(text, xml) {
156 eval(text);
157 tg.populate();
159 tracer.onError = function(x) {
160 spin(0);
161 E('trace-error').innerHTML = 'ERROR: ' + E('_f_addr').value + ' - ' + x;
162 E('trace-error').style.visibility = 'visible';
165 var addr = E('_f_addr').value;
166 var hops = E('_f_hops').value;
167 var wait = E('_f_wait').value;
168 tracer.post('trace.cgi', 'addr=' + addr + '&hops=' + hops + '&wait=' + wait);
170 cookie.set('traceaddr', addr);
171 cookie.set('tracehops', hops);
172 cookie.set('tracewait', wait);
175 function init()
177 var s;
179 if ((s = cookie.get('traceaddr')) != null) E('_f_addr').value = s;
180 if ((s = cookie.get('tracehops')) != null) E('_f_hops').value = s;
181 if ((s = cookie.get('tracewait')) != null) E('_f_wait').value = s;
183 E('_f_addr').onkeypress = function(ev) { if (checkEvent(ev).keyCode == 13) trace(); }
185 </script>
187 </head>
188 <body onload='init()'>
189 <form action='javascript:{}'>
190 <table id='container' cellspacing=0>
191 <tr><td colspan=2 id='header'>
192 <div class='title'>Tomato</div>
193 <div class='version'>Version <% version(); %></div>
194 </td></tr>
195 <tr id='body'><td id='navi'><script type='text/javascript'>navi()</script></td>
196 <td id='content'>
197 <div id='ident'><% ident(); %></div>
199 <!-- / / / -->
201 <div class='section-title'>Traceroute</div>
202 <div class='section'>
203 <script type='text/javascript'>
204 createFieldTable('', [
205 { title: 'Address', name: 'f_addr', type: 'text', maxlen: 64, size: 32, value: '', suffix: ' <input type="button" value="Trace" onclick="trace()" id="traceb">' },
206 { title: 'Maximum Hops', name: 'f_hops', type: 'text', maxlen: 2, size: 4, value: '20' },
207 { title: 'Maximum Wait Time', name: 'f_wait', type: 'text', maxlen: 2, size: 4, value: '3', suffix: ' <small>(seconds per hop)</small>' }
209 </script>
210 </div>
212 <div style='visibility:hidden' id='trace-error'></div>
214 <div style='visibility:hidden;text-align:right' id='wait'>Please wait... <img src='spin.gif' style='vertical-align:top'></div>
216 <table id='ttr-grid' class='tomato-grid' cellspacing=1></table>
218 <div style='height:10px;' onclick='javascript:E("debug").style.display=""'></div>
219 <textarea id='debug' style='width:99%;height:300px;display:none'></textarea>
221 <!-- / / / -->
223 </td></tr>
224 <tr><td id='footer' colspan=2>&nbsp;</td></tr>
225 </table>
226 </form>
227 <script type='text/javascript'>tg.setup();</script>
228 </body>
229 </html>