Project

General

Profile

Download (29.1 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
	$captiveportalconcurrent = "-concurrent.rrd";
179
	$captiveportalloggedin = "-loggedin.rrd";
180
	$captiveportaltotalusers = "-totalusers.rrd";
181

    
182
	$rrdtool = "/usr/bin/nice -n20 /usr/local/bin/rrdtool";
183
	$netstat = "/usr/bin/netstat";
184
	$awk = "/usr/bin/awk";
185
	$tar = "/usr/bin/tar";
186
	$pfctl = "/sbin/pfctl";
187
	$sysctl = "/sbin/sysctl";
188
	$php = "/usr/local/bin/php";
189
	$cpustats = "/usr/local/sbin/cpustats";
190
	$spamd_gather = "/usr/local/bin/spamd_gather_stats.php";
191
	$ifconfig = "/sbin/ifconfig";
192
	$captiveportal_gather = "/usr/local/bin/captiveportal_gather_stats.php";
193

    
194
	$rrdtrafficinterval = 60;
195
	$rrdwirelessinterval = 60;
196
	$rrdqueuesinterval = 60;
197
	$rrdqueuesdropinterval = 60;
198
	$rrdpacketsinterval = 60;
199
	$rrdstatesinterval = 60;
200
	$rrdspamdinterval = 60;
201
	$rrdlbpoolinterval = 60;
202
	$rrdprocinterval = 60;
203
	$rrdmeminterval = 60;
204
	$rrdcellularinterval = 60;
205
	$rrdvpninterval = 60;
206
	$rrdcaptiveportalinterval = 60;
207

    
208
	$trafficvalid = $rrdtrafficinterval * 2;
209
	$wirelessvalid = $rrdwirelessinterval * 2;
210
	$queuesvalid = $rrdqueuesinterval * 2;
211
	$queuesdropvalid = $rrdqueuesdropinterval * 2;
212
	$packetsvalid = $rrdpacketsinterval * 2;
213
	$statesvalid = $rrdstatesinterval*2;
214
	$spamdvalid = $rrdspamdinterval * 2;
215
	$lbpoolvalid = $rrdlbpoolinterval * 2;
216
	$procvalid = $rrdlbpoolinterval * 2;
217
	$memvalid = $rrdmeminterval * 2;
218
	$cellularvalid = $rrdcellularinterval * 2;
219
	$vpnvalid = $rrdvpninterval * 2;
220
	$captiveportalvalid = $rrdcaptiveportalinterval * 2;
221

    
222
	/* Asume GigE for now */
223
	$downstream = 125000000;
224
	$upstream = 125000000;
225

    
226
	/* read the shaper config */
227
	read_altq_config();
228

    
229
	$rrdrestore = "";
230
	$rrdreturn = "";
231

    
232
	if (isset ($config['rrd']['enable'])) {
233

    
234
		/* create directory if needed */
235
		if (!is_dir($rrddbpath)) {
236
			mkdir($rrddbpath, 0775);
237
		}
238
		chown($rrddbpath, "nobody");
239

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

    
253
		/* db update script */
254
		$rrdupdatesh = "#!/bin/sh\n";
255
		$rrdupdatesh .= "\n";
256
		$rrdupdatesh .= "counter=1\n";
257
		$rrdupdatesh .= "while [ \"\$counter\" -ne 0 ]\n";
258
		$rrdupdatesh .= "do\n";
259
		$rrdupdatesh .= "";
260

    
261
		$i = 0;
262
		$ifdescrs = get_configured_interface_with_descr();
263
		/* IPsec counters */
264
		$ifdescrs['ipsec'] = "IPsec";
265
		/* OpenVPN server counters */
266
		if(is_array($config['openvpn']['openvpn-server'])) {
267
			foreach($config['openvpn']['openvpn-server'] as $server) {
268
				$serverid = "ovpns" . $server['vpnid'];
269
				$ifdescrs[$serverid] = "{$server['description']}";
270
			}
271
		}
272

    
273
		/* process all real and pseudo interfaces */
274
		foreach ($ifdescrs as $ifname => $ifdescr) {
275
			$temp = get_real_interface($ifname);
276
			if($temp <> "") {
277
				$realif = $temp;
278
			}
279

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

    
292
				create_new_rrd($rrdcreate);
293
			}
294

    
295
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
296
			if($g['booting']) {
297
				mwexec("$rrdtool update $rrddbpath$ifname$traffic N:U:U:U:U");
298
			}
299

    
300
			$rrdupdatesh .= "\n";
301
			$rrdupdatesh .= "# polling traffic for interface $ifname $realif \n";
302
			$rrdupdatesh .= "TMPFILE=`mktemp -q /tmp/STATS_{$realif}.XXXXXX` \n";
303
			$rrdupdatesh .= "$pfctl -vvsI -i {$realif} > \$TMPFILE \n";
304
			$rrdupdatesh .= "unset BYTES \n";
305
			$rrdupdatesh .= "BYTES=`cat \$TMPFILE | awk '/In4\/Pass|Out4\/Pass/ {printf \$6 \":\"}'`\\\n";
306
			$rrdupdatesh .= "`cat \$TMPFILE | awk '/In4\/Block|Out4\/Block/ {printf \$6 \":\"}'|sed -e 's/.\$//'`\n";
307
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$traffic N:\$BYTES\n";
308

    
309
			/* PACKETS, set up the rrd file */
310
			if (!file_exists("$rrddbpath$ifname$packets")) {
311
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$packets --step $rrdpacketsinterval ";
312
				$rrdcreate .= "DS:inpass:COUNTER:$packetsvalid:0:$downstream ";
313
				$rrdcreate .= "DS:outpass:COUNTER:$packetsvalid:0:$upstream ";
314
				$rrdcreate .= "DS:inblock:COUNTER:$packetsvalid:0:$downstream ";
315
				$rrdcreate .= "DS:outblock:COUNTER:$packetsvalid:0:$upstream ";
316
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
317
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
318
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
319
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
320

    
321
				create_new_rrd($rrdcreate);
322
			}
323

    
324
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
325
			if($g['booting']) {
326
				mwexec("$rrdtool update $rrddbpath$ifname$packets N:U:U:U:U");
327
			}
328

    
329
			$rrdupdatesh .= "\n";
330
			$rrdupdatesh .= "# polling packets for interface $ifname $realif \n";
331
			$rrdupdatesh .= "unset PACKETS \n";
332
			$rrdupdatesh .= "PACKETS=`cat \$TMPFILE | awk '/In4\/Pass|Out4\/Pass/ {printf \$4 \":\"}'`\\\n";
333
			$rrdupdatesh .= "`cat \$TMPFILE | awk '/In4\/Block|Out4\/Block/ {printf \$4 \":\"}'|sed -e 's/.\$//'`\n";
334
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$packets N:\$PACKETS\n";
335
			$rrdupdatesh .= "rm \$TMPFILE \n";
336

    
337
			/* WIRELESS, set up the rrd file */
338
			if($config['interfaces'][$ifname]['wireless']['mode'] == "bss") {
339
				if (!file_exists("$rrddbpath$ifname$wireless")) {
340
					$rrdcreate = "$rrdtool create $rrddbpath$ifname$wireless --step $rrdwirelessinterval ";
341
					$rrdcreate .= "DS:snr:GAUGE:$wirelessvalid:0:1000 ";
342
					$rrdcreate .= "DS:rate:GAUGE:$wirelessvalid:0:1000 ";
343
					$rrdcreate .= "DS:channel:GAUGE:$wirelessvalid:0:1000 ";
344
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
345
					$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
346
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
347
					$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
348
	
349
					create_new_rrd($rrdcreate);
350
				}
351

    
352
				/* enter UNKNOWN values in the RRD so it knows we rebooted. */
353
				if($g['booting']) {
354
					mwexec("$rrdtool update $rrddbpath$ifname$wireless N:U:U:U");
355
				}
356

    
357
				$rrdupdatesh .= "\n";
358
				$rrdupdatesh .= "# polling wireless for interface $ifname $realif \n";
359
				$rrdupdatesh .= "WIFI=`$ifconfig {$realif} list sta| $awk 'gsub(\"M\", \"\") {getline 2;print substr(\$5, 0, length(\$5)-2) \":\" $4 \":\" $3}'`\n";
360
				$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$wireless N:${WIFI}\n";
361
			}
362

    
363
			/* OpenVPN, set up the rrd file */
364
			if(stristr($ifname, "ovpns")) {
365
				if (!file_exists("$rrddbpath$ifname$vpnusers")) {
366
					$rrdcreate = "$rrdtool create $rrddbpath$ifname$vpnusers --step $rrdvpninterval ";
367
					$rrdcreate .= "DS:users:GAUGE:$vpnvalid:0:10000 ";
368
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
369
					$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
370
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
371
					$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
372
	
373
					create_new_rrd($rrdcreate);
374
				}
375

    
376
				/* enter UNKNOWN values in the RRD so it knows we rebooted. */
377
				if($g['booting']) {
378
					mwexec("$rrdtool update $rrddbpath$ifname$vpnusers N:U");
379
				}
380

    
381
				if(is_array($config['openvpn']['openvpn-server'])) {
382
					foreach($config['openvpn']['openvpn-server'] as $server) {
383
						if("ovpns{$server['vpnid']}" == $ifname) {
384
							$port = $server['local_port'];
385
							$vpnid = $server['vpnid'];
386
						}
387
					}
388
				}
389
				$rrdupdatesh .= "\n";
390
				$rrdupdatesh .= "# polling vpn users for interface $ifname $realif port $port\n";
391
				$rrdupdatesh .= "list_current_users() {\n";
392
				$rrdupdatesh .= " sleep 0.2\n";
393
				$rrdupdatesh .= " echo \"status 2\"\n";
394
				$rrdupdatesh .= " sleep 0.2\n";
395
				$rrdupdatesh .= " echo \"quit\"\n";
396
				$rrdupdatesh .= "}\n";
397
				$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";
398
				$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$vpnusers N:\${OVPN}\n";
399
			}
400

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

    
433
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
434
					$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
435
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
436
					$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
437

    
438
					create_new_rrd($rrdcreate);
439
				}
440

    
441
				if (!file_exists("$rrddbpath$ifname$queuesdrop")) {
442
					$rrdcreate = "$rrdtool create $rrddbpath$ifname$queuesdrop --step $rrdqueuesdropinterval ";
443
					/* loop list of shaper queues */
444
					$q = 0;
445
					foreach ($qlist as $qname => $q) {
446
						$rrdcreate .= "DS:$qname:COUNTER:$queuesdropvalid:0:$qbandwidth ";
447
					}
448

    
449
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
450
					$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
451
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
452
					$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
453

    
454
					create_new_rrd($rrdcreate);
455
				}
456

    
457
				if($g['booting']) {
458
					$rrdqcommand = "-t ";
459
					$rrducommand = "N";
460
					$qi = 0;
461
					foreach ($qlist as $qname => $q) {
462
						if($qi == 0) {
463
							$rrdqcommand .= "{$qname}";
464
						} else {
465
							$rrdqcommand .= ":{$qname}";
466
						}
467
						$qi++;
468
						$rrducommand .= ":U";
469
					}
470
					mwexec("$rrdtool update $rrddbpath$ifname$queues $rrdqcommand $rrducommand");
471
					mwexec("$rrdtool update $rrddbpath$ifname$queuesdrop $rrdqcommand $rrducommand");
472
				}
473

    
474
				/* awk function to gather shaper data */
475
				/* yes, it's special */
476
				$rrdupdatesh .= "` pfctl -vsq -i {$realif} | awk 'BEGIN {printf \"$rrdtool update $rrddbpath$ifname$queues \" } ";
477
				$rrdupdatesh .= "{ ";
478
				$rrdupdatesh .= "if ((\$1 == \"queue\") && ( \$2 ~ /^q/ )) { ";
479
				$rrdupdatesh .= " dsname = dsname \":\" \$2 ; ";
480
				$rrdupdatesh .= " q=1; ";
481
				$rrdupdatesh .= "} ";
482
				$rrdupdatesh .= " else if ((\$4 == \"bytes:\") && ( q == 1 ) ) { ";
483
				$rrdupdatesh .= " dsdata = dsdata \":\" \$5 ; ";
484
				$rrdupdatesh .= " q=0; ";
485
				$rrdupdatesh .= "} ";
486
				$rrdupdatesh .= "} END { ";
487
				$rrdupdatesh .= " dsname = substr(dsname,2); ";
488
				$rrdupdatesh .= " dsdata = substr(dsdata,2); ";
489
				$rrdupdatesh .= " printf \"-t \" dsname \" N:\" dsdata }' ";
490
				$rrdupdatesh .= " dsname=\"\" dsdata=\"\"`\n\n";
491

    
492
				$rrdupdatesh .= "` pfctl -vsq -i {$realif} | awk 'BEGIN {printf \"$rrdtool update $rrddbpath$ifname$queuesdrop \" } ";
493
				$rrdupdatesh .= "{ ";
494
				$rrdupdatesh .= "if ((\$1 == \"queue\") && ( \$2 ~ /^q/ )) { ";
495
				$rrdupdatesh .= " dsname = dsname \":\" \$2 ; ";
496
				$rrdupdatesh .= " q=1; ";
497
				$rrdupdatesh .= "} ";
498
				$rrdupdatesh .= " else if ((\$4 == \"bytes:\") && ( q == 1 ) ) { ";
499
				$rrdupdatesh .= " dsdata = dsdata \":\" \$8 ; ";
500
				$rrdupdatesh .= " q=0; ";
501
				$rrdupdatesh .= "} ";
502
				$rrdupdatesh .= "} END { ";
503
				$rrdupdatesh .= " dsname = substr(dsname,2); ";
504
				$rrdupdatesh .= " dsdata = substr(dsdata,2); ";
505
				$rrdupdatesh .= " printf \"-t \" dsname \" N:\" dsdata }' ";
506
				$rrdupdatesh .= " dsname=\"\" dsdata=\"\"`\n\n";
507
			}
