Project

General

Profile

Download (12.2 KB) Statistics
| Branch: | Tag: | Revision:
1 5b237745 Scott Ullrich
#!/usr/local/bin/php -f
2
<?php
3 b46bfcf5 Bill Marquette
/* $Id$ */
4 5b237745 Scott Ullrich
/*
5
	graph.php
6 16d9e6e4 Scott Ullrich
	Copyright (C) 2004 Scott Ullrich
7
	originally part of m0n0wall (http://m0n0.ch/wall)
8 5b237745 Scott Ullrich
	Copyright (C) 2004 T. Lechat <dev@lechat.org> and Manuel Kasper <mk@neon1.net>.
9
	All rights reserved.
10 66f8696f Scott Ullrich
11 5b237745 Scott Ullrich
	Redistribution and use in source and binary forms, with or without
12
	modification, are permitted provided that the following conditions are met:
13 66f8696f Scott Ullrich
14 5b237745 Scott Ullrich
	1. Redistributions of source code must retain the above copyright notice,
15
	   this list of conditions and the following disclaimer.
16 66f8696f Scott Ullrich
17 5b237745 Scott Ullrich
	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 66f8696f Scott Ullrich
21 5b237745 Scott Ullrich
	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 f977ac60 Bill Marquette
include("guiconfig.inc");
34
35 5b237745 Scott Ullrich
// VERSION 1.0.4
36
37
/********** HTTP GET Based Conf ***********/
38
$ifnum=@$_GET["ifnum"];							//BSD / SNMP interface name / number
39
$ifname=@$_GET["ifname"]?$_GET["ifname"]:"Interface $ifnum";		//Interface name that will be showed on top right of graph
40
41
/********* Other conf *******/
42
$scale_type="up";		//Autoscale default setup : "up" = only increase scale; "follow" = increase and decrease scale according to current graphed datas
43
$nb_plot=120;			//NB plot in graph
44
$time_interval=1;		//Refresh time Interval
45
$first_stage_time_interval=2;	//First stage time Intervall
46
47
$urldata=@$_SERVER["SCRIPT_NAME"];
48
$fetch_link = "ifstats.cgi?$ifnum";
49
50
//Style
51
$style['bg']="fill:white;stroke:none;stroke-width:0;opacity:1;";
52
$style['axis']="fill:black;stroke:black;stroke-width:1;";
53 66f8696f Scott Ullrich
$style['in']="fill:#CC0000; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:7;";
54
$style['out']="fill:#000000; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:7;";
55
$style['graph_in']="fill:none;stroke:#CC0000;stroke-width:1;opacity:0.8;";
56
$style['graph_out']="fill:none;stroke:#000000;stroke-width:1;opacity:0.8;";
57 5b237745 Scott Ullrich
$style['legend']="fill:black; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:4;";
58 66f8696f Scott Ullrich
$style['graphname']="fill:#CC0000; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:8;";
59 5b237745 Scott Ullrich
$style['grid_txt']="fill:gray; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:6;";
60
$style['grid']="stroke:gray;stroke-width:1;opacity:0.5;";
61 66f8696f Scott Ullrich
$style['switch_unit']="fill:#CC0000; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:4; text-decoration:underline;";
62
$style['switch_scale']="fill:#CC0000; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:4; text-decoration:underline;";
63 5b237745 Scott Ullrich
$style['error']="fill:blue; font-family:Arial; font-size:4;";
64
$style['collect_initial']="fill:gray; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:4;";
65
66
//Error text if we cannot fetch data : depends on which method is used
67
$error_text = "Cannot get data about interface $ifnum";
68
69
$height=100;		//SVG internal height : do not modify
70
$width=200;		//SVG internal width : do not modify
71
72
/********* Graph DATA **************/
73
header("Content-type: image/svg+xml");
74
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)">
75
<g id="graph" style="visibility:visible">
76
	<rect id="bg" x1="0" y1="0" x2="<?=$width?>" y2="<?=$height?>" style="<?=$style['bg']?>"/>
77
	<line id="axis_x" x1="0" y1="0" x2="0" y2="<?=$height?>" style="<?=$style['axis']?>"/>
