Project

General

Profile

Download (30.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(sprintf(gettext('RRD dump failed exited with %1$s, the error is: %2$s'), $dumpret, $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(sprintf(gettext('RRD create failed exited with %1$s, the error is: %2$s'), $rrdcreatereturn, $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(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));
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(sprintf(gettext('The new RRD now has %1$s DS values and %2$s RRA databases'), $numdsnew, $numrranew));
155
	return $rrdoldxml;
156
}
157

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

    
161
	if($g['booting']) 
162
		echo gettext("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(sprintf(gettext('RRD restore failed exited with %1$s, the error is: %2$s%3$s'), $rrdreturn, $rrdrestore, "\n"));
248
					}
249
				}
250
			}
251
		}
252

    
253
		/* db update script */
254
		$rrdupdatesh = "#!/bin/sh\n";
255
		$rrdupdatesh .= "\n";
256
		$rrdupdatesh .= "export TERM=dumb\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:";
308
			$rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '\\\n";
309
			$rrdupdatesh .= "/In4\/Pass/ { b4pi = \$6 };/Out4\/Pass/ { b4po = \$6 };/In4\/Block/ { b4bi = \$6 };/Out4\/Block/ { b4bo = \$6 };\\\n";
310
			$rrdupdatesh .= "/In6\/Pass/ { b6pi = \$6 };/Out6\/Pass/ { b6po = \$6 };/In6\/Block/ { b6bi = \$6 };/Out6\/Block/ { b6bo = \$6 };\\\n";
311
			$rrdupdatesh .= "END {print b4pi \":\" b4po \":\" b4bi \":\" b4bo \":\" b6pi \":\" b6po \":\" b6bi \":\" b6bo};'`\n";
312

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

    
329
				create_new_rrd($rrdcreate);
330
			}
331

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

    
337
			$rrdupdatesh .= "\n";
338
			$rrdupdatesh .= "# polling packets for interface $ifname $realif \n";
339
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$packets N:";
340
			$rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '\\\n";
341
			$rrdupdatesh .= "/In4\/Pass/ { b4pi = \$4 };/Out4\/Pass/ { b4po = \$4 };/In4\/Block/ { b4bi = \$4 };/Out4\/Block/ { b4bo = \$4 };\\\n";
342
			$rrdupdatesh .= "/In6\/Pass/ { b6pi = \$4 };/Out6\/Pass/ { b6po = \$4 };/In6\/Block/ { b6bi = \$4 };/Out6\/Block/ { b6bo = \$4 };\\\n";
343
			$rrdupdatesh .= "END {print b4pi \":\" b4po \":\" b4bi \":\" b4bo \":\" b6pi \":\" b6po \":\" b6bi \":\" b6bo};'`\n";
344

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

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

    
365
				$rrdupdatesh .= "\n";
366
				$rrdupdatesh .= "# polling wireless for interface $ifname $realif \n";
367
				$rrdupdatesh .= "WIFI=`$ifconfig {$realif} list sta| $awk 'gsub(\"M\", \"\") {getline 2;print substr(\$5, 0, length(\$5)-2) \":\" $4 \":\" $3}'`\n";
368
				$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$wireless N:${WIFI}\n";
369
			}
370

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

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

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

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

    
441
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
442
					$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
443
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
444
					$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
445

    
446
					create_new_rrd($rrdcreate);
447
				}
448

    
449
				if (!file_exists("$rrddbpath$ifname$queuesdrop")) {
450
					$rrdcreate = "$rrdtool create $rrddbpath$ifname$queuesdrop --step $rrdqueuesdropinterval ";
451
					/* loop list of shaper queues */
452
					$q = 0;
453
					foreach ($qlist as $qname => $q) {
454
						$rrdcreate .= "DS:$qname:COUNTER:$queuesdropvalid:0:$qbandwidth ";
455
					}
456

    
457
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
458
					$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
459
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
460
					$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
461

    
462
					create_new_rrd($rrdcreate);
463
				}
464

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

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

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

    
519
		/* System only statistics */
520
		$ifname = "system";
521

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

    
535
			create_new_rrd($rrdcreate);
536
		}
537

    
538
		/* enter UNKNOWN values in the RRD so it knows we rebooted. */
