Project

General

Profile

Download (12.2 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
include("guiconfig.inc");
34

    
35
// 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
$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
$style['legend']="fill:black; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:4;";
58
$style['graphname']="fill:#CC0000; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:8;";
59
$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
$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
$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
	var datetime = (now.getMonth()+1) + "/" + now.getDate() + "/" + now.getFullYear() + ' ' +
147
		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

    
185
		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
		/* determine peak for sensible scaling */
206
		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
				max = plot_out[index_plot];
211
		} 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

    
225
		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

    
249
				if (i == 8)
250
					rmax *= 1.024;
251
			}
252
		}
253

    
254
		scale = <?=$height?> / rmax;
255

    
256
		/* 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

    
261
		i = 0;
262

    
263
		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
</svg>
(42-42/117)