Project

General

Profile

Download (40.6 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	rrd.inc
4

    
5
	part of pfSense (https://www.pfsense.org)
6
	Copyright (C) 2010 Seth Mos <seth.mos@dds.nl>
7
	Copyright (c) 2010-2016 Electric Sheep Fencing, LLC.
8
	All rights reserved.
9

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

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

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

    
21
	3. All advertising materials mentioning features or use of this software
22
	   must display the following acknowledgment:
23
	   "This product includes software developed by the pfSense Project
24
	   for use in the pfSense® software distribution. (http://www.pfsense.org/).
25

    
26
	4. The names "pfSense" and "pfSense Project" must not be used to
27
	   endorse or promote products derived from this software without
28
	   prior written permission. For written permission, please contact
29
	   coreteam@pfsense.org.
30

    
31
	5. Products derived from this software may not be called "pfSense"
32
	   nor may "pfSense" appear in their names without prior written
33
	   permission of the Electric Sheep Fencing, LLC.
34

    
35
	6. Redistributions of any form whatsoever must retain the following
36
	   acknowledgment:
37

    
38
	"This product includes software developed by the pfSense Project
39
	for use in the pfSense software distribution (http://www.pfsense.org/).
40

    
41
	THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
42
	EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
44
	PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
45
	ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
46
	SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47
	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48
	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49
	HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
50
	STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
51
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
52
	OF THE POSSIBILITY OF SUCH DAMAGE.
53
*/
54

    
55
/* include all configuration functions */
56

    
57
global $rrd_graph_list;
58
$rrd_graph_list = array("eighthour", "day", "week", "month", "quarter", "year", "fouryear");
59
global $rrd_period_list;
60
$rrd_period_list = array("absolute" => gettext("Absolute Timespans"), "current" => gettext("Current Period"), "previous" => gettext("Previous Period"));
61
global $rrd_graph_length_list;
62
$rrd_graph_length_list = array(
63
	"eighthour" => 28800,
64
	"day" => 86400,
65
	"week" => 604800,
66
	"month" => 2678400,
67
	"quarter" => 7948800,
68
	"year" => 31622400,
69
	"fouryear" => 126230400);
70
global $rrd_style_list;
71
$rrd_style_list = array('inverse' => gettext('Inverse'),
72
		'absolute' => gettext('Absolute'));
73

    
74
function dump_rrd_to_xml($rrddatabase, $xmldumpfile) {
75
	$rrdtool = "/usr/bin/nice -n20 /usr/local/bin/rrdtool";
76
	unlink_if_exists($xmldumpfile);
77

    
78
	exec("$rrdtool dump " . escapeshellarg($rrddatabase) . " {$xmldumpfile} 2>&1", $dumpout, $dumpret);
79
	if ($dumpret <> 0) {
80
		$dumpout = implode(" ", $dumpout);
81
		log_error(sprintf(gettext('RRD dump failed exited with %1$s, the error is: %2$s'), $dumpret, $dumpout));
82
	}
83
	return($dumpret);
84
}
85

    
86
function restore_rrd() {
87
	global $g, $config;
88

    
89
	$rrddbpath = "{$g['vardb_path']}/rrd/";
90
	$rrdtool = "/usr/bin/nice -n20 /usr/local/bin/rrdtool";
91

    
92
	$rrdrestore = "";
93
	$rrdreturn = "";
94
	if (file_exists("{$g['cf_conf_path']}/rrd.tgz") && (isset($config['system']['use_mfs_tmpvar']) || $g['platform'] != $g['product_name'])) {
95
		foreach (glob("{$rrddbpath}/*.xml") as $xml_file) {
96
			@unlink($xml_file);
97
		}
98
		unset($rrdrestore);
99
		$_gb = exec("cd /;LANG=C /usr/bin/tar -tf {$g['cf_conf_path']}/rrd.tgz", $rrdrestore, $rrdreturn);
100
		if ($rrdreturn != 0) {
101
			log_error(sprintf(gettext('RRD restore failed exited with %1$s, the error is: %2$s'), $rrdreturn, $rrdrestore));
102
			return;
103
		}
104
		foreach ($rrdrestore as $xml_file) {
105
			$rrd_file = '/' . substr($xml_file, 0, -4) . '.rrd';
106
			if (file_exists("{$rrd_file}")) {
107
				@unlink($rrd_file);
108
			}
109
			file_put_contents("{$g['tmp_path']}/rrd_restore", $xml_file);
110
			$_gb = exec("cd /;LANG=C /usr/bin/tar -xf {$g['cf_conf_path']}/rrd.tgz -T {$g['tmp_path']}/rrd_restore");
111
			if (!file_exists("/{$xml_file}")) {
112
				log_error(sprintf(gettext("Could not extract %s RRD xml file from archive!"), $xml_file));
113
				continue;
114
			}
115
			$_gb = exec("$rrdtool restore -f '/{$xml_file}' '{$rrd_file}'", $output, $status);
116
			if ($status) {
117
				log_error(sprintf(gettext("rrdtool restore -f '%1\$s' '%2\$s' failed returning %3\$s."), $xml_file, $rrd_file, $status));
118
				continue;
119
			}
120
			unset($output);
121
			@unlink("/{$xml_file}");
122
		}
123
		unset($rrdrestore);
124
		@unlink("{$g['tmp_path']}/rrd_restore");
125
		/* If this backup is still there on a full install, but we aren't going to use ram disks, remove the archive since this is a transition. */
126
		if (($g['platform'] == $g['product_name']) && !isset($config['system']['use_mfs_tmpvar'])) {
127
			unlink_if_exists("{$g['cf_conf_path']}/rrd.tgz");
128
		}
129
		return true;
130
	}
131
	return false;
132
}
133

    
134
function create_new_rrd($rrdcreatecmd) {
135
	$rrdcreateoutput = array();
136
	$rrdcreatereturn = 0;
137
	$_gb = exec("$rrdcreatecmd 2>&1", $rrdcreateoutput, $rrdcreatereturn);
138
	if ($rrdcreatereturn <> 0) {
139
		$rrdcreateoutput = implode(" ", $rrdcreateoutput);
140
		log_error(sprintf(gettext('RRD create failed exited with %1$s, the error is: %2$s'), $rrdcreatereturn, $rrdcreateoutput));
141
	}
142
	unset($rrdcreateoutput);
143
	return $rrdcreatereturn;
144
}
145

    
146
function migrate_rrd_format($rrdoldxml, $rrdnewxml) {
147
	if (!file_exists("/tmp/rrd_notice_sent.txt")) {
148
		$_gb = exec("echo 'Converting RRD configuration to new format.  This might take a bit...' | wall");
149
		@touch("/tmp/rrd_notice_sent.txt");
150
	}
151
	$numrraold = count($rrdoldxml['rra']);
152
	$numrranew = count($rrdnewxml['rra']);
153
	$numdsold = count($rrdoldxml['ds']);
154
	$numdsnew = count($rrdnewxml['ds']);
155
	log_error(sprintf(gettext('Import RRD has %1$s DS values and %2$s RRA databases, new format RRD has %3$s DS values and %4$s RRA databases'), $numdsold, $numrraold, $numdsnew , $numrranew));
156

    
157
	/* add data sources not found in the old array from the new array */
158
	$i = 0;
159
	foreach ($rrdnewxml['ds'] as $ds) {
160
		if (!is_array($rrdoldxml['ds'][$i])) {
161
			$rrdoldxml['ds'][$i] = $rrdnewxml['ds'][$i];
162
			/* set unknown values to 0 */
163
			$rrdoldxml['ds'][$i]['last_ds'] = " 0.0000000000e+00 ";
164
			$rrdoldxml['ds'][$i]['value'] = " 0.0000000000e+00 ";
165
			$rrdoldxml['ds'][$i]['unknown_sec'] = "0";
166
		}
167
		$i++;
168
	}
169

    
170
	$i = 0;
171
	$rracountold = count($rrdoldxml['rra']);
172
	$rracountnew = count($rrdnewxml['rra']);
173
	/* process each RRA, which contain a database */
174
	foreach ($rrdnewxml['rra'] as $rra) {
175
		if (!is_array($rrdoldxml['rra'][$i])) {
176
			$rrdoldxml['rra'][$i] = $rrdnewxml['rra'][$i];
177
		}
178

    
179
		$d = 0;
180
		/* process cdp_prep */
181
		$cdp_prep = $rra['cdp_prep'];
182
		foreach ($cdp_prep['ds'] as $ds) {
183
			if (!is_array($rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d])) {
184
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d] = $rrdnewxml['rra'][$i]['cdp_prep']['ds'][$d];
185
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d]['primary_value'] = " 0.0000000000e+00 ";
186
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d]['secondary_value'] = " 0.0000000000e+00 ";
187
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d]['value'] = " 0.0000000000e+00 ";
188
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d]['unknown_datapoints'] = "0";
189
			}
190
			$d++;
191
		}