78
	<line id="axis_y" x1="0" y1="<?=$height?>" x2="<?=$width?>" y2="<?=$height?>" style="<?=$style['axis']?>"/>
79
	<path id="graph_out" d="M0 <?=$height?> L 0 <?=$height?>" style="<?=$style['graph_out']?>"/>
80
	<path id="graph_in"  d="M0 <?=$height?> L 0 <?=$height?>" style="<?=$style['graph_in']?>"/>
81
	<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]?>"/>
82
	<text id="grid_txt1" x="<?=$width?>" y="<?=$height/4*1?>" style="<?=$style['grid_txt']?> text-anchor:end"> </text>
83
	<text id="grid_txt2" x="<?=$width?>" y="<?=$height/4*2?>" style="<?=$style['grid_txt']?> text-anchor:end"> </text>
84
	<text id="grid_txt3" x="<?=$width?>" y="<?=$height/4*3?>" style="<?=$style['grid_txt']?> text-anchor:end"> </text>
85
	<text id="graph_in_lbl" x="5" y="8" style="<?=$style['in']?>">In</text>
86
	<text id="graph_out_lbl" x="5" y="16" style="<?=$style['out']?> ">Out</text>
87
	<text id="graph_in_txt" x="20" y="8" style="<?=$style['in']?>"> </text>
88
	<text id="graph_out_txt" x="20" y="16" style="<?=$style['out']?> "> </text>
89
	<text id="ifname" x="<?=$width?>" y="8" style="<?=$style['graphname']?> text-anchor:end"><?=$ifname?></text>
90
	<text id="switch_unit" x="<?=$width*0.55?>" y="5" style="<?=$style['switch_unit']?>">Switch to bytes/s</text>
91
	<text id="switch_scale" x="<?=$width*0.55?>" y="11" style="<?=$style['switch_scale']?>">AutoScale (<?=$scale_type?>)</text>
92
	<text id="datetime" x="<?=$width*0.33?>" y="5" style="<?=$style['legend']?>"> </text>
93
	<text id="graphlast" x="<?=$width*0.55?>" y="17" style="<?=$style['legend']?>">Graph shows last <?=$time_interval*$nb_plot?> seconds</text>
94
	<polygon id="axis_arrow_x" style="<?=$style['axis']?>" points="<?=($width) . "," . ($height)?> <?=($width-2) . "," . ($height-2)?> <?=($width-2) . "," . $height?>"/>
95
	<text id="error" x="<?=$width*0.5?>" y="<?=$height*0.5?>"  style="visibility:hidden;<?=$style['error']?> text-anchor:middle"><?=$error_text?></text>
96
	<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>
