Project

General

Profile

Download (28.1 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
  Copyright (C) 2008 Seth Mos
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
/* include all configuration functions */
31
require_once("config.inc");
32

    
33
function dump_rrd_to_xml($rrddatabase, $xmldumpfile) {
34
	$rrdtool = "/usr/bin/nice -n20 /usr/local/bin/rrdtool";
35
	if(file_exists($xmldumpfile))
36
		exec("rm {$xmldumpfile}");
37

    
38
	exec("$rrdtool dump {$rrddatabase} {$xmldumpfile} 2>&1", $dumpout, $dumpret);
39
	if ($dumpret <> 0) {
40
		$dumpout = implode(" ", $dumpout);
41
		log_error("RRD dump failed exited with $dumpret, the error is: $dumpout");
42
	}
43
	return($dumpret);
44
}
45

    
46
function create_new_rrd($rrdcreatecmd) {
47
	$rrdcreateoutput = array();
48
	$rrdcreatereturn = 0;
49
	exec("$rrdcreatecmd 2>&1", $rrdcreateoutput, $rrdcreatereturn);
50
	if ($rrdcreatereturn <> 0) {
51
		$rrdcreateoutput = implode(" ", $rrdcreateoutput);
52
		log_error("RRD create failed exited with $rrdcreatereturn, the error is: $rrdcreateoutput");
53
	}
54
	return $rrdcreatereturn;
55
}
56

    
57
function migrate_rrd_format($rrdoldxml, $rrdnewxml) {
58
	exec("echo 'Converting RRD configuration to new format.  This might take a bit...' | wall");
59
	$numrraold = count($rrdoldxml['rra']);
60
	$numdsold = count($rrdoldxml['ds']);
61
	$numrranew = count($rrdnewxml['rra']);
62
	$numdsnew = count($rrdnewxml['ds']);
63
	log_error("Import RRD has $numdsold DS values and $numrraold RRA databases, new format RRD has $numdsnew DS values and $numrranew RRA databases");
64
	
65
	/* add data sources not found in the old array from the new array */
66
	$i = 0;
67
	foreach($rrdnewxml['ds'] as $ds) {
68
		if(!is_array($rrdoldxml['ds'][$i])) {
69
			$rrdoldxml['ds'][$i] = $rrdnewxml['ds'][$i];
70
			/* set unknown values to 0 */
71
			$rrdoldxml['ds'][$i]['last_ds'] = " 0.0000000000e+00 ";
72
			$rrdoldxml['ds'][$i]['value'] = " 0.0000000000e+00 ";
73
			$rrdoldxml['ds'][$i]['unknown_sec'] = "0";
74
		}
75
		$i++;
76
	}
77

    
78
	$i = 0;
79
	$rracountold = count($rrdoldxml['rra']);
80
	$rracountnew = count($rrdnewxml['rra']);
81
	/* process each RRA, which contain a database */
82
	foreach($rrdnewxml['rra'] as $rra) {
83
		if(!is_array($rrdoldxml['rra'][$i])) {
84
			$rrdoldxml['rra'][$i] = $rrdnewxml['rra'][$i];
85
		}
86

    
87
		$d = 0;
88
		/* process cdp_prep */
89
		$cdp_prep = $rra['cdp_prep'];
90
		foreach($cdp_prep['ds'] as $ds) {
91
			if(!is_array($rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d])) {
92
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d] = $rrdnewxml['rra'][$i]['cdp_prep']['ds'][$d];
93
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d]['primary_value'] = " 0.0000000000e+00 ";
94
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d]['secondary_value'] = " 0.0000000000e+00 ";
95
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d]['value'] = " 0.0000000000e+00 ";
96
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d]['unknown_datapoints'] = "0";
97
			}
98
			$d++;
99
		}
100

    
101
		/* process database */
102
		$rows = $rra['database'];
103
		$k = 0;
104
		$rowcountold = count($rrdoldxml['rra'][$i]['database']['row']);
105
		$rowcountnew = count($rrdnewxml['rra'][$i]['database']['row']);
106
		$rowcountdiff = $rowcountnew - $rowcountold;
107
		/* save old rows for a bit before we put the required empty rows before it */
108
		$rowsdata = $rows;
109
		$rowsempty = array();
110
		$r = 0;
