Project

General

Profile

Download (25.6 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("RRD dump failed exited with $dumpret, the error is: $dumpout");
46
	}
47
	return($dumpret);
48
}
49

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

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

    
85
	$i = 0;
86
	$rracountold = count($rrdoldxml['rra']);
87
	$rracountnew = count($rrdnewxml['rra']);
88
	/* process each RRA, which contain a database */
89
	foreach($rrdnewxml['rra'] as $rra) {
90
		if(!is_array($rrdoldxml['rra'][$i])) {
91
			$rrdoldxml['rra'][$i] = $rrdnewxml['rra'][$i];
92
		}
93

    
94
		$d = 0;
95
		/* process cdp_prep */
96
		$cdp_prep = $rra['cdp_prep'];
97
		foreach($cdp_prep['ds'] as $ds) {
98
			if(!is_array($rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d])) {
99
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d] = $rrdnewxml['rra'][$i]['cdp_prep']['ds'][$d];
100
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d]['primary_value'] = " 0.0000000000e+00 ";
101
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d]['secondary_value'] = " 0.0000000000e+00 ";
102
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d]['value'] = " 0.0000000000e+00 ";
103
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d]['unknown_datapoints'] = "0";
104
			}
105
			$d++;
106
		}
107

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

    
152
	$numrranew = count($rrdoldxml['rra']);
153
	$numdsnew = count($rrdoldxml['ds']);
154
	log_error("The new RRD now has $numdsnew DS values and $numrranew RRA databases");
155
	return $rrdoldxml;