508
		}
509
		$i++;
510

    
511
		/* System only statistics */
512
		$ifname = "system";
513

    
514
		/* STATES, create pf states database */
515
		if(! file_exists("$rrddbpath$ifname$states")) {
516
			$rrdcreate = "$rrdtool create $rrddbpath$ifname$states --step $rrdstatesinterval ";
517
			$rrdcreate .= "DS:pfrate:GAUGE:$statesvalid:0:10000000 ";
518
			$rrdcreate .= "DS:pfstates:GAUGE:$statesvalid:0:10000000 ";
519
			$rrdcreate .= "DS:pfnat:GAUGE:$statesvalid:0:10000000 ";
520
			$rrdcreate .= "DS:srcip:GAUGE:$statesvalid:0:10000000 ";
521
			$rrdcreate .= "DS:dstip:GAUGE:$statesvalid:0:10000000 ";
522
			$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
523
			$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
524
			$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
525
			$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
526

    
527
			create_new_rrd($rrdcreate);
528
		}
529

    
530
		/* enter UNKNOWN values in the RRD so it knows we rebooted. */
531
		if($g['booting']) {
532
			mwexec("$rrdtool update $rrddbpath$ifname$states N:U:U:U:U:U");
533
		}
534

    
535
		/* the pf states gathering function. */