539
		if($g['booting']) {
540
			mwexec("$rrdtool update $rrddbpath$ifname$states N:U:U:U:U:U");
541
		}
542

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

    
554
		/* End pf states statistics */
555

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

    
569
			create_new_rrd($rrdcreate);
570
		}
571

    
572
		/* enter UNKNOWN values in the RRD so it knows we rebooted. */
573
		if($g['booting']) {
574
			mwexec("$rrdtool update $rrddbpath$ifname$proc N:U:U:U:U:U");
575
		}
576

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

    
583
		/* End CPU statistics */
584

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

    
606
			create_new_rrd($rrdcreate);
607
		}
608

    
609
		/* enter UNKNOWN values in the RRD so it knows we rebooted. */
610
		if($g['booting']) {
611
			mwexec("$rrdtool update $rrddbpath$ifname$mem N:U:U:U:U:U");
612
		}
613

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

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

    
643
				create_new_rrd($rrdcreate);
644
			}
645

    
646
			$rrdupdatesh .= "\n";
647
			$rrdupdatesh .= "# polling spamd for connections and tarpitness \n";
648
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$spamd \\\n";
649
			$rrdupdatesh .= "`$php -q $spamd_gather`\n";
650

    
651
		}
652
		/* End System statistics */
653

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

    
667
				create_new_rrd($rrdcreate);
668
			}
669

    
670
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
671
			if($g['booting']) {
672
				mwexec("$rrdtool update $rrddbpath$ifname$cellular N:U:U");
673
			}
674

    
675
			$rrdupdatesh .= "\n";
676
			$rrdupdatesh .= "# polling 3G\n";
677
			$rrdupdatesh .= "dev=`usbconfig show_ifdrv | awk -F. '/ u3g|umodem/ {print \"/dev/\" $1 \".\" $2}'`\n";
678
			$rrdupdatesh .= "if [ -n \"\$dev\" ]; then $rrdtool update $rrddbpath$ifname$cellular N:`3gstat -s -d \$dev`\n";
679
			$rrdupdatesh .= "else $rrdtool update $rrddbpath$ifname$cellular N:U:U; fi\n";
680
		}
681

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

    
705
				create_new_rrd($rrdcreate);
706
			}
707

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

    
740
				create_new_rrd($rrdcreate);
741
			}
742

    
743
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
744
			if($g['booting']) {
745
				mwexec("$rrdtool update $rrddbpath$ifname$captiveportalloggedin N:U");
746
			}
747

    
748
			/* the Captive Portal stats gathering function. */
749
			$rrdupdatesh .= "\n";
750
			$rrdupdatesh .= "# polling Captive Portal for number of logged in users\n";
751
			$rrdupdatesh .= "CP=`$php -q $captiveportal_gather loggedin`\n";
752
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$captiveportalloggedin \${CP}\n";
753

    
754
		}
755

    
756
		$rrdupdatesh .= "sleep 60\n";
757
		$rrdupdatesh .= "done\n";
758
		log_error(gettext("Creating rrd update script"));
759
		/* write the rrd update script */
760
		$updaterrdscript = "{$g['vardb_path']}/rrd/updaterrd.sh";
761
		$fd = fopen("$updaterrdscript", "w");
762
		fwrite($fd, "$rrdupdatesh");
763
		fclose($fd);
764

    
765
		/* kill off traffic collectors */
766
		kill_traffic_collector();
767

    
768
		/* start traffic collector */
769
		mwexec_bg("/usr/bin/nice -n20 /bin/sh $updaterrdscript");
770

    
771
	} else {
772
		/* kill off traffic collectors */
773
		kill_traffic_collector();
774
	}
775

    
776
	$databases = glob("{$rrddbpath}/*.rrd");
777
	foreach($databases as $database) {
778
		chown($database, "nobody");
779
	}
780

    
781
	if($g['booting']) 
782
		echo gettext("done.") . "\n";
783
		
784
}
785

    
786
function kill_traffic_collector() {
787
	mwexec("killall rrdtool", true);
788
	mwexec("/bin/pkill -a -f updaterrd.sh", true);
789
}
790

    
791
?>
(44-44/65)