Project

General

Profile

Download (12.3 KB) Statistics
| Branch: | Tag: | Revision:
1
#!/usr/local/bin/php -f
2
<?php
3
/* $Id$ */
4
/*
5
	graph.php
6
	Copyright (C) 2004 Scott Ullrich
7
	originally part of m0n0wall (http://m0n0.ch/wall)
8
	Copyright (C) 2004 T. Lechat <dev@lechat.org> and Manuel Kasper <mk@neon1.net>.
9
	All rights reserved.
10

    
11
	Redistribution and use in source and binary forms, with or without
12
	modification, are permitted provided that the following conditions are met:
13

    
14
	1. Redistributions of source code must retain the above copyright notice,
15
	   this list of conditions and the following disclaimer.
16

    
17
	2. Redistributions in binary form must reproduce the above copyright
18
	   notice, this list of conditions and the following disclaimer in the
19
	   documentation and/or other materials provided with the distribution.
20

    
21
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
22
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
23
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
25
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
	POSSIBILITY OF SUCH DAMAGE.
31
*/
32

    
33
/* Headers are evil, must omit them */
34
$omit_nocacheheaders = true;
35
require_once('guiconfig.inc');
36

    
37
// VERSION 1.0.4
38

    
39
/********** HTTP GET Based Conf ***********/
40
$ifnum=@$_GET["ifnum"];							//BSD / SNMP interface name / number
41
$ifname=@$_GET["ifname"]?$_GET["ifname"]:"Interface $ifnum";		//Interface name that will be showed on top right of graph
42

    
43
/********* Other conf *******/
44
$scale_type="up";		//Autoscale default setup : "up" = only increase scale; "follow" = increase and decrease scale according to current graphed datas
45
$nb_plot=120;			//NB plot in graph
46
$time_interval=1;		//Refresh time Interval
47
$first_stage_time_interval=2;	//First stage time Intervall
48

    
49
$urldata=@$_SERVER["SCRIPT_NAME"];
50
$fetch_link = "ifstats.cgi?$ifnum";
51

    
52
//Style
53
$style['bg']="fill:white;stroke:none;stroke-width:0;opacity:1;";
54
$style['axis']="fill:black;stroke:black;stroke-width:1;";
55
$style['in']="fill:#CC0000; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:7;";
56
$style['out']="fill:#000000; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:7;";
57
$style['graph_in']="fill:none;stroke:#CC0000;stroke-width:1;opacity:0.8;";
58
$style['graph_out']="fill:none;stroke:#000000;stroke-width:1;opacity:0.8;";
59
$style['legend']="fill:black; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:4;";
60
$style['graphname']="fill:#CC0000; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:8;";
61
$style['grid_txt']="fill:gray; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:6;";
62
$style['grid']="stroke:gray;stroke-width:1;opacity:0.5;";
63
$style['switch_unit']="fill:#CC0000; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:4; text-decoration:underline;";
64
$style['switch_scale']="fill:#CC0000; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:4; text-decoration:underline;";
65
$style['error']="fill:blue; font-family:Arial; font-size:4;";
66
$style['collect_initial']="fill:gray; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:4;";
67

    
68
//Error text if we cannot fetch data : depends on which method is used
69
$error_text = "Cannot get data about interface $ifnum";
70

    
71
$height=100;		//SVG internal height : do not modify
72
$width=200;		//SVG internal width : do not modify
73

    
74
/********* Graph DATA **************/
75
header("Content-type: image/svg+xml");
76
print('<?xml version="1.0" encoding="iso-8859-1"?>' . "\n");?><svg width="100%" height="100%" viewBox="0 0 <?=$width?> <?=$height?>" preserveAspectRatio="none" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="init(evt)">
77
<g id="graph" style="visibility:visible">
78
	<rect id="bg" x1="0" y1="0" x2="<?=$width?>" y2="<?=$height?>" style="<?=$style['bg']?>"/>
79
	<line id="axis_x" x1="0" y1="0" x2="0" y2="<?=$height?>" style="<?=$style['axis']?>"/>
