Project

General

Profile

Download (29.4 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 .= "export TERM=serial\n";
257
		$rrdupdatesh .= "counter=1\n";
258
		$rrdupdatesh .= "while [ \"\$counter\" -ne 0 ]\n";
259
		$rrdupdatesh .= "do\n";
260
		$rrdupdatesh .= "";
261

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

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

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

    
297
				create_new_rrd($rrdcreate);
298
			}
299

    
300
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
301
			if($g['booting']) {
302
				mwexec("$rrdtool update $rrddbpath$ifname$traffic N:U:U:U:U:U:U:U:U");
303
			}
304

    
305
			$rrdupdatesh .= "\n";
306
			$rrdupdatesh .= "# polling traffic for interface $ifname $realif IPv4/IPv6 counters \n";
307
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$traffic N:\\\n";
308
			$rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '/In4\/Pass|Out4\/Pass|In6\/Pass|Out6\/Pass|In4\/Block|Out4\/Block|In6\/Block|Out6\/Block/ {printf \$6 \":\"}'|sed -e 's/.\$//'`\n";
309

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

    
326
				create_new_rrd($rrdcreate);
327
			}
328

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

    
334
			$rrdupdatesh .= "\n";
335
			$rrdupdatesh .= "# polling packets for interface $ifname $realif \n";
336
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$packets N:\\\n";
337
			$rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '/In4\/Pass|Out4\/Pass|In6\/Pass|Out6\/Pass|In4\/Block|Out4\/Block|In6\/Block|Out6\/Block/ {printf \$4 \":\"}'|sed -e 's/.\$//'`\n";
338

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

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

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

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

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

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

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

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

    
440
					create_new_rrd($rrdcreate);
441
				}
442

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

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

    
456
					create_new_rrd($rrdcreate);
457
				}
458

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

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

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

    
513
		/* System only statistics */
514
		$ifname = "system";
515

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

    
529
			create_new_rrd($rrdcreate);
530
		}
531

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

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

    
548
		/* End pf states statistics */
549

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

    
563
			create_new_rrd($rrdcreate);
564
		}
565

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

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

    
577
		/* End CPU statistics */
578

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

    
600
			create_new_rrd($rrdcreate);
601
		}
602

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

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

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

    
637
				create_new_rrd($rrdcreate);
638
			}
639

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

    
645
		}
646
		/* End System statistics */
647

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

    
661
				create_new_rrd($rrdcreate);
662
			}
663

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

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

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

    
699
				create_new_rrd($rrdcreate);
700
			}
701

    
702
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
703
			if($g['booting']) {
704
				mwexec("$rrdtool update $rrddbpath$ifname$captiveportalconcurrent N:U");
705
			}
706
			
707
			/* the Captive Portal stats gathering function. */
708
			$rrdupdatesh .= "\n";
709
			$rrdupdatesh .= "# polling Captive Portal for number of concurrent users\n";
710
			$rrdupdatesh .= "CP=`$php -q $captiveportal_gather concurrent`\n";
711
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$captiveportalconcurrent \${CP}\n";
712
			
713
			$ifname= "captiveportal";
714
			if (!file_exists("$rrddbpath$ifname$captiveportalloggedin")) {
715
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$captiveportalloggedin --step $rrdcaptiveportalinterval ";
716
				$rrdcreate .= "DS:loggedinusers:GAUGE:$captiveportalvalid:0:10000 ";
717
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
718
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
719
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
720
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
721
				$rrdcreate .= "RRA:MIN:0.5:1:1000 ";
722
				$rrdcreate .= "RRA:MIN:0.5:5:1000 ";
723
				$rrdcreate .= "RRA:MIN:0.5:60:1000 ";
724
				$rrdcreate .= "RRA:MIN:0.5:720:3000 ";
725
				$rrdcreate .= "RRA:MAX:0.5:1:1000 ";
726
				$rrdcreate .= "RRA:MAX:0.5:5:1000 ";
727
				$rrdcreate .= "RRA:MAX:0.5:60:1000 ";
728
				$rrdcreate .= "RRA:MAX:0.5:720:3000 ";
729
				$rrdcreate .= "RRA:LAST:0.5:1:1000 ";
730
				$rrdcreate .= "RRA:LAST:0.5:5:1000 ";
731
				$rrdcreate .= "RRA:LAST:0.5:60:1000 ";
732
				$rrdcreate .= "RRA:LAST:0.5:720:3000 ";
733

    
734
				create_new_rrd($rrdcreate);
735
			}
736

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

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

    
748
		}
749

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

    
759
		/* kill off traffic collectors */
760
		kill_traffic_collector();
761

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

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

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

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

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

    
785
?>
(41-41/61)