Project

General

Profile

Download (30.5 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
			exec("$rrdtool restore '{$xml_file}' '{$rrd_file}'");
73
			unlink($xml_file);
74
		}
75
		return true;
76
	}
77
	return false;
78
}
79

    
80
function create_new_rrd($rrdcreatecmd) {
81
	$rrdcreateoutput = array();
82
	$rrdcreatereturn = 0;
83
	exec("$rrdcreatecmd 2>&1", $rrdcreateoutput, $rrdcreatereturn);
84
	if ($rrdcreatereturn <> 0) {
85
		$rrdcreateoutput = implode(" ", $rrdcreateoutput);
86
		log_error(sprintf(gettext('RRD create failed exited with %1$s, the error is: %2$s'), $rrdcreatereturn, $rrdcreateoutput));
87
	}
88
	return $rrdcreatereturn;
89
}
90

    
91
function migrate_rrd_format($rrdoldxml, $rrdnewxml) {
92
	if(!file_exists("/tmp/rrd_notice_sent.txt")) {
93
		exec("echo 'Converting RRD configuration to new format.  This might take a bit...' | wall");
94
		touch("/tmp/rrd_notice_sent.txt");
95
	}
96
	$numrraold = count($rrdoldxml['rra']);
97
	$numdsold = count($rrdoldxml['ds']);
98
	$numrranew = count($rrdnewxml['rra']);
99
	$numdsnew = count($rrdnewxml['ds']);
100
	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));
101
	
102
	/* add data sources not found in the old array from the new array */
103
	$i = 0;
104
	foreach($rrdnewxml['ds'] as $ds) {
105
		if(!is_array($rrdoldxml['ds'][$i])) {
106
			$rrdoldxml['ds'][$i] = $rrdnewxml['ds'][$i];
107
			/* set unknown values to 0 */
108
			$rrdoldxml['ds'][$i]['last_ds'] = " 0.0000000000e+00 ";
109
			$rrdoldxml['ds'][$i]['value'] = " 0.0000000000e+00 ";
110
			$rrdoldxml['ds'][$i]['unknown_sec'] = "0";
111
		}
112
		$i++;
113
	}
114

    
115
	$i = 0;
116
	$rracountold = count($rrdoldxml['rra']);
117
	$rracountnew = count($rrdnewxml['rra']);
118
	/* process each RRA, which contain a database */
119
	foreach($rrdnewxml['rra'] as $rra) {
120
		if(!is_array($rrdoldxml['rra'][$i])) {
121
			$rrdoldxml['rra'][$i] = $rrdnewxml['rra'][$i];
122
		}
123

    
124
		$d = 0;
125
		/* process cdp_prep */
126
		$cdp_prep = $rra['cdp_prep'];
127
		foreach($cdp_prep['ds'] as $ds) {
128
			if(!is_array($rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d])) {
129
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d] = $rrdnewxml['rra'][$i]['cdp_prep']['ds'][$d];
130
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d]['primary_value'] = " 0.0000000000e+00 ";
131
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d]['secondary_value'] = " 0.0000000000e+00 ";
132
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d]['value'] = " 0.0000000000e+00 ";
133
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d]['unknown_datapoints'] = "0";
134
			}
135
			$d++;
136
		}
137

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

    
182
	$numrranew = count($rrdoldxml['rra']);
183
	$numdsnew = count($rrdoldxml['ds']);
184
	log_error(sprintf(gettext('The new RRD now has %1$s DS values and %2$s RRA databases'), $numdsnew, $numrranew));
185
	return $rrdoldxml;
