Project

General

Profile

Download (30.7 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
  Copyright (C) 2010 Seth Mos <seth.mos@dds.nl>
5
  All rights reserved.
6

    
7
  Redistribution and use in source and binary forms, with or without
8
  modification, are permitted provided that the following conditions are met:
9

    
10
1. Redistributions of source code must retain the above copyright notice,
11
  this list of conditions and the following disclaimer.
12

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

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

    
28
  */
29

    
30
/*
31
	pfSense_BUILDER_BINARIES:	/bin/rm	/usr/bin/nice	/usr/local/bin/rrdtool	/bin/cd
32
	pfSense_MODULE:	rrd
33
*/
34

    
35
/* include all configuration functions */
36

    
37
function dump_rrd_to_xml($rrddatabase, $xmldumpfile) {
38
	$rrdtool = "/usr/bin/nice -n20 /usr/local/bin/rrdtool";
39
	if(file_exists($xmldumpfile))
40
		mwexec("rm {$xmldumpfile}");
41

    
42
	exec("$rrdtool dump {$rrddatabase} {$xmldumpfile} 2>&1", $dumpout, $dumpret);
43
	if ($dumpret <> 0) {
44
		$dumpout = implode(" ", $dumpout);
45
		log_error(sprintf(gettext('RRD dump failed exited with %1$s, the error is: %2$s'), $dumpret, $dumpout));
46
	}
47
	return($dumpret);
48
}
49

    
50
function restore_rrd() {
51
	global $g;
52

    
53
	$rrddbpath = "/var/db/rrd/";
54
	$rrdtool = "/usr/bin/nice -n20 /usr/local/bin/rrdtool";
55

    
56
	$rrdrestore = "";
57
	$rrdreturn = "";
58
	if (file_exists("{$g['cf_conf_path']}/rrd.tgz")) {
59
		foreach (glob("{$rrddbpath}/*.xml") as $xml_file) {
60
			unlink($xml_file);
61
		}
62
		exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/rrd.tgz 2>&1", $rrdrestore, $rrdreturn);
63
		$rrdrestore = implode(" ", $rrdrestore);
64
		if($rrdreturn != 0) {
65
			log_error("RRD restore failed exited with $rrdreturn, the error is: $rrdrestore\n");
66
		}
67
		foreach (glob("{$rrddbpath}/*.xml") as $xml_file) {
68
			$rrd_file = preg_replace('/\.xml$/', ".rrd", $xml_file);
69
			if (file_exists("{$rrd_file}")) {
70
				unlink($rrd_file);
71
			}
72
			$output = array();
73
			$status = null;
74
			exec("$rrdtool restore -f '{$xml_file}' '{$rrd_file}'", $output, $status);
75
			if ($status) {
76
				log_error("rrdtool restore -f '{$xml_file}' '{$rrd_file}' failed returning {$status}.");
77
				continue;
78
			}
79
			unlink($xml_file);
80
		}
81
		return true;
82
	}
83
	return false;
84
}
85

    
86
function create_new_rrd($rrdcreatecmd) {
87
	$rrdcreateoutput = array();
88
	$rrdcreatereturn = 0;
89
	exec("$rrdcreatecmd 2>&1", $rrdcreateoutput, $rrdcreatereturn);
90
	if ($rrdcreatereturn <> 0) {
91
		$rrdcreateoutput = implode(" ", $rrdcreateoutput);
92
		log_error(sprintf(gettext('RRD create failed exited with %1$s, the error is: %2$s'), $rrdcreatereturn, $rrdcreateoutput));
93
	}
94
	return $rrdcreatereturn;
95
}
96

    
97
function migrate_rrd_format($rrdoldxml, $rrdnewxml) {
98
	if(!file_exists("/tmp/rrd_notice_sent.txt")) {
99
		exec("echo 'Converting RRD configuration to new format.  This might take a bit...' | wall");
100
		touch("/tmp/rrd_notice_sent.txt");
101
	}
102
	$numrraold = count($rrdoldxml['rra']);
103
	$numdsold = count($rrdoldxml['ds']);
104
	$numrranew = count($rrdnewxml['rra']);
105
	$numdsnew = count($rrdnewxml['ds']);
106
	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));
107

    
108
	/* add data sources not found in the old array from the new array */
109
	$i = 0;
110
	foreach($rrdnewxml['ds'] as $ds) {
111
		if(!is_array($rrdoldxml['ds'][$i])) {
112
			$rrdoldxml['ds'][$i] = $rrdnewxml['ds'][$i];
113
			/* set unknown values to 0 */
114
			$rrdoldxml['ds'][$i]['last_ds'] = " 0.0000000000e+00 ";
115
			$rrdoldxml['ds'][$i]['value'] = " 0.0000000000e+00 ";
116
			$rrdoldxml['ds'][$i]['unknown_sec'] = "0";
117
		}
118
		$i++;
119
	}
120

    
121
	$i = 0;
122
	$rracountold = count($rrdoldxml['rra']);
123
	$rracountnew = count($rrdnewxml['rra']);
124
	/* process each RRA, which contain a database */
