Migrate UI cleanup phase 4 from MIPS into ARM
[tomato.git] / release / src-rt-6.x.4708 / router / www / tools-trace.asp
blobdeb7c162e5ff8296e1158bff766c454883c37c54
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 <meta name="viewport" content="width=device-width">
15 <title>[<% ident(); %>] Tools: Trace</title>
16 <link rel='stylesheet' type='text/css' href='tomato.css'>
17 <link rel='stylesheet' type='text/css' href='color.css'>
18 <script type='text/javascript' src='tomato.js'></script>
20 <!-- / / / -->
21 <style type='text/css'>
22 #ttr-grid .co1, #ttr-grid .co3 {
23 text-align: right;
25 #ttr-grid .co1 {
26 width: 30px;
28 #ttr-grid .co2 {
29 width: 410px;
31 #ttr-grid .co4, #ttr-grid .co5, #ttr-grid .co6 {
32 text-align: right;
33 width: 70px;
35 #ttr-grid .header .co1 {
36 text-align: left;
38 </style>
40 <script type='text/javascript' src='debug.js'></script>
42 <script type='text/javascript'>
43 // <% nvram(''); %> // http_id
45 var tracedata = '';
47 var tg = new TomatoGrid();
48 tg.setup = function() {
49 this.init('ttr-grid');
50 this.headerSet(['Hop', 'Address', 'Min (ms)', 'Max (ms)', 'Avg (ms)', '+/- (ms)']);
52 tg.populate = function() {
53 var seq = 1;
54 var buf = tracedata.split('\n');
55 var i, j, k;
56 var s, f;
57 var addr, emsg, min, max, avg;
58 var time;
59 var last = -1;
61 this.removeAllData();
62 for (i = 0; i < buf.length; ++i) {
63 if (!buf[i].match(/^\s*(\d+)\s+(.+)$/)) continue;
64 if (RegExp.$1 != seq) continue;
66 s = RegExp.$2;
68 if (s.match(/^([\w\.:\-]+)\s+\(([\d\.:A-Fa-f]+)\)/)) {
69 addr = RegExp.$1;
70 if (addr != RegExp.$2) addr += ' (' + RegExp.$2 + ')';
72 else addr = '*';
74 min = max = avg = '';
75 change = '';
76 if (time = s.match(/(\d+\.\d+) ms/g)) { // odd: captures 'ms'
77 min = 0xFFFF;
78 avg = max = 0;
79 k = 0;
80 for (j = 0; j < time.length; ++j) {
81 f = parseFloat(time[j]);
82 if (isNaN(f)) continue;
83 if (f < min) min = f;
84 if (f > max) max = f;
85 avg += f;
86 ++k
88 if (k) {
89 avg /= k;
90 if (last >= 0) {
91 change = avg - last;
92 change = change.toFixed(2);
94 last = avg;
95 min = min.toFixed(2);
96 max = max.toFixed(2);
97 avg = avg.toFixed(2);
99 else {
100 min = max = avg = '';
101 last = -1;
104 else last = -1;
106 if (s.match(/ (![<>\w+-]+)/)) emsg = RegExp.$1;
107 else emsg = null;
109 this.insertData(-1, [seq, addr, min, max, avg, change])
110 ++seq;
113 E('debug').value = tracedata;
114 tracedata = '';
115 spin(0);
118 function verifyFields(focused, quiet)
120 var s;
121 var e;
123 e = E('_f_addr');
124 s = e.value.trim();
125 if (!s.match(/^[\w\-\.\:]+$/)) {
126 ferror.set(e, 'Invalid hostname/address', quiet);
127 return 0;
129 ferror.clear(e);
131 return v_range('_f_hops', quiet, 2, 40) && v_range('_f_wait', quiet, 2, 10);
134 var tracer = null;
136 function spin(x)
138 E('traceb').disabled = x;
139 E('_f_addr').disabled = x;
140 E('_f_hops').disabled = x;
141 E('_f_wait').disabled = x;
142 E('wait').style.visibility = x ? 'visible' : 'hidden';
143 if (!x) tracer = null;
146 function trace()
148 // Opera 8 sometimes sends 2 clicks
149 if (tracer) return;
151 if (!verifyFields(null, 0)) return;
152 spin(1);
153 E('trace-error').style.visibility = 'hidden';
155 tracer = new XmlHttp();
156 tracer.onCompleted = function(text, xml) {
157 eval(text);
158 tg.populate();
160 tracer.onError = function(x) {
161 spin(0);
162 E('trace-error').innerHTML = 'ERROR: ' + E('_f_addr').value + ' - ' + x;
163 E('trace-error').style.visibility = 'visible';
166 var addr = E('_f_addr').value;
167 var hops = E('_f_hops').value;
168 var wait = E('_f_wait').value;
169 tracer.post('trace.cgi', 'addr=' + addr + '&hops=' + hops + '&wait=' + wait);
171 cookie.set('traceaddr', addr);
172 cookie.set('tracehops', hops);
173 cookie.set('tracewait', wait);
176 function init()
178 var s;
180 if ((s = cookie.get('traceaddr')) != null) E('_f_addr').value = s;
181 if ((s = cookie.get('tracehops')) != null) E('_f_hops').value = s;
182 if ((s = cookie.get('tracewait')) != null) E('_f_wait').value = s;
184 E('_f_addr').onkeypress = function(ev) { if (checkEvent(ev).keyCode == 13) trace(); }
186 </script>
188 </head>
189 <body onload='init()'>
190 <form action='javascript:{}'>
191 <table id='container' cellspacing=0>
192 <tr><td colspan=2 id='header'>
193 <div class='title'>Tomato</div>
194 <div class='version'>Version <% version(); %></div>
195 </td></tr>
196 <tr id='body'><td id='navi'><script type='text/javascript'>navi()</script></td>
197 <td id='content'>
198 <div id='ident'><% ident(); %></div>
200 <!-- / / / -->
202 <div class='section-title'>Traceroute</div>
203 <div class='section'>
204 <script type='text/javascript'>
205 createFieldTable('', [
206 { title: 'Address', name: 'f_addr', type: 'text', maxlen: 64, size: 32, value: '', suffix: ' <input type="button" value="Trace" onclick="trace()" id="traceb">' },
207 { title: 'Maximum Hops', name: 'f_hops', type: 'text', maxlen: 2, size: 4, value: '20' },
208 { title: 'Maximum Wait Time', name: 'f_wait', type: 'text', maxlen: 2, size: 4, value: '3', suffix: ' <small>seconds (per hop)</small>' }
210 </script>
211 </div>
213 <div style='visibility:hidden' id='trace-error'></div>
215 <div style='visibility:hidden;text-align:right' id='wait'>Please wait... <img src='spin.gif' style='vertical-align:top'></div>
217 <table id='ttr-grid' class='tomato-grid' cellspacing=1></table>
219 <div style='height:10px;' onclick='javascript:E("debug").style.display=""'></div>
220 <textarea id='debug' style='width:99%;height:300px;display:none'></textarea>
222 <!-- / / / -->
224 </td></tr>
225 <tr><td id='footer' colspan=2>&nbsp;</td></tr>
226 </table>
227 </form>
228 <script type='text/javascript'>tg.setup();</script>
229 </body>
230 </html>