536
		$rrdupdatesh .= "\n";
537
		$rrdupdatesh .= "pfctl_si_out=\"` $pfctl -si > /tmp/pfctl_si_out `\"\n";
538
		$rrdupdatesh .= "pfctl_ss_out=\"` $pfctl -ss > /tmp/pfctl_ss_out`\"\n";
539
		$rrdupdatesh .= "pfrate=\"` cat /tmp/pfctl_si_out | egrep \"inserts|removals\" | awk '{ pfrate = \$3 + pfrate } {print pfrate}'|tail -1 `\"\n";
540
		$rrdupdatesh .= "pfstates=\"` cat /tmp/pfctl_ss_out | egrep -v \"<\\-.*?<\\-|\\->.*?\\->\" | wc -l|sed 's/ //g'`\"\n";
541
		$rrdupdatesh .= "pfnat=\"` cat /tmp/pfctl_ss_out | egrep '<\\-.*?<\\-|\\->.*?\\->' | wc -l|sed 's/ //g' `\"\n";
542
		$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";
543
		$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";
544
		$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$states N:\$pfrate:\$pfstates:\$pfnat:\$srcip:\$dstip\n\n";
545

    
546
		/* End pf states statistics */
547

    
548
		/* CPU, create CPU statistics database */
549
		if(! file_exists("$rrddbpath$ifname$proc")) {
550
			$rrdcreate = "$rrdtool create $rrddbpath$ifname$proc --step $rrdprocinterval ";
551
			$rrdcreate .= "DS:user:GAUGE:$procvalid:0:10000000 ";
552
			$rrdcreate .= "DS:nice:GAUGE:$procvalid:0:10000000 ";
553
			$rrdcreate .= "DS:system:GAUGE:$procvalid:0:10000000 ";
554
			$rrdcreate .= "DS:interrupt:GAUGE:$procvalid:0:10000000 ";
555
			$rrdcreate .= "DS:processes:GAUGE:$procvalid:0:10000000 ";
556
			$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
557
			$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
558
			$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
559
			$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
560

    
561
			create_new_rrd($rrdcreate);
562
		}