80
	<line id="axis_y" x1="0" y1="<?=$height?>" x2="<?=$width?>" y2="<?=$height?>" style="<?=$style['axis']?>"/>
81
	<path id="graph_out" d="M0 <?=$height?> L 0 <?=$height?>" style="<?=$style['graph_out']?>"/>
82
	<path id="graph_in"  d="M0 <?=$height?> L 0 <?=$height?>" style="<?=$style['graph_in']?>"/>
83
	<path id="grid"  d="M0 <?=$height/4*1?> L <?=$width?> <?=$height/4*1?> M0 <?=$height/4*2?> L <?=$width?> <?=$height/4*2?> M0 <?=$height/4*3?> L <?=$width?> <?=$height/4*3?>" style="<?=$style[grid]?>"/>
84
	<text id="grid_txt1" x="<?=$width?>" y="<?=$height/4*1?>" style="<?=$style['grid_txt']?> text-anchor:end"> </text>
85
	<text id="grid_txt2" x="<?=$width?>" y="<?=$height/4*2?>" style="<?=$style['grid_txt']?> text-anchor:end"> </text>
86
	<text id="grid_txt3" x="<?=$width?>" y="<?=$height/4*3?>" style="<?=$style['grid_txt']?> text-anchor:end"> </text>
87
	<text id="graph_in_lbl" x="5" y="8" style="<?=$style['in']?>">In</text>
88
	<text id="graph_out_lbl" x="5" y="16" style="<?=$style['out']?> ">Out</text>
89
	<text id="graph_in_txt" x="20" y="8" style="<?=$style['in']?>"> </text>
90
	<text id="graph_out_txt" x="20" y="16" style="<?=$style['out']?> "> </text>
91
	<text id="ifname" x="<?=$width?>" y="8" style="<?=$style['graphname']?> text-anchor:end"><?=$ifname?></text>
92
	<text id="switch_unit" x="<?=$width*0.55?>" y="5" style="<?=$style['switch_unit']?>">Switch to bytes/s</text>
93
	<text id="switch_scale" x="<?=$width*0.55?>" y="11" style="<?=$style['switch_scale']?>">AutoScale (<?=$scale_type?>)</text>
94
	<text id="datetime" x="<?=$width*0.33?>" y="5" style="<?=$style['legend']?>"> </text>
95
	<text id="graphlast" x="<?=$width*0.55?>" y="17" style="<?=$style['legend']?>">Graph shows last <?=$time_interval*$nb_plot?> seconds</text>
96
	<polygon id="axis_arrow_x" style="<?=$style['axis']?>" points="<?=($width) . "," . ($height)?> <?=($width-2) . "," . ($height-2)?> <?=($width-2) . "," . $height?>"/>
97
	<text id="error" x="<?=$width*0.5?>" y="<?=$height*0.5?>"  style="visibility:hidden;<?=$style['error']?> text-anchor:middle"><?=$error_text?></text>
98
	<text id="collect_initial" x="<?=$width*0.5?>" y="<?=$height*0.5?>"  style="visibility:hidden;<?=$style['collect_initial']?> text-anchor:middle">Collecting initial data, please wait...</text>