192

    
193
		/* process database */
194
		$rows = $rra['database'];
195
		$k = 0;
196
		$rowcountold = count($rrdoldxml['rra'][$i]['database']['row']);
197
		$rowcountnew = count($rrdnewxml['rra'][$i]['database']['row']);
198
		$rowcountdiff = $rowcountnew - $rowcountold;
199
		/* save old rows for a bit before we put the required empty rows before it */
200
		$rowsdata = $rows;
201
		$rowsempty = array();
202
		$r = 0;
203
		while ($r < $rowcountdiff) {
204
			$rowsempty[] = $rrdnewxml['rra'][$i]['database']['row'][$r];
205
			$r++;
206
		}
207
		$rows = $rowsempty + $rowsdata;
208
		/* now foreach the rows in the database */
209
		foreach ($rows['row'] as $row) {
210
			if (!is_array($rrdoldxml['rra'][$i]['database']['row'][$k])) {
211
				$rrdoldxml['rra'][$i]['database']['row'][$k] = $rrdnewxml['rra'][$i]['database']['row'][$k];
212
			}
213
			$m = 0;
214
			$vcountold = count($rrdoldxml['rra'][$i]['database']['row'][$k]['v']);
215
			$vcountnew = count($rrdnewxml['rra'][$i]['database']['row'][$k]['v']);
216
			foreach ($row['v'] as $value) {
217
				if (empty($rrdoldxml['rra'][$i]['database']['row'][$k]['v'][$m])) {
218
					if (isset($valid)) {
219
						$rrdoldxml['rra'][$i]['database']['row'][$k]['v'][$m] = "0.0000000000e+00 ";
220
					} else {
221
						$rrdoldxml['rra'][$i]['database']['row'][$k]['v'][$m] = $rrdnewxml['rra'][$i]['database']['row'][$k]['v'][$m];
222
					}
223
				} else {
224
					if ($value <> " NaN ") {
225
						$valid = true;
226
					} else {
227
						$valid = false;
228
					}
229
				}
230
				$m++;
231
			}
232
			$k++;
233
		}
234
		$i++;
235
	}
236

    
237
	$numrranew = count($rrdoldxml['rra']);
238
	$numdsnew = count($rrdoldxml['ds']);
239
	log_error(sprintf(gettext('The new RRD now has %1$s DS values and %2$s RRA databases'), $numdsnew, $numrranew));
240
	return $rrdoldxml;