563

    
564
		/* enter UNKNOWN values in the RRD so it knows we rebooted. */
565
		if($g['booting']) {
566
			mwexec("$rrdtool update $rrddbpath$ifname$proc N:U:U:U:U:U");
567
		}
568

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

    
575
		/* End CPU statistics */
576

    
577
		/* Memory, create Memory statistics database */
578
		if(! file_exists("$rrddbpath$ifname$mem")) {
579
			$rrdcreate = "$rrdtool create $rrddbpath$ifname$mem --step $rrdmeminterval ";
580
			$rrdcreate .= "DS:active:GAUGE:$memvalid:0:10000000 ";
581
			$rrdcreate .= "DS:inactive:GAUGE:$memvalid:0:10000000 ";
582
			$rrdcreate .= "DS:free:GAUGE:$memvalid:0:10000000 ";
583
			$rrdcreate .= "DS:cache:GAUGE:$memvalid:0:10000000 ";
584
			$rrdcreate .= "DS:wire:GAUGE:$memvalid:0:10000000 ";
585
			$rrdcreate .= "RRA:MIN:0.5:1:1000 ";
586
			$rrdcreate .= "RRA:MIN:0.5:5:1000 ";
587
			$rrdcreate .= "RRA:MIN:0.5:60:1000 ";
588
			$rrdcreate .= "RRA:MIN:0.5:720:3000 ";
589
			$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
590
			$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
591
			$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
592
			$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
593
			$rrdcreate .= "RRA:MAX:0.5:1:1000 ";
594
			$rrdcreate .= "RRA:MAX:0.5:5:1000 ";
595
			$rrdcreate .= "RRA:MAX:0.5:60:1000 ";
596
			$rrdcreate .= "RRA:MAX:0.5:720:3000";
597

    
598
			create_new_rrd($rrdcreate);
599
		}