156
}
157

    
158
function enable_rrd_graphing() {
159
	global $config, $g, $altq_list_queues;
160

    
161
	if($g['booting']) 
162
		echo "Generating RRD graphs...";
163

    
164
	$rrddbpath = "/var/db/rrd/";
165
	$rrdgraphpath = "/usr/local/www/rrd";
166

    
167
	$traffic = "-traffic.rrd";
168
	$packets = "-packets.rrd";
169
	$states = "-states.rrd";
170
	$wireless = "-wireless.rrd";
171
	$queues = "-queues.rrd";
172
	$queuesdrop = "-queuedrops.rrd";
173
	$spamd = "-spamd.rrd";
174
	$proc = "-processor.rrd";
175
	$mem = "-memory.rrd";
176
	$cellular = "-cellular.rrd";
177
	$vpnusers = "-vpnusers.rrd";
178

    
179
	$rrdtool = "/usr/bin/nice -n20 /usr/local/bin/rrdtool";
180
	$netstat = "/usr/bin/netstat";
181
	$awk = "/usr/bin/awk";
182
	$tar = "/usr/bin/tar";
183
	$pfctl = "/sbin/pfctl";
184
	$sysctl = "/sbin/sysctl";
185
	$php = "/usr/local/bin/php";
186
	$top = "/usr/bin/top";
187
	$spamd_gather = "/usr/local/bin/spamd_gather_stats.php";
188
	$ifconfig = "/sbin/ifconfig";
189

    
190
	$rrdtrafficinterval = 60;
191
	$rrdwirelessinterval = 60;
192
	$rrdqueuesinterval = 60;
193
	$rrdqueuesdropinterval = 60;
194
	$rrdpacketsinterval = 60;
195
	$rrdstatesinterval = 60;
196
	$rrdspamdinterval = 60;
197
	$rrdlbpoolinterval = 60;
198
	$rrdprocinterval = 60;
199
	$rrdmeminterval = 60;
200
	$rrdcellularinterval = 60;
201
	$rrdvpninterval = 60;
202

    
203
	$trafficvalid = $rrdtrafficinterval * 2;
204
	$wirelessvalid = $rrdwirelessinterval * 2;
205
	$queuesvalid = $rrdqueuesinterval * 2;
206
	$queuesdropvalid = $rrdqueuesdropinterval * 2;
207
	$packetsvalid = $rrdpacketsinterval * 2;
208
	$statesvalid = $rrdstatesinterval*2;
209
	$spamdvalid = $rrdspamdinterval * 2;
210
	$lbpoolvalid = $rrdlbpoolinterval * 2;
211
	$procvalid = $rrdlbpoolinterval * 2;
212
	$memvalid = $rrdmeminterval * 2;
213
	$cellularvalid = $rrdcellularinterval * 2;
214
	$vpnvalid = $rrdvpninterval * 2;
215

    
216
	/* Asume GigE for now */
217
	$downstream = 125000000;
218
	$upstream = 125000000;
219

    
220
	/* read the shaper config */
221
	read_altq_config();
222

    
223
	$rrdrestore = "";
224
	$rrdreturn = "";
225

    
226
	if (isset ($config['rrd']['enable'])) {
227

    
228
		/* create directory if needed */
229
		if (!is_dir($rrddbpath)) {
230
			mkdir($rrddbpath, 0775);
231
		}
232
		chown($rrddbpath, "nobody");
233

    
234
		if ($g['booting']) {
235
			if ($g['platform'] != "pfSense") {
236
				/* restore the databases, if we have one */
237
				if (file_exists("{$g['cf_conf_path']}/rrd.tgz")) {
238
					exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/rrd.tgz 2>&1", $rrdrestore, $rrdreturn);
239
					$rrdrestore = implode(" ", $rrdrestore);
240
					if($rrdreturn <> 0) {
241
						log_error("RRD restore failed exited with $rrdreturn, the error is: $rrdrestore\n");
242
					}
243
				}
244
			}
245
		}
246

    
247
		/* db update script */
248
		$rrdupdatesh = "#!/bin/sh\n";
249
		$rrdupdatesh .= "\n";
250
		$rrdupdatesh .= "counter=1\n";
251
		$rrdupdatesh .= "while [ \"\$counter\" -ne 0 ]\n";
252
		$rrdupdatesh .= "do\n";
253
		$rrdupdatesh .= "";
254

    
255
		$i = 0;
256
		$ifdescrs = get_configured_interface_with_descr();
257
		/* IPsec counters */
258
		$ifdescrs['ipsec'] = "IPsec";
259
		/* OpenVPN server counters */
260
		if(is_array($config['openvpn']['openvpn-server'])) {
261
			foreach($config['openvpn']['openvpn-server'] as $server) {
262
				$serverid = "ovpns" . $server['vpnid'];
263
				$ifdescrs[$serverid] = "{$server['description']}";
264
			}
265
		}
266

    
267
		/* process all real and pseudo interfaces */
268
		foreach ($ifdescrs as $ifname => $ifdescr) {
269
			$temp = get_real_interface($ifname);
270
			if($temp <> "") {
271
				$realif = $temp;
272
			}
273

    
274
			/* TRAFFIC, set up the rrd file */
275
			if (!file_exists("$rrddbpath$ifname$traffic")) {
276
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$traffic --step $rrdtrafficinterval ";
277
				$rrdcreate .= "DS:inpass:COUNTER:$trafficvalid:0:$downstream ";
278
				$rrdcreate .= "DS:outpass:COUNTER:$trafficvalid:0:$upstream ";
279
				$rrdcreate .= "DS:inblock:COUNTER:$trafficvalid:0:$downstream ";
280
				$rrdcreate .= "DS:outblock:COUNTER:$trafficvalid:0:$upstream ";
281
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
282
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
283
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
284
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
285

    
286
				create_new_rrd($rrdcreate);
287
			}
288

    
289
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
290
			if($g['booting']) {
291
				mwexec("$rrdtool update $rrddbpath$ifname$traffic N:U:U:U:U");
292
			}
293

    
294
			$rrdupdatesh .= "\n";
295
			$rrdupdatesh .= "# polling traffic for interface $ifname $realif \n";
296
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$traffic N:\\\n";
297
			$rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '/In4\/Pass|Out4\/Pass/ {printf \$6 \":\"}'`\\\n";
298
			$rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '/In4\/Block|Out4\/Block/ {printf \$6 \":\"}'|sed -e 's/.\$//'`\n";
299

    
300
			/* PACKETS, set up the rrd file */
301
			if (!file_exists("$rrddbpath$ifname$packets")) {
302
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$packets --step $rrdpacketsinterval ";
303
				$rrdcreate .= "DS:inpass:COUNTER:$packetsvalid:0:$downstream ";
304
				$rrdcreate .= "DS:outpass:COUNTER:$packetsvalid:0:$upstream ";
305
				$rrdcreate .= "DS:inblock:COUNTER:$packetsvalid:0:$downstream ";
306
				$rrdcreate .= "DS:outblock:COUNTER:$packetsvalid:0:$upstream ";
307
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
308
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
309
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
310
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
311

    
312
				create_new_rrd($rrdcreate);
313
			}
314

    
315
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
316
			if($g['booting']) {
317
				mwexec("$rrdtool update $rrddbpath$ifname$packets N:U:U:U:U");
318
			}
319

    
320
			$rrdupdatesh .= "\n";
321
			$rrdupdatesh .= "# polling packets for interface $ifname $realif \n";
322
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$packets N:\\\n";
323
			$rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '/In4\/Pass|Out4\/Pass/ {printf \$4 \":\"}'`\\\n";
324
			$rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '/In4\/Block|Out4\/Block/ {printf \$4 \":\"}'|sed -e 's/.\$//'`\n";
325

    
326
			/* WIRELESS, set up the rrd file */
327
			if($config['interfaces'][$ifname]['wireless']['mode'] == "bss") {
328
				if (!file_exists("$rrddbpath$ifname$wireless")) {
329
					$rrdcreate = "$rrdtool create $rrddbpath$ifname$wireless --step $rrdwirelessinterval ";
330
					$rrdcreate .= "DS:snr:GAUGE:$wirelessvalid:0:1000 ";
331
					$rrdcreate .= "DS:rate:GAUGE:$wirelessvalid:0:1000 ";
332
					$rrdcreate .= "DS:channel:GAUGE:$wirelessvalid:0:1000 ";
333
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
334
					$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
335
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
336
					$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
337
	
338
					create_new_rrd($rrdcreate);
339
				}
340

    
341
				/* enter UNKNOWN values in the RRD so it knows we rebooted. */
342
				if($g['booting']) {
343
					mwexec("$rrdtool update $rrddbpath$ifname$wireless N:U:U:U");
344
				}
345

    
346
				$rrdupdatesh .= "\n";
347
				$rrdupdatesh .= "# polling wireless for interface $ifname $realif \n";
348
				$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$wireless N:\\\n";
349
				$rrdupdatesh .= "`$ifconfig {$realif} list sta| $awk 'gsub(\"M\", \"\") {getline 2;print substr(\$5, 0, length(\$5)-2) \":\" $4 \":\" $3}'`\n";
350
			}
351

    
352
			/* OpenVPN, set up the rrd file */
353
			if(stristr($ifname, "ovpns")) {
354
				if (!file_exists("$rrddbpath$ifname$vpnusers")) {
355
					$rrdcreate = "$rrdtool create $rrddbpath$ifname$vpnusers --step $rrdvpninterval ";
356
					$rrdcreate .= "DS:users:GAUGE:$vpnvalid:0:10000 ";
357
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
358
					$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
359
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
360
					$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
361
	
362
					create_new_rrd($rrdcreate);
363
				}
364

    
365
				/* enter UNKNOWN values in the RRD so it knows we rebooted. */
366
				if($g['booting']) {
367
					mwexec("$rrdtool update $rrddbpath$ifname$vpnusers N:U");
368
				}
369

    
370
				if(is_array($config['openvpn']['openvpn-server'])) {
371
					foreach($config['openvpn']['openvpn-server'] as $server) {
372
						if("ovpns{$server['vpnid']}" == $ifname) {
373
							$port = $server['local_port'];
374
							$vpnid = $server['vpnid'];
375
						}
376
					}
377
				}
378
				$rrdupdatesh .= "\n";
379
				$rrdupdatesh .= "# polling vpn users for interface $ifname $realif port $port\n";
380
				$rrdupdatesh .= "list_current_users() {\n";
381
				$rrdupdatesh .= " sleep 0.2\n";
382
				$rrdupdatesh .= " echo \"status 2\"\n";
383
				$rrdupdatesh .= " sleep 0.2\n";
384
				$rrdupdatesh .= " echo \"quit\"\n";
385
				$rrdupdatesh .= "}\n";
386
				$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$vpnusers N:\\\n";
387
				$rrdupdatesh .= "`list_current_users | nc -U {$g['varetc_path']}/openvpn/server{$vpnid}.sock | awk -F\",\" '/^CLIENT_LIST/ {print \$2}' | wc -l | awk '{print $1}'` &\n";
388
			}
389

    
390
			/* QUEUES, set up the queues databases */
391
			if ($altq_list_queues[$ifname]) {
392
				$altq =& $altq_list_queues[$ifname];
393
				/* NOTE: Is it worth as its own function?! */
394
				switch ($altq->GetBwscale()) {
395
					case "Gb":
396
						$factor = 1024 * 1024 * 1024;
397
							break;
398
					case "Mb":
399
							$factor = 1024 * 1024;
400
							break;
401
					case "Kb":
402
							$factor = 1024;
403
							break;
404
					case "b":
405
					default:
406
							$factor = 1;
407
							break;
408
				}
409
				$qbandwidth = $altq->GetBandwidth() * $factor;
410
				if ($qbandwidth <=0) {
411
					$qbandwidth = 100 * 1000 * 1000; /* 100Mbit */
412
				}
413
				$qlist =& $altq->get_queue_list($notused);
414
				if (!file_exists("$rrddbpath$ifname$queues")) {
415
					$rrdcreate = "$rrdtool create $rrddbpath$ifname$queues --step $rrdqueuesinterval ";
416
					/* loop list of shaper queues */
417
					$q = 0;
418
					foreach ($qlist as $qname => $q) {
419
						$rrdcreate .= "DS:$qname:COUNTER:$queuesvalid:0:$qbandwidth ";
420
					}
421

    
422
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
423
					$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
424
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
425
					$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
426

    
427
					create_new_rrd($rrdcreate);
428
				}
429

    
430
				if (!file_exists("$rrddbpath$ifname$queuesdrop")) {
431
					$rrdcreate = "$rrdtool create $rrddbpath$ifname$queuesdrop --step $rrdqueuesdropinterval ";
432
					/* loop list of shaper queues */
433
					$q = 0;
434
					foreach ($qlist as $qname => $q) {
435
						$rrdcreate .= "DS:$qname:COUNTER:$queuesdropvalid:0:$qbandwidth ";
436
					}
437

    
438
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
439
					$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
440
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
441
					$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
442

    
443
					create_new_rrd($rrdcreate);
444
				}
445

    
446
				if($g['booting']) {
447
					$rrdqcommand = "-t ";
448
					$rrducommand = "N";
449
					$q = 0;
450
					foreach ($qlist as $qname => $q) {
451
						if($q == 0) {
452
							$rrdqcommand .= "{$qname}";
453
						} else {
454
							$rrdqcommand .= ":{$qname}";
455
						}
456
						$q++;
457
						$rrducommand .= ":U";
458
					}
459
					mwexec("$rrdtool update $rrddbpath$ifname$queues $rrdqcommand $rrducommand");
460
					mwexec("$rrdtool update $rrddbpath$ifname$queuesdrop $rrdqcommand $rrducommand");
461
				}
462

    
463
				/* awk function to gather shaper data */
464
				/* yes, it's special */
465
				$rrdupdatesh .= "` pfctl -vsq -i {$realif} | awk 'BEGIN {printf \"$rrdtool update $rrddbpath$ifname$queues \" } ";
466
				$rrdupdatesh .= "{ ";
467
				$rrdupdatesh .= "if ((\$1 == \"queue\") && ( \$2 ~ /^q/ )) { ";
468
				$rrdupdatesh .= " dsname = dsname \":\" \$2 ; ";
469
				$rrdupdatesh .= " q=1; ";
470
				$rrdupdatesh .= "} ";
471
				$rrdupdatesh .= " else if ((\$4 == \"bytes:\") && ( q == 1 ) ) { ";
472
				$rrdupdatesh .= " dsdata = dsdata \":\" \$5 ; ";
473
				$rrdupdatesh .= " q=0; ";
474
				$rrdupdatesh .= "} ";
475
				$rrdupdatesh .= "} END { ";
476
				$rrdupdatesh .= " dsname = substr(dsname,2); ";
477
				$rrdupdatesh .= " dsdata = substr(dsdata,2); ";
478
				$rrdupdatesh .= " printf \"-t \" dsname \" N:\" dsdata }' ";
479
				$rrdupdatesh .= " dsname=\"\" dsdata=\"\"`\n\n";
480

    
481
				$rrdupdatesh .= "` pfctl -vsq -i {$realif} | awk 'BEGIN {printf \"$rrdtool update $rrddbpath$ifname$queuesdrop \" } ";
482
				$rrdupdatesh .= "{ ";
483
				$rrdupdatesh .= "if ((\$1 == \"queue\") && ( \$2 ~ /^q/ )) { ";
484
				$rrdupdatesh .= " dsname = dsname \":\" \$2 ; ";
485
				$rrdupdatesh .= " q=1; ";
486
				$rrdupdatesh .= "} ";
487
				$rrdupdatesh .= " else if ((\$4 == \"bytes:\") && ( q == 1 ) ) { ";
488
				$rrdupdatesh .= " dsdata = dsdata \":\" \$8 ; ";
489
				$rrdupdatesh .= " q=0; ";
490
				$rrdupdatesh .= "} ";
491
				$rrdupdatesh .= "} END { ";
492
				$rrdupdatesh .= " dsname = substr(dsname,2); ";
493
				$rrdupdatesh .= " dsdata = substr(dsdata,2); ";
494
				$rrdupdatesh .= " printf \"-t \" dsname \" N:\" dsdata }' ";
495
				$rrdupdatesh .= " dsname=\"\" dsdata=\"\"`\n\n";
496
			}
497
		}
498
		$i++;
499

    
500
		/* System only statistics */
501
		$ifname = "system";
502

    
503
		/* STATES, create pf states database */
504
		if(! file_exists("$rrddbpath$ifname$states")) {
505
			$rrdcreate = "$rrdtool create $rrddbpath$ifname$states --step $rrdstatesinterval ";
506
			$rrdcreate .= "DS:pfrate:GAUGE:$statesvalid:0:10000000 ";
507
			$rrdcreate .= "DS:pfstates:GAUGE:$statesvalid:0:10000000 ";
508
			$rrdcreate .= "DS:pfnat:GAUGE:$statesvalid:0:10000000 ";
509
			$rrdcreate .= "DS:srcip:GAUGE:$statesvalid:0:10000000 ";
510
			$rrdcreate .= "DS:dstip:GAUGE:$statesvalid:0:10000000 ";
511
			$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
512
			$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
513
			$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
514
			$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
515

    
516
			create_new_rrd($rrdcreate);
517
		}
518

    
519
		/* enter UNKNOWN values in the RRD so it knows we rebooted. */
520
		if($g['booting']) {
521
			mwexec("$rrdtool update $rrddbpath$ifname$states N:U:U:U:U:U");
522
		}
523

    
524
		/* the pf states gathering function. */
525
		$rrdupdatesh .= "\n";
526
		$rrdupdatesh .= "pfctl_si_out=\"` $pfctl -si > /tmp/pfctl_si_out `\"\n";
527
		$rrdupdatesh .= "pfctl_ss_out=\"` $pfctl -ss > /tmp/pfctl_ss_out`\"\n";
528
		$rrdupdatesh .= "pfrate=\"` cat /tmp/pfctl_si_out | egrep \"inserts|removals\" | awk '{ pfrate = \$3 + pfrate } {print pfrate}'|tail -1 `\"\n";
529
		$rrdupdatesh .= "pfstates=\"` cat /tmp/pfctl_ss_out | egrep -v \"<\\-.*?<\\-|\\->.*?\\->\" | wc -l|sed 's/ //g'`\"\n";
530
		$rrdupdatesh .= "pfnat=\"` cat /tmp/pfctl_ss_out | egrep '<\\-.*?<\\-|\\->.*?\\->' | wc -l|sed 's/ //g' `\"\n";
531
		$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";
532
		$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";
533
		$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$states N:\$pfrate:\$pfstates:\$pfnat:\$srcip:\$dstip\n\n";
534

    
535
		/* End pf states statistics */
536

    
537
		/* CPU, create CPU statistics database */
538
		if(! file_exists("$rrddbpath$ifname$proc")) {
539
			$rrdcreate = "$rrdtool create $rrddbpath$ifname$proc --step $rrdprocinterval ";
540
			$rrdcreate .= "DS:user:GAUGE:$procvalid:0:10000000 ";
541
			$rrdcreate .= "DS:nice:GAUGE:$procvalid:0:10000000 ";
542
			$rrdcreate .= "DS:system:GAUGE:$procvalid:0:10000000 ";
543
			$rrdcreate .= "DS:interrupt:GAUGE:$procvalid:0:10000000 ";
544
			$rrdcreate .= "DS:processes:GAUGE:$procvalid:0:10000000 ";
545
			$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
546
			$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
547
			$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
548
			$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
549

    
550
			create_new_rrd($rrdcreate);
551
		}
552

    
553
		/* enter UNKNOWN values in the RRD so it knows we rebooted. */
554
		if($g['booting']) {
555
			mwexec("$rrdtool update $rrddbpath$ifname$proc N:U:U:U:U:U");
556
		}
557

    
558
		/* the CPU stats gathering function. */
559
		$rrdupdatesh .= "`$top -d 2 -s 1 0 | $awk '{gsub(/%/, \"\")} BEGIN { \\\n";
560
		$rrdupdatesh .= "printf \"$rrdtool update $rrddbpath$ifname$proc \" } \\\n";
561
		$rrdupdatesh .= "{ if ( \$2 == \"processes:\" ) { processes = \$1; } \\\n";
562
		$rrdupdatesh .= "else if ( \$1 == \"CPU:\" ) { user = \$2; nice = \$4; sys = \$6; interrupt = \$8; } \\\n";
563
		$rrdupdatesh .= "} END { printf \"N:\"user\":\"nice\":\"sys\":\"interrupt\":\"processes }'`\n\n";
564

    
565
		/* End CPU statistics */
566

    
567
		/* Memory, create Memory statistics database */
568
		if(! file_exists("$rrddbpath$ifname$mem")) {
569
			$rrdcreate = "$rrdtool create $rrddbpath$ifname$mem --step $rrdmeminterval ";
570
			$rrdcreate .= "DS:active:GAUGE:$memvalid:0:10000000 ";
571
			$rrdcreate .= "DS:inactive:GAUGE:$memvalid:0:10000000 ";
572
			$rrdcreate .= "DS:free:GAUGE:$memvalid:0:10000000 ";
573
			$rrdcreate .= "DS:cache:GAUGE:$memvalid:0:10000000 ";
574
			$rrdcreate .= "DS:wire:GAUGE:$memvalid:0:10000000 ";
575
			$rrdcreate .= "RRA:MIN:0.5:1:1000 ";
576
			$rrdcreate .= "RRA:MIN:0.5:5:1000 ";
577
			$rrdcreate .= "RRA:MIN:0.5:60:1000 ";
578
			$rrdcreate .= "RRA:MIN:0.5:720:3000 ";
579
			$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
580
			$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
581
			$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
582
			$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
583
			$rrdcreate .= "RRA:MAX:0.5:1:1000 ";
584
			$rrdcreate .= "RRA:MAX:0.5:5:1000 ";
585
			$rrdcreate .= "RRA:MAX:0.5:60:1000 ";
586
			$rrdcreate .= "RRA:MAX:0.5:720:3000";
587

    
588
			create_new_rrd($rrdcreate);
589
		}
590

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

    
596
		/* the Memory stats gathering function. */
597
		$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 | ";
598
		$rrdupdatesh .= " $awk '{getline active;getline inactive;getline free;getline cache;getline wire;printf \"$rrdtool update $rrddbpath$ifname$mem N:\"";
599
		$rrdupdatesh .= "((active/$0) * 100)\":\"((inactive/$0) * 100)\":\"((free/$0) * 100)\":\"((cache/$0) * 100)\":\"(wire/$0 * 100)}'`\n\n";
600
		
601
		/* End Memory statistics */
602

    
603
		/* SPAMD, set up the spamd rrd file */
604
		if (isset($config['installedpackages']['spamdsettings']) &&
605
			 isset ($config['installedpackages']['spamdsettings']['config'][0]['enablerrd'])) {
606
			/* set up the spamd rrd file */
607
			if (!file_exists("$rrddbpath$ifname$spamd")) {
608
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$spamd --step $rrdspamdinterval ";
609
				$rrdcreate .= "DS:conn:GAUGE:$spamdvalid:0:10000 ";
610
				$rrdcreate .= "DS:time:GAUGE:$spamdvalid:0:86400 ";
611
				$rrdcreate .= "RRA:MIN:0.5:1:1000 ";
612
				$rrdcreate .= "RRA:MIN:0.5:5:1000 ";
613
				$rrdcreate .= "RRA:MIN:0.5:60:1000 ";
614
				$rrdcreate .= "RRA:MIN:0.5:720:3000 ";
615
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
616
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
617
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
618
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
619
				$rrdcreate .= "RRA:MAX:0.5:1:1000 ";
620
				$rrdcreate .= "RRA:MAX:0.5:5:1000 ";
621
				$rrdcreate .= "RRA:MAX:0.5:60:1000 ";
622
				$rrdcreate .= "RRA:MAX:0.5:720:3000 ";
623

    
624
				create_new_rrd($rrdcreate);
625
			}
626

    
627
			$rrdupdatesh .= "\n";
628
			$rrdupdatesh .= "# polling spamd for connections and tarpitness \n";
629
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$spamd \\\n";
630
			$rrdupdatesh .= "`$php -q $spamd_gather`\n";
631

    
632
		}
633
		/* End System statistics */
634

    
635
		/* 3G WIRELESS, set up the rrd file */
636
		/* XXX: Are multiple 3G interfaces not possible? smos@ */
637
		if(isset($config['ppps']['ppp'])) {
638
			$ifname = "ppp";
639
			if (!file_exists("$rrddbpath$ifname$cellular")) {
640
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$cellular --step $rrdcellularinterval ";
641
				$rrdcreate .= "DS:signal1:GAUGE:$cellularvalid:-200:200 ";
642
				$rrdcreate .= "DS:signal2:GAUGE:$cellularvalid:-200:200 ";
643
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
644
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
645
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
646
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
647

    
648
				create_new_rrd($rrdcreate);
649
			}
650

    
651
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
652
			if($g['booting']) {
653
				mwexec("$rrdtool update $rrddbpath$ifname$cellular N:U:U");
654
			}
655

    
656
			$rrdupdatesh .= "\n";
657
			$rrdupdatesh .= "# polling 3G\n";
658
			$rrdupdatesh .= "dev=`usbconfig show_ifdrv | awk -F. '/ u3g|umodem/ {print \"/dev/\" $1 \".\" $2}'`\n";
659
			$rrdupdatesh .= "if [ -n \"\$dev\" ]; then $rrdtool update $rrddbpath$ifname$cellular N:`3gstat -s -d \$dev`\n";
660
			$rrdupdatesh .= "else $rrdtool update $rrddbpath$ifname$cellular N:U:U; fi\n";
661
		}
662

    
663

    
664
		$rrdupdatesh .= "sleep 60\n";
665
		$rrdupdatesh .= "done\n";
666
		log_error("Creating rrd update script");
667
		/* write the rrd update script */
668
		$updaterrdscript = "{$g['vardb_path']}/rrd/updaterrd.sh";
669
		$fd = fopen("$updaterrdscript", "w");
670
		fwrite($fd, "$rrdupdatesh");
671
		fclose($fd);
672

    
673
		/* kill off traffic collectors */
674
		kill_traffic_collector();
675

    
676
		/* start traffic collector */
677
		mwexec_bg("/usr/bin/nice -n20 /bin/sh $updaterrdscript");
678

    
679
	} else {
680
		/* kill off traffic collectors */
681
		kill_traffic_collector();
682
	}
683

    
684
	$databases = glob("{$rrddbpath}/*.rrd");
685
	foreach($databases as $database) {
686
		chown($database, "nobody");
687
	}
688

    
689
	if($g['booting']) 
690
		echo "done.\n";
691
		
692
}
693

    
694
function kill_traffic_collector() {
695
	mwexec("/bin/pkill -f updaterrd.sh", true);
696
}
697

    
698
?>
(35-35/54)