Project

General

Profile

Download (29.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("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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
296
				create_new_rrd($rrdcreate);
297
			}
298

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

    
304
			$rrdupdatesh .= "\n";
305
			$rrdupdatesh .= "# polling traffic for interface $ifname $realif IPv4/IPv6 counters \n";
306
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$traffic N:\\\n";
307
			$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";
308

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

    
325
				create_new_rrd($rrdcreate);
326
			}
327

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

    
333
			$rrdupdatesh .= "\n";
334
			$rrdupdatesh .= "# polling packets for interface $ifname $realif \n";
335
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$packets N:\\\n";
336
			$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";
337

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

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

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

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

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

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

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

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

    
439
					create_new_rrd($rrdcreate);
440
				}
441

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

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

    
455
					create_new_rrd($rrdcreate);
456
				}
457

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

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

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

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

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

    
528
			create_new_rrd($rrdcreate);
529
		}
530

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

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

    
547
		/* End pf states statistics */
548

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

    
562
			create_new_rrd($rrdcreate);
563
		}
564

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

    
570
		/* the CPU stats gathering function. */
571
		$rrdupdatesh .= "$top -d 2 -s 1 0 | tail -n7 > /tmp/top_output.txt\n";
572
		$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$proc N:\\\n";
573
		$rrdupdatesh .= "`$awk < /tmp/top_output.txt '{gsub(/%/, \"\")} \\\n";
574
		$rrdupdatesh .= "{ if ( \$2 == \"processes:\" ) { processes = \$1; } \\\n";
575
		$rrdupdatesh .= "else if ( \$1 == \"CPU:\" ) { user = \$2; nice = \$4; sys = \$6; interrupt = \$8; } \\\n";
576
		$rrdupdatesh .= "} END { printf user\":\"nice\":\"sys\":\"interrupt\":\"processes }'`\n\n";
577

    
578
		/* End CPU statistics */
579

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

    
601
			create_new_rrd($rrdcreate);
602
		}
603

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

    
609
		/* the Memory stats gathering function. */
610
		$rrdupdatesh .= "`$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 | ";
611
		$rrdupdatesh .= " $awk '{getline active;getline inactive;getline free;getline cache;getline wire;printf \"$rrdtool update $rrddbpath$ifname$mem N:\"";
612
		$rrdupdatesh .= "((active/$0) * 100)\":\"((inactive/$0) * 100)\":\"((free/$0) * 100)\":\"((cache/$0) * 100)\":\"(wire/$0 * 100)}'`\n\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$captiveportal")) {
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 .= "$rrdtool update $rrddbpath$ifname$captiveportalconcurrent \\\n";
711
			$rrdupdatesh .= "`$php -q $captiveportal_gather concurrent`\n";
712
			
713
			$ifname= "captiveportal";
714
			if (!file_exists("$rrddbpath$ifname$captiveportal")) {
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 and concurrent users\n";
745
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$captiveportalloggedin \\\n";
746
			$rrdupdatesh .= "`$php -q $captiveportal_gather loggedin`\n";
747
		}
748

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

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

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

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

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

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

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

    
785
?>
(41-41/61)