111
		while($r < $rowcountdiff) {
112
			$rowsempty[] = $rrdnewxml['rra'][$i]['database']['row'][$r];
113
			$r++;
114
		}
115
		$rows = $rowsempty + $rowsdata;
116
		/* now foreach the rows in the database */
117
		foreach($rows['row'] as $row) {
118
			if(!is_array($rrdoldxml['rra'][$i]['database']['row'][$k])) {
119
				$rrdoldxml['rra'][$i]['database']['row'][$k] = $rrdnewxml['rra'][$i]['database']['row'][$k];
120
			}
121
			$m = 0;
122
			$vcountold = count($rrdoldxml['rra'][$i]['database']['row'][$k]['v']);
123
			$vcountnew = count($rrdnewxml['rra'][$i]['database']['row'][$k]['v']);
124
			foreach($row['v'] as $value) {
125
				if(empty($rrdoldxml['rra'][$i]['database']['row'][$k]['v'][$m])) {
126
					if(isset($valid)) {
127
						$rrdoldxml['rra'][$i]['database']['row'][$k]['v'][$m] = "0.0000000000e+00 ";
128
					} else {
129
						$rrdoldxml['rra'][$i]['database']['row'][$k]['v'][$m] = $rrdnewxml['rra'][$i]['database']['row'][$k]['v'][$m];
130
					}
131
				} else {
132
					if($value <> " NaN ") {
133
						$valid = true;
134
					} else {
135
						$valid = false;
136
					}
137
				}
138
				$m++;
139
			}
140
			$k++;
141
		}
142
		$i++;
143
	}
144

    
145
	$numrranew = count($rrdoldxml['rra']);
146
	$numdsnew = count($rrdoldxml['ds']);
147
	log_error("The new RRD now has $numdsnew DS values and $numrranew RRA databases");
148
	return $rrdoldxml;