186
}
187

    
188
function enable_rrd_graphing() {
189
	global $config, $g, $altq_list_queues;
190

    
191
	if($g['booting']) 
192
		echo gettext("Generating RRD graphs...");
193

    
194
	$rrddbpath = "/var/db/rrd/";
195
	$rrdgraphpath = "/usr/local/www/rrd";
196

    
197
	$traffic = "-traffic.rrd";
198
	$packets = "-packets.rrd";
199
	$states = "-states.rrd";
200
	$wireless = "-wireless.rrd";
201
	$queues = "-queues.rrd";
202
	$queuesdrop = "-queuedrops.rrd";
203
	$spamd = "-spamd.rrd";
204
	$proc = "-processor.rrd";
205
	$mem = "-memory.rrd";
206
	$cellular = "-cellular.rrd";
207
	$vpnusers = "-vpnusers.rrd";
208
	$captiveportalconcurrent = "-concurrent.rrd";
209
	$captiveportalloggedin = "-loggedin.rrd";
210
	$captiveportaltotalusers = "-totalusers.rrd";
211

    
212
	$rrdtool = "/usr/bin/nice -n20 /usr/local/bin/rrdtool";
213
	$netstat = "/usr/bin/netstat";
214
	$awk = "/usr/bin/awk";
215
	$tar = "/usr/bin/tar";
216
	$pfctl = "/sbin/pfctl";
217
	$sysctl = "/sbin/sysctl";
218
	$php = "/usr/local/bin/php";
219
	$cpustats = "/usr/local/sbin/cpustats";
220
	$spamd_gather = "/usr/local/bin/spamd_gather_stats.php";
221
	$ifconfig = "/sbin/ifconfig";
222
	$captiveportal_gather = "/usr/local/bin/captiveportal_gather_stats.php";
223

    
224
	$rrdtrafficinterval = 60;
225
	$rrdwirelessinterval = 60;
226
	$rrdqueuesinterval = 60;
227
	$rrdqueuesdropinterval = 60;
228
	$rrdpacketsinterval = 60;
229
	$rrdstatesinterval = 60;
230
	$rrdspamdinterval = 60;
231
	$rrdlbpoolinterval = 60;
232
	$rrdprocinterval = 60;
233
	$rrdmeminterval = 60;
234
	$rrdcellularinterval = 60;
235
	$rrdvpninterval = 60;
236
	$rrdcaptiveportalinterval = 60;
237

    
238
	$trafficvalid = $rrdtrafficinterval * 2;
239
	$wirelessvalid = $rrdwirelessinterval * 2;
240
	$queuesvalid = $rrdqueuesinterval * 2;
241
	$queuesdropvalid = $rrdqueuesdropinterval * 2;
242
	$packetsvalid = $rrdpacketsinterval * 2;
243
	$statesvalid = $rrdstatesinterval*2;
244
	$spamdvalid = $rrdspamdinterval * 2;
245
	$lbpoolvalid = $rrdlbpoolinterval * 2;
246
	$procvalid = $rrdlbpoolinterval * 2;
247
	$memvalid = $rrdmeminterval * 2;
248
	$cellularvalid = $rrdcellularinterval * 2;
249
	$vpnvalid = $rrdvpninterval * 2;
250
	$captiveportalvalid = $rrdcaptiveportalinterval * 2;
251

    
252
	/* Asume GigE for now */
253
	$downstream = 125000000;
254
	$upstream = 125000000;
255

    
256
	/* read the shaper config */
257
	read_altq_config();
258

    
259
	if (isset ($config['rrd']['enable'])) {
260

    
261
		/* create directory if needed */
262
		if (!is_dir($rrddbpath)) {
263
			mkdir($rrddbpath, 0775);
264
		}
265
		chown($rrddbpath, "nobody");
266

    
267
		if ($g['booting']) {
268
			if ($g['platform'] != "pfSense") {
269
				restore_rrd();
270
			}
271
		}
272

    
273
		/* db update script */
274
		$rrdupdatesh = "#!/bin/sh\n";
275
		$rrdupdatesh .= "\n";
276
		$rrdupdatesh .= "export TERM=dumb\n";
277
		$rrdupdatesh .= "counter=1\n";
278
		$rrdupdatesh .= "while [ \"\$counter\" -ne 0 ]\n";
279
		$rrdupdatesh .= "do\n";
280
		$rrdupdatesh .= "";
281

    
282
		$i = 0;
283
		$ifdescrs = get_configured_interface_with_descr();
284
		/* IPsec counters */
285
		$ifdescrs['ipsec'] = "IPsec";
286
		/* OpenVPN server counters */
287
		if(is_array($config['openvpn']['openvpn-server'])) {
288
			foreach($config['openvpn']['openvpn-server'] as $server) {
289
				$serverid = "ovpns" . $server['vpnid'];
290
				$ifdescrs[$serverid] = "{$server['description']}";
291
			}
292
		}
293

    
294
		/* process all real and pseudo interfaces */
295
		foreach ($ifdescrs as $ifname => $ifdescr) {
296
			$temp = get_real_interface($ifname);
297
			if($temp <> "") {
298
				$realif = $temp;
299
			}
300

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

    
317
				create_new_rrd($rrdcreate);
318
			}
319

    
320
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
321
			if($g['booting']) {
322
				mwexec("$rrdtool update $rrddbpath$ifname$traffic N:U:U:U:U:U:U:U:U");
323
			}
324

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

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

    
349
				create_new_rrd($rrdcreate);
350
			}
351

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

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

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

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

    
385
				$rrdupdatesh .= "\n";
386
				$rrdupdatesh .= "# polling wireless for interface $ifname $realif \n";
387
				$rrdupdatesh .= "WIFI=`$ifconfig {$realif} list sta| $awk 'gsub(\"M\", \"\") {getline 2;print substr(\$5, 0, length(\$5)-2) \":\" $4 \":\" $3}'`\n";
388
				$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$wireless N:${WIFI}\n";
389
			}