241
}
242

    
243
function enable_rrd_graphing() {
244
	global $config, $g, $altq_list_queues;
245

    
246
	if (platform_booting()) {
247
		echo gettext("Generating RRD graphs...");
248
	}
249

    
250
	$rrddbpath = "{$g['vardb_path']}/rrd/";
251
	$rrdgraphpath = "/usr/local/www/rrd";
252

    
253
	$traffic = "-traffic.rrd";
254
	$packets = "-packets.rrd";
255
	$states = "-states.rrd";
256
	$wireless = "-wireless.rrd";
257
	$queues = "-queues.rrd";
258
	$queuesdrop = "-queuedrops.rrd";
259
	$spamd = "-spamd.rrd";
260
	$proc = "-processor.rrd";
261
	$mem = "-memory.rrd";
262
	$mbuf = "-mbuf.rrd";
263
	$cellular = "-cellular.rrd";
264
	$vpnusers = "-vpnusers.rrd";
265
	$captiveportalconcurrent = "-concurrent.rrd";
266
	$captiveportalloggedin = "-loggedin.rrd";
267
	$ntpd = "ntpd.rrd";
268
	$dhcpd = "-dhcpd.rrd";
269

    
270
	$rrdtool = "/usr/bin/nice -n20 /usr/local/bin/rrdtool";
271
	$netstat = "/usr/bin/netstat";
272
	$awk = "/usr/bin/awk";
273
	$tar = "/usr/bin/tar";
274
	$pfctl = "/sbin/pfctl";
275
	$sysctl = "/sbin/sysctl";
276
	$php = "/usr/local/bin/php-cgi";
277
	$cpustats = "/usr/local/sbin/cpustats";
278
	$spamd_gather = "/usr/local/bin/spamd_gather_stats.php";
279
	$ifconfig = "/sbin/ifconfig";
280
	$captiveportal_gather = "/usr/local/bin/captiveportal_gather_stats.php";
281
	$dhcpd_gather = "/usr/local/bin/dhcpd_gather_stats.php";
282
	$ntpq = "/usr/local/sbin/ntpq";
283

    
284
	$rrdtrafficinterval = 60;
285
	$rrdwirelessinterval = 60;
286
	$rrdqueuesinterval = 60;
287
	$rrdqueuesdropinterval = 60;
288
	$rrdpacketsinterval = 60;
289
	$rrdstatesinterval = 60;
290
	$rrdspamdinterval = 60;
291
	$rrdlbpoolinterval = 60;
292
	$rrdprocinterval = 60;
293
	$rrdmeminterval = 60;
294
	$rrdmbufinterval = 60;
295
	$rrdcellularinterval = 60;
296
	$rrdvpninterval = 60;
297
	$rrdcaptiveportalinterval = 60;
298
	$rrdntpdinterval = 60;
299
	$rrddhcpdinterval = 60;
300

    
301
	$trafficvalid = $rrdtrafficinterval * 2;
302
	$wirelessvalid = $rrdwirelessinterval * 2;
303
	$queuesvalid = $rrdqueuesinterval * 2;
304
	$queuesdropvalid = $rrdqueuesdropinterval * 2;
305
	$packetsvalid = $rrdpacketsinterval * 2;
306
	$statesvalid = $rrdstatesinterval*2;
307
	$spamdvalid = $rrdspamdinterval * 2;
308
	$lbpoolvalid = $rrdlbpoolinterval * 2;
309
	$procvalid = $rrdlbpoolinterval * 2;
310
	$memvalid = $rrdmeminterval * 2;
311
	$mbufvalid = $rrdmbufinterval * 2;
312
	$cellularvalid = $rrdcellularinterval * 2;
313
	$vpnvalid = $rrdvpninterval * 2;
314
	$captiveportalvalid = $rrdcaptiveportalinterval * 2;
315
	$ntpdvalid = $rrdntpdinterval * 2;
316
	$dhcpdvalid = $rrddhcpdinterval * 2;
317

    
318
	/* Assume 2*10GigE for now */
319
	$downstream = 2500000000;
320
	$upstream = 2500000000;
321

    
322
	/* read the shaper config */
323
	read_altq_config();
324

    
325
	if (isset ($config['rrd']['enable'])) {
326

    
327
		/* create directory if needed */
328
		if (!is_dir($rrddbpath)) {
329
			mkdir($rrddbpath, 0775);
330
		}
331
		chown($rrddbpath, "nobody");
332

    
333
		if (platform_booting()) {
334
			restore_rrd();
335
		}
336

    
337
		/* db update script */
338
		$rrdupdatesh = "#!/bin/sh\n";
339
		$rrdupdatesh .= "\n";
340
		$rrdupdatesh .= "export TERM=dumb\n";
341
		$rrdupdatesh .= "\n";
342
		$rrdupdatesh .= 'echo $$ > ' . $g['varrun_path'] . '/updaterrd.sh.pid';
343
		$rrdupdatesh .= "\n";
344
		$rrdupdatesh .= "counter=1\n";
345
		$rrdupdatesh .= "while [ \"\$counter\" -ne 0 ]\n";
346
		$rrdupdatesh .= "do\n";
347
		$rrdupdatesh .= "";
348

    
349
		$i = 0;
350
		$ifdescrs = get_configured_interface_with_descr();
351
		/* IPsec counters */
352
		$ifdescrs['ipsec'] = "IPsec";
353
		/* OpenVPN server counters */
354
		if (is_array($config['openvpn']['openvpn-server'])) {
355
			foreach ($config['openvpn']['openvpn-server'] as $server) {
356
				$serverid = "ovpns" . $server['vpnid'];
357
				$ifdescrs[$serverid] = "{$server['description']}";
358
			}
359
		}
360

    
361
		if (platform_booting()) {
362
			if (!is_dir($rrddbpath)) {
363
				mkdir($rrddbpath, 0775);
364
			}
365

    
366
			@chown($rrddbpath, "nobody");
367
		}
368

    
369
		/* process all real and pseudo interfaces */
370
		foreach ($ifdescrs as $ifname => $ifdescr) {
371
			$temp = get_real_interface($ifname);
372
			if ($temp <> "") {
373
				$realif = $temp;
374
			}
375

    
376
			/* TRAFFIC, set up the rrd file */
377
			if (!file_exists("$rrddbpath$ifname$traffic")) {
378
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$traffic --step $rrdtrafficinterval ";
379
				$rrdcreate .= "DS:inpass:COUNTER:$trafficvalid:0:$downstream ";
380
				$rrdcreate .= "DS:outpass:COUNTER:$trafficvalid:0:$upstream ";
381
				$rrdcreate .= "DS:inblock:COUNTER:$trafficvalid:0:$downstream ";
382
				$rrdcreate .= "DS:outblock:COUNTER:$trafficvalid:0:$upstream ";
383
				$rrdcreate .= "DS:inpass6:COUNTER:$trafficvalid:0:$downstream ";
384
				$rrdcreate .= "DS:outpass6:COUNTER:$trafficvalid:0:$upstream ";
385
				$rrdcreate .= "DS:inblock6:COUNTER:$trafficvalid:0:$downstream ";
386
				$rrdcreate .= "DS:outblock6:COUNTER:$trafficvalid:0:$upstream ";
387
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
388
				$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
389
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
390
				$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
391

    
392
				create_new_rrd($rrdcreate);
393
				unset($rrdcreate);
394
			}
395

    
396
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
397
			if (platform_booting()) {
398
				mwexec("$rrdtool update $rrddbpath$ifname$traffic N:U:U:U:U:U:U:U:U");
399
			}
400

    
401
			$rrdupdatesh .= "\n";
402
			$rrdupdatesh .= "# polling traffic for interface $ifname $realif IPv4/IPv6 counters \n";
403
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$traffic N:";
404
			$rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '\\\n";
405
			$rrdupdatesh .= "/In4\/Pass/ { b4pi = \$6 };/Out4\/Pass/ { b4po = \$6 };/In4\/Block/ { b4bi = \$6 };/Out4\/Block/ { b4bo = \$6 };\\\n";
406
			$rrdupdatesh .= "/In6\/Pass/ { b6pi = \$6 };/Out6\/Pass/ { b6po = \$6 };/In6\/Block/ { b6bi = \$6 };/Out6\/Block/ { b6bo = \$6 };\\\n";
407
			$rrdupdatesh .= "END {print b4pi \":\" b4po \":\" b4bi \":\" b4bo \":\" b6pi \":\" b6po \":\" b6bi \":\" b6bo};'`\n";
408

    
409
			/* PACKETS, set up the rrd file */
410
			if (!file_exists("$rrddbpath$ifname$packets")) {
411
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$packets --step $rrdpacketsinterval ";
412
				$rrdcreate .= "DS:inpass:COUNTER:$packetsvalid:0:$downstream ";
413
				$rrdcreate .= "DS:outpass:COUNTER:$packetsvalid:0:$upstream ";
414
				$rrdcreate .= "DS:inblock:COUNTER:$packetsvalid:0:$downstream ";
415
				$rrdcreate .= "DS:outblock:COUNTER:$packetsvalid:0:$upstream ";
416
				$rrdcreate .= "DS:inpass6:COUNTER:$packetsvalid:0:$downstream ";
417
				$rrdcreate .= "DS:outpass6:COUNTER:$packetsvalid:0:$upstream ";
418
				$rrdcreate .= "DS:inblock6:COUNTER:$packetsvalid:0:$downstream ";
419
				$rrdcreate .= "DS:outblock6:COUNTER:$packetsvalid:0:$upstream ";
420
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
421
				$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
422
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
423
				$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
424

    
425
				create_new_rrd($rrdcreate);
426
				unset($rrdcreate);
427
			}
428

    
429
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
430
			if (platform_booting()) {
431
				mwexec("$rrdtool update $rrddbpath$ifname$packets N:U:U:U:U:U:U:U:U");
432
			}
433

    
434
			$rrdupdatesh .= "\n";
435
			$rrdupdatesh .= "# polling packets for interface $ifname $realif \n";
436
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$packets N:";
437
			$rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '\\\n";
438
			$rrdupdatesh .= "/In4\/Pass/ { b4pi = \$4 };/Out4\/Pass/ { b4po = \$4 };/In4\/Block/ { b4bi = \$4 };/Out4\/Block/ { b4bo = \$4 };\\\n";
439
			$rrdupdatesh .= "/In6\/Pass/ { b6pi = \$4 };/Out6\/Pass/ { b6po = \$4 };/In6\/Block/ { b6bi = \$4 };/Out6\/Block/ { b6bo = \$4 };\\\n";
440
			$rrdupdatesh .= "END {print b4pi \":\" b4po \":\" b4bi \":\" b4bo \":\" b6pi \":\" b6po \":\" b6bi \":\" b6bo};'`\n";
441

    
442
			/* WIRELESS, set up the rrd file */
443
			if ($config['interfaces'][$ifname]['wireless']['mode'] == "bss") {
444
				if (!file_exists("$rrddbpath$ifname$wireless")) {
445
					$rrdcreate = "$rrdtool create $rrddbpath$ifname$wireless --step $rrdwirelessinterval ";
446
					$rrdcreate .= "DS:snr:GAUGE:$wirelessvalid:0:1000 ";
447
					$rrdcreate .= "DS:rate:GAUGE:$wirelessvalid:0:1000 ";
448
					$rrdcreate .= "DS:channel:GAUGE:$wirelessvalid:0:1000 ";
449
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
450
					$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
451
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
452
					$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
453

    
454
					create_new_rrd($rrdcreate);
455
					unset($rrdcreate);
456
				}
457

    
458
				/* enter UNKNOWN values in the RRD so it knows we rebooted. */
459
				if (platform_booting()) {
460
					mwexec("$rrdtool update $rrddbpath$ifname$wireless N:U:U:U");
461
				}
462

    
463
				$rrdupdatesh .= "\n";
464
				$rrdupdatesh .= "# polling wireless for interface $ifname $realif \n";
465
				$rrdupdatesh .= "WIFI=`$ifconfig {$realif} list sta| $awk 'gsub(\"M\", \"\") {getline 2;print substr(\$5, 0, length(\$5)-2) \":\" $4 \":\" $3}'`\n";
466
				$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$wireless N:\${WIFI}\n";
467
			}
468

    
469
			/* OpenVPN, set up the rrd file */
470
			if (stristr($ifname, "ovpns")) {
471
				if (!file_exists("$rrddbpath$ifname$vpnusers")) {
472
					$rrdcreate = "$rrdtool create $rrddbpath$ifname$vpnusers --step $rrdvpninterval ";
473
					$rrdcreate .= "DS:users:GAUGE:$vpnvalid:0:10000 ";
474
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
475
					$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
476
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
477
					$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
478

    
479
					create_new_rrd($rrdcreate);
480
					unset($rrdcreate);
481
				}
482

    
483
				/* enter UNKNOWN values in the RRD so it knows we rebooted. */
484
				if (platform_booting()) {
485
					mwexec("$rrdtool update $rrddbpath$ifname$vpnusers N:U");
486
				}
487

    
488
				if (is_array($config['openvpn']['openvpn-server'])) {
489
					foreach ($config['openvpn']['openvpn-server'] as $server) {
490
						if ("ovpns{$server['vpnid']}" == $ifname) {
491
							$port = $server['local_port'];
492
							$vpnid = $server['vpnid'];
493
						}
494
					}
495
				}
496
				$rrdupdatesh .= "\n";
497
				$rrdupdatesh .= "# polling vpn users for interface $ifname $realif port $port\n";
498
				$rrdupdatesh .= "list_current_users() {\n";
499
				$rrdupdatesh .= " sleep 0.2\n";
500
				$rrdupdatesh .= " echo \"status 2\"\n";
501
				$rrdupdatesh .= " sleep 0.2\n";
502
				$rrdupdatesh .= " echo \"quit\"\n";
503
				$rrdupdatesh .= "}\n";
504
				$rrdupdatesh .= "OVPN=`list_current_users | nc -U {$g['varetc_path']}/openvpn/server{$vpnid}.sock | awk -F\",\" '/^CLIENT_LIST/ {print \$2}' | wc -l | awk '{print $1}'`\n";
505
				$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$vpnusers N:\${OVPN}\n";
506
			}
507

    
508
			/* QUEUES, set up the queues databases */
509
			if ($altq_list_queues[$ifname]) {
510
				$altq =& $altq_list_queues[$ifname];
511
				/* NOTE: Is it worth as its own function?! */
512
				switch ($altq->GetBwscale()) {
513
					case "Gb":
514
						$factor = 1024 * 1024 * 1024;
515
						break;
516
					case "Mb":
517
						$factor = 1024 * 1024;
518
						break;
519
					case "Kb":
520
						$factor = 1024;
521
						break;
522
					case "b":
523
					default:
524
						$factor = 1;
525
						break;
526
				}
527
				$qbandwidth = $altq->GetBandwidth() * $factor;
528
				if ($qbandwidth <= 0) {
529
					$qbandwidth = 100 * 1000 * 1000; /* 100Mbit */
530
				}
531
				$qlist =& $altq->get_queue_list($notused);
532
				if (!file_exists("$rrddbpath$ifname$queues")) {
533
					$rrdcreate = "$rrdtool create $rrddbpath$ifname$queues --step $rrdqueuesinterval ";
534
					/* loop list of shaper queues */
535
					$q = 0;
536
					foreach ($qlist as $qname => $q) {
537
						$rrdcreate .= "DS:$qname:COUNTER:$queuesvalid:0:$qbandwidth ";
538
					}
539

    
540
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
541
					$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
542
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
543
					$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
544

    
545
					create_new_rrd($rrdcreate);
546
					unset($rrdcreate);
547
				}
548

    
549
				if (!file_exists("$rrddbpath$ifname$queuesdrop")) {
550
					$rrdcreate = "$rrdtool create $rrddbpath$ifname$queuesdrop --step $rrdqueuesdropinterval ";
551
					/* loop list of shaper queues */
552
					$q = 0;
553
					foreach ($qlist as $qname => $q) {
554
						$rrdcreate .= "DS:$qname:COUNTER:$queuesdropvalid:0:$qbandwidth ";
555
					}
556

    
557
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
558
					$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
559
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
560
					$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
561

    
562
					create_new_rrd($rrdcreate);
563
					unset($rrdcreate);
564
				}
565

    
566
				if (platform_booting()) {
567
					$rrdqcommand = "-t ";
568
					$rrducommand = "N";
569
					$qi = 0;
570
					foreach ($qlist as $qname => $q) {
571
						if ($qi == 0) {
572
							$rrdqcommand .= "{$qname}";
573
						} else {
574
							$rrdqcommand .= ":{$qname}";
575
						}
576
						$qi++;
577
						$rrducommand .= ":U";
578
					}
579
					mwexec("$rrdtool update $rrddbpath$ifname$queues $rrdqcommand $rrducommand");
580
					mwexec("$rrdtool update $rrddbpath$ifname$queuesdrop $rrdqcommand $rrducommand");
581
				}
582

    
583
				/* awk function to gather shaper data */
584
				/* yes, it's special */
585
				$rrdupdatesh .= "` pfctl -vsq -i {$realif} | awk 'BEGIN {printf \"$rrdtool update $rrddbpath$ifname$queues \" } ";
586
				$rrdupdatesh .= "{ ";
587
				$rrdupdatesh .= "if ((\$1 == \"queue\") && ( \$2 ~ /^q/ )) { ";
588
				$rrdupdatesh .= " dsname = dsname \":\" \$2 ; ";
589
				$rrdupdatesh .= " q=1; ";
590
				$rrdupdatesh .= "} ";
591
				$rrdupdatesh .= " else if ((\$4 == \"bytes:\") && ( q == 1 ) ) { ";
592
				$rrdupdatesh .= " dsdata = dsdata \":\" \$5 ; ";
593
				$rrdupdatesh .= " q=0; ";
594
				$rrdupdatesh .= "} ";
595
				$rrdupdatesh .= "} END { ";
596
				$rrdupdatesh .= " dsname = substr(dsname,2); ";
597
				$rrdupdatesh .= " dsdata = substr(dsdata,2); ";
598
				$rrdupdatesh .= " printf \"-t \" dsname \" N:\" dsdata }' ";
599
				$rrdupdatesh .= " dsname=\"\" dsdata=\"\"`\n\n";
600

    
601
				$rrdupdatesh .= "` pfctl -vsq -i {$realif} | awk 'BEGIN {printf \"$rrdtool update $rrddbpath$ifname$queuesdrop \" } ";
602
				$rrdupdatesh .= "{ ";
603
				$rrdupdatesh .= "if ((\$1 == \"queue\") && ( \$2 ~ /^q/ )) { ";
604
				$rrdupdatesh .= " dsname = dsname \":\" \$2 ; ";
605
				$rrdupdatesh .= " q=1; ";
606
				$rrdupdatesh .= "} ";
607
				$rrdupdatesh .= " else if ((\$4 == \"bytes:\") && ( q == 1 ) ) { ";
608
				$rrdupdatesh .= " dsdata = dsdata \":\" \$8 ; ";
609
				$rrdupdatesh .= " q=0; ";
610
				$rrdupdatesh .= "} ";
611
				$rrdupdatesh .= "} END { ";
612
				$rrdupdatesh .= " dsname = substr(dsname,2); ";
613
				$rrdupdatesh .= " dsdata = substr(dsdata,2); ";
614
				$rrdupdatesh .= " printf \"-t \" dsname \" N:\" dsdata }' ";
615
				$rrdupdatesh .= " dsname=\"\" dsdata=\"\"`\n\n";
616
			}
617

    
618
			/* 3G interfaces */
619
			if (preg_match("/ppp[0-9]+/i", $realif))	{
620
				if (!file_exists("$rrddbpath$ifname$cellular")) {
621
					$rrdcreate = "$rrdtool create $rrddbpath$ifname$cellular --step $rrdcellularinterval ";
622
					$rrdcreate .= "DS:rssi:GAUGE:$cellularvalid:0:100 ";
623
					$rrdcreate .= "DS:upstream:GAUGE:$cellularvalid:0:100000000 ";
624
					$rrdcreate .= "DS:downstream:GAUGE:$cellularvalid:0:100000000 ";
625
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
626
					$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
627
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
628
					$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
629
					create_new_rrd($rrdcreate);
630
					unset($rrdcreate);
631
				}
632

    
633
				/* enter UNKNOWN values in the RRD so it knows we rebooted. */
634
				if (platform_booting()) {
635
					mwexec("$rrdtool update $rrddbpath$ifname$cellular N:U:U:U");
636
				}
637

    
638
				$rrdupdatesh .= "\n";
639
				$rrdupdatesh .= "# polling 3G\n";
640
				$rrdupdatesh .= "GSTATS=`awk -F, 'getline 2 {print \$2 \":\" \$8 \":\" \$9}' < /tmp/3gstats.$ifname`\n";
641
				$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$cellular N:\"\$GSTATS\"";
642
			}
643

    
644
		}
645
		$i++;
646

    
647
		/* System only statistics */
648
		$ifname = "system";
649

    
650
		/* STATES, create pf states database */
651
		if (!file_exists("$rrddbpath$ifname$states")) {
652
			$rrdcreate = "$rrdtool create $rrddbpath$ifname$states --step $rrdstatesinterval ";
653
			$rrdcreate .= "DS:pfrate:GAUGE:$statesvalid:0:10000000 ";
654
			$rrdcreate .= "DS:pfstates:GAUGE:$statesvalid:0:10000000 ";
655
			$rrdcreate .= "DS:pfnat:GAUGE:$statesvalid:0:10000000 ";
656
			$rrdcreate .= "DS:srcip:GAUGE:$statesvalid:0:10000000 ";
657
			$rrdcreate .= "DS:dstip:GAUGE:$statesvalid:0:10000000 ";
658
			$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
659
			$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
660
			$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
661
			$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
662

    
663
			create_new_rrd($rrdcreate);
664
			unset($rrdcreate);
665
		}
666

    
667
		/* enter UNKNOWN values in the RRD so it knows we rebooted. */
668
		if (platform_booting()) {
669
			mwexec("$rrdtool update $rrddbpath$ifname$states N:U:U:U:U:U");
670
		}
671

    
672
		/* the pf states gathering function. */
673
		$rrdupdatesh .= "\n";
674
		$rrdupdatesh .= "pfctl_si_out=\"` $pfctl -si > /tmp/pfctl_si_out `\"\n";
675
		$rrdupdatesh .= "pfctl_ss_out=\"` $pfctl -ss > /tmp/pfctl_ss_out`\"\n";
676
		$rrdupdatesh .= "pfrate=\"` cat /tmp/pfctl_si_out | egrep \"inserts|removals\" | awk '{ pfrate = \$3 + pfrate } {print pfrate}'|tail -1 `\"\n";
677
		$rrdupdatesh .= "pfstates=\"` cat /tmp/pfctl_ss_out | egrep -v \"<\\-.*?<\\-|\\->.*?\\->\" | wc -l|sed 's/ //g'`\"\n";
678
		$rrdupdatesh .= "pfnat=\"` cat /tmp/pfctl_ss_out | egrep '<\\-.*?<\\-|\\->.*?\\->' | wc -l|sed 's/ //g' `\"\n";
679
		$rrdupdatesh .= "srcip=\"` cat /tmp/pfctl_ss_out | egrep -v '<\\-.*?<\\-|\\->.*?\\->' | grep '\\->' | awk '{print \$3}' | awk -F: '{print \$1}' | sort -u|wc -l|sed 's/ //g' `\"\n";
680
		$rrdupdatesh .= "dstip=\"` cat /tmp/pfctl_ss_out | egrep -v '<\\-.*?<\\-|\\->.*?\\->' | grep '<\\-' | awk '{print \$3}' | awk -F: '{print \$1}' | sort -u|wc -l|sed 's/ //g' `\"\n";
681
		$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$states N:\$pfrate:\$pfstates:\$pfnat:\$srcip:\$dstip\n\n";
682

    
683
		/* End pf states statistics */
684

    
685
		/* CPU, create CPU statistics database */
686
		if (!file_exists("$rrddbpath$ifname$proc")) {
687
			$rrdcreate = "$rrdtool create $rrddbpath$ifname$proc --step $rrdprocinterval ";
688
			$rrdcreate .= "DS:user:GAUGE:$procvalid:0:10000000 ";
689
			$rrdcreate .= "DS:nice:GAUGE:$procvalid:0:10000000 ";
690
			$rrdcreate .= "DS:system:GAUGE:$procvalid:0:10000000 ";
691
			$rrdcreate .= "DS:interrupt:GAUGE:$procvalid:0:10000000 ";
692
			$rrdcreate .= "DS:processes:GAUGE:$procvalid:0:10000000 ";
693
			$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
694
			$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
695
			$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
696
			$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
697

    
698
			create_new_rrd($rrdcreate);
699
			unset($rrdcreate);
700
		}
701

    
702
		/* enter UNKNOWN values in the RRD so it knows we rebooted. */
703
		if (platform_booting()) {
704
			mwexec("$rrdtool update $rrddbpath$ifname$proc N:U:U:U:U:U");
705
		}
706

    
707
		/* the CPU stats gathering function. */
708
		$rrdupdatesh .= "CPU=`$cpustats | cut -f1-4 -d':'`\n";
709
		/* Using ps uxaH will count all processes including system threads. Top was undercounting. */
710
		$rrdupdatesh .= "PROCS=`ps uxaH | wc -l | awk '{print \$1;}'`\n";
711
		$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$proc N:\${CPU}:\${PROCS}\n";
712

    
713
		/* End CPU statistics */
714

    
715
		/* Memory, create Memory statistics database */
716
		if (!file_exists("$rrddbpath$ifname$mem")) {
717
			$rrdcreate = "$rrdtool create $rrddbpath$ifname$mem --step $rrdmeminterval ";
718
			$rrdcreate .= "DS:active:GAUGE:$memvalid:0:10000000 ";
719
			$rrdcreate .= "DS:inactive:GAUGE:$memvalid:0:10000000 ";
720
			$rrdcreate .= "DS:free:GAUGE:$memvalid:0:10000000 ";
721
			$rrdcreate .= "DS:cache:GAUGE:$memvalid:0:10000000 ";
722
			$rrdcreate .= "DS:wire:GAUGE:$memvalid:0:10000000 ";
723
			$rrdcreate .= "RRA:MIN:0.5:1:1200 ";
724
			$rrdcreate .= "RRA:MIN:0.5:5:720 ";
725
			$rrdcreate .= "RRA:MIN:0.5:60:1860 ";
726
			$rrdcreate .= "RRA:MIN:0.5:1440:2284 ";
727
			$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
728
			$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
729
			$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
730
			$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
731
			$rrdcreate .= "RRA:MAX:0.5:1:1200 ";
732
			$rrdcreate .= "RRA:MAX:0.5:5:720 ";
733
			$rrdcreate .= "RRA:MAX:0.5:60:1860 ";
734
			$rrdcreate .= "RRA:MAX:0.5:1440:2284";
735

    
736
			create_new_rrd($rrdcreate);
737
			unset($rrdcreate);
738
		}
739

    
740
		/* enter UNKNOWN values in the RRD so it knows we rebooted. */
741
		if (platform_booting()) {
742
			mwexec("$rrdtool update $rrddbpath$ifname$mem N:U:U:U:U:U");
743
		}
744

    
745
		/* the Memory stats gathering function. */
746
		$rrdupdatesh .= "MEM=`$sysctl -n vm.stats.vm.v_page_count vm.stats.vm.v_active_count vm.stats.vm.v_inactive_count vm.stats.vm.v_free_count vm.stats.vm.v_cache_count vm.stats.vm.v_wire_count | ";
747
		$rrdupdatesh .= " $awk '{getline active;getline inactive;getline free;getline cache;getline wire;printf ";
748
		$rrdupdatesh .= "((active/$0) * 100)\":\"((inactive/$0) * 100)\":\"((free/$0) * 100)\":\"((cache/$0) * 100)\":\"(wire/$0 * 100)}'`\n";
749
		$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$mem N:\${MEM}\n";
750

    
751
		/* End Memory statistics */
752

    
753
		/* mbuf, create mbuf statistics database */
754
		if (!file_exists("$rrddbpath$ifname$mbuf")) {
755
			$rrdcreate = "$rrdtool create $rrddbpath$ifname$mbuf --step $rrdmbufinterval ";
756
			$rrdcreate .= "DS:current:GAUGE:$mbufvalid:0:10000000 ";
757
			$rrdcreate .= "DS:cache:GAUGE:$mbufvalid:0:10000000 ";
758
			$rrdcreate .= "DS:total:GAUGE:$mbufvalid:0:10000000 ";
759
			$rrdcreate .= "DS:max:GAUGE:$mbufvalid:0:10000000 ";
760
			$rrdcreate .= "RRA:MIN:0.5:1:1200 ";
761
			$rrdcreate .= "RRA:MIN:0.5:5:720 ";
762
			$rrdcreate .= "RRA:MIN:0.5:60:1860 ";
763
			$rrdcreate .= "RRA:MIN:0.5:1440:2284 ";
764
			$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
765
			$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
766
			$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
767
			$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
768
			$rrdcreate .= "RRA:MAX:0.5:1:1200 ";
769
			$rrdcreate .= "RRA:MAX:0.5:5:720 ";
770
			$rrdcreate .= "RRA:MAX:0.5:60:1860 ";
771
			$rrdcreate .= "RRA:MAX:0.5:1440:2284";
772

    
773
			create_new_rrd($rrdcreate);
774
			unset($rrdcreate);
775
		}
776

    
777
		/* enter UNKNOWN values in the RRD so it knows we rebooted. */
778
		if (platform_booting()) {
779
			mwexec("$rrdtool update $rrddbpath$ifname$mbuf N:U:U:U:U");
780
		}
781

    
782
		/* the mbuf stats gathering function. */
783
		$rrdupdatesh .= "MBUF=`$netstat -m | ";
784
		$rrdupdatesh .= " $awk '/mbuf clusters in use/ { gsub(/\//, \":\", $1); print $1; }'`\n";
785
		$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$mbuf N:\${MBUF}\n";
786

    
787
		/* End mbuf statistics */
788

    
789
		/* SPAMD, set up the spamd rrd file */
790
		if (isset($config['installedpackages']['spamdsettings']) &&
791
		    $config['installedpackages']['spamdsettings']['config'][0]['enablerrd']) {
792
			/* set up the spamd rrd file */
793
			if (!file_exists("$rrddbpath$ifname$spamd")) {
794
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$spamd --step $rrdspamdinterval ";
795
				$rrdcreate .= "DS:conn:GAUGE:$spamdvalid:0:10000 ";
796
				$rrdcreate .= "DS:time:GAUGE:$spamdvalid:0:86400 ";
797
				$rrdcreate .= "RRA:MIN:0.5:1:1200 ";
798
				$rrdcreate .= "RRA:MIN:0.5:5:720 ";
799
				$rrdcreate .= "RRA:MIN:0.5:60:1860 ";
800
				$rrdcreate .= "RRA:MIN:0.5:1440:2284 ";
801
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
802
				$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
803
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
804
				$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
805
				$rrdcreate .= "RRA:MAX:0.5:1:1200 ";
806
				$rrdcreate .= "RRA:MAX:0.5:5:720 ";
807
				$rrdcreate .= "RRA:MAX:0.5:60:1860 ";
808
				$rrdcreate .= "RRA:MAX:0.5:1440:2284 ";
809

    
810
				create_new_rrd($rrdcreate);
811
				unset($rrdcreate);
812
			}
813

    
814
			$rrdupdatesh .= "\n";
815
			$rrdupdatesh .= "# polling spamd for connections and tarpitness \n";
816
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$spamd \\\n";
817
			$rrdupdatesh .= "`$php -q $spamd_gather`\n";
818

    
819
		}
820
		/* End System statistics */
821

    
822
		/* Captive Portal statistics, set up the rrd file */
823
		if (is_array($config['captiveportal'])) {
824
			foreach ($config['captiveportal'] as $cpkey => $cp) {
825
				if (!isset($cp['enable'])) {
826
					continue;
827
				}
828

    
829
				$ifname= "captiveportal";
830
				$concurrent_filename = $rrddbpath . $ifname . '-' . $cpkey . $captiveportalconcurrent;
831
				if (!file_exists("$concurrent_filename")) {
832
					$rrdcreate = "$rrdtool create $concurrent_filename --step $rrdcaptiveportalinterval ";
833
					$rrdcreate .= "DS:concurrentusers:GAUGE:$captiveportalvalid:0:10000 ";
834
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
835
					$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
836
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
837
					$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
838
					$rrdcreate .= "RRA:MIN:0.5:1:1200 ";
839
					$rrdcreate .= "RRA:MIN:0.5:5:720 ";
840
					$rrdcreate .= "RRA:MIN:0.5:60:1860 ";
841
					$rrdcreate .= "RRA:MIN:0.5:1440:2284 ";
842
					$rrdcreate .= "RRA:MAX:0.5:1:1200 ";
843
					$rrdcreate .= "RRA:MAX:0.5:5:720 ";
844
					$rrdcreate .= "RRA:MAX:0.5:60:1860 ";
845
					$rrdcreate .= "RRA:MAX:0.5:1440:2284 ";
846
					$rrdcreate .= "RRA:LAST:0.5:1:1200 ";
847
					$rrdcreate .= "RRA:LAST:0.5:5:720 ";
848
					$rrdcreate .= "RRA:LAST:0.5:60:1860 ";
849
					$rrdcreate .= "RRA:LAST:0.5:1440:2284 ";
850

    
851
					create_new_rrd($rrdcreate);
852
					unset($rrdcreate);
853
				}
854

    
855
				/* enter UNKNOWN values in the RRD so it knows we rebooted. */
856
				if (platform_booting()) {
857
					mwexec("$rrdtool update $concurrent_filename N:U");
858
				}
859

    
860
				/* the Captive Portal stats gathering function. */
861
				$rrdupdatesh .= "\n";
862
				$rrdupdatesh .= "# polling Captive Portal for number of concurrent users\n";
863
				$rrdupdatesh .= "CP=`${php} -q ${captiveportal_gather} '${cpkey}' 'concurrent'`\n";
864
				$rrdupdatesh .= "$rrdtool update $concurrent_filename \${CP}\n";
865

    
866
				$loggedin_filename = $rrddbpath . $ifname . '-' . $cpkey . $captiveportalloggedin;
867
				if (!file_exists("$loggedin_filename")) {
868
					$rrdcreate = "$rrdtool create $loggedin_filename --step $rrdcaptiveportalinterval ";
869
					$rrdcreate .= "DS:loggedinusers:GAUGE:$captiveportalvalid:0:10000 ";
870
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
871
					$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
872
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
873
					$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
874
					$rrdcreate .= "RRA:MIN:0.5:1:1200 ";
875
					$rrdcreate .= "RRA:MIN:0.5:5:720 ";
876
					$rrdcreate .= "RRA:MIN:0.5:60:1860 ";
877
					$rrdcreate .= "RRA:MIN:0.5:1440:2284 ";
878
					$rrdcreate .= "RRA:MAX:0.5:1:1200 ";
879
					$rrdcreate .= "RRA:MAX:0.5:5:720 ";
880
					$rrdcreate .= "RRA:MAX:0.5:60:1860 ";
881
					$rrdcreate .= "RRA:MAX:0.5:1440:2284 ";
882
					$rrdcreate .= "RRA:LAST:0.5:1:1200 ";
883
					$rrdcreate .= "RRA:LAST:0.5:5:720 ";
884
					$rrdcreate .= "RRA:LAST:0.5:60:1860 ";
885
					$rrdcreate .= "RRA:LAST:0.5:1440:2284 ";
886

    
887
					create_new_rrd($rrdcreate);
888
					unset($rrdcreate);
889
				}
890

    
891
				/* enter UNKNOWN values in the RRD so it knows we rebooted. */
892
				if (platform_booting()) {
893
					mwexec("$rrdtool update $loggedin_filename N:U");
894
				}
895

    
896
				/* the Captive Portal stats gathering function. */
897
				$rrdupdatesh .= "\n";
898
				$rrdupdatesh .= "# polling Captive Portal for number of logged in users\n";
899
				$rrdupdatesh .= "CP=`${php} -q ${captiveportal_gather} '${cpkey}' 'loggedin'`\n";
900
				$rrdupdatesh .= "$rrdtool update $loggedin_filename \${CP}\n";
901

    
902
			}
903
		}
904
		/* End Captive Portal statistics */
905

    
906
		/* NTP, set up the ntpd rrd file */
907
		if (isset($config['ntpd']['statsgraph'])) {
908
			/* set up the ntpd rrd file */
909
			if (!file_exists("$rrddbpath$ntpd")) {
910
				$rrdcreate = "$rrdtool create $rrddbpath$ntpd --step $rrdntpdinterval ";
911
				$rrdcreate .= "DS:offset:GAUGE:$ntpdvalid:-1000:1000 ";
912
				$rrdcreate .= "DS:sjit:GAUGE:$ntpdvalid:0:1000 ";
913
				$rrdcreate .= "DS:cjit:GAUGE:$ntpdvalid:0:1000 ";
914
				$rrdcreate .= "DS:wander:GAUGE:$ntpdvalid:0:1000 ";
915
				$rrdcreate .= "DS:freq:GAUGE:$ntpdvalid:0:1000 ";
916
				$rrdcreate .= "DS:disp:GAUGE:$ntpdvalid:0:1000 ";
917
				$rrdcreate .= "RRA:MIN:0.5:1:1200 ";
918
				$rrdcreate .= "RRA:MIN:0.5:5:720 ";
919
				$rrdcreate .= "RRA:MIN:0.5:60:1860 ";
920
				$rrdcreate .= "RRA:MIN:0.5:1440:2284 ";
921
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
922
				$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
923
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
924
				$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
925
				$rrdcreate .= "RRA:MAX:0.5:1:1200 ";
926
				$rrdcreate .= "RRA:MAX:0.5:5:720 ";
927
				$rrdcreate .= "RRA:MAX:0.5:60:1860 ";
928
				$rrdcreate .= "RRA:MAX:0.5:1440:2284 ";
929

    
930
				create_new_rrd($rrdcreate);
931
				unset($rrdcreate);
932
			}
933

    
934
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
935
			if (platform_booting()) {
936
				mwexec("$rrdtool update $rrddbpath$ntpd N:U:U:U:U:U:U");
937
			}
938

    
939
			/* the ntp stats gathering function. */
940
			$rrdupdatesh .= "\n";
941
			$rrdupdatesh .= "$ntpq -c rv | $awk 'BEGIN{ RS=\",\"}{ print }' >> /tmp/ntp-rrdstats.$$\n";
942
			$rrdupdatesh .= "NOFFSET=`grep offset /tmp/ntp-rrdstats.$$ | awk 'BEGIN{FS=\"=\"}{print $2}'`\n";
943
			$rrdupdatesh .= "NFREQ=`grep frequency /tmp/ntp-rrdstats.$$ | awk 'BEGIN{FS=\"=\"}{print $2}'`\n";
944
			$rrdupdatesh .= "NSJIT=`grep sys_jitter /tmp/ntp-rrdstats.$$ | awk 'BEGIN{FS=\"=\"}{print $2}'`\n";
945
			$rrdupdatesh .= "NCJIT=`grep clk_jitter /tmp/ntp-rrdstats.$$ | awk 'BEGIN{FS=\"=\"}{print $2}'`\n";
946
			$rrdupdatesh .= "NWANDER=`grep clk_wander /tmp/ntp-rrdstats.$$ | awk 'BEGIN{FS=\"=\"}{print $2}'`\n";
947
			$rrdupdatesh .= "NDISPER=`grep rootdisp /tmp/ntp-rrdstats.$$ | awk 'BEGIN{FS=\"=\"}{print $2}'`\n";
948
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ntpd \N:\${NOFFSET}:\${NSJIT}:\${NCJIT}:\${NWANDER}:\${NFREQ}:\${NDISPER}\n";
949
			$rrdupdatesh .= "rm /tmp/ntp-rrdstats.$$\n";
950
			$rrdupdatesh .= "\n";
951

    
952
		}
953
		/* End NTP statistics */
954

    
955
		/* Start dhcpd statistics */
956
		if (is_array($config['dhcpd'])) {
957
			foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {
958
				if (isset($config['dhcpd'][$dhcpif]['statsgraph'])) {
959
					if (!file_exists("$rrddbpath$dhcpif$dhcpd")) {
960
						$rrdcreate = "$rrdtool create $rrddbpath$dhcpif$dhcpd --step $rrddhcpdinterval ";
961
						$rrdcreate .= "DS:leases:GAUGE:$dhcpdvalid:0:100000 ";
962
						$rrdcreate .= "DS:staticleases:GAUGE:$dhcpdvalid:0:100000 ";
963
						$rrdcreate .= "DS:dhcprange:GAUGE:$dhcpdvalid:0:100000 ";
964
						$rrdcreate .= "RRA:MIN:0.5:1:1200 ";
965
						$rrdcreate .= "RRA:MIN:0.5:5:720 ";
966
						$rrdcreate .= "RRA:MIN:0.5:60:1860 ";
967
						$rrdcreate .= "RRA:MIN:0.5:1440:2284 ";
968
						$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
969
						$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
970
						$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
971
						$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
972
						$rrdcreate .= "RRA:MAX:0.5:1:1200 ";
973
						$rrdcreate .= "RRA:MAX:0.5:5:720 ";
974
						$rrdcreate .= "RRA:MAX:0.5:60:1860 ";
975
						$rrdcreate .= "RRA:MAX:0.5:1440:2284 ";
976
						create_new_rrd($rrdcreate);
977
						unset($rrdcreate);
978
					}
979

    
980
					/* enter UNKNOWN values in the RRD so it knows we rebooted. */
981
					if (platform_booting()) {
982
						mwexec("$rrdtool update $rrddbpath$dhcpif$dhcpd N:U:U:U");
983
					}
984

    
985
					$rrdupdatesh .= "\n";
986
					$rrdupdatesh .= "# polling leases for dhcp \n";
987
					$rrdupdatesh .= "DHCP=`${php} -q ${dhcpd_gather} '${dhcpif}'`\n";
988
					$rrdupdatesh .= "$rrdtool update $rrddbpath$dhcpif$dhcpd \${DHCP}\n";
989

    
990
				}
991
			}
992
		}
993
		/* END dhcpd statistics */
994

    
995
		/* Start gateway quality */
996
		$rrdupdatesh .= <<<EOD
997

    
998
# Gateway quality graphs
999
for sock in {$g['varrun_path']}/dpinger_*.sock; do
1000
	if [ ! -S "\$sock" ]; then
1001
		continue
1002
	fi
1003

    
1004
	t=\$(/usr/bin/nc -U \$sock)
1005
	if [ -z "\$t" ]; then
1006
		continue
1007
	fi
1008

    
1009
	gw=\$(echo "\$t" | awk '{ print \$1 }')
1010
	delay=\$(echo "\$t" | awk '{ print \$2 }')
1011
	stddev=\$(echo "\$t" | awk '{ print \$3 }')
1012
	loss=\$(echo "\$t" | awk '{ print \$4 }')
1013

    
1014
	if echo "\$loss" | grep -Eqv '^[0-9]+\$'; then
1015
		loss="U"
1016
	fi
1017
	if echo "\$delay" | grep -Eqv '^[0-9]+\$'; then
1018
		delay="U"
1019
	else
1020
		# Convert delay to millisecond
1021
		delay=\$(echo "scale=7; \$delay / 1000 / 1000" | /usr/bin/bc)
1022
	fi
1023
	if echo "\$stddev" | grep -Eqv '^[0-9]+\$'; then
1024
		stddev="U"
1025
	else
1026
		# Convert stddev to millisecond
1027
		stddev=\$(echo "scale=7; \$stddev / 1000 / 1000" | /usr/bin/bc)
1028
	fi
1029

    
1030
	if [ ! -f {$rrddbpath}\$gw-quality.rrd ]; then
1031
		{$rrdtool} create {$rrddbpath}\$gw-quality.rrd --step 60 \\
1032
		DS:loss:GAUGE:120:0:100 \\
1033
		DS:delay:GAUGE:120:0:100000 \\
1034
		DS:stddev:GAUGE:120:0:100000 \\
1035
		RRA:AVERAGE:0.5:1:1200 \\
1036
		RRA:AVERAGE:0.5:5:720 \\
1037
		RRA:AVERAGE:0.5:60:1860 \\
1038
		RRA:AVERAGE:0.5:1440:2284
1039

    
1040
		{$rrdtool} update {$rrddbpath}\$gw-quality.rrd -t loss:delay:stddev N:U:U:U
1041
	fi
1042

    
1043
	{$rrdtool} update {$rrddbpath}\$gw-quality.rrd -t loss:delay:stddev N:\$loss:\$delay:\$stddev
1044
done
1045

    
1046
EOD;
1047
		/* End gateway quality */
1048

    
1049
		$rrdupdatesh .= "sleep 60\n";
1050
		$rrdupdatesh .= "done\n";
1051
		log_error(gettext("Creating rrd update script"));
1052
		/* write the rrd update script */
1053
		$updaterrdscript = "{$g['vardb_path']}/rrd/updaterrd.sh";
1054
		$fd = fopen("$updaterrdscript", "w");
1055
		fwrite($fd, "$rrdupdatesh");
1056
		fclose($fd);
1057

    
1058
		unset($rrdupdatesh);
1059

    
1060
		/* kill off traffic collectors */
1061
		kill_traffic_collector();
1062

    
1063
		/* start traffic collector */
1064
		mwexec_bg("/usr/bin/nice -n20 /bin/sh $updaterrdscript");
1065

    
1066
	} else {
1067
		/* kill off traffic collectors */
1068
		kill_traffic_collector();
1069
	}
1070

    
1071
	$databases = glob("{$rrddbpath}/*.rrd");
1072
	foreach ($databases as $database) {
1073
		chown($database, "nobody");
1074
	}
1075

    
1076
	if (platform_booting()) {
1077
		echo gettext("done.") . "\n";
1078
	}
1079

    
1080
}
1081

    
1082
function kill_traffic_collector() {
1083
	global $g;
1084

    
1085
	killbypid("{$g['varrun_path']}/updaterrd.sh.pid");
1086
}
1087

    
1088
?>
(46-46/65)