Project

General

Profile

Download (11.4 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * status_graph.php
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2016 Rubicon Communications, LLC (Netgate)
7
 * All rights reserved.
8
 *
9
 * originally based on m0n0wall (http://m0n0.ch/wall)
10
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
11
 * All rights reserved.
12
 *
13
 * Licensed under the Apache License, Version 2.0 (the "License");
14
 * you may not use this file except in compliance with the License.
15
 * You may obtain a copy of the License at
16
 *
17
 * http://www.apache.org/licenses/LICENSE-2.0
18
 *
19
 * Unless required by applicable law or agreed to in writing, software
20
 * distributed under the License is distributed on an "AS IS" BASIS,
21
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22
 * See the License for the specific language governing permissions and
23
 * limitations under the License.
24
 */
25

    
26
##|+PRIV
27
##|*IDENT=page-status-trafficgraph
28
##|*NAME=Status: Traffic Graph
29
##|*DESCR=Allow access to the 'Status: Traffic Graph' page.
30
##|*MATCH=status_graph.php*
31
##|*MATCH=bandwidth_by_ip.php*
32
##|*MATCH=graph.php*
33
##|*MATCH=ifstats.php*
34
##|-PRIV
35

    
36
require_once("guiconfig.inc");
37
require_once("ipsec.inc");
38

    
39
// Get configured interface list
40
$ifdescrs = get_configured_interface_with_descr();
41
if (ipsec_enabled()) {
42
	$ifdescrs['enc0'] = gettext("IPsec");
43
}
44

    
45
foreach (array('server', 'client') as $mode) {
46
	if (is_array($config['openvpn']["openvpn-{$mode}"])) {
47
		foreach ($config['openvpn']["openvpn-{$mode}"] as $id => $setting) {
48
			if (!isset($setting['disable'])) {
49
				$ifdescrs['ovpn' . substr($mode, 0, 1) . $setting['vpnid']] = gettext("OpenVPN") . " " . $mode . ": ".htmlspecialchars($setting['description']);
50
			}
51
		}
52
	}
53
}
54

    
55
// Compatiblity to restore GET parameters used pre-2.3
56
// Useful to save a URL for a given graph configuration
57
if (isset($_GET['if']) && !isset($_POST['if'])) {
58
	$_POST['if'] = $_GET['if'];
59
}
60
if (isset($_GET['sort']) && !isset($_POST['sort'])) {
61
	$_POST['sort'] = $_GET['sort'];
62
}
63
if (isset($_GET['filter']) && !isset($_POST['filter'])) {
64
	$_POST['filter'] = $_GET['filter'];
65
}
66
if (isset($_GET['hostipformat']) && !isset($_POST['hostipformat'])) {
67
	$_POST['hostipformat'] = $_GET['hostipformat'];
68
}
69

    
70
if ($_POST['if']) {
71
	$curif = $_POST['if'];
72
	$found = false;
73
	foreach ($ifdescrs as $descr => $ifdescr) {
74
		if ($descr == $curif) {
75
			$found = true;
76
			break;
77
		}
78
	}
79
	if ($found === false) {
80
		header("Location: status_graph.php");
81
		exit;
82
	}
83
} else {
84
	if (empty($ifdescrs["wan"])) {
85
		/* Handle the case when WAN has been disabled. Use the first key in ifdescrs. */
86
		reset($ifdescrs);
87
		$curif = key($ifdescrs);
88
	} else {
89
		$curif = "wan";
90
	}
91
}
92
if ($_POST['sort']) {
93
	$cursort = $_POST['sort'];
94
} else {
95
	$cursort = "";
96
}
97
if ($_POST['filter']) {
98
	$curfilter = $_POST['filter'];
99
} else {
100
	$curfilter = "";
101
}
102
if ($_POST['hostipformat']) {
103
	$curhostipformat = $_POST['hostipformat'];
104
} else {
105
	$curhostipformat = "";
106
}
107

    
108
function iflist() {
109
	global $ifdescrs;
110

    
111
	$iflist = array();
112

    
113
	foreach ($ifdescrs as $ifn => $ifd) {
114
		$iflist[$ifn] = $ifd;
115
	}
116

    
117
	return($iflist);
118
}
119

    
120
$pgtitle = array(gettext("Status"), gettext("Traffic Graph"));
121

    
122
include("head.inc");
123

    
124
$form = new Form(false);
125
$form->addClass('auto-submit');
126

    
127
$section = new Form_Section('Graph Settings');
128

    
129
$group = new Form_Group('');
130

    
131
$group->add(new Form_Select(
132
	'if',
133
	null,
134
	$curif,
135
	iflist()
136
))->setHelp('Interface');
137

    
138
$group->add(new Form_Select(
139
	'sort',
140
	null,
141
	$cursort,
142
	array (
143
		'in'	=> gettext('Bandwidth In'),
144
		'out'	=> gettext('Bandwidth Out')
145
	)
146
))->setHelp('Sort by');
147

    
148
$group->add(new Form_Select(
149
	'filter',
150
	null,
151
	$curfilter,
152
	array (
153
		'local'	=> gettext('Local'),
154
		'remote'=> gettext('Remote'),
155
		'all'	=> gettext('All')
156
	)
157
))->setHelp('Filter');
158

    
159
$group->add(new Form_Select(
160
	'hostipformat',
161
	null,
162
	$curhostipformat,
163
	array (
164
		''			=> gettext('IP Address'),
165
		'hostname'	=> gettext('Host Name'),
166
		'descr'		=> gettext('Description'),
167
		'fqdn'		=> gettext('FQDN')
168
	)
169
))->setHelp('Display');
170

    
171
$section->add($group);
172

    
173
$form->add($section);
174
print $form;
175

    
176
?>
177

    
178
<script src="/vendor/d3/d3.min.js"></script>
179
<script src="/vendor/nvd3/nv.d3.js"></script>
180
<script src="/vendor/visibility/visibility-1.2.3.min.js"></script>
181

    
182
<link href="/vendor/nvd3/nv.d3.css" media="screen, projection" rel="stylesheet" type="text/css">
183

    
184
<script type="text/javascript">
185

    
186
//<![CDATA[
187
events.push(function() {
188

    
189
	var InterfaceString = "<?=$curif?>";
190

    
191
	//store saved settings in a fresh localstorage
192
	localStorage.clear();
193
	localStorage.setItem('interfaces', JSON.stringify(InterfaceString.split("|"))); //TODO see if can be switched to interfaces
194
	localStorage.setItem('interval', 1);
195
	localStorage.setItem('invert', "true");
196
	localStorage.setItem('size', 1);
197

    
198
	window.charts = {};
199
    window.myData = {};
200
    window.updateIds = 0;
201
    window.latest = [];
202
    var refreshInterval = localStorage.getItem('interval');
203

    
204
    //TODO make it fall on a second value so it increments better
205
    var now = then = new Date(Date.now());
206

    
207
    var nowTime = now.getTime();
208

    
209
	$.each( JSON.parse(localStorage.getItem('interfaces')), function( key, value ) {
210

    
211
		myData[value] = [];
212
		updateIds = 0;
213

    
214
		var itemIn = new Object();
215
		var itemOut = new Object();
216

    
217
		itemIn.key = value + " (in)";
218
		if(localStorage.getItem('invert') === "true") { itemIn.area = true; }
219
		itemIn.first = true;
220
		itemIn.values = [{x: nowTime, y: 0}];
221
		myData[value].push(itemIn);
222

    
223
		itemOut.key = value + " (out)";
224
		if(localStorage.getItem('invert') === "true") { itemOut.area = true; }
225
		itemOut.first = true;
226
		itemOut.values = [{x: nowTime, y: 0}];
227
		myData[value].push(itemOut);
228

    
229
	});
230

    
231
	draw_graph(refreshInterval, then);
232

    
233
	//re-draw graph when the page goes from inactive (in it's window) to active
234
	Visibility.change(function (e, state) {
235
		if(state === "visible") {
236

    
237
			now = then = new Date(Date.now());
238

    
239
			var nowTime = now.getTime();
240

    
241
			$.each( JSON.parse(localStorage.getItem('interfaces')), function( key, value ) {
242

    
243
				Visibility.stop(updateIds);
244

    
245
				myData[value] = [];
246

    
247
				var itemIn = new Object();
248
				var itemOut = new Object();
249

    
250
				itemIn.key = value + " (in)";
251
				if(localStorage.getItem('invert') === "true") { itemIn.area = true; }
252
				itemIn.first = true;
253
				itemIn.values = [{x: nowTime, y: 0}];
254
				myData[value].push(itemIn);
255

    
256
				itemOut.key = value + " (out)";
257
				if(localStorage.getItem('invert') === "true") { itemOut.area = true; }
258
				itemOut.first = true;
259
				itemOut.values = [{x: nowTime, y: 0}];
260
				myData[value].push(itemOut);
261

    
262
			});
263

    
264
			draw_graph(refreshInterval, then);
265

    
266
		}
267
	});
268

    
269
	// save new config defaults
270
    $( '#traffic-graph-form' ).submit(function(event) {
271

    
272
		var error = false;
273
		$("#traffic-chart-error").hide();
274

    
275
		var interfaces = $( "#traffic-graph-interfaces" ).val();
276
		refreshInterval = parseInt($( "#traffic-graph-interval" ).val());
277
		var invert = $( "#traffic-graph-invert" ).val();
278
		var size = $( "#traffic-graph-size" ).val();
279

    
280
		//TODO validate interfaces data and throw error
281

    
282
		if(!Number.isInteger(refreshInterval) || refreshInterval < 1 || refreshInterval > 10) {
283
			error = 'Refresh Interval is not a valid number between 1 and 10.';
284
		}
285

    
286
		if(invert != "true" && invert != "false") {
287

    
288
			error = 'Invert is not a boolean of true or false.';
289

    
290
		}
291

    
292
		if(!error) {
293

    
294
			var formData = {
295
				'traffic-graph-interfaces' : interfaces,
296
				'traffic-graph-interval'   : refreshInterval,
297
				'traffic-graph-invert'     : invert,
298
				'traffic-graph-size'       : size
299
			};
300

    
301
			$.ajax({
302
				type        : 'POST',
303
				url         : '/widgets/widgets/traffic_graphs.widget.php',
304
				data        : formData,
305
				dataType    : 'json',
306
				encode      : true
307
			})
308
			.done(function(message) {
309

    
310
				if(message.success) {
311

    
312
					Visibility.stop(updateIds);
313

    
314
					//remove all old graphs (divs/svgs)
315
					$( ".traffic-widget-chart" ).remove();
316

    
317
					localStorage.setItem('interfaces', JSON.stringify(interfaces));
318
					localStorage.setItem('interval', refreshInterval);
319
					localStorage.setItem('invert', invert);
320
					localStorage.setItem('size', size);
321

    
322
					//redraw graph with new settings
323
					now = then = new Date(Date.now());
324

    
325
					var freshData = [];
326

    
327
					var nowTime = now.getTime();
328

    
329
					$.each( interfaces, function( key, value ) {
330

    
331
						//create new graphs (divs/svgs)
332
						$("#widget-traffic_graphs_panel-body").append('<div id="traffic-chart-' + value + '" class="d3-chart traffic-widget-chart"><svg></svg></div>');
333

    
334
						myData[value] = [];
335

    
336
						var itemIn = new Object();
337
						var itemOut = new Object();
338

    
339
						itemIn.key = value + " (in)";
340
						if(localStorage.getItem('invert') === "true") { itemIn.area = true; }
341
						itemIn.first = true;
342
						itemIn.values = [{x: nowTime, y: 0}];
343
						myData[value].push(itemIn);
344

    
345
						itemOut.key = value + " (out)";
346
						if(localStorage.getItem('invert') === "true") { itemOut.area = true; }
347
						itemOut.first = true;
348
						itemOut.values = [{x: nowTime, y: 0}];
349
						myData[value].push(itemOut);
350

    
351
					});
352

    
353
					draw_graph(refreshInterval, then);
354

    
355
					$( "#traffic-graph-message" ).removeClass("text-danger").addClass("text-success");
356
					$( "#traffic-graph-message" ).text(message.success);
357

    
358
					setTimeout(function() {
359
						$( "#traffic-graph-message" ).empty();
360
						$( "#traffic-graph-message" ).removeClass("text-success");
361
					}, 5000);
362

    
363
				} else {
364

    
365
					$( "#traffic-graph-message" ).addClass("text-danger");
366
					$( "#traffic-graph-message" ).text(message.error);
367

    
368
					console.warn(message.error);
369

    
370
				}
371

    
372
	        })
373
	        .fail(function() {
374

    
375
			    console.warn( "The Traffic Graphs widget AJAX request failed." );
376

    
377
			});
378

    
379
	    } else {
380

    
381
			$( "#traffic-graph-message" ).addClass("text-danger");
382
			$( "#traffic-graph-message" ).text(error);
383

    
384
			console.warn(error);
385

    
386
	    }
387

    
388
        event.preventDefault();
389
    });
390

    
391
});
392
//]]>
393
</script>
394

    
395
<script src="/js/traffic-graphs.js"></script>
396

    
397
<script type="text/javascript">
398
//<![CDATA[
399

    
400
function updateBandwidth() {
401
	$.ajax(
402
		'/bandwidth_by_ip.php',
403
		{
404
			type: 'get',
405
			data: $(document.forms[0]).serialize(),
406
			success: function (data) {
407
				var hosts_split = data.split("|");
408

    
409
				$('#top10-hosts').empty();
410

    
411
				//parse top ten bandwidth abuser hosts
412
				for (var y=0; y<10; y++) {
413
					if ((y < hosts_split.length) && (hosts_split[y] != "") && (hosts_split[y] != "no info")) {
414
						hostinfo = hosts_split[y].split(";");
415

    
416
						$('#top10-hosts').append('<tr>'+
417
							'<td>'+ hostinfo[0] +'</td>'+
418
							'<td>'+ hostinfo[1] +' <?=gettext("Bits/sec");?></td>'+
419
							'<td>'+ hostinfo[2] +' <?=gettext("Bits/sec");?></td>'+
420
						'</tr>');
421
					}
422
				}
423
			},
424
	});
425
}
426

    
427
events.push(function() {
428
	$('form.auto-submit').on('change', function() {
429
		$(this).submit();
430
	});
431

    
432
	setInterval('updateBandwidth()', 3000);
433

    
434
	updateBandwidth();
435
});
436
//]]>
437
</script>
438
<?php
439

    
440
/* link the ipsec interface magically */
441
if (ipsec_enabled()) {
442
	$ifdescrs['enc0'] = gettext("IPsec");
443
}
444

    
445
?>
446
<div class="panel panel-default">
447
	<div class="panel-heading">
448
		<h2 class="panel-title"><?=gettext("Traffic Graph");?></h2>
449
	</div>
450
	<div class="panel-body">
451
		<div class="col-sm-6">
452
			<div id="traffic-chart-<?=$curif?>" class="d3-chart traffic-widget-chart">
453
				<svg></svg>
454
			</div>
455
		</div>
456
		<div class="col-sm-6">
457
			<table class="table table-striped table-condensed">
458
				<thead>
459
					<tr>
460
						<th><?=(($curhostipformat == "") ? gettext("Host IP") : gettext("Host Name or IP")); ?></th>
461
						<th><?=gettext("Bandwidth In"); ?></th>
462
						<th><?=gettext("Bandwidth Out"); ?></th>
463
					</tr>
464
				</thead>
465
				<tbody id="top10-hosts">
466
					<!-- to be added by javascript -->
467
				</tbody>
468
			</table>
469
		</div>
470
	</div>
471
</div>
472
<?php include("foot.inc");
(161-161/225)