390

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

    
404
				/* enter UNKNOWN values in the RRD so it knows we rebooted. */
405
				if($g['booting']) {
406
					mwexec("$rrdtool update $rrddbpath$ifname$vpnusers N:U");
407
				}
408

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

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

    
461
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
462
					$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
463
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
464
					$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
465

    
466
					create_new_rrd($rrdcreate);
467
				}
468

    
469
				if (!file_exists("$rrddbpath$ifname$queuesdrop")) {
470
					$rrdcreate = "$rrdtool create $rrddbpath$ifname$queuesdrop --step $rrdqueuesdropinterval ";
471
					/* loop list of shaper queues */
472
					$q = 0;
473
					foreach ($qlist as $qname => $q) {
474
						$rrdcreate .= "DS:$qname:COUNTER:$queuesdropvalid:0:$qbandwidth ";
475
					}
476

    
477
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
478
					$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
479
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
480
					$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
481

    
482
					create_new_rrd($rrdcreate);
483
				}
484

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

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

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

    
539
		/* System only statistics */
540
		$ifname = "system";
541

    
542
		/* STATES, create pf states database */
543
		if(! file_exists("$rrddbpath$ifname$states")) {
544
			$rrdcreate = "$rrdtool create $rrddbpath$ifname$states --step $rrdstatesinterval ";
545
			$rrdcreate .= "DS:pfrate:GAUGE:$statesvalid:0:10000000 ";
546
			$rrdcreate .= "DS:pfstates:GAUGE:$statesvalid:0:10000000 ";
547
			$rrdcreate .= "DS:pfnat:GAUGE:$statesvalid:0:10000000 ";
548
			$rrdcreate .= "DS:srcip:GAUGE:$statesvalid:0:10000000 ";
549
			$rrdcreate .= "DS:dstip:GAUGE:$statesvalid:0:10000000 ";
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

    
555
			create_new_rrd($rrdcreate);
556
		}
557

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

    
563
		/* the pf states gathering function. */
564
		$rrdupdatesh .= "\n";
565
		$rrdupdatesh .= "pfctl_si_out=\"` $pfctl -si > /tmp/pfctl_si_out `\"\n";
566
		$rrdupdatesh .= "pfctl_ss_out=\"` $pfctl -ss > /tmp/pfctl_ss_out`\"\n";
567
		$rrdupdatesh .= "pfrate=\"` cat /tmp/pfctl_si_out | egrep \"inserts|removals\" | awk '{ pfrate = \$3 + pfrate } {print pfrate}'|tail -1 `\"\n";