600

    
601
		/* enter UNKNOWN values in the RRD so it knows we rebooted. */
602
		if($g['booting']) {
603
			mwexec("$rrdtool update $rrddbpath$ifname$mem N:U:U:U:U:U");
604
		}
605

    
606
		/* the Memory stats gathering function. */
607
		$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 | ";
608
		$rrdupdatesh .= " $awk '{getline active;getline inactive;getline free;getline cache;getline wire;printf ";
609
		$rrdupdatesh .= "((active/$0) * 100)\":\"((inactive/$0) * 100)\":\"((free/$0) * 100)\":\"((cache/$0) * 100)\":\"(wire/$0 * 100)}'`\n";
610
		$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$mem N:\${MEM}\n";
611
		
612
		/* End Memory statistics */
613

    
614
		/* SPAMD, set up the spamd rrd file */
615
		if (isset($config['installedpackages']['spamdsettings']) &&
616
			 $config['installedpackages']['spamdsettings']['config'][0]['enablerrd']) {
617
			/* set up the spamd rrd file */
618
			if (!file_exists("$rrddbpath$ifname$spamd")) {
619
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$spamd --step $rrdspamdinterval ";
620
				$rrdcreate .= "DS:conn:GAUGE:$spamdvalid:0:10000 ";
621
				$rrdcreate .= "DS:time:GAUGE:$spamdvalid:0:86400 ";
622
				$rrdcreate .= "RRA:MIN:0.5:1:1000 ";
623
				$rrdcreate .= "RRA:MIN:0.5:5:1000 ";
624
				$rrdcreate .= "RRA:MIN:0.5:60:1000 ";
625
				$rrdcreate .= "RRA:MIN:0.5:720:3000 ";
626
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
627
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
628
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
629
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
630
				$rrdcreate .= "RRA:MAX:0.5:1:1000 ";
631
				$rrdcreate .= "RRA:MAX:0.5:5:1000 ";
632
				$rrdcreate .= "RRA:MAX:0.5:60:1000 ";
633
				$rrdcreate .= "RRA:MAX:0.5:720:3000 ";
634

    
635
				create_new_rrd($rrdcreate);
636
			}
637

    
638
			$rrdupdatesh .= "\n";
639
			$rrdupdatesh .= "# polling spamd for connections and tarpitness \n";
640
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$spamd \\\n";
641
			$rrdupdatesh .= "`$php -q $spamd_gather`\n";
642

    
643
		}
