Project

General

Profile

Download (30.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(sprintf(gettext('RRD dump failed exited with %1$s, the error is: %2$s'), $dumpret, $dumpout));
46
	}
47
	return($dumpret);
48
}
49

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

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

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

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

    
97
function migrate_rrd_format($rrdoldxml, $rrdnewxml) {
98
	if(!file_exists("/tmp/rrd_notice_sent.txt")) {
99
		exec("echo 'Converting RRD configuration to new format.  This might take a bit...' | wall");
100
		touch("/tmp/rrd_notice_sent.txt");
101
	}
102
	$numrraold = count($rrdoldxml['rra']);
103
	$numdsold = count($rrdoldxml['ds']);
104
	$numrranew = count($rrdnewxml['rra']);
105
	$numdsnew = count($rrdnewxml['ds']);
106
	log_error(sprintf(gettext('Import RRD has %1$s DS values and %2$s RRA databases, new format RRD has %3$s DS values and %4$s RRA databases'), $numdsold, $numrraold, $numdsnew ,$numrranew));
107
	
108
	/* add data sources not found in the old array from the new array */
109
	$i = 0;
110
	foreach($rrdnewxml['ds'] as $ds) {
111
		if(!is_array($rrdoldxml['ds'][$i])) {
112
			$rrdoldxml['ds'][$i] = $rrdnewxml['ds'][$i];
113
			/* set unknown values to 0 */
114
			$rrdoldxml['ds'][$i]['last_ds'] = " 0.0000000000e+00 ";
115
			$rrdoldxml['ds'][$i]['value'] = " 0.0000000000e+00 ";
116
			$rrdoldxml['ds'][$i]['unknown_sec'] = "0";
117
		}
118
		$i++;
119
	}
120

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
279
		/* db update script */
280
		$rrdupdatesh = "#!/bin/sh\n";
281
		$rrdupdatesh .= "\n";
282
		$rrdupdatesh .= "export TERM=dumb\n";
283
		$rrdupdatesh .= "counter=1\n";
284
		$rrdupdatesh .= "while [ \"\$counter\" -ne 0 ]\n";
285
		$rrdupdatesh .= "do\n";
286
		$rrdupdatesh .= "";
287

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

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

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

    
323
				create_new_rrd($rrdcreate);
324
			}
325

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

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

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

    
355
				create_new_rrd($rrdcreate);
356
			}
357

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

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

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

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

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

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

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

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

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

    
467
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
468
					$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
469
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
470
					$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
471

    
472
					create_new_rrd($rrdcreate);
473
				}
474

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

    
483
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
484
					$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
485
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
486
					$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
487

    
488
					create_new_rrd($rrdcreate);
489
				}
490

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

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

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

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

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

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

    
568
		}
569
		$i++;
570

    
571
		/* System only statistics */
572
		$ifname = "system";
573

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

    
587
			create_new_rrd($rrdcreate);
588
		}
589

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

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

    
606
		/* End pf states statistics */
607

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

    
621
			create_new_rrd($rrdcreate);
622
		}
623

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

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

    
635
		/* End CPU statistics */
636

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

    
658
			create_new_rrd($rrdcreate);
659
		}
660

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

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

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

    
695
				create_new_rrd($rrdcreate);
696
			}
697

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

    
703
		}
704
		/* End System statistics */
705

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

    
729
				create_new_rrd($rrdcreate);
730
			}
731

    
732
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
733
			if($g['booting']) {
734
				mwexec("$rrdtool update $rrddbpath$ifname$captiveportalconcurrent N:U");
735
			}
736
			
737
			/* the Captive Portal stats gathering function. */
738
			$rrdupdatesh .= "\n";
739
			$rrdupdatesh .= "# polling Captive Portal for number of concurrent users\n";
740
			$rrdupdatesh .= "CP=`$php -q $captiveportal_gather concurrent`\n";
741
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$captiveportalconcurrent \${CP}\n";
742
			
743
			$ifname= "captiveportal";
744
			if (!file_exists("$rrddbpath$ifname$captiveportalloggedin")) {
745
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$captiveportalloggedin --step $rrdcaptiveportalinterval ";
746
				$rrdcreate .= "DS:loggedinusers:GAUGE:$captiveportalvalid:0:10000 ";
747
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
748
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
749
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
750
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
751
				$rrdcreate .= "RRA:MIN:0.5:1:1000 ";
752
				$rrdcreate .= "RRA:MIN:0.5:5:1000 ";
753
				$rrdcreate .= "RRA:MIN:0.5:60:1000 ";
754
				$rrdcreate .= "RRA:MIN:0.5:720:3000 ";
755
				$rrdcreate .= "RRA:MAX:0.5:1:1000 ";
756
				$rrdcreate .= "RRA:MAX:0.5:5:1000 ";
757
				$rrdcreate .= "RRA:MAX:0.5:60:1000 ";
758
				$rrdcreate .= "RRA:MAX:0.5:720:3000 ";
759
				$rrdcreate .= "RRA:LAST:0.5:1:1000 ";
760
				$rrdcreate .= "RRA:LAST:0.5:5:1000 ";
761
				$rrdcreate .= "RRA:LAST:0.5:60:1000 ";
762
				$rrdcreate .= "RRA:LAST:0.5:720:3000 ";
763

    
764
				create_new_rrd($rrdcreate);
765
			}
766

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

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

    
778
		}
779

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

    
789
		/* kill off traffic collectors */
790
		kill_traffic_collector();
791

    
792
		/* start traffic collector */
793
		mwexec_bg("/usr/bin/nice -n20 /bin/sh $updaterrdscript");
794

    
795
	} else {
796
		/* kill off traffic collectors */
797
		kill_traffic_collector();
798
	}
799

    
800
	$databases = glob("{$rrddbpath}/*.rrd");
801
	foreach($databases as $database) {
802
		chown($database, "nobody");
803
	}
804

    
805
	if($g['booting']) 
806
		echo gettext("done.") . "\n";
807
		
808
}
809

    
810
function kill_traffic_collector() {
811
	mwexec("killall rrdtool", true);
812
	mwexec("/bin/pkill -a -f updaterrd.sh", true);
813
}
814

    
815
?>
(45-45/66)