568
		$rrdupdatesh .= "pfstates=\"` cat /tmp/pfctl_ss_out | egrep -v \"<\\-.*?<\\-|\\->.*?\\->\" | wc -l|sed 's/ //g'`\"\n";
569
		$rrdupdatesh .= "pfnat=\"` cat /tmp/pfctl_ss_out | egrep '<\\-.*?<\\-|\\->.*?\\->' | wc -l|sed 's/ //g' `\"\n";
570
		$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";
571
		$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";
572
		$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$states N:\$pfrate:\$pfstates:\$pfnat:\$srcip:\$dstip\n\n";
573

    
574
		/* End pf states statistics */
575

    
576
		/* CPU, create CPU statistics database */
577
		if(! file_exists("$rrddbpath$ifname$proc")) {
578
			$rrdcreate = "$rrdtool create $rrddbpath$ifname$proc --step $rrdprocinterval ";
579
			$rrdcreate .= "DS:user:GAUGE:$procvalid:0:10000000 ";
580
			$rrdcreate .= "DS:nice:GAUGE:$procvalid:0:10000000 ";
581
			$rrdcreate .= "DS:system:GAUGE:$procvalid:0:10000000 ";
582
			$rrdcreate .= "DS:interrupt:GAUGE:$procvalid:0:10000000 ";
583
			$rrdcreate .= "DS:processes:GAUGE:$procvalid:0:10000000 ";
584
			$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
585
			$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
586
			$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
587
			$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
588

    
589
			create_new_rrd($rrdcreate);
590
		}
591

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

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

    
603
		/* End CPU statistics */
604

    
605
		/* Memory, create Memory statistics database */
606
		if(! file_exists("$rrddbpath$ifname$mem")) {
607
			$rrdcreate = "$rrdtool create $rrddbpath$ifname$mem --step $rrdmeminterval ";
608
			$rrdcreate .= "DS:active:GAUGE:$memvalid:0:10000000 ";
609
			$rrdcreate .= "DS:inactive:GAUGE:$memvalid:0:10000000 ";
610
			$rrdcreate .= "DS:free:GAUGE:$memvalid:0:10000000 ";
611
			$rrdcreate .= "DS:cache:GAUGE:$memvalid:0:10000000 ";
612
			$rrdcreate .= "DS:wire:GAUGE:$memvalid:0:10000000 ";
613
			$rrdcreate .= "RRA:MIN:0.5:1:1000 ";
614
			$rrdcreate .= "RRA:MIN:0.5:5:1000 ";
615
			$rrdcreate .= "RRA:MIN:0.5:60:1000 ";
616
			$rrdcreate .= "RRA:MIN:0.5:720:3000 ";
617
			$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
618
			$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
619
			$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
620
			$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
621
			$rrdcreate .= "RRA:MAX:0.5:1:1000 ";
622
			$rrdcreate .= "RRA:MAX:0.5:5:1000 ";
623
			$rrdcreate .= "RRA:MAX:0.5:60:1000 ";
624
			$rrdcreate .= "RRA:MAX:0.5:720:3000";
625

    
626
			create_new_rrd($rrdcreate);
627
		}
628

    
629
		/* enter UNKNOWN values in the RRD so it knows we rebooted. */
630
		if($g['booting']) {
631
			mwexec("$rrdtool update $rrddbpath$ifname$mem N:U:U:U:U:U");
632
		}
633

    
634
		/* the Memory stats gathering function. */
635
		$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 | ";
636
		$rrdupdatesh .= " $awk '{getline active;getline inactive;getline free;getline cache;getline wire;printf ";
637
		$rrdupdatesh .= "((active/$0) * 100)\":\"((inactive/$0) * 100)\":\"((free/$0) * 100)\":\"((cache/$0) * 100)\":\"(wire/$0 * 100)}'`\n";
638
		$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$mem N:\${MEM}\n";
639
		
640
		/* End Memory statistics */
641

    
642
		/* SPAMD, set up the spamd rrd file */
