diff options
author | Stephen Beaver <sbeaver@netgate.com> | 2015-11-10 10:25:30 -0500 |
---|---|---|
committer | Stephen Beaver <sbeaver@netgate.com> | 2015-11-10 10:25:30 -0500 |
commit | af9fd483747d1070400f475d79a8d13b9dd5de69 (patch) | |
tree | d86e746e6c6b8e7f4becffbefd7adb6df3b24a75 /src | |
parent | f1551428c4fe708232fc80239ec207640b058a28 (diff) | |
parent | 588a6068e476c2867948735ece7a5e8c886abd5a (diff) | |
download | pfsense-af9fd483747d1070400f475d79a8d13b9dd5de69.zip pfsense-af9fd483747d1070400f475d79a8d13b9dd5de69.tar.gz |
Merge pull request #2036 from heper/patch-1
Diffstat (limited to 'src')
-rw-r--r-- | src/etc/inc/rrd.inc | 44 | ||||
-rw-r--r-- | src/usr/local/bin/dhcpd_gather_stats.php | 208 | ||||
-rw-r--r-- | src/usr/local/www/services_dhcp.php | 14 | ||||
-rw-r--r-- | src/usr/local/www/status_rrd_graph.php | 22 | ||||
-rw-r--r-- | src/usr/local/www/status_rrd_graph_img.php | 27 |
5 files changed, 312 insertions, 3 deletions
diff --git a/src/etc/inc/rrd.inc b/src/etc/inc/rrd.inc index d1ec4aa..0c05062 100644 --- a/src/etc/inc/rrd.inc +++ b/src/etc/inc/rrd.inc @@ -228,6 +228,7 @@ function enable_rrd_graphing() { $captiveportalconcurrent = "-concurrent.rrd"; $captiveportalloggedin = "-loggedin.rrd"; $ntpd = "ntpd.rrd"; + $dhcpd = "-dhcpd.rrd"; $rrdtool = "/usr/bin/nice -n20 /usr/local/bin/rrdtool"; $netstat = "/usr/bin/netstat"; @@ -240,6 +241,7 @@ function enable_rrd_graphing() { $spamd_gather = "/usr/local/bin/spamd_gather_stats.php"; $ifconfig = "/sbin/ifconfig"; $captiveportal_gather = "/usr/local/bin/captiveportal_gather_stats.php"; + $dhcpd_gather = "/usr/local/bin/dhcpd_gather_stats.php"; $ntpq = "/usr/local/sbin/ntpq"; $rrdtrafficinterval = 60; @@ -257,6 +259,7 @@ function enable_rrd_graphing() { $rrdvpninterval = 60; $rrdcaptiveportalinterval = 60; $rrdntpdinterval = 60; + $rrddhcpdinterval = 60; $trafficvalid = $rrdtrafficinterval * 2; $wirelessvalid = $rrdwirelessinterval * 2; @@ -273,7 +276,8 @@ function enable_rrd_graphing() { $vpnvalid = $rrdvpninterval * 2; $captiveportalvalid = $rrdcaptiveportalinterval * 2; $ntpdvalid = $rrdntpdinterval * 2; - + $dhcpdvalid = $rrddhcpdinterval * 2; + /* Assume 2*10GigE for now */ $downstream = 2500000000; $upstream = 2500000000; @@ -910,6 +914,44 @@ function enable_rrd_graphing() { } /* End NTP statistics */ + + /* Start dhcpd statistics */ + foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) { + if (isset($config['dhcpd'][$dhcpif]['statsgraph'])) { + if (!file_exists("$rrddbpath$dhcpif$dhcpd")) { + $rrdcreate = "$rrdtool create $rrddbpath$dhcpif$dhcpd --step $rrddhcpdinterval "; + $rrdcreate .= "DS:leases:GAUGE:$dhcpdvalid:0:100000 "; + $rrdcreate .= "DS:staticleases:GAUGE:$dhcpdvalid:0:100000 "; + $rrdcreate .= "RRA:MIN:0.5:1:1200 "; + $rrdcreate .= "RRA:MIN:0.5:5:720 "; + $rrdcreate .= "RRA:MIN:0.5:60:1860 "; + $rrdcreate .= "RRA:MIN:0.5:1440:2284 "; + $rrdcreate .= "RRA:AVERAGE:0.5:1:1200 "; + $rrdcreate .= "RRA:AVERAGE:0.5:5:720 "; + $rrdcreate .= "RRA:AVERAGE:0.5:60:1860 "; + $rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 "; + $rrdcreate .= "RRA:MAX:0.5:1:1200 "; + $rrdcreate .= "RRA:MAX:0.5:5:720 "; + $rrdcreate .= "RRA:MAX:0.5:60:1860 "; + $rrdcreate .= "RRA:MAX:0.5:1440:2284 "; + create_new_rrd($rrdcreate); + unset($rrdcreate); + } + + /* enter UNKNOWN values in the RRD so it knows we rebooted. */ + if (platform_booting()) { + mwexec("$rrdtool update $rrddbpath$dhcpif$dhcpd N:U:U:U:U:U:U:U:U"); + } + + $rrdupdatesh .= "\n"; + $rrdupdatesh .= "# polling leases for dhcp \n"; + $rrdupdatesh .= "DHCP=`${php} -q ${dhcpd_gather} '${dhcpif}'`\n"; + $rrdupdatesh .= "$rrdtool update $rrddbpath$dhcpif$dhcpd \${DHCP}\n"; + + } + } + + /* END dhcpd statistics */ $rrdupdatesh .= "sleep 60\n"; $rrdupdatesh .= "done\n"; diff --git a/src/usr/local/bin/dhcpd_gather_stats.php b/src/usr/local/bin/dhcpd_gather_stats.php new file mode 100644 index 0000000..128fe0f --- /dev/null +++ b/src/usr/local/bin/dhcpd_gather_stats.php @@ -0,0 +1,208 @@ +#!/usr/local/bin/php-cgi -q +<?php +/* $Id$ */ +/* + dhcpd_gather_stats.php + Copyright (C) 2013-2015 Electric Sheep Fencing, LP + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +require_once("config.inc"); +require("interfaces.inc"); +/* echo the rrd required syntax */ +echo "N:"; +$result = "NaN"; +$result_static="NaN"; + +if (is_array($config['dhcpd'][$argv[1]])) { + + $leasesfile = "{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases"; + $leases_contents = file($leasesfile); + $dhcpif = $argv[1] ; + + function remove_duplicate($array, $field) { + foreach ($array as $sub) { + $cmp[] = $sub[$field]; + } + $unique = array_unique(array_reverse($cmp, true)); + foreach ($unique as $k => $rien) { + $new[] = $array[$k]; + } + return $new; + } + $awk = "/usr/bin/awk"; + /* this pattern sticks comments into a single array item */ + $cleanpattern = "'{ gsub(\"#.*\", \"\");} { gsub(\";\", \"\"); print;}'"; + /* We then split the leases file by } */ + $splitpattern = "'BEGIN { RS=\"}\";} {for (i=1; i<=NF; i++) printf \"%s \", \$i; printf \"}\\n\";}'"; + + /* stuff the leases file in a proper format into a array by line */ + exec("/bin/cat {$leasesfile} | {$awk} {$cleanpattern} | {$awk} {$splitpattern}", $leases_content); + $pools = array(); + $leases = array(); + $i = 0; + $l = 0; + $p = 0; + + // Put everything together again + foreach ($leases_content as $lease) { + /* split the line by space */ + $data = explode(" ", $lease); + /* walk the fields */ + $f = 0; + $fcount = count($data); + /* with less than 20 fields there is nothing useful */ + if ($fcount < 20) { + $i++; + continue; + } + while ($f < $fcount) { + switch ($data[$f]) { + case "failover": + $pools[$p]['name'] = trim($data[$f+2], '"'); + $pools[$p]['name'] = "{$pools[$p]['name']} (" . convert_friendly_interface_to_friendly_descr(substr($pools[$p]['name'], 5)) . ")"; + $pools[$p]['mystate'] = $data[$f+7]; + $pools[$p]['peerstate'] = $data[$f+14]; + $pools[$p]['mydate'] = $data[$f+10]; + $pools[$p]['mydate'] .= " " . $data[$f+11]; + $pools[$p]['peerdate'] = $data[$f+17]; + $pools[$p]['peerdate'] .= " " . $data[$f+18]; + $p++; + $i++; + continue 3; + case "lease": + $leases[$l]['ip'] = $data[$f+1]; + $leases[$l]['type'] = "dynamic"; + $f = $f+2; + break; + case "starts": + $leases[$l]['start'] = $data[$f+2]; + $leases[$l]['start'] .= " " . $data[$f+3]; + $f = $f+3; + break; + case "ends": + if ($data[$f+1] == "never") { + // Quote from dhcpd.leases(5) man page: + // If a lease will never expire, date is never instead of an actual date. + $leases[$l]['end'] = gettext("Never"); + $f = $f+1; + } else { + $leases[$l]['end'] = $data[$f+2]; + $leases[$l]['end'] .= " " . $data[$f+3]; + $f = $f+3; + } + break; + case "tstp": + $f = $f+3; + break; + case "tsfp": + $f = $f+3; + break; + case "atsfp": + $f = $f+3; + break; + case "cltt": + $f = $f+3; + break; + case "binding": + switch ($data[$f+2]) { + case "active": + $leases[$l]['act'] = "active"; + break; + case "free": + $leases[$l]['act'] = "expired"; + $leases[$l]['online'] = "offline"; + break; + case "backup": + $leases[$l]['act'] = "reserved"; + $leases[$l]['online'] = "offline"; + break; + } + $f = $f+1; + break; + case "next": + /* skip the next binding statement */ + $f = $f+3; + break; + case "rewind": + /* skip the rewind binding statement */ + $f = $f+3; + break; + case "uid": + $f = $f+1; + break; + } + $f++; + } + $l++; + $i++; + /* slowly chisel away at the source array */ + array_shift($leases_content); + } + /* remove the old array */ + unset($lease_content); + + /* remove duplicate items by mac address */ + if (count($leases) > 0) { + $leases = remove_duplicate($leases, "ip"); + } + + if (count($pools) > 0) { + $pools = remove_duplicate($pools, "name"); + asort($pools); + } + + foreach ($config['interfaces'] as $ifname => $ifarr) { + if (is_array($config['dhcpd'][$ifname]) && + is_array($config['dhcpd'][$ifname]['staticmap'])) { + $staticmap_array_index = 0; + foreach ($config['dhcpd'][$ifname]['staticmap'] as $static) { + $slease = array(); + $slease['ip'] = $static['ipaddr']; + $slease['act'] = "static"; + $slease['staticmap_array_index'] = $staticmap_array_index; + $leases[] = $slease; + $staticmap_array_index++; + } + } + } + $ifcfgip = get_interface_ip($dhcpif); + $ifcfgsn = get_interface_subnet($dhcpif); + $subnet_start = ip2ulong(long2ip32(ip2long($ifcfgip) & gen_subnet_mask_long($ifcfgsn))); + $subnet_end = ip2ulong(long2ip32(ip2long($ifcfgip) | (~gen_subnet_mask_long($ifcfgsn)))); + + foreach ($leases as $data) { + $lip = ip2ulong($data['ip']); + + if ($data['act'] != "active" && $data['act'] != "static" && $_GET['all'] != 1) + continue; + if ($data['act'] != "static") { + if (($lip >= ip2ulong($config['dhcpd'][$dhcpif]['range']['from'])) && ($lip <= ip2ulong($config['dhcpd'][$dhcpif]['range']['to']))) { + $result = $result + 1; + } + } + else { + if (($lip >= $subnet_start) && ($lip <= $subnet_end)) { + $result_static = $result_static + 1; + } + } + } +} +echo "$result:$result_static" ; diff --git a/src/usr/local/www/services_dhcp.php b/src/usr/local/www/services_dhcp.php index fb12e2b..9dff157 100644 --- a/src/usr/local/www/services_dhcp.php +++ b/src/usr/local/www/services_dhcp.php @@ -69,6 +69,8 @@ require("guiconfig.inc"); require_once("filter.inc"); +require_once('rrd.inc'); +require_once("shaper.inc"); if (!$g['services_dhcp_server_enable']) { header("Location: /"); @@ -201,6 +203,7 @@ if (is_array($dhcpdconf)) { $pconfig['rootpath'] = $dhcpdconf['rootpath']; $pconfig['netmask'] = $dhcpdconf['netmask']; $pconfig['numberoptions'] = $dhcpdconf['numberoptions']; + $pconfig['statsgraph'] = $dhcpdconf['statsgraph']; } $ifcfgip = $config['interfaces'][$if]['ipaddr']; @@ -564,6 +567,11 @@ if (isset($_POST['submit'])) { $dhcpdconf['filename32'] = $_POST['filename32']; $dhcpdconf['filename64'] = $_POST['filename64']; $dhcpdconf['rootpath'] = $_POST['rootpath']; + unset($dhcpdconf['statsgraph']); + if ($_POST['statsgraph']) { + $dhcpdconf['statsgraph'] = $_POST['statsgraph']; + enable_rrd_graphing(); + } // Handle the custom options rowhelper if (isset($dhcpdconf['numberoptions']['item'])) { @@ -955,6 +963,12 @@ if (!is_numeric($pool) && !($act == "newpool")) { $pconfig['dhcpleaseinlocaltime'] ))->setHelp('By default DHCP leases are displayed in UTC time. By checking this box DHCP lease time will be displayed in local time and set to the time zone selected.' . ' This will be used for all DHCP interfaces lease time'); + $section->addInput(new Form_Checkbox( + 'statsgraph', + 'RRD graphs', + 'Enable RRD graphs', + $pconfig['statsgraph'] + ))->setHelp('By default RRD graphs are disabled.'); } // DDNS diff --git a/src/usr/local/www/status_rrd_graph.php b/src/usr/local/www/status_rrd_graph.php index cebdc75..ab4de9d 100644 --- a/src/usr/local/www/status_rrd_graph.php +++ b/src/usr/local/www/status_rrd_graph.php @@ -70,7 +70,6 @@ require("shaper.inc"); require_once("rrd.inc"); unset($input_errors); - /* if the rrd graphs are not enabled redirect to settings page */ if (!isset($config['rrd']['enable'])) { header("Location: status_rrd_graph_settings.php"); @@ -170,6 +169,15 @@ if ($_POST['option']) { continue 2; } } + case "dhcpd": + foreach ($databases as $database) { + if (preg_match("/[-]dhcpd\.rrd/i", $database)) { + /* pick off the 1st database we find that matches the dhcpd graph */ + $name = explode("-", $database); + $curoption = "$name[0]"; + continue 2; + } + } case "captiveportal": $curoption = "allgraphs"; break; @@ -270,6 +278,10 @@ foreach ($databases as $database) { if (stristr($database, "ntpd") && isset($config['ntpd']['statsgraph'])) { $ntpd = true; } + if (stristr($database, "-dhcpd") && is_array($config['dhcpd'])) { + $dhcpd = true; + } + } /* append the existing array to the header */ $ui_databases = array_merge($dbheader, $databases); @@ -412,13 +424,14 @@ function get_dates($curperiod, $graph) { } function make_tabs() { - global $curcat; + global $curcat, $queues,$wireless,$cellular,$vpnusers, $captiveportal,$dhcpd; $tab_array = array(); $tab_array[] = array(gettext("System"), ($curcat == "system"), "status_rrd_graph.php?cat=system"); $tab_array[] = array(gettext("Traffic"), ($curcat == "traffic"), "status_rrd_graph.php?cat=traffic"); $tab_array[] = array(gettext("Packets"), ($curcat == "packets"), "status_rrd_graph.php?cat=packets"); $tab_array[] = array(gettext("Quality"), ($curcat == "quality"), "status_rrd_graph.php?cat=quality"); + if($queues) { $tab_array[] = array(gettext("Queues"), ($curcat == "queues"), "status_rrd_graph.php?cat=queues"); @@ -444,6 +457,11 @@ function make_tabs() { if(isset($config['ntpd']['statsgraph'])) { $tab_array[] = array("NTP", ($curcat == "ntpd"), "status_rrd_graph.php?cat=ntpd"); } + + if($dhcpd) { + $tab_array[] = array(gettext("Dhcp Server"), ($curcat == "dhcpd"), "status_rrd_graph.php?cat=dhcpd"); + } + $tab_array[] = array(gettext("Custom"), ($curcat == "custom"), "status_rrd_graph.php?cat=custom"); $tab_array[] = array(gettext("Settings"), ($curcat == "settings"), "status_rrd_graph_settings.php"); diff --git a/src/usr/local/www/status_rrd_graph_img.php b/src/usr/local/www/status_rrd_graph_img.php index 5ec51d5..4c789a1 100644 --- a/src/usr/local/www/status_rrd_graph_img.php +++ b/src/usr/local/www/status_rrd_graph_img.php @@ -284,6 +284,8 @@ $colorntpd = array('0080FF', '00E344', 'FF0000', '000000'); /* Captive Portal Concurrent Concurrent Users */ $colorcaptiveportalusers = array('990000'); +$colordhcpd = array('990000', '0000FF'); + switch ($curstyle) { case "absolute": $multiplier = 1; @@ -1233,6 +1235,31 @@ if ((strstr($curdatabase, "-traffic.rrd")) && (file_exists("$rrddbpath$curdataba $graphcmd .= "GPRINT:\"wander:LAST:%7.2lf %S \" "; $graphcmd .= "COMMENT:\"\\n\" "; $graphcmd .= "COMMENT:\"\t\t\t\t\t\t\t\t\t\t\t\t\t" . strftime('%b %d %H\:%M\:%S %Y') . "\" "; +} elseif ((strstr($curdatabase, "-dhcpd.rrd")) && (file_exists("$rrddbpath$curdatabase"))) { + /* define graphcmd for dhcpd stats */ + $graphcmd = "$rrdtool graph $rrdtmppath$curdatabase-$curgraph.png "; + $graphcmd .= "--start $start --end $end --step $step "; + $graphcmd .= "--vertical-label \"Dhcp Leases\" "; + $graphcmd .= "--color SHADEA#eeeeee --color SHADEB#eeeeee "; + $graphcmd .= "--title \"" . php_uname('n') . " - {$prettydb} - {$hperiod} - {$havg} average\" "; + $graphcmd .= "--height 200 --width 620 "; + $graphcmd .= "DEF:\"$curif-leases=$rrddbpath$curdatabase:leases:AVERAGE:step=$step\" "; + $graphcmd .= "DEF:\"$curif-staticleases=$rrddbpath$curdatabase:staticleases:AVERAGE:step=$step\" "; + $graphcmd .= "LINE1:\"$curif-leases#{$colordhcpd[0]}:Active Leases\" "; + $graphcmd .= "LINE1:\"$curif-staticleases#{$colordhcpd[1]}:Static Leases\" "; + $graphcmd .= "COMMENT:\"\\n\" "; + $graphcmd .= "COMMENT:\"\t\t\t current\t\t average\t maximum\\n\" "; + $graphcmd .= "COMMENT:\"Leases Active\t\" "; + $graphcmd .= "GPRINT:\"$curif-leases:LAST:%8.0lf \" "; + $graphcmd .= "GPRINT:\"$curif-leases:AVERAGE:%8.0lf \" "; + $graphcmd .= "GPRINT:\"$curif-leases:MAX:%8.0lf \" "; + $graphcmd .= "COMMENT:\"\\n\" "; + $graphcmd .= "COMMENT:\"Leases Static\t\" "; + $graphcmd .= "GPRINT:\"$curif-staticleases:LAST:%8.0lf \" "; + $graphcmd .= "GPRINT:\"$curif-staticleases:AVERAGE:%8.0lf \" "; + $graphcmd .= "GPRINT:\"$curif-staticleases:MAX:%8.0lf \" "; + $graphcmd .= "COMMENT:\"\\n\" "; + $graphcmd .= "COMMENT:\"\t\t\t\t\t\t\t\t\t\t\t\t\t" . strftime('%b %d %H\:%M\:%S %Y') . "\" "; } else { $data = false; log_error(sprintf(gettext("Sorry we do not have data to graph for %s"),$curdatabase)); |