125
	foreach($rrdnewxml['rra'] as $rra) {
126
		if(!is_array($rrdoldxml['rra'][$i])) {
127
			$rrdoldxml['rra'][$i] = $rrdnewxml['rra'][$i];
128
		}
129

    
130
		$d = 0;
131
		/* process cdp_prep */
132
		$cdp_prep = $rra['cdp_prep'];
133
		foreach($cdp_prep['ds'] as $ds) {
134
			if(!is_array($rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d])) {
135
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d] = $rrdnewxml['rra'][$i]['cdp_prep']['ds'][$d];
136
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d]['primary_value'] = " 0.0000000000e+00 ";
137
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d]['secondary_value'] = " 0.0000000000e+00 ";
138
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d]['value'] = " 0.0000000000e+00 ";
139
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d]['unknown_datapoints'] = "0";
140
			}
141
			$d++;
142
		}
143

    
144
		/* process database */
145
		$rows = $rra['database'];
146
		$k = 0;
147
		$rowcountold = count($rrdoldxml['rra'][$i]['database']['row']);
148
		$rowcountnew = count($rrdnewxml['rra'][$i]['database']['row']);
149
		$rowcountdiff = $rowcountnew - $rowcountold;
150
		/* save old rows for a bit before we put the required empty rows before it */
151
		$rowsdata = $rows;
152
		$rowsempty = array();
153
		$r = 0;
154
		while($r < $rowcountdiff) {
155
			$rowsempty[] = $rrdnewxml['rra'][$i]['database']['row'][$r];
156
			$r++;
157
		}
158
		$rows = $rowsempty + $rowsdata;
159
		/* now foreach the rows in the database */
160
		foreach($rows['row'] as $row) {
161
			if(!is_array($rrdoldxml['rra'][$i]['database']['row'][$k])) {
162
				$rrdoldxml['rra'][$i]['database']['row'][$k] = $rrdnewxml['rra'][$i]['database']['row'][$k];
163
			}
164
			$m = 0;
165
			$vcountold = count($rrdoldxml['rra'][$i]['database']['row'][$k]['v']);
166
			$vcountnew = count($rrdnewxml['rra'][$i]['database']['row'][$k]['v']);
167
			foreach($row['v'] as $value) {
168
				if(empty($rrdoldxml['rra'][$i]['database']['row'][$k]['v'][$m])) {
169
					if(isset($valid)) {
170
						$rrdoldxml['rra'][$i]['database']['row'][$k]['v'][$m] = "0.0000000000e+00 ";
171
					} else {
172
						$rrdoldxml['rra'][$i]['database']['row'][$k]['v'][$m] = $rrdnewxml['rra'][$i]['database']['row'][$k]['v'][$m];
173
					}
174
				} else {
175
					if($value <> " NaN ") {
176
						$valid = true;
177
					} else {
178
						$valid = false;
179
					}
180
				}
181
				$m++;
182
			}
183
			$k++;
184
		}
185
		$i++;
186
	}
187

    
188
	$numrranew = count($rrdoldxml['rra']);
189
	$numdsnew = count($rrdoldxml['ds']);
190
	log_error(sprintf(gettext('The new RRD now has %1$s DS values and %2$s RRA databases'), $numdsnew, $numrranew));
191
	return $rrdoldxml;