643
		if (isset($config['installedpackages']['spamdsettings']) &&
644
			 $config['installedpackages']['spamdsettings']['config'][0]['enablerrd']) {
645
			/* set up the spamd rrd file */
646
			if (!file_exists("$rrddbpath$ifname$spamd")) {
647
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$spamd --step $rrdspamdinterval ";
648
				$rrdcreate .= "DS:conn:GAUGE:$spamdvalid:0:10000 ";
649
				$rrdcreate .= "DS:time:GAUGE:$spamdvalid:0:86400 ";
650
				$rrdcreate .= "RRA:MIN:0.5:1:1000 ";
651
				$rrdcreate .= "RRA:MIN:0.5:5:1000 ";
652
				$rrdcreate .= "RRA:MIN:0.5:60:1000 ";
653
				$rrdcreate .= "RRA:MIN:0.5:720:3000 ";
654
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
655
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
656
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
657
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
658
				$rrdcreate .= "RRA:MAX:0.5:1:1000 ";
659
				$rrdcreate .= "RRA:MAX:0.5:5:1000 ";
660
				$rrdcreate .= "RRA:MAX:0.5:60:1000 ";
661
				$rrdcreate .= "RRA:MAX:0.5:720:3000 ";
662

    
663
				create_new_rrd($rrdcreate);
664
			}
665

    
666
			$rrdupdatesh .= "\n";
667
			$rrdupdatesh .= "# polling spamd for connections and tarpitness \n";
668
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$spamd \\\n";
669
			$rrdupdatesh .= "`$php -q $spamd_gather`\n";
670

    
671
		}
672
		/* End System statistics */
673

    
674
		/* 3G WIRELESS, set up the rrd file */
675
		/* XXX: Are multiple 3G interfaces not possible? smos@ */
676
		if(isset($config['ppps']['ppp'])) {
677
			$ifname = "ppp";
678
			if (!file_exists("$rrddbpath$ifname$cellular")) {
679
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$cellular --step $rrdcellularinterval ";
680
				$rrdcreate .= "DS:signal1:GAUGE:$cellularvalid:-200:200 ";
681
				$rrdcreate .= "DS:signal2:GAUGE:$cellularvalid:-200:200 ";
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

    
687
				create_new_rrd($rrdcreate);
688
			}
689

    
690
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
691
			if($g['booting']) {
692
				mwexec("$rrdtool update $rrddbpath$ifname$cellular N:U:U");
693
			}
694

    
695
			$rrdupdatesh .= "\n";
696
			$rrdupdatesh .= "# polling 3G\n";
697
			$rrdupdatesh .= "dev=`usbconfig show_ifdrv | awk -F. '/ u3g|umodem/ {print \"/dev/\" $1 \".\" $2}'`\n";
698
			$rrdupdatesh .= "if [ -n \"\$dev\" ]; then $rrdtool update $rrddbpath$ifname$cellular N:`3gstat -s -d \$dev`\n";
699
			$rrdupdatesh .= "else $rrdtool update $rrddbpath$ifname$cellular N:U:U; fi\n";
700
		}
701

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

    
725
				create_new_rrd($rrdcreate);
726
			}
727

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

    
760
				create_new_rrd($rrdcreate);
761
			}
762

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

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

    
774
		}
775

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

    
785
		/* kill off traffic collectors */
786
		kill_traffic_collector();
787

    
788
		/* start traffic collector */
789
		mwexec_bg("/usr/bin/nice -n20 /bin/sh $updaterrdscript");
790

    
791
	} else {
792
		/* kill off traffic collectors */
793
		kill_traffic_collector();
794
	}
795

    
796
	$databases = glob("{$rrddbpath}/*.rrd");
797
	foreach($databases as $database) {
798
		chown($database, "nobody");
799
	}
800

    
801
	if($g['booting']) 
802
		echo gettext("done.") . "\n";
803
		
804
}
805

    
806
function kill_traffic_collector() {
807
	mwexec("killall rrdtool", true);
808
	mwexec("/bin/pkill -a -f updaterrd.sh", true);
809
}
810

    
811
?>
(44-44/65)