99
</g>
100

    
101
<script type="text/ecmascript"><![CDATA[
102
var SVGDoc;
103
var last_ifin=0;
104
var last_ifout=0;
105
var last_ugmt=0;
106
var diff_ugmt=0;
107
var diff_ifin=0;
108
var diff_ifout=0;
109
var max = 0;
110
plot_in=new Array();
111
plot_out=new Array();
112

    
113
var isfirst=1;
114
var index_plot=0;
115
var step = <?=$width?> / <?=$nb_plot?> ;
116
var unit = 'bits';
117
var scale_type = '<?=$scale_type?>';
118

    
119
function init(evt) {
120
	SVGDoc = evt.getTarget().getOwnerDocument();
121
	SVGDoc.getElementById("switch_unit").addEventListener("mousedown", switch_unit, false);
122
	SVGDoc.getElementById("switch_scale").addEventListener("mousedown", switch_scale, false);
123

    
124
	go();
125
}
126

    
127
function switch_unit(event)
128
{
129
	SVGDoc.getElementById('switch_unit').getFirstChild().setData('Switch to ' + unit + '/s');
130
	if(unit=='bits') unit='bytes';else unit='bits';
131
}
132

    
133
function switch_scale(event)
134
{
135
	if(scale_type=='up') scale_type='follow';else scale_type='up';
136
	SVGDoc.getElementById('switch_scale').getFirstChild().setData('AutoScale (' + scale_type + ')');
137
}
138

    
139
function go() {
140
	getURL('<?=$fetch_link?>',urlcallback);
141
}
142

    
143
function urlcallback(obj) {
144
	var error = 0;
145
	now = new Date();
146

    
147
	//Show datetimelegend
148
	var datetime = (now.getMonth()+1) + "/" + now.getDate() + "/" + now.getFullYear() + ' ' +
149
		LZ(now.getHours()) + ":" + LZ(now.getMinutes()) + ":" + LZ(now.getSeconds());
150
	SVGDoc.getElementById('datetime').getFirstChild().setData(datetime);
151

    
152
	//shift plot to left if nb_plot is already completed
153
	var i=0;
154
	if(index_plot > <?=$nb_plot?>)
155
	{
156
		while (i <= <?=$nb_plot?>)
157
		{
158
			var a=i+1;
159
			plot_in[i]=plot_in[a];
160
			plot_out[i]=plot_out[a];
161
			i=i+1;
162
		}
163
		index_plot = <?=$nb_plot?>;
164
		plot_in[index_plot]=0;
165
		plot_out[index_plot]=0;
166
	}
167

    
168
	//if Geturl returns something
169
	if (obj.success){
170
		var t=obj.content.split("|");
171
		var ugmt = parseFloat(t[0]);//ugmt is an unixtimestamp style
172
		var ifin = parseInt(t[1]);//ifin must be in bytes
173
		var ifout = parseInt(t[2]);//ifout must be in bytes
174
		var scale;
175

    
176
		if(!isNumber(ifin) || !isNumber(ifout)) {
177
			goerror();
178
			return;
179
		} else {
180
			SVGDoc.getElementById("error").getStyle().setProperty ('visibility', 'hidden');
181
		}
182

    
183
		diff_ugmt  = ugmt - last_ugmt;
184
		diff_ifin  = ifin - last_ifin;
185
		diff_ifout = ifout - last_ifout;
186

    
187
		if (diff_ugmt == 0)
188
			diff_ugmt = 1;	/* avoid division by zero */
189

    
190
		last_ugmt = ugmt;
191
		last_ifin = ifin;
192
		last_ifout = ifout;
193

    
194
		if(isfirst) {
195
			SVGDoc.getElementById("collect_initial").getStyle().setProperty ('visibility', 'visible');
196
			setTimeout('go()',<?=1000*$first_stage_time_interval?>);
197
			isfirst=0;
198
			return;
199
		} else SVGDoc.getElementById("collect_initial").getStyle().setProperty ('visibility', 'hidden');
200

    
201
		plot_in[index_plot] = diff_ifin / diff_ugmt;
202
		plot_out[index_plot]= diff_ifout / diff_ugmt;
203

    
204
		SVGDoc.getElementById('graph_in_txt').getFirstChild().setData(formatSpeed(plot_in[index_plot],unit));
205
		SVGDoc.getElementById('graph_out_txt').getFirstChild().setData(formatSpeed(plot_out[index_plot],unit));
206

    
207
		/* determine peak for sensible scaling */
208
		if (scale_type == 'up') {
209
			if (plot_in[index_plot] > max)
210
				max = plot_in[index_plot];
211
			if (plot_out[index_plot] > max)
212
				max = plot_out[index_plot];
213
		} else if (scale_type == 'follow') {
214
			i = 0;
215
			max = 0;
216
			while (i <= <?=$nb_plot?>) {
217
				if (plot_in[i] > max)
218
					max = plot_in[i];
219
				if (plot_out[i] > max)
220
					max = plot_out[i];
221
				i++;
222
			}
223
		}
224

    
225
		var rmax;
226

    
227
		if (unit == 'bits') {
228
			/* round up max, such that
229
		   		100 kbps -> 200 kbps -> 400 kbps -> 800 kbps -> 1 Mbps -> 2 Mbps -> ... */
230
			rmax = 12500;
231
			i = 0;
232
			while (max > rmax) {
233
				i++;
234
				if (i && (i % 4 == 0))
235
					rmax *= 1.25;
236
				else
237
					rmax *= 2;
238
			}
239
		} else {
240
			/* round up max, such that
241
		   		10 KB/s -> 20 KB/s -> 40 KB/s -> 80 KB/s -> 100 KB/s -> 200 KB/s -> 400 KB/s -> 800 KB/s -> 1 MB/s ... */
242
			rmax = 10240;
243
			i = 0;
244
			while (max > rmax) {
245
				i++;
246
				if (i && (i % 4 == 0))
247
					rmax *= 1.25;
248
				else
249
					rmax *= 2;
250

    
251
				if (i == 8)
252
					rmax *= 1.024;
253
			}
254
		}
255

    
256
		scale = <?=$height?> / rmax;
257

    
258
		/* change labels accordingly */
259
		SVGDoc.getElementById('grid_txt1').getFirstChild().setData(formatSpeed(3*rmax/4,unit));
260
		SVGDoc.getElementById('grid_txt2').getFirstChild().setData(formatSpeed(2*rmax/4,unit));
261
		SVGDoc.getElementById('grid_txt3').getFirstChild().setData(formatSpeed(rmax/4,unit));
262

    
263
		i = 0;
264

    
265
		while (i <= index_plot)
266
		{
267
			var x = step * i;
268
			var y_in= <?=$height?> - (plot_in[i] * scale);
269
			var y_out= <?=$height?> - (plot_out[i] * scale);
270
			if(i==0) {
271
				var path_in = "M" + x + " " + y_in;
272
				var path_out = "M" + x + " " + y_out;
273
			}
274
			else
275
			{
276
				var path_in = path_in + " L" + x + " " + y_in;
277
				var path_out = path_out + " L" + x + " " + y_out;
278
			}
279
			i = i + 1;
280
		}
281

    
282
		index_plot = index_plot+1;
283
		SVGDoc.getElementById('graph_in').setAttribute("d", path_in);
284
		SVGDoc.getElementById('graph_out').setAttribute("d", path_out);
285

    
286
		setTimeout('go()',<?=1000*$time_interval?>);
287
	}
288
	else
289
	{ //In case of Geturl fails
290
		goerror();
291
	}
292
}
293

    
294
function goerror() {
295
	SVGDoc.getElementById("error").getStyle().setProperty ('visibility', 'visible');
296
	setTimeout('go()',<?=1000*$time_interval?>);
297
}
298

    
299
function isNumber(a) {
300
    return typeof a == 'number' && isFinite(a);
301
}
302

    
303
function formatSpeed(speed,unit){
304
	if(unit=='bits') return formatSpeedBits(speed);
305
	else if(unit=='bytes') return formatSpeedBytes(speed);
306
}
307

    
308
function formatSpeedBits(speed) {
309
	// format speed in bits/sec, input: bytes/sec
310
	if (speed <	125000)
311
		return Math.round(speed / 125) + " Kbps";
312
	else if (speed < 125000000)
313
		return Math.round(speed / 1250)/100 + " Mbps";
314
	else
315
		return Math.round(speed / 1250000)/100 + " Gbps";	/* wow! */
316
}
317
function formatSpeedBytes(speed) {
318
	// format speed in bytes/sec, input:  bytes/sec
319
	if (speed <	1048576)
320
		return Math.round(speed / 10.24)/100 + " KB/s";
321
	else if (speed < 1073741824)
322
		return Math.round(speed / 10485.76)/100 + " MB/s";
323
	else
324
		return Math.round(speed / 10737418.24)/100 + " GB/s";	/* wow! */
325
}
326
function LZ(x) {
327
	return (x < 0 || x > 9 ? "" : "0") + x
328
}
329
]]></script>
330
</svg>
(51-51/146)