97
</g>
98
99
<script type="text/ecmascript"><![CDATA[
100
var SVGDoc;
101
var last_ifin=0;
102
var last_ifout=0;
103
var last_ugmt=0;
104
var diff_ugmt=0;
105
var diff_ifin=0;
106
var diff_ifout=0;
107
var max = 0;
108
plot_in=new Array();
109
plot_out=new Array();
110
111
var isfirst=1;
112
var index_plot=0;
113
var step = <?=$width?> / <?=$nb_plot?> ;
114
var unit = 'bits';
115
var scale_type = '<?=$scale_type?>';
116
117
function init(evt) {
118
	SVGDoc = evt.getTarget().getOwnerDocument();
119
	SVGDoc.getElementById("switch_unit").addEventListener("mousedown", switch_unit, false);
120
	SVGDoc.getElementById("switch_scale").addEventListener("mousedown", switch_scale, false);
121
122
	go();
123
}
124
125
function switch_unit(event)
126
{
127
	SVGDoc.getElementById('switch_unit').getFirstChild().setData('Switch to ' + unit + '/s');
128
	if(unit=='bits') unit='bytes';else unit='bits';
129
}
130
131
function switch_scale(event)
132
{
133
	if(scale_type=='up') scale_type='follow';else scale_type='up';
134
	SVGDoc.getElementById('switch_scale').getFirstChild().setData('AutoScale (' + scale_type + ')');
135
}
136
137
function go() {
138
	getURL('<?=$fetch_link?>',urlcallback);
139
}
140
141
function urlcallback(obj) {
142
	var error = 0;
143
	now = new Date();
144
145
	//Show datetimelegend
146 66f8696f Scott Ullrich
	var datetime = (now.getMonth()+1) + "/" + now.getDate() + "/" + now.getFullYear() + ' ' +
147 5b237745 Scott Ullrich
		LZ(now.getHours()) + ":" + LZ(now.getMinutes()) + ":" + LZ(now.getSeconds());
148
	SVGDoc.getElementById('datetime').getFirstChild().setData(datetime);
149
150
	//shift plot to left if nb_plot is already completed
151
	var i=0;
152
	if(index_plot > <?=$nb_plot?>)
153
	{
154
		while (i <= <?=$nb_plot?>)
155
		{
156
			var a=i+1;
157
			plot_in[i]=plot_in[a];
158
			plot_out[i]=plot_out[a];
159
			i=i+1;
160
		}
161
		index_plot = <?=$nb_plot?>;
162
		plot_in[index_plot]=0;
163
		plot_out[index_plot]=0;
164
	}
165
166
	//if Geturl returns something
167
	if (obj.success){
168
		var t=obj.content.split("|");
169
		var ugmt = parseFloat(t[0]);//ugmt is an unixtimestamp style
170
		var ifin = parseInt(t[1]);//ifin must be in bytes
171
		var ifout = parseInt(t[2]);//ifout must be in bytes
172
		var scale;
173
174
		if(!isNumber(ifin) || !isNumber(ifout)) {
175
			goerror();
176
			return;
177
		} else {
178
			SVGDoc.getElementById("error").getStyle().setProperty ('visibility', 'hidden');
179
		}
180
181
		diff_ugmt  = ugmt - last_ugmt;
182
		diff_ifin  = ifin - last_ifin;
183
		diff_ifout = ifout - last_ifout;
184 66f8696f Scott Ullrich
185 5b237745 Scott Ullrich
		if (diff_ugmt == 0)
186
			diff_ugmt = 1;	/* avoid division by zero */
187
188
		last_ugmt = ugmt;
189
		last_ifin = ifin;
190
		last_ifout = ifout;
191
192
		if(isfirst) {
193
			SVGDoc.getElementById("collect_initial").getStyle().setProperty ('visibility', 'visible');
194
			setTimeout('go()',<?=1000*$first_stage_time_interval?>);
195
			isfirst=0;
196
			return;
197
		} else SVGDoc.getElementById("collect_initial").getStyle().setProperty ('visibility', 'hidden');
198
199
		plot_in[index_plot] = diff_ifin / diff_ugmt;
200
		plot_out[index_plot]= diff_ifout / diff_ugmt;
201
202
		SVGDoc.getElementById('graph_in_txt').getFirstChild().setData(formatSpeed(plot_in[index_plot],unit));
203
		SVGDoc.getElementById('graph_out_txt').getFirstChild().setData(formatSpeed(plot_out[index_plot],unit));
204
205 66f8696f Scott Ullrich
		/* determine peak for sensible scaling */
206 5b237745 Scott Ullrich
		if (scale_type == 'up') {
207
			if (plot_in[index_plot] > max)
208
				max = plot_in[index_plot];
209
			if (plot_out[index_plot] > max)
210 66f8696f Scott Ullrich
				max = plot_out[index_plot];
211 5b237745 Scott Ullrich
		} else if (scale_type == 'follow') {
212
			i = 0;
213
			max = 0;
214
			while (i <= <?=$nb_plot?>) {
215
				if (plot_in[i] > max)
216
					max = plot_in[i];
217
				if (plot_out[i] > max)
218
					max = plot_out[i];
219
				i++;
220
			}
221
		}
222
223
		var rmax;
224 66f8696f Scott Ullrich
225 5b237745 Scott Ullrich
		if (unit == 'bits') {
226
			/* round up max, such that
227
		   		100 kbps -> 200 kbps -> 400 kbps -> 800 kbps -> 1 Mbps -> 2 Mbps -> ... */
228
			rmax = 12500;
229
			i = 0;
230
			while (max > rmax) {
231
				i++;
232
				if (i && (i % 4 == 0))
233
					rmax *= 1.25;
234
				else
235
					rmax *= 2;
236
			}
237
		} else {
238
			/* round up max, such that
239
		   		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 ... */
240
			rmax = 10240;
241
			i = 0;
242
			while (max > rmax) {
243
				i++;
244
				if (i && (i % 4 == 0))
245
					rmax *= 1.25;
246
				else
247
					rmax *= 2;
248 66f8696f Scott Ullrich
249 5b237745 Scott Ullrich
				if (i == 8)
250
					rmax *= 1.024;
251
			}
252
		}
253 66f8696f Scott Ullrich
254 5b237745 Scott Ullrich
		scale = <?=$height?> / rmax;
255 66f8696f Scott Ullrich
256 5b237745 Scott Ullrich
		/* change labels accordingly */
257
		SVGDoc.getElementById('grid_txt1').getFirstChild().setData(formatSpeed(3*rmax/4,unit));
258
		SVGDoc.getElementById('grid_txt2').getFirstChild().setData(formatSpeed(2*rmax/4,unit));
259
		SVGDoc.getElementById('grid_txt3').getFirstChild().setData(formatSpeed(rmax/4,unit));
260 66f8696f Scott Ullrich
261 5b237745 Scott Ullrich
		i = 0;
262 66f8696f Scott Ullrich
263 5b237745 Scott Ullrich
		while (i <= index_plot)
264
		{
265
			var x = step * i;
266
			var y_in= <?=$height?> - (plot_in[i] * scale);
267
			var y_out= <?=$height?> - (plot_out[i] * scale);
268
			if(i==0) {
269
				var path_in = "M" + x + " " + y_in;
270
				var path_out = "M" + x + " " + y_out;
271
			}
272
			else
273
			{
274
				var path_in = path_in + " L" + x + " " + y_in;
275
				var path_out = path_out + " L" + x + " " + y_out;
276
			}
277
			i = i + 1;
278
		}
279
280
		index_plot = index_plot+1;
281
		SVGDoc.getElementById('graph_in').setAttribute("d", path_in);
282
		SVGDoc.getElementById('graph_out').setAttribute("d", path_out);
283
284
		setTimeout('go()',<?=1000*$time_interval?>);
285
	}
286
	else
287
	{ //In case of Geturl fails
288
		goerror();
289
	}
290
}
291
292
function goerror() {
293
	SVGDoc.getElementById("error").getStyle().setProperty ('visibility', 'visible');
294
	setTimeout('go()',<?=1000*$time_interval?>);
295
}
296
297
function isNumber(a) {
298
    return typeof a == 'number' && isFinite(a);
299
}
300
301
function formatSpeed(speed,unit){
302
	if(unit=='bits') return formatSpeedBits(speed);
303
	else if(unit=='bytes') return formatSpeedBytes(speed);
304
}
305
306
function formatSpeedBits(speed) {
307
	// format speed in bits/sec, input: bytes/sec
308
	if (speed <	125000)
309
		return Math.round(speed / 125) + " Kbps";
310
	else if (speed < 125000000)
311
		return Math.round(speed / 1250)/100 + " Mbps";
312
	else
313
		return Math.round(speed / 1250000)/100 + " Gbps";	/* wow! */
314
}
315
function formatSpeedBytes(speed) {
316
	// format speed in bytes/sec, input:  bytes/sec
317
	if (speed <	1048576)
318
		return Math.round(speed / 10.24)/100 + " KB/s";
319
	else if (speed < 1073741824)
320
		return Math.round(speed / 10485.76)/100 + " MB/s";
321
	else
322
		return Math.round(speed / 10737418.24)/100 + " GB/s";	/* wow! */
323
}
324
function LZ(x) {
325
	return (x < 0 || x > 9 ? "" : "0") + x
326
}
327
]]></script>
328 b46bfcf5 Bill Marquette
</svg>