192
}
193

    
194
function enable_rrd_graphing() {
195
	global $config, $g, $altq_list_queues;
196

    
197
	if($g['booting'])
198
		echo gettext("Generating RRD graphs...");
199

    
200
	$rrddbpath = "/var/db/rrd/";
201
	$rrdgraphpath = "/usr/local/www/rrd";
202

    
203
	$traffic = "-traffic.rrd";
204
	$packets = "-packets.rrd";
205
	$states = "-states.rrd";
206
	$wireless = "-wireless.rrd";
207
	$queues = "-queues.rrd";
208
	$queuesdrop = "-queuedrops.rrd";
209
	$spamd = "-spamd.rrd";
210
	$proc = "-processor.rrd";
211
	$mem = "-memory.rrd";
212
	$cellular = "-cellular.rrd";
213
	$vpnusers = "-vpnusers.rrd";
214
	$captiveportalconcurrent = "-concurrent.rrd";
215
	$captiveportalloggedin = "-loggedin.rrd";
216
	$captiveportaltotalusers = "-totalusers.rrd";
217

    
218
	$rrdtool = "/usr/bin/nice -n20 /usr/local/bin/rrdtool";
219
	$netstat = "/usr/bin/netstat";
220
	$awk = "/usr/bin/awk";
221
	$tar = "/usr/bin/tar";
222
	$pfctl = "/sbin/pfctl";
223
	$sysctl = "/sbin/sysctl";
224
	$php = "/usr/local/bin/php";
225
	$cpustats = "/usr/local/sbin/cpustats";
226
	$spamd_gather = "/usr/local/bin/spamd_gather_stats.php";
227
	$ifconfig = "/sbin/ifconfig";
228
	$captiveportal_gather = "/usr/local/bin/captiveportal_gather_stats.php";
229

    
230
	$rrdtrafficinterval = 60;
231
	$rrdwirelessinterval = 60;
232
	$rrdqueuesinterval = 60;
233
	$rrdqueuesdropinterval = 60;
234
	$rrdpacketsinterval = 60;
235
	$rrdstatesinterval = 60;
236
	$rrdspamdinterval = 60;
237
	$rrdlbpoolinterval = 60;
238
	$rrdprocinterval = 60;
239
	$rrdmeminterval = 60;
240
	$rrdcellularinterval = 60;
241
	$rrdvpninterval = 60;
242
	$rrdcaptiveportalinterval = 60;
243

    
244
	$trafficvalid = $rrdtrafficinterval * 2;
245
	$wirelessvalid = $rrdwirelessinterval * 2;
246
	$queuesvalid = $rrdqueuesinterval * 2;
247
	$queuesdropvalid = $rrdqueuesdropinterval * 2;
248
	$packetsvalid = $rrdpacketsinterval * 2;
249
	$statesvalid = $rrdstatesinterval*2;
250
	$spamdvalid = $rrdspamdinterval * 2;
251
	$lbpoolvalid = $rrdlbpoolinterval * 2;
252
	$procvalid = $rrdlbpoolinterval * 2;
253
	$memvalid = $rrdmeminterval * 2;
254
	$cellularvalid = $rrdcellularinterval * 2;
255
	$vpnvalid = $rrdvpninterval * 2;
256
	$captiveportalvalid = $rrdcaptiveportalinterval * 2;
257

    
258
	/* Asume GigE for now */
259
	$downstream = 125000000;
260
	$upstream = 125000000;
261

    
262
	/* read the shaper config */
263
	read_altq_config();
264

    
265
	if (isset ($config['rrd']['enable'])) {
266

    
267
		/* create directory if needed */
268
		if (!is_dir($rrddbpath)) {
269
			mkdir($rrddbpath, 0775);
270
		}
271
		chown($rrddbpath, "nobody");
272

    
273
		if ($g['booting']) {
274
			if ($g['platform'] != "pfSense") {
275
				restore_rrd();
276
			}
277
		}
278

    
279
		/* db update script */
280
		$rrdupdatesh = "#!/bin/sh\n";
281
		$rrdupdatesh .= "\n";
282
		$rrdupdatesh .= "export TERM=dumb\n";
283
		$rrdupdatesh .= "\n";
284
		$rrdupdatesh .= 'echo $$ > ' . $g['varrun_path'] . '/updaterrd.sh.pid';
285
		$rrdupdatesh .= "\n";
286
		$rrdupdatesh .= "counter=1\n";
287
		$rrdupdatesh .= "while [ \"\$counter\" -ne 0 ]\n";
288
		$rrdupdatesh .= "do\n";
289
		$rrdupdatesh .= "";
290

    
291
		$i = 0;
292
		$ifdescrs = get_configured_interface_with_descr();
293
		/* IPsec counters */
294
		$ifdescrs['ipsec'] = "IPsec";
295
		/* OpenVPN server counters */
296
		if(is_array($config['openvpn']['openvpn-server'])) {
297
			foreach($config['openvpn']['openvpn-server'] as $server) {
298
				$serverid = "ovpns" . $server['vpnid'];
299
				$ifdescrs[$serverid] = "{$server['description']}";
300
			}
301
		}
302

    
303
		/* process all real and pseudo interfaces */
304
		foreach ($ifdescrs as $ifname => $ifdescr) {
305
			$temp = get_real_interface($ifname);
306
			if($temp <> "") {
307
				$realif = $temp;
308
			}
309

    
310
			/* TRAFFIC, set up the rrd file */
311
			if (!file_exists("$rrddbpath$ifname$traffic")) {
312
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$traffic --step $rrdtrafficinterval ";
313
				$rrdcreate .= "DS:inpass:COUNTER:$trafficvalid:0:$downstream ";
314
				$rrdcreate .= "DS:outpass:COUNTER:$trafficvalid:0:$upstream ";
315
				$rrdcreate .= "DS:inblock:COUNTER:$trafficvalid:0:$downstream ";
316
				$rrdcreate .= "DS:outblock:COUNTER:$trafficvalid:0:$upstream ";
317
				$rrdcreate .= "DS:inpass6:COUNTER:$trafficvalid:0:$downstream ";
318
				$rrdcreate .= "DS:outpass6:COUNTER:$trafficvalid:0:$upstream ";
319
				$rrdcreate .= "DS:inblock6:COUNTER:$trafficvalid:0:$downstream ";
320
				$rrdcreate .= "DS:outblock6:COUNTER:$trafficvalid:0:$upstream ";
321
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
322
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
323
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
324
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
325

    
326
				create_new_rrd($rrdcreate);
327
			}
328

    
329
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
330
			if($g['booting']) {
331
				mwexec("$rrdtool update $rrddbpath$ifname$traffic N:U:U:U:U:U:U:U:U");
332
			}
333

    
334
			$rrdupdatesh .= "\n";
335
			$rrdupdatesh .= "# polling traffic for interface $ifname $realif IPv4/IPv6 counters \n";
336
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$traffic N:";
337
			$rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '\\\n";
338
			$rrdupdatesh .= "/In4\/Pass/ { b4pi = \$6 };/Out4\/Pass/ { b4po = \$6 };/In4\/Block/ { b4bi = \$6 };/Out4\/Block/ { b4bo = \$6 };\\\n";
339
			$rrdupdatesh .= "/In6\/Pass/ { b6pi = \$6 };/Out6\/Pass/ { b6po = \$6 };/In6\/Block/ { b6bi = \$6 };/Out6\/Block/ { b6bo = \$6 };\\\n";
340
			$rrdupdatesh .= "END {print b4pi \":\" b4po \":\" b4bi \":\" b4bo \":\" b6pi \":\" b6po \":\" b6bi \":\" b6bo};'`\n";
341

    
342
			/* PACKETS, set up the rrd file */
343
			if (!file_exists("$rrddbpath$ifname$packets")) {
344
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$packets --step $rrdpacketsinterval ";
345
				$rrdcreate .= "DS:inpass:COUNTER:$packetsvalid:0:$downstream ";
346
				$rrdcreate .= "DS:outpass:COUNTER:$packetsvalid:0:$upstream ";
347
				$rrdcreate .= "DS:inblock:COUNTER:$packetsvalid:0:$downstream ";
348
				$rrdcreate .= "DS:outblock:COUNTER:$packetsvalid:0:$upstream ";
349
				$rrdcreate .= "DS:inpass6:COUNTER:$packetsvalid:0:$downstream ";
350
				$rrdcreate .= "DS:outpass6:COUNTER:$packetsvalid:0:$upstream ";
351
				$rrdcreate .= "DS:inblock6:COUNTER:$packetsvalid:0:$downstream ";
352
				$rrdcreate .= "DS:outblock6:COUNTER:$packetsvalid:0:$upstream ";
353
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
354
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
355
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
356
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
357

    
358
				create_new_rrd($rrdcreate);
359
			}
360

    
361
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
362
			if($g['booting']) {
363
				mwexec("$rrdtool update $rrddbpath$ifname$packets N:U:U:U:U:U:U:U:U");
364
			}
365

    
366
			$rrdupdatesh .= "\n";
367
			$rrdupdatesh .= "# polling packets for interface $ifname $realif \n";
368
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$packets N:";
369
			$rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '\\\n";
370
			$rrdupdatesh .= "/In4\/Pass/ { b4pi = \$4 };/Out4\/Pass/ { b4po = \$4 };/In4\/Block/ { b4bi = \$4 };/Out4\/Block/ { b4bo = \$4 };\\\n";
371
			$rrdupdatesh .= "/In6\/Pass/ { b6pi = \$4 };/Out6\/Pass/ { b6po = \$4 };/In6\/Block/ { b6bi = \$4 };/Out6\/Block/ { b6bo = \$4 };\\\n";
372
			$rrdupdatesh .= "END {print b4pi \":\" b4po \":\" b4bi \":\" b4bo \":\" b6pi \":\" b6po \":\" b6bi \":\" b6bo};'`\n";
373

    
374
			/* WIRELESS, set up the rrd file */
375
			if($config['interfaces'][$ifname]['wireless']['mode'] == "bss") {
376
				if (!file_exists("$rrddbpath$ifname$wireless")) {
377
					$rrdcreate = "$rrdtool create $rrddbpath$ifname$wireless --step $rrdwirelessinterval ";
378
					$rrdcreate .= "DS:snr:GAUGE:$wirelessvalid:0:1000 ";
379
					$rrdcreate .= "DS:rate:GAUGE:$wirelessvalid:0:1000 ";
380
					$rrdcreate .= "DS:channel:GAUGE:$wirelessvalid:0:1000 ";
381
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
382
					$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
383
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
384
					$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
385

    
386
					create_new_rrd($rrdcreate);
387
				}
388

    
389
				/* enter UNKNOWN values in the RRD so it knows we rebooted. */
390
				if($g['booting']) {
391
					mwexec("$rrdtool update $rrddbpath$ifname$wireless N:U:U:U");
392
				}
393

    
394
				$rrdupdatesh .= "\n";
395
				$rrdupdatesh .= "# polling wireless for interface $ifname $realif \n";
396
				$rrdupdatesh .= "WIFI=`$ifconfig {$realif} list sta| $awk 'gsub(\"M\", \"\") {getline 2;print substr(\$5, 0, length(\$5)-2) \":\" $4 \":\" $3}'`\n";
397
				$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$wireless N:\${WIFI}\n";
398
			}
399

    
400
			/* OpenVPN, set up the rrd file */
401
			if(stristr($ifname, "ovpns")) {
402
				if (!file_exists("$rrddbpath$ifname$vpnusers")) {
403
					$rrdcreate = "$rrdtool create $rrddbpath$ifname$vpnusers --step $rrdvpninterval ";
404
					$rrdcreate .= "DS:users:GAUGE:$vpnvalid:0:10000 ";
405
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
406
					$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
407
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
408
					$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
409

    
410
					create_new_rrd($rrdcreate);
411
				}
412

    
413
				/* enter UNKNOWN values in the RRD so it knows we rebooted. */
414
				if($g['booting']) {
415
					mwexec("$rrdtool update $rrddbpath$ifname$vpnusers N:U");
416
				}
417

    
418
				if(is_array($config['openvpn']['openvpn-server'])) {
419
					foreach($config['openvpn']['openvpn-server'] as $server) {
420
						if("ovpns{$server['vpnid']}" == $ifname) {
421
							$port = $server['local_port'];
422
							$vpnid = $server['vpnid'];
423
						}
424
					}
425
				}
426
				$rrdupdatesh .= "\n";
427
				$rrdupdatesh .= "# polling vpn users for interface $ifname $realif port $port\n";
428
				$rrdupdatesh .= "list_current_users() {\n";
429
				$rrdupdatesh .= " sleep 0.2\n";
430
				$rrdupdatesh .= " echo \"status 2\"\n";
431
				$rrdupdatesh .= " sleep 0.2\n";
432
				$rrdupdatesh .= " echo \"quit\"\n";
433
				$rrdupdatesh .= "}\n";
434
				$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";
435
				$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$vpnusers N:\${OVPN}\n";
436
			}
437

    
438
			/* QUEUES, set up the queues databases */
439
			if ($altq_list_queues[$ifname]) {
440
				$altq =& $altq_list_queues[$ifname];
441
				/* NOTE: Is it worth as its own function?! */
442
				switch ($altq->GetBwscale()) {
443
					case "Gb":
444
						$factor = 1024 * 1024 * 1024;
445
							break;
446
					case "Mb":
447
							$factor = 1024 * 1024;
448
							break;
449
					case "Kb":
450
							$factor = 1024;
451
							break;
452
					case "b":
453
					default:
454
							$factor = 1;
455
							break;
456
				}
457
				$qbandwidth = $altq->GetBandwidth() * $factor;
458
				if ($qbandwidth <=0) {
459
					$qbandwidth = 100 * 1000 * 1000; /* 100Mbit */
460
				}
461
				$qlist =& $altq->get_queue_list($notused);
462
				if (!file_exists("$rrddbpath$ifname$queues")) {
463
					$rrdcreate = "$rrdtool create $rrddbpath$ifname$queues --step $rrdqueuesinterval ";
464
					/* loop list of shaper queues */
465
					$q = 0;
466
					foreach ($qlist as $qname => $q) {
467
						$rrdcreate .= "DS:$qname:COUNTER:$queuesvalid:0:$qbandwidth ";
468
					}
469

    
470
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
471
					$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
472
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
473
					$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
474

    
475
					create_new_rrd($rrdcreate);
476
				}
477

    
478
				if (!file_exists("$rrddbpath$ifname$queuesdrop")) {
479
					$rrdcreate = "$rrdtool create $rrddbpath$ifname$queuesdrop --step $rrdqueuesdropinterval ";
480
					/* loop list of shaper queues */
481
					$q = 0;
482
					foreach ($qlist as $qname => $q) {
483
						$rrdcreate .= "DS:$qname:COUNTER:$queuesdropvalid:0:$qbandwidth ";
484
					}
485

    
486
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
487
					$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
488
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
489
					$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
490

    
491
					create_new_rrd($rrdcreate);
492
				}
493

    
494
				if($g['booting']) {
495
					$rrdqcommand = "-t ";
496
					$rrducommand = "N";
497
					$qi = 0;
498
					foreach ($qlist as $qname => $q) {
499
						if($qi == 0) {
500
							$rrdqcommand .= "{$qname}";
501
						} else {
502
							$rrdqcommand .= ":{$qname}";
503
						}
504
						$qi++;
505
						$rrducommand .= ":U";
506
					}
507
					mwexec("$rrdtool update $rrddbpath$ifname$queues $rrdqcommand $rrducommand");
508
					mwexec("$rrdtool update $rrddbpath$ifname$queuesdrop $rrdqcommand $rrducommand");
509
				}
510

    
511
				/* awk function to gather shaper data */
512
				/* yes, it's special */
513
				$rrdupdatesh .= "` pfctl -vsq -i {$realif} | awk 'BEGIN {printf \"$rrdtool update $rrddbpath$ifname$queues \" } ";
514
				$rrdupdatesh .= "{ ";
515
				$rrdupdatesh .= "if ((\$1 == \"queue\") && ( \$2 ~ /^q/ )) { ";
516
				$rrdupdatesh .= " dsname = dsname \":\" \$2 ; ";
517
				$rrdupdatesh .= " q=1; ";
518
				$rrdupdatesh .= "} ";
519
				$rrdupdatesh .= " else if ((\$4 == \"bytes:\") && ( q == 1 ) ) { ";
520
				$rrdupdatesh .= " dsdata = dsdata \":\" \$5 ; ";
521
				$rrdupdatesh .= " q=0; ";
522
				$rrdupdatesh .= "} ";
523
				$rrdupdatesh .= "} END { ";
524
				$rrdupdatesh .= " dsname = substr(dsname,2); ";
525
				$rrdupdatesh .= " dsdata = substr(dsdata,2); ";
526
				$rrdupdatesh .= " printf \"-t \" dsname \" N:\" dsdata }' ";
527
				$rrdupdatesh .= " dsname=\"\" dsdata=\"\"`\n\n";
528

    
529
				$rrdupdatesh .= "` pfctl -vsq -i {$realif} | awk 'BEGIN {printf \"$rrdtool update $rrddbpath$ifname$queuesdrop \" } ";
530
				$rrdupdatesh .= "{ ";
531
				$rrdupdatesh .= "if ((\$1 == \"queue\") && ( \$2 ~ /^q/ )) { ";
532
				$rrdupdatesh .= " dsname = dsname \":\" \$2 ; ";
533
				$rrdupdatesh .= " q=1; ";
534
				$rrdupdatesh .= "} ";
535
				$rrdupdatesh .= " else if ((\$4 == \"bytes:\") && ( q == 1 ) ) { ";
536
				$rrdupdatesh .= " dsdata = dsdata \":\" \$8 ; ";
537
				$rrdupdatesh .= " q=0; ";
538
				$rrdupdatesh .= "} ";
539
				$rrdupdatesh .= "} END { ";
540
				$rrdupdatesh .= " dsname = substr(dsname,2); ";
541
				$rrdupdatesh .= " dsdata = substr(dsdata,2); ";
542
				$rrdupdatesh .= " printf \"-t \" dsname \" N:\" dsdata }' ";
543
				$rrdupdatesh .= " dsname=\"\" dsdata=\"\"`\n\n";
544
			}
545

    
546
			/* 3G interfaces */
547
			if(preg_match("/ppp[0-9]+/i", $realif))	{
548
				if (!file_exists("$rrddbpath$ifname$cellular")) {
549
					$rrdcreate = "$rrdtool create $rrddbpath$ifname$cellular --step $rrdcellularinterval ";
550
					$rrdcreate .= "DS:rssi:GAUGE:$cellularvalid:0:100 ";
551
					$rrdcreate .= "DS:upstream:GAUGE:$cellularvalid:0:100000000 ";
552
					$rrdcreate .= "DS:downstream:GAUGE:$cellularvalid:0:100000000 ";
553
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
554
					$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
555
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
556
					$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
557
					create_new_rrd($rrdcreate);
558
				}
559

    
560
				/* enter UNKNOWN values in the RRD so it knows we rebooted. */
561
				if($g['booting']) {
562
					mwexec("$rrdtool update $rrddbpath$ifname$cellular N:U:U:U");
563
				}
564

    
565
				$rrdupdatesh .= "\n";
566
				$rrdupdatesh .= "# polling 3G\n";
567
				$rrdupdatesh .= "GSTATS=`awk -F, 'getline 2 {print \$2 \":\" \$8 \":\" \$9}' < /tmp/3gstats.$ifname`\n";
568
				$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$cellular N:\"\$GSTATS\"";
569
			}
570

    
571
		}
572
		$i++;
573

    
574
		/* System only statistics */
575
		$ifname = "system";
576

    
577
		/* STATES, create pf states database */
578
		if(! file_exists("$rrddbpath$ifname$states")) {
579
			$rrdcreate = "$rrdtool create $rrddbpath$ifname$states --step $rrdstatesinterval ";
580
			$rrdcreate .= "DS:pfrate:GAUGE:$statesvalid:0:10000000 ";
581
			$rrdcreate .= "DS:pfstates:GAUGE:$statesvalid:0:10000000 ";
582
			$rrdcreate .= "DS:pfnat:GAUGE:$statesvalid:0:10000000 ";
583
			$rrdcreate .= "DS:srcip:GAUGE:$statesvalid:0:10000000 ";
584
			$rrdcreate .= "DS:dstip:GAUGE:$statesvalid:0:10000000 ";
585
			$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
586
			$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
587
			$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
588
			$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
589

    
590
			create_new_rrd($rrdcreate);
591
		}
592

    
593
		/* enter UNKNOWN values in the RRD so it knows we rebooted. */
594
		if($g['booting']) {
595
			mwexec("$rrdtool update $rrddbpath$ifname$states N:U:U:U:U:U");
596
		}
597

    
598
		/* the pf states gathering function. */
599
		$rrdupdatesh .= "\n";
600
		$rrdupdatesh .= "pfctl_si_out=\"` $pfctl -si > /tmp/pfctl_si_out `\"\n";
601
		$rrdupdatesh .= "pfctl_ss_out=\"` $pfctl -ss > /tmp/pfctl_ss_out`\"\n";
602
		$rrdupdatesh .= "pfrate=\"` cat /tmp/pfctl_si_out | egrep \"inserts|removals\" | awk '{ pfrate = \$3 + pfrate } {print pfrate}'|tail -1 `\"\n";
603
		$rrdupdatesh .= "pfstates=\"` cat /tmp/pfctl_ss_out | egrep -v \"<\\-.*?<\\-|\\->.*?\\->\" | wc -l|sed 's/ //g'`\"\n";
604
		$rrdupdatesh .= "pfnat=\"` cat /tmp/pfctl_ss_out | egrep '<\\-.*?<\\-|\\->.*?\\->' | wc -l|sed 's/ //g' `\"\n";
605
		$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";
606
		$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";
607
		$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$states N:\$pfrate:\$pfstates:\$pfnat:\$srcip:\$dstip\n\n";
608

    
609
		/* End pf states statistics */
610

    
611
		/* CPU, create CPU statistics database */
612
		if(! file_exists("$rrddbpath$ifname$proc")) {
613
			$rrdcreate = "$rrdtool create $rrddbpath$ifname$proc --step $rrdprocinterval ";
614
			$rrdcreate .= "DS:user:GAUGE:$procvalid:0:10000000 ";
615
			$rrdcreate .= "DS:nice:GAUGE:$procvalid:0:10000000 ";
616
			$rrdcreate .= "DS:system:GAUGE:$procvalid:0:10000000 ";
617
			$rrdcreate .= "DS:interrupt:GAUGE:$procvalid:0:10000000 ";
618
			$rrdcreate .= "DS:processes:GAUGE:$procvalid:0:10000000 ";
619
			$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
620
			$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
621
			$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
622
			$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
623

    
624
			create_new_rrd($rrdcreate);
625
		}
626

    
627
		/* enter UNKNOWN values in the RRD so it knows we rebooted. */
628
		if($g['booting']) {
629
			mwexec("$rrdtool update $rrddbpath$ifname$proc N:U:U:U:U:U");
630
		}
631

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

    
638
		/* End CPU statistics */
639

    
640
		/* Memory, create Memory statistics database */
641
		if(! file_exists("$rrddbpath$ifname$mem")) {
642
			$rrdcreate = "$rrdtool create $rrddbpath$ifname$mem --step $rrdmeminterval ";
643
			$rrdcreate .= "DS:active:GAUGE:$memvalid:0:10000000 ";
644
			$rrdcreate .= "DS:inactive:GAUGE:$memvalid:0:10000000 ";
645
			$rrdcreate .= "DS:free:GAUGE:$memvalid:0:10000000 ";
646
			$rrdcreate .= "DS:cache:GAUGE:$memvalid:0:10000000 ";
647
			$rrdcreate .= "DS:wire:GAUGE:$memvalid:0:10000000 ";
648
			$rrdcreate .= "RRA:MIN:0.5:1:1000 ";
649
			$rrdcreate .= "RRA:MIN:0.5:5:1000 ";
650
			$rrdcreate .= "RRA:MIN:0.5:60:1000 ";
651
			$rrdcreate .= "RRA:MIN:0.5:720:3000 ";
652
			$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
653
			$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
654
			$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
655
			$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
656
			$rrdcreate .= "RRA:MAX:0.5:1:1000 ";
657
			$rrdcreate .= "RRA:MAX:0.5:5:1000 ";
658
			$rrdcreate .= "RRA:MAX:0.5:60:1000 ";
659
			$rrdcreate .= "RRA:MAX:0.5:720:3000";
660

    
661
			create_new_rrd($rrdcreate);
662
		}
663

    
664
		/* enter UNKNOWN values in the RRD so it knows we rebooted. */
665
		if($g['booting']) {
666
			mwexec("$rrdtool update $rrddbpath$ifname$mem N:U:U:U:U:U");
667
		}
668

    
669
		/* the Memory stats gathering function. */
670
		$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 | ";
671
		$rrdupdatesh .= " $awk '{getline active;getline inactive;getline free;getline cache;getline wire;printf ";
672
		$rrdupdatesh .= "((active/$0) * 100)\":\"((inactive/$0) * 100)\":\"((free/$0) * 100)\":\"((cache/$0) * 100)\":\"(wire/$0 * 100)}'`\n";
673
		$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$mem N:\${MEM}\n";
674

    
675
		/* End Memory statistics */
676

    
677
		/* SPAMD, set up the spamd rrd file */
678
		if (isset($config['installedpackages']['spamdsettings']) &&
679
			 $config['installedpackages']['spamdsettings']['config'][0]['enablerrd']) {
680
			/* set up the spamd rrd file */
681
			if (!file_exists("$rrddbpath$ifname$spamd")) {
682
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$spamd --step $rrdspamdinterval ";
683
				$rrdcreate .= "DS:conn:GAUGE:$spamdvalid:0:10000 ";
684
				$rrdcreate .= "DS:time:GAUGE:$spamdvalid:0:86400 ";
685
				$rrdcreate .= "RRA:MIN:0.5:1:1000 ";
686
				$rrdcreate .= "RRA:MIN:0.5:5:1000 ";
687
				$rrdcreate .= "RRA:MIN:0.5:60:1000 ";
688
				$rrdcreate .= "RRA:MIN:0.5:720:3000 ";
689
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
690
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
691
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
692
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
693
				$rrdcreate .= "RRA:MAX:0.5:1:1000 ";
694
				$rrdcreate .= "RRA:MAX:0.5:5:1000 ";
695
				$rrdcreate .= "RRA:MAX:0.5:60:1000 ";
696
				$rrdcreate .= "RRA:MAX:0.5:720:3000 ";
697

    
698
				create_new_rrd($rrdcreate);
699
			}
700

    
701
			$rrdupdatesh .= "\n";
702
			$rrdupdatesh .= "# polling spamd for connections and tarpitness \n";
703
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$spamd \\\n";
704
			$rrdupdatesh .= "`$php -q $spamd_gather`\n";
705

    
706
		}
707
		/* End System statistics */
708

    
709
		/* Captive Portal statistics, set up the rrd file */
710
		if(isset($config['captiveportal']['enable'])) {
711
			$ifname= "captiveportal";
712
			if (!file_exists("$rrddbpath$ifname$captiveportalconcurrent")) {
713
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$captiveportalconcurrent --step $rrdcaptiveportalinterval ";
714
				$rrdcreate .= "DS:concurrentusers:GAUGE:$captiveportalvalid:0:10000 ";
715
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
716
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
717
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
718
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
719
				$rrdcreate .= "RRA:MIN:0.5:1:1000 ";
720
				$rrdcreate .= "RRA:MIN:0.5:5:1000 ";
721
				$rrdcreate .= "RRA:MIN:0.5:60:1000 ";
722
				$rrdcreate .= "RRA:MIN:0.5:720:3000 ";
723
				$rrdcreate .= "RRA:MAX:0.5:1:1000 ";
724
				$rrdcreate .= "RRA:MAX:0.5:5:1000 ";
725
				$rrdcreate .= "RRA:MAX:0.5:60:1000 ";
726
				$rrdcreate .= "RRA:MAX:0.5:720:3000 ";
727
				$rrdcreate .= "RRA:LAST:0.5:1:1000 ";
728
				$rrdcreate .= "RRA:LAST:0.5:5:1000 ";
729
				$rrdcreate .= "RRA:LAST:0.5:60:1000 ";
730
				$rrdcreate .= "RRA:LAST:0.5:720:3000 ";
731

    
732
				create_new_rrd($rrdcreate);
733
			}
734

    
735
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
736
			if($g['booting']) {
737
				mwexec("$rrdtool update $rrddbpath$ifname$captiveportalconcurrent N:U");
738
			}
739

    
740
			/* the Captive Portal stats gathering function. */
741
			$rrdupdatesh .= "\n";
742
			$rrdupdatesh .= "# polling Captive Portal for number of concurrent users\n";
743
			$rrdupdatesh .= "CP=`$php -q $captiveportal_gather concurrent`\n";
744
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$captiveportalconcurrent \${CP}\n";
745

    
746
			$ifname= "captiveportal";
747
			if (!file_exists("$rrddbpath$ifname$captiveportalloggedin")) {
748
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$captiveportalloggedin --step $rrdcaptiveportalinterval ";
749
				$rrdcreate .= "DS:loggedinusers:GAUGE:$captiveportalvalid:0:10000 ";
750
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
751
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
752
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
753
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
754
				$rrdcreate .= "RRA:MIN:0.5:1:1000 ";
755
				$rrdcreate .= "RRA:MIN:0.5:5:1000 ";
756
				$rrdcreate .= "RRA:MIN:0.5:60:1000 ";
757
				$rrdcreate .= "RRA:MIN:0.5:720:3000 ";
758
				$rrdcreate .= "RRA:MAX:0.5:1:1000 ";
759
				$rrdcreate .= "RRA:MAX:0.5:5:1000 ";
760
				$rrdcreate .= "RRA:MAX:0.5:60:1000 ";
761
				$rrdcreate .= "RRA:MAX:0.5:720:3000 ";
762
				$rrdcreate .= "RRA:LAST:0.5:1:1000 ";
763
				$rrdcreate .= "RRA:LAST:0.5:5:1000 ";
764
				$rrdcreate .= "RRA:LAST:0.5:60:1000 ";
765
				$rrdcreate .= "RRA:LAST:0.5:720:3000 ";
766

    
767
				create_new_rrd($rrdcreate);
768
			}
769

    
770
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
771
			if($g['booting']) {
772
				mwexec("$rrdtool update $rrddbpath$ifname$captiveportalloggedin N:U");
773
			}
774

    
775
			/* the Captive Portal stats gathering function. */
776
			$rrdupdatesh .= "\n";
777
			$rrdupdatesh .= "# polling Captive Portal for number of logged in users\n";
778
			$rrdupdatesh .= "CP=`$php -q $captiveportal_gather loggedin`\n";
779
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$captiveportalloggedin \${CP}\n";
780

    
781
		}
782

    
783
		$rrdupdatesh .= "sleep 60\n";
784
		$rrdupdatesh .= "done\n";
785
		log_error(gettext("Creating rrd update script"));
786
		/* write the rrd update script */
787
		$updaterrdscript = "{$g['vardb_path']}/rrd/updaterrd.sh";
788
		$fd = fopen("$updaterrdscript", "w");
789
		fwrite($fd, "$rrdupdatesh");
790
		fclose($fd);
791

    
792
		/* kill off traffic collectors */
793
		kill_traffic_collector();
794

    
795
		/* start traffic collector */
796
		mwexec_bg("/usr/bin/nice -n20 /bin/sh $updaterrdscript");
797

    
798
	} else {
799
		/* kill off traffic collectors */
800
		kill_traffic_collector();
801
	}
802

    
803
	$databases = glob("{$rrddbpath}/*.rrd");
804
	foreach($databases as $database) {
805
		chown($database, "nobody");
806
	}
807

    
808
	if($g['booting'])
809
		echo gettext("done.") . "\n";
810

    
811
}
812

    
813
function kill_traffic_collector() {
814
	global $g;
815

    
816
	killbypid("{$g['varrun_path']}/updaterrd.sh.pid");
817
}
818

    
819
?>
(46-46/67)