149
}
150

    
151
function enable_rrd_graphing() {
152
	global $config, $g, $altq_list_queues;
153

    
154
	if($g['booting']) 
155
		echo "Generating RRD graphs...";
156

    
157
	$rrddbpath = "/var/db/rrd/";
158
	$rrdgraphpath = "/usr/local/www/rrd";
159

    
160
	$traffic = "-traffic.rrd";
161
	$packets = "-packets.rrd";
162
	$states = "-states.rrd";
163
	$wireless = "-wireless.rrd";
164
	$queues = "-queues.rrd";
165
	$queuesdrop = "-queuedrops.rrd";
166
	$spamd = "-spamd.rrd";
167
	$proc = "-processor.rrd";
168
	$mem = "-memory.rrd";
169

    
170
	$rrdtool = "/usr/bin/nice -n20 /usr/local/bin/rrdtool";
171
	$netstat = "/usr/bin/netstat";
172
	$awk = "/usr/bin/awk";
173
	$tar = "/usr/bin/tar";
174
	$pfctl = "/sbin/pfctl";
175
	$sysctl = "/sbin/sysctl";
176
	$php = "/usr/local/bin/php";
177
	$top = "/usr/bin/top";
178
	$spamd_gather = "/usr/local/bin/spamd_gather_stats.php";
179
	$ifconfig = "/sbin/ifconfig";
180

    
181
	$rrdtrafficinterval = 60;
182
	$rrdwirelessinterval = 60;
183
	$rrdqueuesinterval = 60;
184
	$rrdqueuesdropinterval = 60;
185
	$rrdpacketsinterval = 60;
186
	$rrdstatesinterval = 60;
187
	$rrdspamdinterval = 60;
188
	$rrdlbpoolinterval = 60;
189
	$rrdprocinterval = 60;
190
	$rrdmeminterval = 60;
191

    
192
	$trafficvalid = $rrdtrafficinterval * 2;
193
	$wirelessvalid = $rrdwirelessinterval * 2;
194
	$queuesvalid = $rrdqueuesinterval * 2;
195
	$queuesdropvalid = $rrdqueuesdropinterval * 2;
196
	$packetsvalid = $rrdpacketsinterval * 2;
197
	$statesvalid = $rrdstatesinterval*2;
198
	$spamdvalid = $rrdspamdinterval * 2;
199
	$lbpoolvalid = $rrdlbpoolinterval * 2;
200
	$procvalid = $rrdlbpoolinterval * 2;
201
	$memvalid = $rrdmeminterval * 2;
202

    
203
	/* Asume GigE for now */
204
	$downstream = 125000000;
205
	$upstream = 125000000;
206

    
207
	/* read the shaper config */
208
	read_altq_config();
209

    
210
	$rrdrestore = "";
211
	$rrdreturn = "";
212

    
213
	if (isset ($config['rrd']['enable'])) {
214

    
215
		/* create directory if needed */
216
		if (!is_dir("$rrddbpath")) {
217
			mkdir("$rrddbpath", 0755);
218
		}
219

    
220
		if ($g['booting']) {
221
			if ($g['platform'] != "pfSense") {
222
				/* restore the databases, if we have one */
223
				if (file_exists("{$g['cf_conf_path']}/rrd.tgz")) {
224
					exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/rrd.tgz 2>&1", $rrdrestore, $rrdreturn);
225
					$rrdrestore = implode(" ", $rrdrestore);
226
					if($rrdreturn <> 0) {
227
						log_error("RRD restore failed exited with $rrdreturn, the error is: $rrdrestore\n");
228
					}
229
				}
230
			}
231
		}
232

    
233
		/* db update script */
234
		$rrdupdatesh = "#!/bin/sh\n";
235
		$rrdupdatesh .= "\n";
236
		$rrdupdatesh .= "counter=1\n";
237
		$rrdupdatesh .= "while [ \"\$counter\" -ne 0 ]\n";
238
		$rrdupdatesh .= "do\n";
239
		$rrdupdatesh .= "";
240

    
241
		$i = 0;
242
		$vfaces = array (
243
			"vlan.?*",
244
			"enc.?*"
245
		);
246
		$ifdescrs = get_interface_list(true, true, $vfaces);
247
		$ifdescrs['enc0']['friendly'] = "ipsec";
248
		$ifdescrs['enc0']['descr'] = "IPsec";
249
		$ifdescrs['enc0']['up'] = true;
250

    
251
		foreach ($ifdescrs as $realif => $ifdescr) {
252
			$ifname = $ifdescr['friendly'];
253
			$state = $ifdescr['up'];
254

    
255
			/* skip interfaces that do not have a friendly name */
256
			if ("$ifname" == "") {
257
				continue;
258
			}
259

    
260
			/* or are down */
261
			if (!$state) {
262
				continue;
263
			}
264

    
265
			/* TRAFFIC, set up the rrd file */
266
			if (!file_exists("$rrddbpath$ifname$traffic")) {
267
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$traffic --step $rrdtrafficinterval ";
268
				$rrdcreate .= "DS:inpass:COUNTER:$trafficvalid:0:$downstream ";
269
				$rrdcreate .= "DS:outpass:COUNTER:$trafficvalid:0:$upstream ";
270
				$rrdcreate .= "DS:inblock:COUNTER:$trafficvalid:0:$downstream ";
271
				$rrdcreate .= "DS:outblock:COUNTER:$trafficvalid:0:$upstream ";
272
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
273
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
274
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
275
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
276

    
277
				create_new_rrd($rrdcreate);
278
			}
279

    
280
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
281
			if($g['booting']) {
282
				exec("$rrdtool update $rrddbpath$ifname$traffic N:U:U:U:U");
283
			}
284

    
285
			$rrdupdatesh .= "\n";
286
			$rrdupdatesh .= "# polling traffic for interface $ifname $realif \n";
287
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$traffic N:\\\n";
288
			$rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '/In4\/Pass|Out4\/Pass/ {printf \$6 \":\"}'`\\\n";
289
			$rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '/In4\/Block|Out4\/Block/ {printf \$6 \":\"}'|sed -e 's/.\$//'`\n";
290

    
291
			/* PACKETS, set up the rrd file */
292
			if (!file_exists("$rrddbpath$ifname$packets")) {
293
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$packets --step $rrdpacketsinterval ";
294
				$rrdcreate .= "DS:inpass:COUNTER:$packetsvalid:0:$downstream ";
295
				$rrdcreate .= "DS:outpass:COUNTER:$packetsvalid:0:$upstream ";
296
				$rrdcreate .= "DS:inblock:COUNTER:$packetsvalid:0:$downstream ";
297
				$rrdcreate .= "DS:outblock:COUNTER:$packetsvalid:0:$upstream ";
298
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
299
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
300
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
301
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
302

    
303
				create_new_rrd($rrdcreate);
304
			}
305

    
306
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
307
			if($g['booting']) {
308
				exec("$rrdtool update $rrddbpath$ifname$packets N:U:U:U:U");
309
			}
310

    
311
			$rrdupdatesh .= "\n";
312
			$rrdupdatesh .= "# polling packets for interface $ifname $realif \n";
313
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$packets N:\\\n";
314
			$rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '/In4\/Pass|Out4\/Pass/ {printf \$4 \":\"}'`\\\n";
315
			$rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '/In4\/Block|Out4\/Block/ {printf \$4 \":\"}'|sed -e 's/.\$//'`\n";
316

    
317
			/* WIRELESS, set up the rrd file */
318
			if($config['interfaces'][$ifname]['wireless']['mode'] == "bss") {
319
				if (!file_exists("$rrddbpath$ifname$wireless")) {
320
					$rrdcreate = "$rrdtool create $rrddbpath$ifname$wireless --step $rrdwirelessinterval ";
321
					$rrdcreate .= "DS:snr:GAUGE:$wirelessvalid:0:1000 ";
322
					$rrdcreate .= "DS:rate:GAUGE:$wirelessvalid:0:1000 ";
323
					$rrdcreate .= "DS:channel:GAUGE:$wirelessvalid:0:1000 ";
324
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
325
					$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
326
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
327
					$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
328
	
329
					create_new_rrd($rrdcreate);
330
				}
331

    
332
				/* enter UNKNOWN values in the RRD so it knows we rebooted. */
333
				if($g['booting']) {
334
					exec("$rrdtool update $rrddbpath$ifname$wireless N:U:U:U");
335
				}
336

    
337
				$rrdupdatesh .= "\n";
338
				$rrdupdatesh .= "# polling wireless for interface $ifname $realif \n";
339
				$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$wireless N:\\\n";
340
				$rrdupdatesh .= "`$ifconfig {$realif} list ap| $awk 'gsub(\"M\", \"\") {getline 2;print substr(\$5, 0, length(\$5)-2) \":\" $4 \":\" $3}'`\n";
341
			}
342

    
343
				/* QUEUES, set up the queues databases */
344
				if ($altq_list_queues[$ifname]) {
345
					$altq =& $altq_list_queues[$ifname];
346
					/* NOTE: Is it worth as its own function?! */
347
					switch ($altq->GetBwscale()) {
348
                                        case "Gb":
349
                                        	$factor = 1024 * 1024 * 1024;
350
                                                break;
351
                                        case "Mb":
352
                                                $factor = 1024 * 1024;
353
                                                break;
354
                                        case "Kb":
355
                                                $factor = 1024;
356
                                                break;
357
                                        case "b":
358
                                        default:
359
                                                $factor = 1;
360
                                                break;
361
                                        }
362
					$qbandwidth = $altq->GetBandwidth() * $factor;
363
					if ($qbandwidth <=0)
364
						$qbandwidth = 100 * 1000 * 1000; /* 100Mbit */
365
					$qlist =& $altq->get_queue_list($notused);
366
					if (!file_exists("$rrddbpath$ifname$queues")) {
367
						$rrdcreate = "$rrdtool create $rrddbpath$ifname$queues --step $rrdqueuesinterval ";
368
						/* loop list of shaper queues */
369
						$q = 0;
370
						foreach ($qlist as $qname => $q) {
371
							$rrdcreate .= "DS:$qname:COUNTER:$queuesvalid:0:$qbandwidth ";
372
						}
373

    
374
						$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
375
						$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
376
						$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
377
						$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
378

    
379
						create_new_rrd($rrdcreate);
380
					}
381

    
382
					if (!file_exists("$rrddbpath$ifname$queuesdrop")) {
383
						$rrdcreate = "$rrdtool create $rrddbpath$ifname$queuesdrop --step $rrdqueuesdropinterval ";
384
						/* loop list of shaper queues */
385
						$q = 0;
386
						foreach ($qlist as $qname => $q) {
387
							$rrdcreate .= "DS:$qname:COUNTER:$queuesdropvalid:0:$qbandwidth ";
388
						}
389

    
390
						$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
391
						$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
392
						$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
393
						$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
394

    
395
						create_new_rrd($rrdcreate);
396
					}
397

    
398
					if($g['booting']) {
399
						$rrdqcommand = "-t ";
400
						$rrducommand = "N";
401
						$q = 0;
402
						foreach ($qlist as $qname => $q) {
403
							if($q == 0) {
404
								$rrdqcommand .= "{$qname}";
405
							} else {
406
								$rrdqcommand .= ":{$qname}";
407
							}
408
							$q++;
409
							$rrducommand .= ":U";
410
						}
411
						mwexec("$rrdtool update $rrddbpath$ifname$queues $rrdqcommand $rrducommand");
412
						mwexec("$rrdtool update $rrddbpath$ifname$queuesdrop $rrdqcommand $rrducommand");
413
					}
414

    
415
					/* awk function to gather shaper data */
416
					/* yes, it's special */
417
					$rrdupdatesh .= "` pfctl -vsq -i {$realif} | awk 'BEGIN {printf \"$rrdtool update $rrddbpath$ifname$queues \" } ";
418
					$rrdupdatesh .= "{ ";
419
					$rrdupdatesh .= "if ((\$1 == \"queue\") && ( \$2 ~ /^q/ )) { ";
420
					$rrdupdatesh .= "dsname = dsname \":\" \$2 ; ";
421
					$rrdupdatesh .= "q=1; ";
422
					$rrdupdatesh .= "} ";
423
					$rrdupdatesh .= "else if ((\$4 == \"bytes:\") && ( q == 1 ) ) { ";
424
					$rrdupdatesh .= "dsdata = dsdata \":\" \$5 ; ";
425
					$rrdupdatesh .= "q=0; ";
426
					$rrdupdatesh .= "} ";
427
					$rrdupdatesh .= "} END { ";
428
					$rrdupdatesh .= "dsname = substr(dsname,2); ";
429
					$rrdupdatesh .= "dsdata = substr(dsdata,2); ";
430
					$rrdupdatesh .= "printf \"-t \" dsname \" N:\" dsdata }' ";
431
					$rrdupdatesh .= "dsname=\"\" dsdata=\"\"`\n\n";
432

    
433
					$rrdupdatesh .= "` pfctl -vsq -i {$realif} | awk 'BEGIN {printf \"$rrdtool update $rrddbpath$ifname$queuesdrop \" } ";
434
					$rrdupdatesh .= "{ ";
435
					$rrdupdatesh .= "if ((\$1 == \"queue\") && ( \$2 ~ /^q/ )) { ";
436
					$rrdupdatesh .= "dsname = dsname \":\" \$2 ; ";
437
					$rrdupdatesh .= "q=1; ";
438
					$rrdupdatesh .= "} ";
439
					$rrdupdatesh .= "else if ((\$4 == \"bytes:\") && ( q == 1 ) ) { ";
440
					$rrdupdatesh .= "dsdata = dsdata \":\" \$8 ; ";
441
					$rrdupdatesh .= "q=0; ";
442
					$rrdupdatesh .= "} ";
443
					$rrdupdatesh .= "} END { ";
444
					$rrdupdatesh .= "dsname = substr(dsname,2); ";
445
					$rrdupdatesh .= "dsdata = substr(dsdata,2); ";
446
					$rrdupdatesh .= "printf \"-t \" dsname \" N:\" dsdata }' ";
447
					$rrdupdatesh .= "dsname=\"\" dsdata=\"\"`\n\n";
448
				}
449
		}
450
		$i++;
451

    
452
		/* System only statistics */
453
		$ifname = "system";
454

    
455
			/* STATES, create pf states database */
456
			if(! file_exists("$rrddbpath$ifname$states")) {
457
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$states --step $rrdstatesinterval ";
458
				$rrdcreate .= "DS:pfrate:GAUGE:$statesvalid:0:10000000 ";
459
				$rrdcreate .= "DS:pfstates:GAUGE:$statesvalid:0:10000000 ";
460
				$rrdcreate .= "DS:pfnat:GAUGE:$statesvalid:0:10000000 ";
461
				$rrdcreate .= "DS:srcip:GAUGE:$statesvalid:0:10000000 ";
462
				$rrdcreate .= "DS:dstip:GAUGE:$statesvalid:0:10000000 ";
463
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
464
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
465
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
466
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
467

    
468
				create_new_rrd($rrdcreate);
469
			}
470

    
471
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
472
			if($g['booting']) {
473
				exec("$rrdtool update $rrddbpath$ifname$states N:U:U:U:U:U");
474
			}
475

    
476
 			/* the pf states gathering function. */
477
 			$rrdupdatesh .= "\n";
478
			$rrdupdatesh .= "pfctl_si_out=\"` $pfctl -si > /tmp/pfctl_si_out `\"\n";
479
			$rrdupdatesh .= "pfctl_ss_out=\"` $pfctl -ss > /tmp/pfctl_ss_out`\"\n";
480
			$rrdupdatesh .= "pfrate=\"` cat /tmp/pfctl_si_out | egrep \"inserts|removals\" | awk '{ pfrate = \$3 + pfrate } {print pfrate}'|tail -1 `\"\n";
481
 			$rrdupdatesh .= "pfstates=\"` cat /tmp/pfctl_ss_out | egrep -v \"<\\-.*?<\\-|\\->.*?\\->\" | wc -l|sed 's/ //g'`\"\n";
482
			$rrdupdatesh .= "pfnat=\"` cat /tmp/pfctl_ss_out | egrep '<\\-.*?<\\-|\\->.*?\\->' | wc -l|sed 's/ //g' `\"\n";
483
 			$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";
484
 			$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";
485
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$states N:\$pfrate:\$pfstates:\$pfnat:\$srcip:\$dstip\n\n";
486

    
487
			/* End pf states statistics */
488

    
489
			/* CPU, create CPU statistics database */
490
			if(! file_exists("$rrddbpath$ifname$proc")) {
491
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$proc --step $rrdprocinterval ";
492
				$rrdcreate .= "DS:user:GAUGE:$procvalid:0:10000000 ";
493
				$rrdcreate .= "DS:nice:GAUGE:$procvalid:0:10000000 ";
494
				$rrdcreate .= "DS:system:GAUGE:$procvalid:0:10000000 ";
495
				$rrdcreate .= "DS:interrupt:GAUGE:$procvalid:0:10000000 ";
496
				$rrdcreate .= "DS:processes:GAUGE:$procvalid:0:10000000 ";
497
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
498
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
499
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
500
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
501

    
502
				create_new_rrd($rrdcreate);
503
			}
504

    
505
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
506
			if($g['booting']) {
507
				exec("$rrdtool update $rrddbpath$ifname$proc N:U:U:U:U:U");
508
			}
509

    
510
 			/* the CPU stats gathering function. */
511
 			$rrdupdatesh .= "`$top -d 2 -s 1 0 | $awk '{gsub(/%/, \"\")} BEGIN { \\\n";
512
			$rrdupdatesh .= "printf \"$rrdtool update $rrddbpath$ifname$proc \" } \\\n";
513
			$rrdupdatesh .= "{ if ( \$2 == \"processes:\" ) { processes = \$1; } \\\n";
514
			$rrdupdatesh .= "else if ( \$1 == \"CPU:\" ) { user = \$2; nice = \$4; sys = \$6; interrupt = \$8; } \\\n";
515
			$rrdupdatesh .= "} END { printf \"N:\"user\":\"nice\":\"sys\":\"interrupt\":\"processes }'`\n\n";
516

    
517
			/* End CPU statistics */
518

    
519
			/* Memory, create Memory statistics database */
520
			if(! file_exists("$rrddbpath$ifname$mem")) {
521
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$mem --step $rrdmeminterval ";
522
				$rrdcreate .= "DS:active:GAUGE:$memvalid:0:10000000 ";
523
				$rrdcreate .= "DS:inactive:GAUGE:$memvalid:0:10000000 ";
524
				$rrdcreate .= "DS:free:GAUGE:$memvalid:0:10000000 ";
525
				$rrdcreate .= "DS:cache:GAUGE:$memvalid:0:10000000 ";
526
				$rrdcreate .= "DS:wire:GAUGE:$memvalid:0:10000000 ";
527
				$rrdcreate .= "RRA:MIN:0.5:1:1000 ";
528
				$rrdcreate .= "RRA:MIN:0.5:5:1000 ";
529
				$rrdcreate .= "RRA:MIN:0.5:60:1000 ";
530
				$rrdcreate .= "RRA:MIN:0.5:720:3000 ";
531
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
532
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
533
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
534
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
535
				$rrdcreate .= "RRA:MAX:0.5:1:1000 ";
536
				$rrdcreate .= "RRA:MAX:0.5:5:1000 ";
537
				$rrdcreate .= "RRA:MAX:0.5:60:1000 ";
538
				$rrdcreate .= "RRA:MAX:0.5:720:3000";
539

    
540
				create_new_rrd($rrdcreate);
541
			}
542

    
543
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
544
			if($g['booting']) {
545
				exec("$rrdtool update $rrddbpath$ifname$mem N:U:U:U:U:U");
546
			}
547

    
548
 			/* the Memory stats gathering function. */
549
 			$rrdupdatesh .= "`$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 | ";
550
			$rrdupdatesh .= " $awk '{getline active;getline inactive;getline free;getline cache;getline wire;printf \"$rrdtool update $rrddbpath$ifname$mem N:\"";
551
			$rrdupdatesh .= "((active/$0) * 100)\":\"((inactive/$0) * 100)\":\"((free/$0) * 100)\":\"((cache/$0) * 100)\":\"(wire/$0 * 100)}'`\n\n";
552
			
553
			/* End Memory statistics */
554

    
555
			/* SPAMD, set up the spamd rrd file */
556
			if (isset($config['installedpackages']['spamdsettings']) &&
557
				 isset ($config['installedpackages']['spamdsettings']['config'][0]['enablerrd'])) {
558
				/* set up the spamd rrd file */
559
				if (!file_exists("$rrddbpath$ifname$spamd")) {
560
					$rrdcreate = "$rrdtool create $rrddbpath$ifname$spamd --step $rrdspamdinterval ";
561
					$rrdcreate .= "DS:conn:GAUGE:$spamdvalid:0:10000 ";
562
					$rrdcreate .= "DS:time:GAUGE:$spamdvalid:0:86400 ";
563
					$rrdcreate .= "RRA:MIN:0.5:1:1000 ";
564
					$rrdcreate .= "RRA:MIN:0.5:5:1000 ";
565
					$rrdcreate .= "RRA:MIN:0.5:60:1000 ";
566
					$rrdcreate .= "RRA:MIN:0.5:720:3000 ";
567
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
568
					$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
569
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
570
					$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
571
					$rrdcreate .= "RRA:MAX:0.5:1:1000 ";
572
					$rrdcreate .= "RRA:MAX:0.5:5:1000 ";
573
					$rrdcreate .= "RRA:MAX:0.5:60:1000 ";
574
					$rrdcreate .= "RRA:MAX:0.5:720:3000 ";
575

    
576
					create_new_rrd($rrdcreate);
577
				}
578

    
579
				$rrdupdatesh .= "\n";
580
				$rrdupdatesh .= "# polling spamd for connections and tarpitness \n";
581
				$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$spamd \\\n";
582
				$rrdupdatesh .= "`$php -q $spamd_gather`\n";
583

    
584
			}
585
		/* End System statistics */
586

    
587
		$rrdupdatesh .= "sleep 60\n";
588
		$rrdupdatesh .= "done\n";
589
		log_error("Creating rrd update script");
590
		/* write the rrd update script */
591
		$updaterrdscript = "{$g['vardb_path']}/rrd/updaterrd.sh";
592
		$fd = fopen("$updaterrdscript", "w");
593
		fwrite($fd, "$rrdupdatesh");
594
		fclose($fd);
595

    
596
		/* kill off traffic collectors */
597
		kill_traffic_collector();
598

    
599
		/* start traffic collector */
600
		mwexec_bg("/usr/bin/nice -n20 /bin/sh $updaterrdscript");
601

    
602
	} else {
603
		/* kill off traffic collectors */
604
		kill_traffic_collector();
605
	}
606

    
607
	if($g['booting']) 
608
		echo "done.\n";
609
		
610
}
611

    
612
function kill_traffic_collector() {
613
	mwexec("ps awwwux | grep '/[u]pdaterrd.sh' | awk '{print $2}' | xargs kill");
614
}
615

    
616
/* This xml 2 array function is courtesy of the php.net comment section on xml_parse.
617
 * it is roughly 4 times faster then our existing pfSense parser but due to the large
618
 * size of the RRD xml dumps this is required.
619
 * The reason we do not use it for pfSense is that it does not know about array fields
620
 * which causes it to fail on array fields with single items. Possible Todo?
621
 */