644
		/* End System statistics */
645

    
646
		/* 3G WIRELESS, set up the rrd file */
647
		/* XXX: Are multiple 3G interfaces not possible? smos@ */
648
		if(isset($config['ppps']['ppp'])) {
649
			$ifname = "ppp";
650
			if (!file_exists("$rrddbpath$ifname$cellular")) {
651
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$cellular --step $rrdcellularinterval ";
652
				$rrdcreate .= "DS:signal1:GAUGE:$cellularvalid:-200:200 ";
653
				$rrdcreate .= "DS:signal2:GAUGE:$cellularvalid:-200:200 ";
654
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
655
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
656
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
657
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
658

    
659
				create_new_rrd($rrdcreate);
660
			}
661

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

    
667
			$rrdupdatesh .= "\n";
668
			$rrdupdatesh .= "# polling 3G\n";
669
			$rrdupdatesh .= "dev=`usbconfig show_ifdrv | awk -F. '/ u3g|umodem/ {print \"/dev/\" $1 \".\" $2}'`\n";
670
			$rrdupdatesh .= "if [ -n \"\$dev\" ]; then $rrdtool update $rrddbpath$ifname$cellular N:`3gstat -s -d \$dev`\n";
671
			$rrdupdatesh .= "else $rrdtool update $rrddbpath$ifname$cellular N:U:U; fi\n";
672
		}
673

    
674
		/* Captive Portal statistics, set up the rrd file */
675
		if(isset($config['captiveportal']['enable'])) {
676
			$ifname= "captiveportal";
677
			if (!file_exists("$rrddbpath$ifname$captiveportalconcurrent")) {
678
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$captiveportalconcurrent --step $rrdcaptiveportalinterval ";
679
				$rrdcreate .= "DS:concurrentusers:GAUGE:$captiveportalvalid:0:10000 ";
680
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
681
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
682
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
683
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
684
				$rrdcreate .= "RRA:MIN:0.5:1:1000 ";
685
				$rrdcreate .= "RRA:MIN:0.5:5:1000 ";
686
				$rrdcreate .= "RRA:MIN:0.5:60:1000 ";
687
				$rrdcreate .= "RRA:MIN:0.5:720:3000 ";
688
				$rrdcreate .= "RRA:MAX:0.5:1:1000 ";
689
				$rrdcreate .= "RRA:MAX:0.5:5:1000 ";
690
				$rrdcreate .= "RRA:MAX:0.5:60:1000 ";
691
				$rrdcreate .= "RRA:MAX:0.5:720:3000 ";
692
				$rrdcreate .= "RRA:LAST:0.5:1:1000 ";
693
				$rrdcreate .= "RRA:LAST:0.5:5:1000 ";
694
				$rrdcreate .= "RRA:LAST:0.5:60:1000 ";
695
				$rrdcreate .= "RRA:LAST:0.5:720:3000 ";
696

    
697
				create_new_rrd($rrdcreate);
698
			}
699

    
700
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
701
			if($g['booting']) {
702
				mwexec("$rrdtool update $rrddbpath$ifname$captiveportalconcurrent N:U");
703
			}
704
			
705
			/* the Captive Portal stats gathering function. */
706
			$rrdupdatesh .= "\n";
707
			$rrdupdatesh .= "# polling Captive Portal for number of concurrent users\n";
708
			$rrdupdatesh .= "CP=`$php -q $captiveportal_gather concurrent`\n";
709
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$captiveportalconcurrent \${CP}\n";
710
			
711
			$ifname= "captiveportal";
712
			if (!file_exists("$rrddbpath$ifname$captiveportalloggedin")) {
713
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$captiveportalloggedin --step $rrdcaptiveportalinterval ";
714
				$rrdcreate .= "DS:loggedinusers: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$captiveportalloggedin N:U");
738
			}
739

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

    
746
		}
747

    
748
		$rrdupdatesh .= "sleep 60\n";
749
		$rrdupdatesh .= "done\n";
750
		log_error("Creating rrd update script");
751
		/* write the rrd update script */
752
		$updaterrdscript = "{$g['vardb_path']}/rrd/updaterrd.sh";
753
		$fd = fopen("$updaterrdscript", "w");
754
		fwrite($fd, "$rrdupdatesh");
755
		fclose($fd);
756

    
757
		/* kill off traffic collectors */
758
		kill_traffic_collector();
759

    
760
		/* start traffic collector */
761
		mwexec_bg("/usr/bin/nice -n20 /bin/sh $updaterrdscript");
762

    
763
	} else {
764
		/* kill off traffic collectors */
765
		kill_traffic_collector();
766
	}
767

    
768
	$databases = glob("{$rrddbpath}/*.rrd");
769
	foreach($databases as $database) {
770
		chown($database, "nobody");
771
	}
772

    
773
	if($g['booting']) 
774
		echo "done.\n";
775
		
776
}
777

    
778
function kill_traffic_collector() {
779
	mwexec("killall rrdtool", true);
780
	mwexec("/bin/pkill -a -f updaterrd.sh", true);
781
}
782

    
783
?>
(42-42/62)