622
function xml2array($contents, $get_attributes = 1, $priority = 'tag')
623
{
624
    if (!function_exists('xml_parser_create'))
625
    {
626
        return array ();
627
    }
628
    $parser = xml_parser_create('');
629
    xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8");
630
    xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
631
    xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
632
    xml_parse_into_struct($parser, trim($contents), $xml_values);
633
    xml_parser_free($parser);
634
    if (!$xml_values)
635
        return; //Hmm...
636
    $xml_array = array ();
637
    $parents = array ();
638
    $opened_tags = array ();
639
    $arr = array ();
640
    $current = & $xml_array;
641
    $repeated_tag_index = array ();
642
    foreach ($xml_values as $data)
643
    {
644
        unset ($attributes, $value);
645
        extract($data);
646
        $result = array ();
647
        $attributes_data = array ();
648
        if (isset ($value))
649
        {
650
            if ($priority == 'tag')
651
                $result = $value;
652
            else
653
                $result['value'] = $value;
654
        }
655
        if (isset ($attributes) and $get_attributes)
656
        {
657
            foreach ($attributes as $attr => $val)
658
            {
659
                if ($priority == 'tag')
660
                    $attributes_data[$attr] = $val;
661
                else
662
                    $result['attr'][$attr] = $val; //Set all the attributes in a array called 'attr'
663
            }
664
        }
665
        if ($type == "open")
666
        {
667
            $parent[$level -1] = & $current;
668
            if (!is_array($current) or (!in_array($tag, array_keys($current))))
669
            {
670
                $current[$tag] = $result;
671
                if ($attributes_data)
672
                    $current[$tag . '_attr'] = $attributes_data;
673
                $repeated_tag_index[$tag . '_' . $level] = 1;
674
                $current = & $current[$tag];
675
            }
676
            else
677
            {
678
                if (isset ($current[$tag][0]))
679
                {
680
                    $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
681
                    $repeated_tag_index[$tag . '_' . $level]++;
682
                }
683
                else
684
                {
685
                    $current[$tag] = array (
686
                        $current[$tag],
687
                        $result
688
                    );
689
                    $repeated_tag_index[$tag . '_' . $level] = 2;
690
                    if (isset ($current[$tag . '_attr']))
691
                    {
692
                        $current[$tag]['0_attr'] = $current[$tag . '_attr'];
693
                        unset ($current[$tag . '_attr']);
694
                    }
695
                }
696
                $last_item_index = $repeated_tag_index[$tag . '_' . $level] - 1;
697
                $current = & $current[$tag][$last_item_index];
698
            }
699
        }
700
        elseif ($type == "complete")
701
        {
702
            if (!isset ($current[$tag]))
703
            {
704
                $current[$tag] = $result;
705
                $repeated_tag_index[$tag . '_' . $level] = 1;
706
                if ($priority == 'tag' and $attributes_data)
707
                    $current[$tag . '_attr'] = $attributes_data;
708
            }
709
            else
710
            {
711
                if (isset ($current[$tag][0]) and is_array($current[$tag]))
712
                {
713
                    $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
714
                    if ($priority == 'tag' and $get_attributes and $attributes_data)
715
                    {
716
                        $current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
717
                    }
718
                    $repeated_tag_index[$tag . '_' . $level]++;
719
                }
720
                else
721
                {
722
                    $current[$tag] = array (
723
                        $current[$tag],
724
                        $result
725
                    );
726
                    $repeated_tag_index[$tag . '_' . $level] = 1;
727
                    if ($priority == 'tag' and $get_attributes)
728
                    {
729
                        if (isset ($current[$tag . '_attr']))
730
                        {
731
                            $current[$tag]['0_attr'] = $current[$tag . '_attr'];
732
                            unset ($current[$tag . '_attr']);
733
                        }
734
                        if ($attributes_data)
735
                        {
736
                            $current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
737
                        }
738
                    }
739
                    $repeated_tag_index[$tag . '_' . $level]++; //0 and 1 index is already taken
740
                }
741
            }
742
        }
743
        elseif ($type == 'close')
744
        {
745
            $current = & $parent[$level -1];
746
        }
747
    }
748
    return ($xml_array);
749
}
750

    
751
?>
(29-29/43)