aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config/ifbwstats/ifbwstats.inc392
-rw-r--r--config/ifbwstats/ifbwstats.sh33
-rw-r--r--config/ifbwstats/ifbwstats.xml347
-rw-r--r--config/ifbwstats/ifbwstats_cur.php197
-rw-r--r--config/ifbwstats/ifbwstats_daemon.php352
-rw-r--r--config/ifbwstats/ifbwstats_daily.php142
-rw-r--r--config/ifbwstats/ifbwstats_disp.php206
-rwxr-xr-xpkg_config.7.xml11
-rwxr-xr-xpkg_config.8.xml11
-rwxr-xr-xpkg_config.8.xml.amd6411
10 files changed, 1702 insertions, 0 deletions
diff --git a/config/ifbwstats/ifbwstats.inc b/config/ifbwstats/ifbwstats.inc
new file mode 100644
index 00000000..be07e8cc
--- /dev/null
+++ b/config/ifbwstats/ifbwstats.inc
@@ -0,0 +1,392 @@
+<?php
+/*
+ /usr/local/pkg/ifbwstats.inc
+
+ Contributed - 2010 - Zorac
+
+ cron restart code as identifed below from
+ /usr/local/pkg/cron.inc
+ Copyright (C) 2008 Mark J Crane
+ 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("/usr/local/www/guiconfig.inc");
+
+define( 'LOCK_FILE', "/var/run/ifbwstats.lock" );
+
+function ifbwstats_add_cron()
+{
+ global $config;
+
+ $i = count($config['cron']['item']);
+ $cif = -1; //cron interval entry
+ for ($n=0; $n<$i; $n++)
+ {
+ //find cron interval run
+ if ((strstr($config['cron']['item'][$n]['hour'], '*/3')) && (strstr($config['cron']['item'][$n]['command'], 'ifbwstats_daemon.php')))
+ {
+ $cif = $n;
+ }
+ }
+
+ //daily restart
+ if ($cif < 0) //if entry not found, add it
+ {
+ $config['cron']['item'][$i]['minute'] = '0';
+ $config['cron']['item'][$i]['hour'] = '1';
+ $config['cron']['item'][$i]['mday'] = '*';
+ $config['cron']['item'][$i]['month'] = '*';
+ $config['cron']['item'][$i]['wday'] = '*';
+ $config['cron']['item'][$i]['who'] = 'root';
+ $config['cron']['item'][$i]['command'] = 'kill -INT `cat /var/run/ifbwstats.lock` ; sleep 5 ; /usr/local/etc/rc.d/ifbwstats.sh start';
+ $i++;
+ }
+
+ //restart cron so changes are running
+ //----------start insert from /usr/local/pkg/cron.inc----------
+ configure_cron();
+ $handle = popen("/usr/local/etc/rc.d/cron.sh stop", "r");
+ pclose($handle);
+ $handle = popen("/usr/local/etc/rc.d/cron.sh start", "r");
+ pclose($handle);
+ //----------end insert from /usr/local/pkg/cron.inc----------
+
+ write_config();
+}
+
+function ifbwstats_remove_cron()
+{
+ global $config;
+
+ //find and erase cron entries
+ $i = count($config['cron']['item']);
+ for ($n=0; $n<$i; $n++)
+ {
+ //find cron interval run
+ if ((strstr($config['cron']['item'][$n]['hour'], '1')) && (strstr($config['cron']['item'][$n]['command'], 'ifbwstats'))) unset ($config['cron']['item'][$n]);
+ }
+
+ //restart cron so changes are running
+ //----------start insert from /usr/local/pkg/cron.inc----------
+ configure_cron();
+ $handle = popen("/usr/local/etc/rc.d/cron.sh stop", "r");
+ pclose($handle);
+ $handle = popen("/usr/local/etc/rc.d/cron.sh start", "r");
+ pclose($handle);
+ //----------end insert from /usr/local/pkg/cron.inc----------
+
+ write_config();
+}
+
+function ifbwstats_set_var()
+{
+ global $config;
+
+ $config['installedpackages']['ifbwstats']['config'][0]['firstday'] = 1;
+ $config['installedpackages']['ifbwstats']['config'][0]['intervalrun'] = 280;
+ $config['installedpackages']['ifbwstats']['config'][0]['logging'] = 'no';
+ $config['installedpackages']['ifbwstats']['config'][0]['ifmon'] = 'wan';
+ write_config();
+}
+
+function ifbwstats_remove_var()
+{
+ global $config;
+
+ unset ($config['installedpackages']['ifbwstats']);
+ write_config();
+}
+
+function start_php_script()
+{
+ $handle = popen("/usr/local/etc/rc.d/ifbwstats.sh start", "r");
+ sleep (1);
+ pclose($handle);
+}
+
+function usr1_php_script()
+{
+ if( file_exists( LOCK_FILE ) )
+ {
+ //force interface read via daemon
+ $handle = popen("kill -USR1 `cat /var/run/ifbwstats.lock`", "r");
+ //while (!feof($handle)) sleep (1);
+ sleep (1);
+ pclose($handle);
+ }
+}
+
+function kill_php_script()
+{
+ //if lock file exists, process must be running, therefore kill it and remove lock file
+ if( file_exists( LOCK_FILE ) )
+ {
+ $handle = popen("kill -INT `cat /var/run/ifbwstats.lock`", "r");
+ //while (!feof($handle)) sleep (1);
+ sleep (1);
+ pclose($handle);
+ }
+}
+/*
+function file_put_contents($filename, $data, $file_append = false)
+{
+ $fp = fopen($filename, (!$file_append ? 'w+' : 'a+'));
+ if(!$fp)
+ {
+ trigger_error('file_put_contents cannot write in file.', E_USER_ERROR);
+ return;
+ }
+ fputs($fp, $data);
+ fclose($fp);
+}
+*/
+
+function ifbwstats_add_rc()
+{
+ //add shutdown entry
+ $fp = fopen('/etc/rc.shutdown',"r") or die("Error Reading File");
+ $data = fread($fp, filesize('/etc/rc.shutdown'));
+ fclose($fp);
+ $fpdata = explode("\n", $data);
+ $fpwrite = '';
+ $i = count($fpdata);
+ $fndentry = -1; //found shutdown entry
+ for ($n=0; $n<$i; $n++) if (strstr($fpdata[$n], '# ifBWStats:')) $fndentry = $n;
+ if ($fndentry < 0)
+ {
+ for ($n=0; $n<$i; $n++) if (strstr($fpdata[$n], 'HOME=/; export HOME')) $fndentry = $n-2;
+ for ($n=0; $n<$fndentry+1; $n++) $fpwrite .= $fpdata[$n]."\n";
+ $fpwrite .= "\n".'# ifBWStats: shut down script'."\n".'kill -INT `cat /var/run/ifbwstats.lock`'."\n".'sleep 1'."\n".'# ifBWStats: remove last reading as some platforms may not erase tmp files'."\n".'rm /tmp/ifbwstats-*.last'."\n";
+ for ($n=$fndentry+1; $n<$i-1; $n++) $fpwrite .= $fpdata[$n]."\n";
+ $fpwrite .= $fpdata[$i-1];
+ $fp = fopen('/etc/rc.shutdown',"w") or die("Error Reading File");
+ fwrite($fp, $fpwrite);
+ fclose($fp);
+ }
+
+ //add reboot entry
+ $fp = fopen('/etc/rc.reboot',"r") or die("Error Reading File");
+ $data = fread($fp, filesize('/etc/rc.reboot'));
+ fclose($fp);
+ $fpdata = explode("\n", $data);
+ $fpwrite = '';
+ $i = count($fpdata);
+ $fndentry = -1; //found reboot entry
+ for ($n=0; $n<$i; $n++) if (strstr($fpdata[$n], '# ifBWStats:')) $fndentry = $n;
+ if ($fndentry < 0)
+ {
+ for ($n=0; $n<$i; $n++) if (strstr($fpdata[$n], '# If PLATFORM is pfSense then remove')) $fndentry = $n-2;
+ for ($n=0; $n<$fndentry+1; $n++) $fpwrite .= $fpdata[$n]."\n";
+ $fpwrite .= "\n".'# ifBWStats: shut down script'."\n".'kill -INT `cat /var/run/ifbwstats.lock`'."\n".'sleep 1'."\n".'# ifBWStats: remove last reading as some platforms may not erase tmp files'."\n".'rm /tmp/ifbwstats-*.last'."\n";
+ for ($n=$fndentry+1; $n<$i-1; $n++) $fpwrite .= $fpdata[$n]."\n";
+ $fpwrite .= $fpdata[$i-1];
+ $fp = fopen('/etc/rc.reboot',"w") or die("Error Reading File");
+ fwrite($fp, $fpwrite);
+ fclose($fp);
+ }
+
+ //add halt entry
+ $fp = fopen('/etc/rc.halt',"r") or die("Error Reading File");
+ $data = fread($fp, filesize('/etc/rc.halt'));
+ fclose($fp);
+ $fpdata = explode("\n", $data);
+ $fpwrite = '';
+ $i = count($fpdata);
+ $fndentry = -1; //found halt entry
+ for ($n=0; $n<$i; $n++) if (strstr($fpdata[$n], '# ifBWStats:')) $fndentry = $n;
+ if ($fndentry < 0)
+ {
+ for ($n=0; $n<$i; $n++) if (strstr($fpdata[$n], 'sleep 1')) $fndentry = $n-2;
+ for ($n=0; $n<$fndentry+1; $n++) $fpwrite .= $fpdata[$n]."\n";
+ $fpwrite .= "\n".'# ifBWStats: shut down script'."\n".'kill -INT `cat /var/run/ifbwstats.lock`'."\n".'sleep 1'."\n".'# ifBWStats: remove last reading as some platforms may not erase tmp files'."\n".'rm /tmp/ifbwstats-*.last'."\n";
+ for ($n=$fndentry+1; $n<$i-1; $n++) $fpwrite .= $fpdata[$n]."\n";
+ $fpwrite .= $fpdata[$i-1];
+ $fp = fopen('/etc/rc.halt',"w") or die("Error Reading File");
+ fwrite($fp, $fpwrite);
+ fclose($fp);
+ }
+}
+
+function ifbwstats_remove_rc()
+{
+ //remove shutdown entry
+ $fp = fopen('/etc/rc.shutdown',"r") or die("Error Reading File");
+ $data = fread($fp, filesize('/etc/rc.shutdown'));
+ fclose($fp);
+ $fpdata = explode("\n", $data);
+ $fpwrite = '';
+ $i = count($fpdata);
+ $fndentry = -1; //found shutdown entry
+ for ($n=0; $n<$i; $n++) if ((strstr($fpdata[$n], '# ifBWStats:'))&&($fndentry < 0)) $fndentry = $n;
+ if ($fndentry >= 0)
+ {
+ for ($n=0; $n<$fndentry; $n++) $fpwrite .= $fpdata[$n]."\n";
+ for ($n=$fndentry+6; $n<$i-1; $n++) $fpwrite .= $fpdata[$n]."\n";
+ $fpwrite .= $fpdata[$i-1];
+ $fp = fopen('/etc/rc.shutdown',"w") or die("Error Reading File");
+ fwrite($fp, $fpwrite);
+ fclose($fp);
+ }
+
+ //remove reboot entry
+ $fp = fopen('/etc/rc.reboot',"r") or die("Error Reading File");
+ $data = fread($fp, filesize('/etc/rc.reboot'));
+ fclose($fp);
+ $fpdata = explode("\n", $data);
+ $fpwrite = '';
+ $i = count($fpdata);
+ $fndentry = -1; //found reboot entry
+ for ($n=0; $n<$i; $n++) if ((strstr($fpdata[$n], '# ifBWStats:'))&&($fndentry < 0)) $fndentry = $n;
+ if ($fndentry >= 0)
+ {
+ for ($n=0; $n<$fndentry; $n++) $fpwrite .= $fpdata[$n]."\n";
+ for ($n=$fndentry+6; $n<$i-1; $n++) $fpwrite .= $fpdata[$n]."\n";
+ $fpwrite .= $fpdata[$i-1];
+ $fp = fopen('/etc/rc.reboot',"w") or die("Error Reading File");
+ fwrite($fp, $fpwrite);
+ fclose($fp);
+ }
+
+ //remove halt entry
+ $fp = fopen('/etc/rc.halt',"r") or die("Error Reading File");
+ $data = fread($fp, filesize('/etc/rc.halt'));
+ fclose($fp);
+ $fpdata = explode("\n", $data);
+ $fpwrite = '';
+ $i = count($fpdata);
+ $fndentry = -1; //found halt entry
+ for ($n=0; $n<$i; $n++) if ((strstr($fpdata[$n], '# ifBWStats:'))&&($fndentry < 0)) $fndentry = $n;
+ if ($fndentry >= 0)
+ {
+ for ($n=0; $n<$fndentry; $n++) $fpwrite .= $fpdata[$n]."\n";
+ for ($n=$fndentry+6; $n<$i-1; $n++) $fpwrite .= $fpdata[$n]."\n";
+ $fpwrite .= $fpdata[$i-1];
+ $fp = fopen('/etc/rc.halt',"w") or die("Error Reading File");
+ fwrite($fp, $fpwrite);
+ fclose($fp);
+ }
+}
+
+function cleanup_data_file ($readfile, $writefile)
+{
+ //----------------------------------------maintain file incase of errors in the file----------------------------------------
+ $wandataall = array();
+ $wandataarray = array();
+
+ //read data file
+ $fp = fopen($readfile,"r") or die("Error Reading File");
+ $data = fread($fp, filesize($readfile));
+ fclose($fp);
+ $wandataall = explode("\n", $data);
+ $n = count($wandataall);
+
+ //expode data into two dim. array
+ for ($x=0; $x<$n; $x++)
+ {
+ $line = explode('|',$wandataall[$x]);
+
+ // save it by coulmns otherwise it will saved like rows
+ for ($i=0; $i<=2; $i++)
+ {
+ if ($i==0) $wandataarray[$x][$i] = date("Y-m-d", strtotime($line[$i]));
+ else $wandataarray[$x][$i] = $line[$i];
+ }
+ }
+
+ //sort array into chronological order
+ sort ($wandataarray);
+
+ $m=$n;
+ //check for multiple entries, and if so add them
+ for ($x=0; $x<$n; $x++)
+ {
+ if (($wandataarray[$x][0] == $wandataarray[$x+1][0]) && ($x+1<$m))
+ {
+ $wandataarray[$x][1] = $wandataarray[$x][1] + $wandataarray[$x+1][1];
+ $wandataarray[$x][2] = $wandataarray[$x][2] + $wandataarray[$x+1][2];
+ for ($i = $x+1; $i<$n; $i++)
+ {
+ if (!is_null($wandataarray[$i+1][0])) $wandataarray[$i][0]=$wandataarray[$i+1][0];
+ if (!is_null($wandataarray[$i+1][1])) $wandataarray[$i][1]=$wandataarray[$i+1][1];
+ if (!is_null($wandataarray[$i+1][2])) $wandataarray[$i][2]=$wandataarray[$i+1][2];
+ }
+ $x--;
+ $m--;
+ }
+ }
+
+ //check for missing entries
+ $nextday=$wandataarray[0][0];
+ $x=0;
+ while ($x<$m)
+ {
+ //missing entry between days
+ if ($nextday != $wandataarray[$x][0])
+ {
+ $m++;
+ for ($i=$m; $i>$x; $i--)
+ {
+
+ $wandataarray[$i][0] = $wandataarray[$i-1][0];
+ $wandataarray[$i][1] = $wandataarray[$i-1][1];
+ $wandataarray[$i][2] = $wandataarray[$i-1][2];
+ $wandataarray[$i][3] = $wandataarray[$i-1][3];
+ $wandataarray[$i][4] = $wandataarray[$i-1][4];
+ }
+ //fill in 0 bytes transfered for missing days
+ $wandataarray[$x][0] = $nextday;
+ $wandataarray[$x][1] = 0;
+ $wandataarray[$x][2] = 0;
+ }
+ $x++;
+
+ //add one day to the date
+ $nextday = date("Y-m-d", strtotime(date("Y-m-d", strtotime($nextday)) . " +1 day"));
+
+ //echo 'x: '.$x.' m: '.$m.' array date: '.strtotime($wandataarray[$x-1][0]).' current date: '.strtotime(date("Y-m-d")).'<br>';
+ //add missing entries at end of file if required
+ if (($x==$m)&&(strtotime($wandataarray[$x-1][0] ) < strtotime(date("Y-m-d"))))
+ {
+ $wandataarray[$x][0] = $nextday;
+ $wandataarray[$x][1] = 0;
+ $wandataarray[$x][2] = 0;
+ $m++;
+ }
+ }
+
+ //put array data into variable for wirting
+ $writedata = '';
+ for ($x=0; $x<$m-1; $x++) $writedata .= $wandataarray[$x][0].'|'.$wandataarray[$x][1].'|'.$wandataarray[$x][2]."\n";
+ $writedata .= $wandataarray[$m-1][0].'|'.$wandataarray[$m-1][1].'|'.$wandataarray[$m-1][2];
+
+ //write data file
+ $fp = fopen($writefile,"w") or die("Error Reading File");
+ fwrite($fp, $writedata);
+ fclose($fp);
+ //----------------------------------------end of file maintaince----------------------------------------
+}
+
+
+?> \ No newline at end of file
diff --git a/config/ifbwstats/ifbwstats.sh b/config/ifbwstats/ifbwstats.sh
new file mode 100644
index 00000000..fb7ea4fd
--- /dev/null
+++ b/config/ifbwstats/ifbwstats.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+. /etc/rc.subr
+
+name="ifbwstats"
+start_cmd="${name}_start"
+stop_cmd="${name}_stop"
+restart_cmd="${name}_restart"
+
+# called by pfSense by rc.start_packages on startup
+ifbwstats_start()
+{
+# ifBWStats: initialize ifbwstats_daemon.php script
+/usr/local/bin/php -q /usr/local/www/ifbwstats_daemon.php & 2>/dev/null
+}
+
+ifbwstats_stop()
+{
+################################################################
+# pfSense does not call rc.stop_packages so this is not called
+################################################################
+kill -INT `cat /var/run/ifbwstats.lock`
+}
+
+ifbwstats_restart()
+{
+kill -INT `cat /var/run/ifbwstats.lock`
+sleep 2
+/usr/local/bin/php -q /usr/local/www/ifbwstats_daemon.php & 2>/dev/null
+}
+
+load_rc_config $name
+run_rc_command "$1" \ No newline at end of file
diff --git a/config/ifbwstats/ifbwstats.xml b/config/ifbwstats/ifbwstats.xml
new file mode 100644
index 00000000..948e47b8
--- /dev/null
+++ b/config/ifbwstats/ifbwstats.xml
@@ -0,0 +1,347 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE packagegui SYSTEM "../schema/packages.dtd">
+<?xml-stylesheet type="text/xsl" href="../xsl/package.xsl"?>
+<packagegui>
+ <copyright>
+ <![CDATA[
+/* $Id$ */
+/* ========================================================================== */
+/*
+ ifbwstats.xml
+ part of pfSense (http://www.pfSense.com)
+ Copyright (C) 2010 to whom it may belong
+ All rights reserved.
+
+ Based on m0n0wall (http://m0n0.ch/wall)
+ Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
+ 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.
+ */
+/* ========================================================================== */
+ ]]>
+ </copyright>
+
+ <description>Interface Bandwidth Stats</description>
+ <name>ifbwstats</name>
+ <requirements>None</requirements>
+ <faq>Currently there are no FAQ items provided.</faq>
+ <version>1.0</version>
+ <title>ifBWStats: if Bandwidth Stats Settings</title>
+ <include_file>/usr/local/pkg/ifbwstats.inc</include_file>
+<!-- <service>
+ <name>ifBWStats</name>
+ <rcfile>ifbwstats.sh</rcfile>
+ <description>ifBWStats daemon</description>
+ </service> -->
+ <menu>
+ <name>ifBWStats</name>
+ <tooltiptext></tooltiptext>
+ <section>Status</section>
+ <url>/ifbwstats_cur.php</url>
+ </menu>
+ <tabs>
+ <tab>
+ <text>Daily</text>
+ <url>/ifbwstats_cur.php</url>
+ </tab>
+ <tab>
+ <text>Monthly</text>
+ <url>/ifbwstats_disp.php</url>
+ </tab>
+ <tab>
+ <text>Settings</text>
+ <url>/pkg_edit.php?xml=ifbwstats.xml&amp;id=0</url>
+ <active/>
+ </tab>
+ </tabs>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://192.168.0.5/packages/config/ifbwstats/ifbwstats_daily.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://192.168.0.5/packages/config/ifbwstats/ifbwstats_disp.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://192.168.0.5/packages/config/ifbwstats/ifbwstats_cur.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0777</chmod>
+ <item>http://192.168.0.5/packages/config/ifbwstats/ifbwstats_daemon.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ <item>http://192.168.0.5/packages/config/ifbwstats/ifbwstats.inc</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/etc/rc.d/</prefix>
+ <chmod>0755</chmod>
+ <item>http://192.168.0.5/packages/config/ifbwstats/ifbwstats.sh</item>
+ </additional_files_needed>
+ <fields>
+ <field>
+ <fieldname>firstday</fieldname>
+ <fielddescr>First Day:</fielddescr>
+ <description>This is the first day of your billing period. It can be changed at anytime with no impact on the recorded data.</description>
+ <required/>
+ <type>select</type>
+ <options>
+ <option>
+ <value>1</value>
+ <name>1</name>
+ </option>
+ <option>
+ <value>2</value>
+ <name>2</name>
+ </option>
+ <option>
+ <value>3</value>
+ <name>3</name>
+ </option>
+ <option>
+ <value>4</value>
+ <name>4</name>
+ </option>
+ <option>
+ <value>5</value>
+ <name>5</name>
+ </option>
+ <option>
+ <value>6</value>
+ <name>6</name>
+ </option>
+ <option>
+ <value>7</value>
+ <name>7</name>
+ </option>
+ <option>
+ <value>8</value>
+ <name>8</name>
+ </option>
+ <option>
+ <value>9</value>
+ <name>9</name>
+ </option>
+ <option>
+ <value>10</value>
+ <name>10</name>
+ </option>
+ <option>
+ <value>11</value>
+ <name>11</name>
+ </option>
+ <option>
+ <value>12</value>
+ <name>12</name>
+ </option>
+ <option>
+ <value>13</value>
+ <name>13</name>
+ </option>
+ <option>
+ <value>14</value>
+ <name>14</name>
+ </option>
+ <option>
+ <value>15</value>
+ <name>15</name>
+ </option>
+ <option>
+ <value>16</value>
+ <name>16</name>
+ </option>
+ <option>
+ <value>17</value>
+ <name>17</name>
+ </option>
+ <option>
+ <value>18</value>
+ <name>18</name>
+ </option>
+ <option>
+ <value>19</value>
+ <name>19</name>
+ </option>
+ <option>
+ <value>20</value>
+ <name>20</name>
+ </option>
+ <option>
+ <value>21</value>
+ <name>21</name>
+ </option>
+ <option>
+ <value>22</value>
+ <name>22</name>
+ </option>
+ <option>
+ <value>23</value>
+ <name>23</name>
+ </option>
+ <option>
+ <value>24</value>
+ <name>24</name>
+ </option>
+ <option>
+ <value>25</value>
+ <name>25</name>
+ </option>
+ <option>
+ <value>26</value>
+ <name>26</name>
+ </option>
+ <option>
+ <value>27</value>
+ <name>27</name>
+ </option>
+ <option>
+ <value>28</value>
+ <name>28</name>
+ </option>
+ </options>
+ </field>
+ <field>
+ <fieldname>intervalrun</fieldname>
+ <fielddescr>Connection Speed:</fielddescr>
+ <description>Select the maximum speed your connection is capable of in either the up or down direction. This insure the connection is monitored appropriately.</description>
+ <required/>
+ <type>select</type>
+ <!--
+ 2mbit: 16384sec
+ 5mbit: 6553.6sec
+ 10mbit: 3276.8sec
+ 20mbit: 1638.4sec
+ 50mbit: 655.36sec
+ 100mbit: 327.68sec
+ 200mbit: 163.84sec
+ 500mbit: 65.536sec
+ 1gbit: 32sec
+ -->
+ <options>
+ <option>
+ <value>3000</value>
+ <name>10mbit</name>
+ </option>
+ <option>
+ <value>600</value>
+ <name>50mbit</name>
+ </option>
+ <option>
+ <value>280</value>
+ <name>100mbit</name>
+ </option>
+ <option>
+ <value>60</value>
+ <name>500mbit</name>
+ </option>
+ <option>
+ <value>30</value>
+ <name>1gbit</name>
+ </option>
+ </options>
+ </field>
+ <field>
+ <fieldname>ifmon</fieldname>
+ <fielddescr>Interface to Monitor:</fielddescr>
+ <description>Monitor all interfaces or only the WAN(internet) interfaces. When this is set to WAN, no stats are recorded for any other interfaces.</description>
+ <required/>
+ <type>select</type>
+ <options>
+ <option>
+ <value>wan</value>
+ <name>WAN</name>
+ </option>
+ <option>
+ <value>lan</value>
+ <name>LAN</name>
+ </option>
+ <option>
+ <value>all</value>
+ <name>All</name>
+ </option>
+ </options>
+ </field>
+ <field>
+ <fieldname>logging</fieldname>
+ <fielddescr>Debug Daemon:</fielddescr>
+ <description>Logging of the Daemon's actions to /tmp/ifbwstats.log. Warning, file is not managed and can become very large.</description>
+ <required/>
+ <type>select</type>
+ <options>
+ <option>
+ <value>yes</value>
+ <name>Yes</name>
+ </option>
+ <option>
+ <value>no</value>
+ <name>No</name>
+ </option>
+ </options>
+ </field>
+ </fields>
+ <custom_add_php_command_late>
+ kill_php_script();
+ start_php_script();
+ </custom_add_php_command_late>
+ <custom_php_install_command>
+ update_status ("Adding RC entries...");
+ ifbwstats_add_rc();
+ update_status ("Setting default values...");
+ ifbwstats_set_var();
+ update_status ("Adding CRON entry...");
+ ifbwstats_add_cron();
+ update_status ("Starting php script...");
+ start_php_script();
+ </custom_php_install_command>
+ <custom_php_deinstall_command>
+ update_status ("Kill php script...");
+ kill_php_script();
+ update_status ("Backup data files and remove tmp files...");
+ <![CDATA[
+ exec ('cp /tmp/ifbwstats-*.data /cf/conf/');
+ exec ('rm /tmp/ifbwstats*');
+ ]]>
+ update_status ("Removing RC entries...");
+ ifbwstats_remove_rc();
+ update_status ("Removing CRON entry...");
+ ifbwstats_remove_cron();
+ update_status ("Removing files...");
+ <![CDATA[
+ unlink_if_exists("/usr/local/www/ifbwstats_daily.php");
+ unlink_if_exists("/usr/local/www/ifbwstats_disp.php");
+ unlink_if_exists("/usr/local/www/ifbwstats_daemon.php");
+ unlink_if_exists("/usr/local/www/ifbwstats_cur.php");
+ unlink_if_exists("/usr/local/etc/rc.d/ifbwstats.sh");
+ ]]>
+ update_status ("Remove settings...");
+ ifbwstats_remove_var();
+ </custom_php_deinstall_command>
+</packagegui> \ No newline at end of file
diff --git a/config/ifbwstats/ifbwstats_cur.php b/config/ifbwstats/ifbwstats_cur.php
new file mode 100644
index 00000000..6cb4870e
--- /dev/null
+++ b/config/ifbwstats/ifbwstats_cur.php
@@ -0,0 +1,197 @@
+<?php
+/*
+ /usr/local/www/ifbwstats_daily.php
+
+ Contributed - 2010 - Zorac
+
+
+ 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("guiconfig.inc");
+require_once("ifbwstats.inc");
+$pgtitle = "ifBWStats: Daily Statistics For Current Billing Period";
+include("head.inc");
+
+usr1_php_script();
+
+//set first day of billing period from config, if hasn't been configed, assume the 1st
+if(!$config['installedpackages']['ifbwstats']['config'][0]['firstday']) $firstday = 1;
+else $firstday = $config['installedpackages']['ifbwstats']['config'][0]['firstday'];
+
+echo '<body>';
+include("fbegin.inc");
+echo '<p class="pgtitle">ifBWStats: Daily Statistics For Current Billing Period</p>';
+
+//find all valid data files for active and inactive interfaces
+//assume monitoring all interfaces
+$datafilestores = array();
+$n=0;
+
+//if only monitoring one inteface
+if ($config['installedpackages']['ifbwstats']['config'][0]['ifmon'] != 'all')
+{
+ //dont check conf directory, as if only one interface is being monitored, it must be used and therefore in the tmp dir
+ if (file_exists('/tmp/ifbwstats-'.$config['installedpackages']['ifbwstats']['config'][0]['ifmon'].'.data'))
+ {
+ $datafilestores[$n] = '/tmp/ifbwstats-'.$config['installedpackages']['ifbwstats']['config'][0]['ifmon'].'.data';
+ cleanup_data_file ($datafilestores[$n], $datafilestores[$n]);
+ $n++;
+ }
+}
+else
+{
+ if ($handle = opendir('/tmp'))
+ {
+ while (false !== ($file = readdir($handle)))
+ {
+ if ((preg_match ("/ifbwstats/", $file))&&(preg_match ("/.data/", $file)))
+ {
+ $datafilestores[$n] = '/tmp/'.$file;
+ cleanup_data_file ($datafilestores[$n], $datafilestores[$n]);
+ $n++;
+ }
+ }
+ }
+
+ if ($handle = opendir('/cf/conf'))
+ {
+ while (false !== ($file = readdir($handle)))
+ {
+ $filefound = 'no';
+ if ((preg_match ("/ifbwstats-/", $file))&&(preg_match ("/.data/", $file)))
+ {
+ for ($i = 0; $i < $n; $i++) if (preg_match ("/$file/", $datafilestores[$i])) $filefound = 'yes';
+ if ($filefound == 'no')
+ {
+ cleanup_data_file ('/cf/conf/'.$file, '/tmp/'.$file);
+ $datafilestores[$n] = '/tmp/'.$file;
+ $n++;
+ }
+ }
+ }
+ }
+}
+
+//display tabs
+echo '<table width="100%" border="0" cellpadding="0" cellspacing="0">';
+echo '<tr><td class="tabnavtbl">';
+$tab_array[0] = array ("Daily", true, "ifbwstats_cur.php");
+$tab_array[1] = array ("Monthly", false, "ifbwstats_disp.php");
+$tab_array[2] = array ("Settings", false, "pkg_edit.php?xml=ifbwstats.xml");
+display_top_tabs($tab_array);
+echo '</td></tr>';
+echo '<tr><td>';
+
+//cycle through all valid data files found
+foreach ($datafilestores as $wandataallfile)
+{
+//----------------------------------------begin file statistics monthly display----------------------------------------
+ //read data file
+ $fp = fopen($wandataallfile,"r") or die("Error Reading File");
+ $data = fread($fp, filesize($wandataallfile));
+ fclose($fp);
+ $wandataall = explode("\n", $data);
+ $n = count($wandataall);
+
+ $monthintotal = 0;
+ $monthouttotal = 0;
+
+ $interfacename = str_replace('.data', '', $wandataallfile);
+ $interfacename = str_replace('/tmp/ifbwstats-', '', $interfacename);
+ $interfacename = str_replace('/cf/conf/ifbwstats-', '', $interfacename);
+
+ echo '<div id="mainarea">';
+ echo '<table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">';
+ echo '<tr><td><font size=+1><b>'.$interfacename.' Statistics Summary</b></font></<td></tr>';
+ echo '<tr><td>';
+ echo '<table width="700px" border="0" cellpadding="0" cellspacing="0">';
+ echo '<tr>';
+ echo '<td width="175px" class="listhdrr">Date</td>';
+ echo '<td width="175px" class="listhdrr">Downloaded</b></td>';
+ echo '<td width="175px" class="listhdrr">Uploaded</b></td>';
+ echo '<td width="175px" class="listhdrr">Total Transfered</td>';
+ echo '</tr>';
+ echo '</table>';
+ echo '</td></tr><tr><td>';
+ echo '<div>';
+ echo '<table width="700px" border="0" cellpadding="0" cellspacing="0">';
+ $htmlcode = '';
+ for ($i=0 ; $i < $n ; $i++ )
+ {
+ $dataset=explode("|", $wandataall[$i]);
+ $dateset=explode("-", $dataset[0]);
+ $monthintotal = $monthintotal + $dataset[1];
+ $monthouttotal = $monthouttotal + $dataset[2];
+ $total = round((($dataset[1]+$dataset[2])/1024/1024/1024),2);
+ $dataset[1] = round(($dataset[1]/1024/1024),2);
+ $dataset[2] = round(($dataset[2]/1024/1024),2);
+
+ //show daily stats
+ $htmlcode = $htmlcode.'<tr><td width="175px" class="listlr">'.$dataset[0].'</td><td width="175px" class="listlr">'.$dataset[1].'MB</td><td width="175px" class="listlr">'.$dataset[2].'MB</td><td width="175px" class="listlr">'.$total.'GB</td></tr>';
+
+ //if there is no more data, show month
+ if (($n-1) == $i)
+ {
+ $total = round((($monthintotal + $monthouttotal)/1024/1024/1024),2);
+ $monthintotal = round(($monthintotal/1024/1024/1024),2);
+ $monthouttotal = round(($monthouttotal/1024/1024/1024),2);
+
+ $htmlcode = $htmlcode.'<tr><td width="175px" class="listlr"><b>Current Month Total</b></td><td width="175px" class="listlr"><b>&#8595;'.$monthintotal.'GB</b></td><td width="175px" class="listlr"><b>&#8593;'.$monthouttotal.'GB</b></td><td width="175px" class="listlr"><b>&#8597;'.$total.'GB</b></td></tr>';
+ echo $htmlcode;
+ }
+ //if at the end of the billing cycle, erase month htlmcode as we only want to show the current month
+ if ($dateset[2] == ($firstday-1))
+ {
+ $htmlcode = '';
+ $monthintotal = 0;
+ $monthouttotal = 0;
+ }
+
+ //if the billing cycle starts on the first day of the month, figure out the last day of the previous month, and if appropriate erase htmlcode
+ if ($firstday == '1')
+ {
+ //find the last day of the month
+ $maxday = date("t", strtotime($dateset[0]."-".$dateset[1]."-".$dateset[2]));
+ if ($dateset[2]==$maxday)
+ {
+ $htmlcode = '';
+ $monthintotal = 0;
+ $monthouttotal = 0;
+ }
+ }
+ }
+ echo '</table>';
+ echo '</div>';
+ echo '</td></tr></table>';
+ echo '</div>';
+ unset ($writedata);
+//----------------------------------------end file statistics monthly display----------------------------------------
+}
+//end foreach loop
+echo '</tr></td>';
+echo '</table>';
+
+include("fend.inc");
+echo '</body>';
+echo '</html>';
+?> \ No newline at end of file
diff --git a/config/ifbwstats/ifbwstats_daemon.php b/config/ifbwstats/ifbwstats_daemon.php
new file mode 100644
index 00000000..17026fba
--- /dev/null
+++ b/config/ifbwstats/ifbwstats_daemon.php
@@ -0,0 +1,352 @@
+<?php
+/*
+ /usr/local/www/ifbwstats_daemon.php
+
+ Contributed - 2010 - Zorac
+
+ interface read code using netstat as identifed below from
+ /usr/local/www/ifstats.php
+ Copyright (C) 2005-2006 Scott Ullrich (sullrich@gmail.com)
+ 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.
+
+ command to run
+ /usr/local/bin/php -q /usr/local/www/ifbwstats_daemon.php &
+
+ command to interupt
+ kill -INT pid
+ kill -INT `cat /var/run/ifbwstats.lock`
+
+ command to force interface read without quitting daemon
+ kill -USR1 pid
+ kill -USR1 `cat /var/run/ifbwstats.lock`
+*/
+
+//required for SIGINT and SIGUSR1
+declare(ticks = 1);
+
+//allow php to run as a daemon and not time out
+set_time_limit(0);
+
+require_once("config.inc");
+define( 'LOCK_FILE', "/var/run/ifbwstats.lock" );
+
+function isLocked()
+{
+ # If lock file exists, check if stale. If exists and is not stale, return TRUE
+ # Else, create lock file and return FALSE.
+
+ if( file_exists( LOCK_FILE ) )
+ {
+ # check if it's stale
+ $lockingPID = trim( file_get_contents( LOCK_FILE ) );
+
+ # Get all active PIDs.
+ $pids = explode( "\n", trim( `ps | awk '{print $1}'` ) );
+
+ # If PID is still active, return true
+ if( in_array( $lockingPID, $pids ) )
+ {
+ return true;
+ }
+
+ # Lock-file is stale, so kill it. Then move on to re-creating it.
+ unlink( LOCK_FILE );
+ }
+ file_put_contents( LOCK_FILE, getmypid() . "\n" );
+ return false;
+}
+
+function sig_handler($signo)
+{
+ global $logfile;
+ switch ($signo)
+ {
+ case SIGTERM:
+ if (isset($logfile)) fwrite($logfile, date('Y-m-d H:i:s')." SIGTERM ".getmypid()." \n");
+ break;
+ case SIGINT:
+ global $_MYDAEMON_SHOULD_STOP;
+ $_MYDAEMON_SHOULD_STOP = true;
+ if (isset($logfile)) fwrite($logfile, date('Y-m-d H:i:s')." SIGINT ".getmypid()." \n");
+ break;
+ case SIGUSR1:
+ global $_MYDAEMON_SHOULD_QUERY;
+ $_MYDAEMON_SHOULD_QUERY = true;
+ if (isset($logfile)) fwrite($logfile, date('Y-m-d H:i:s')." SIGUSR1 ".getmypid()." \n");
+ break;
+ }
+}
+
+function interface_query($if)
+{
+ global $config;
+ global $g;
+
+ //set data files for appropriate interface
+ $wandatalastfile = '/tmp/ifbwstats-'.$if.'.last';
+ $wandataallfile = '/tmp/ifbwstats-'.$if.'.data';
+ $wandatabackupfile = '/cf/conf/ifbwstats-'.$if.'.data';
+
+ //assume max is 4GB because of the 32bit counter wrap
+ $maxbytesin = 4294967296;
+ $maxbytesout = 4294967296;
+
+ //create (or clear if already used) variables
+ $wandatacurrent = array();
+ $wandatalast = array();
+ $wandataall = array();
+
+ //----------start modified code insert from ifstats.php----------
+ $ifinfo = array();
+
+ $ifinfo['hwif'] = $config['interfaces'][$if]['if'];
+ if(!$ifinfo['hwif'])
+ $ifinfo['hwif'] = $if;
+
+ $ifinfo['if'] = $ifinfo['hwif'];
+
+ /* run netstat to determine link info */
+ $linkinfo = "";
+ unset($linkinfo);
+ exec("/usr/bin/netstat -I " . $ifinfo['hwif'] . " -nWb -f link", $linkinfo);
+ $linkinfo = preg_split("/\s+/", $linkinfo[1]);
+ if (preg_match("/\*$/", $linkinfo[0])) {
+ $ifinfo['status'] = "down";
+ } else {
+ $ifinfo['status'] = "up";
+ }
+
+ if(preg_match("/^enc|^tun/i", $ifinfo['if'])) {
+ $ifinfo['inbytes'] = $linkinfo[5];
+ $ifinfo['outbytes'] = $linkinfo[8];
+ } else {
+ $ifinfo['inbytes'] = $linkinfo[6];
+ $ifinfo['outbytes'] = $linkinfo[9];
+ }
+ //----------end modified code insert from ifstats.php----------
+
+ //check for errors
+ if ((file_exists($wandatalastfile)) && ($ifinfo['inbytes'] == 0) && ($ifinfo['outbytes'] == 0))
+ {
+ $ifinfo['status'] = "down";
+ }
+
+ if (is_NaN($ifinfo['inbytes']) || is_NaN($outinfo['inbytes']))
+ {
+ $ifinfo['status'] = "down";
+ }
+
+ if ($ifinfo['status'] == "up")
+ {
+ $wandatacurrent[0] = $ifinfo['inbytes'];
+ $wandatacurrent[1] = $ifinfo['outbytes'];
+
+ if (file_exists($wandatalastfile))
+ {
+ //read last read file
+ $wandatalast = explode("|", file_get_contents($wandatalastfile));
+ }
+ else
+ {
+ $wandatalast = $wandatacurrent;
+ }
+
+ if (!is_numeric($wandatalast[0]) || is_NaN($wandatalast[1]))
+ {
+ $wandatalast = $wandatacurrent;
+ }
+
+ $fp = fopen($wandatalastfile,"w") or die("Error Reading File");
+ fwrite($fp, $wandatacurrent[0].'|'.$wandatacurrent[1]);
+ fclose($fp);
+
+ //account for 4gig counter reset
+ if ($wandatacurrent[0] < $wandatalast[0]) $inbytes = ((4294967296 - $wandatalast[0]) + $wandatacurrent[0]);
+ else $inbytes = $wandatacurrent[0] - $wandatalast[0];
+ if ($wandatacurrent[1] < $wandatalast[1]) $outbytes = ((4294967296 - $wandatalast[1]) + $wandatacurrent[1]);
+ else $outbytes = $wandatacurrent[1] - $wandatalast[1];
+
+ //check to make sure inbytes and outbytes are possible, if not, 0 both and erase last data as it may be corrupt
+ if (($inbytes < 0) || ($inbytes > $maxbytesin) || ($outbytes < 0) || ($outbytes > $maxbytesout))
+ {
+ $inbytes = 0;
+ $outbytes = 0;
+ if (file_exists($wandatalastfile)) unlink ($wandatalastfile);
+ }
+
+ $foundfile = 'null';
+ if (file_exists($wandataallfile)) $foundfile = $wandataallfile;
+ else
+ {
+ if (file_exists($wandatabackupfile)) $foundfile = $wandatabackupfile;
+ }
+
+ //if no file is found, create new data, else read file and add to existing data
+ if ($foundfile == 'null')
+ {
+ $wanwritedata = date("Y-m-d").'|'.$inbytes.'|'.$outbytes;
+ }
+ else
+ {
+ //read data file
+ $wandataall = explode("\n", file_get_contents($foundfile));
+ $n = count($wandataall);
+
+ //if last line of data date matchs current date, add to totals, else add new line
+ $dataset = explode("|", $wandataall[$n-1]);
+ if ($dataset[0] == date("Y-m-d"))
+ {
+ $dataset[1]=$dataset[1]+$inbytes;
+ $dataset[2]=$dataset[2]+$outbytes;
+ $wandataall[$n-1]=$dataset[0].'|'.$dataset[1].'|'.$dataset[2];
+ }
+ else
+ {
+ $wandataall[$n] = date("Y-m-d").'|'.$inbytes.'|'.$outbytes;
+ }
+
+ //number of data entries (days)
+ $n = count($wandataall);
+
+ //if more than three years worth of data, trim data to 4 years (1460 days)
+ $start = 0;
+ if ($n > 1460) $start = $n - 1460;
+
+ //generate file data to write
+ for ($i=$start ; $i < ($n-1) ; $i++ ) $wanwritedata = $wanwritedata.$wandataall[$i]."\n";
+ $wanwritedata = $wanwritedata.$wandataall[$n-1];
+ }
+
+ //write data file
+ $fp = fopen($wandataallfile,"w") or die("Error Reading File");
+ fwrite($fp, $wanwritedata);
+ fclose($fp);
+ }
+ else
+ {
+ if (file_exists($wandatalastfile)) unlink ($wandatalastfile);
+ }
+}
+
+pcntl_signal(SIGTERM, 'sig_handler');
+pcntl_signal(SIGINT, 'sig_handler');
+pcntl_signal(SIGUSR1, 'sig_handler');
+
+global $config;
+global $g;
+global $_MYDAEMON_SHOULD_STOP;
+global $_MYDAEMON_SHOULD_QUERY;
+
+//logging -> yes or no
+$logging = $config['installedpackages']['ifbwstats']['config'][0]['logging'];
+
+if ($logging == 'yes')
+{
+ global $logfile;
+ $logfile = fopen("/tmp/ifbwstats-daemon.log","a") or die("Error Reading File");
+ $parentpid = getmypid();
+ fwrite($logfile, date('Y-m-d H:i:s')." Startup - Parent PID is: ".$parentpid."\n");
+}
+
+if ($g['platform'] == 'cdrom')
+{
+ fwrite($logfile, date('Y-m-d H:i:s')." Daemon will not run on CD Rom platform, exiting... \n");
+ fclose ($logfile);
+ exit ();
+}
+if (isLocked())
+{
+ if ($logging == 'yes') fwrite($logfile, date('Y-m-d H:i:s')." Daemon is already running, exiting second instance (".getmypid().") \n");
+ fclose ($logfile);
+ exit ();
+}
+
+// endless loop
+while (1)
+{
+ if (isset($_MYDAEMON_SHOULD_STOP) AND $_MYDAEMON_SHOULD_STOP) break;
+ $pidA = pcntl_fork();
+ if($pidA)
+ {
+ // parent process runs here
+ // wait until the child has finished processing then end the script
+ pcntl_waitpid($pid, $status, WUNTRACED);
+ //calc seconds to midnight
+ $sleeptime = (mktime(23, 59, 55, date ('m, d, Y'))) - time();
+ //use whichever is less, seconds to midnight or interval, running script just prior to midnight insure accurate daily reporting as standard timing interval could be as great at 50min
+ if (($sleeptime > $config['installedpackages']['ifbwstats']['config'][0]['intervalrun']) || ($sleeptime < 5)) $sleeptime = $config['installedpackages']['ifbwstats']['config'][0]['intervalrun'];
+ if ($logging == 'yes') fwrite($logfile, date('Y-m-d H:i:s')." Parent (".$parentpid.") Sleep for: ".$sleeptime."\n");
+ for ($i=0; $i<$sleeptime; $i++)
+ {
+ if ((isset($_MYDAEMON_SHOULD_QUERY) AND $_MYDAEMON_SHOULD_QUERY) || (isset($_MYDAEMON_SHOULD_STOP) AND $_MYDAEMON_SHOULD_STOP))
+ {
+ $_MYDAEMON_SHOULD_QUERY = false;
+ break;
+ }
+ else sleep (1);
+ }
+ }
+ else
+ {
+ //child process runs here
+ if ($logging == 'yes') fwrite($logfile, date('Y-m-d H:i:s')." Child Process ". getmypid(). " Reading Interfaces... (Parent: ".$parentpid.")\n");
+ if ($config['installedpackages']['ifbwstats']['config'][0]['ifmon'] != 'all') interface_query($config['installedpackages']['ifbwstats']['config'][0]['ifmon']);
+ else
+ {
+ foreach ($config[interfaces] as $if => $value)
+ {
+ interface_query($if);
+ }
+ }
+ exit (0);
+ }
+}
+
+//run query one last time
+if ($logging == 'yes') fwrite($logfile, date('Y-m-d H:i:s')." Parent Process ". getmypid(). " Reading Interfaces One Last Time... \n");
+if ($config['installedpackages']['ifbwstats']['config'][0]['ifmon'] != 'all') interface_query($config['installedpackages']['ifbwstats']['config'][0]['ifmon']);
+else
+{
+ foreach ($config[interfaces] as $if => $value)
+ {
+ interface_query($if);
+ }
+}
+// backup data files to conf dir on exit
+if ($g['platform'] != 'pfSense') exec ('/etc/rc.conf_mount_rw');
+exec('cp /tmp/ifbwstats-*.data /cf/conf/');
+if ($g['platform'] != 'pfSense') exec ('/etc/rc.conf_mount_ro');
+
+if ($logging == 'yes')
+{
+ fwrite($logfile, date('Y-m-d H:i:s')." Shutdown Parent ".$parentpid." \n");
+ fclose ($logfile);
+}
+
+if( file_exists( LOCK_FILE ) ) unlink( LOCK_FILE );
+
+exit (0);
+
+?>
+
diff --git a/config/ifbwstats/ifbwstats_daily.php b/config/ifbwstats/ifbwstats_daily.php
new file mode 100644
index 00000000..1bd29ea2
--- /dev/null
+++ b/config/ifbwstats/ifbwstats_daily.php
@@ -0,0 +1,142 @@
+<?php
+/*
+ /usr/local/www/ifbwstats_daily.php
+
+ Contributed - 2010 - Zorac
+
+
+ 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.
+*/
+
+ // determine which month to displayed
+
+ if (isset($_SERVER['REQUEST_URI']))
+ {
+ $url = $_SERVER['REQUEST_URI'];
+ }
+ else
+ {
+ $url = $_SERVER['SCRIPT_NAME'];
+ $url .= (!empty($_SERVER['QUERY_STRING'])) ? '?' . $_SERVER['QUERY_STRING'] : '';
+ }
+
+ $parsed_url = parse_url($url);
+ if (isset($parsed_url['query']))
+ {
+ $queryparts = explode("&", $parsed_url['query']);
+ }
+
+require_once("guiconfig.inc");
+require_once("ifbwstats.inc");
+
+usr1_php_script();
+
+$interfacename = str_replace('.data', '', $queryparts[0]);
+$interfacename = str_replace('/tmp/ifbwstats-', '', $interfacename);
+$interfacename = str_replace('/cf/conf/ifbwstats-', '', $interfacename);
+
+$pgtitle = "ifBWStats: Archived Daily Statistics For ".$interfacename;
+include("head.inc");
+
+echo '<body>';
+include("fbegin.inc");
+echo '<p class="pgtitle">ifBWStats: Daily Statistics For '.$interfacename.'</p>';
+echo '<b>Month Ending: '.str_replace('%20', ' ', $queryparts[3]).'</b><br><br>';
+
+//display tabs
+echo '<table width="100%" border="0" cellpadding="0" cellspacing="0">';
+echo '<tr><td class="tabnavtbl">';
+$tab_array[0] = array ("Daily", false, "ifbwstats_cur.php");
+$tab_array[1] = array ("Monthly", false, "ifbwstats_disp.php");
+$tab_array[2] = array ("Settings", false, "pkg_edit.php?xml=ifbwstats.xml");
+$tab_array[3] = array ("Archive", true, $url);
+display_top_tabs($tab_array);
+echo '</td></tr>';
+echo '<tr><td>';
+echo '<div id="mainarea">';
+
+$foundfile = 'null';
+if (file_exists($queryparts[0])) $foundfile = $queryparts[0];
+if ($foundfile == 'null')
+{
+ echo 'Sorry, no data file found.';
+}
+else
+{
+ $fp = fopen($foundfile,"r") or die("Error Reading File");
+ $data = fread($fp, filesize($foundfile));
+ fclose($fp);
+ $wandataall = explode("\n", $data);
+ $n = count($wandataall);
+
+ $monthintotal = 0;
+ $monthouttotal = 0;
+ $monthdaystart = 0;
+
+ echo '<table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">';
+ echo '<tr>';
+ echo '<td width="175px" class="listhdrr">Date</td>';
+ echo '<td width="175px" class="listhdrr">Downloaded</b></font></td>';
+ echo '<td width="175px" class="listhdrr">Uploaded</b></font></td>';
+ echo '<td width="175px" class="listhdrr">Total Transfered</td>';
+ echo '</tr>';
+
+ for ($i=$queryparts[1] ; $i < $queryparts[2]+1 ; $i++ )
+ {
+ $dataset=explode("|", $wandataall[$i]);
+ $dateset=explode("-", $dataset[0]);
+ $monthintotal = $monthintotal + $dataset[1];
+ $monthouttotal = $monthouttotal + $dataset[2];
+ $total = round((($dataset[1]+$dataset[2])/1024/1024/1024),2);
+ $dataset[1] = round(($dataset[1]/1024/1024),2);
+ $dataset[2] = round(($dataset[2]/1024/1024),2);
+
+ echo '<tr>';
+ echo '<td width="175px" class="listlr">'.$dataset[0].'</td>';
+ echo '<td width="175px" class="listlr">'.$dataset[1].'MB</td>';
+ echo '<td width="175px" class="listlr">'.$dataset[2].'MB</td>';
+ echo '<td width="175px" class="listlr">'.$total.'GB</td>';
+ echo '</tr>';
+ }
+
+ $total = round((($monthintotal + $monthouttotal)/1024/1024/1024),2);
+ $monthintotal = round(($monthintotal/1024/1024/1024),2);
+ $monthouttotal = round(($monthouttotal/1024/1024/1024),2);
+
+ echo '<tr>';
+ echo '<td width="175px" class="listlr"><b>Month Totals</b></td>';
+ echo '<td width="175px" class="listlr"><b>&#8595;'.$monthintotal.'GB</b></td>';
+ echo '<td width="175px" class="listlr"><b>&#8593;'.$monthouttotal.'GB</b></td>';
+ echo '<td width="175px" class="listlr"><b>&#8597;'.$total.'GB</b></td>';
+ echo '</tr>';
+ echo '</table>';
+}
+
+echo '</div>';
+echo '</tr></td>';
+echo '</table>';
+
+include("fend.inc");
+echo '</body>';
+echo '</html>';
+
+?> \ No newline at end of file
diff --git a/config/ifbwstats/ifbwstats_disp.php b/config/ifbwstats/ifbwstats_disp.php
new file mode 100644
index 00000000..c949b6cb
--- /dev/null
+++ b/config/ifbwstats/ifbwstats_disp.php
@@ -0,0 +1,206 @@
+<?php
+/*
+ /usr/local/www/ifbwstats_disp.php
+
+ Contributed - 2010 - Zorac
+
+
+ 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("guiconfig.inc");
+require_once("ifbwstats.inc");
+$pgtitle = "ifBWStats: Monthly Statistics";
+include("head.inc");
+
+usr1_php_script();
+
+//set first day of billing period from config, if hasn't been configed, assume the 1st
+if(!$config['installedpackages']['ifbwstats']['config'][0]['firstday']) $firstday = 1;
+else $firstday = $config['installedpackages']['ifbwstats']['config'][0]['firstday'];
+
+echo '<body>';
+include("fbegin.inc");
+echo '<p class="pgtitle">ifBWStats: Monthly Statistics</p>';
+
+//find all valid data files for active and inactive interfaces
+//assume monitoring all interfaces
+$datafilestores = array();
+$n=0;
+
+//if only monitoring one inteface
+if ($config['installedpackages']['ifbwstats']['config'][0]['ifmon'] != 'all')
+{
+ //dont check conf directory, as if only one interface is being monitored, it must be used and therefore in the tmp dir
+ if (file_exists('/tmp/ifbwstats-'.$config['installedpackages']['ifbwstats']['config'][0]['ifmon'].'.data'))
+ {
+ $datafilestores[$n] = '/tmp/ifbwstats-'.$config['installedpackages']['ifbwstats']['config'][0]['ifmon'].'.data';
+ cleanup_data_file ($datafilestores[$n], $datafilestores[$n]);
+ $n++;
+ }
+}
+else
+{
+ if ($handle = opendir('/tmp'))
+ {
+ while (false !== ($file = readdir($handle)))
+ {
+ if ((preg_match ("/ifbwstats/", $file))&&(preg_match ("/.data/", $file)))
+ {
+ $datafilestores[$n] = '/tmp/'.$file;
+ cleanup_data_file ($datafilestores[$n], $datafilestores[$n]);
+ $n++;
+ }
+ }
+ }
+
+ if ($handle = opendir('/cf/conf'))
+ {
+ while (false !== ($file = readdir($handle)))
+ {
+ $filefound = 'no';
+ if ((preg_match ("/ifbwstats-/", $file))&&(preg_match ("/.data/", $file)))
+ {
+ for ($i = 0; $i < $n; $i++) if (preg_match ("/$file/", $datafilestores[$i])) $filefound = 'yes';
+ if ($filefound == 'no')
+ {
+ cleanup_data_file ('/cf/conf/'.$file, '/tmp/'.$file);
+ $datafilestores[$n] = '/tmp/'.$file;
+ $n++;
+ }
+ }
+ }
+ }
+}
+
+//display tabs
+echo '<table width="100%" border="0" cellpadding="0" cellspacing="0">';
+echo '<tr><td class="tabnavtbl">';
+$tab_array[0] = array ("Daily", false, "ifbwstats_cur.php");
+$tab_array[1] = array ("Monthly", true, "ifbwstats_disp.php");
+$tab_array[2] = array ("Settings", false, "pkg_edit.php?xml=ifbwstats.xml");
+display_top_tabs($tab_array);
+echo '</td></tr>';
+echo '<tr><td>';
+
+//cycle through all valid data files found
+foreach ($datafilestores as $wandataallfile)
+{
+//----------------------------------------begin file statistics monthly display----------------------------------------
+ //read data file
+ $fp = fopen($wandataallfile,"r") or die("Error Reading File");
+ $data = fread($fp, filesize($wandataallfile));
+ fclose($fp);
+ $wandataall = explode("\n", $data);
+ $n = count($wandataall);
+
+ $monthintotal = 0;
+ $monthouttotal = 0;
+ $monthdaystart = 0;
+
+ $interfacename = str_replace('.data', '', $wandataallfile);
+ $interfacename = str_replace('/tmp/ifbwstats-', '', $interfacename);
+ $interfacename = str_replace('/cf/conf/ifbwstats-', '', $interfacename);
+
+ echo '<div id="mainarea">';
+ echo '<table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">';
+ echo '<tr><td><font size=+1><b>'.$interfacename.' Statistics Summary</b></font></<td></tr>';
+ echo '<tr><td>';
+ echo '<table width="700px" border="0" cellpadding="0" cellspacing="0">';
+ echo '<tr>';
+ echo '<td width="175px" class="listhdrr">Month Ending</td>';
+ echo '<td width="175px" class="listhdrr">Downloaded</b></td>';
+ echo '<td width="175px" class="listhdrr">Uploaded</b></td>';
+ echo '<td width="175px" class="listhdrr">Total Transfered</td>';
+ echo '</tr>';
+ echo '</table>';
+ echo '</td></tr><tr><td>';
+ echo '<div>';
+ //echo '<div style="overflow: auto; height: 400px"; width: 620px>';
+ echo '<table width="700px" border="0" cellpadding="0" cellspacing="0">';
+
+ for ($i=0 ; $i < $n ; $i++ )
+ {
+ $dataset=explode("|", $wandataall[$i]);
+ $dateset=explode("-", $dataset[0]);
+ $monthintotal = $monthintotal + $dataset[1];
+ $monthouttotal = $monthouttotal + $dataset[2];
+ $total = round((($dataset[1]+$dataset[2])/1024/1024/1024),2);
+ $dataset[1] = round(($dataset[1]/1024/1024),2);
+ $dataset[2] = round(($dataset[2]/1024/1024),2);
+
+ //show daily stats
+ /*echo '<tr>';
+ echo '<td width="175px" class="listlr">'.$dataset[0].'</td>';
+ echo '<td width="175px" class="listlr">'.$dataset[1].'MB</td>';
+ echo '<td width="175px" class="listlr">'.$dataset[2].'MB</td>';
+ echo '<td width="175px" class="listlr">'.$total.'GB</td>';
+ echo '</tr>';*/
+
+ //as data file saved by day, determin if a monthy total is required to be shown based on setting 'first day of billing period'
+ $showmonth = '0';
+
+ //if at the end of the billing cycle show month totals, 1 to indicate that a full billing period has passed and to show a 'month end' total
+ if ($dateset[2] == ($firstday-1)) $showmonth = '1';
+ //if there is no more data, show month totals, 2 to show 'current month'
+ if (($n-1) == $i) $showmonth = '2';
+ //if the billing cycle starts on the first day of the month, figure out the last day of the previous month, and if appropriate show month totals
+ if ($firstday == '1')
+ {
+ //find the last day of the month
+ $maxday = date("t", strtotime($dateset[0]."-".$dateset[1]."-".$dateset[2]));
+ if ($dateset[2]==$maxday) $showmonth = '1';
+ }
+
+ if (($showmonth == '1')||($showmonth == '2'))
+ {
+ $total = round((($monthintotal + $monthouttotal)/1024/1024/1024),2);
+ $monthintotal = round(($monthintotal/1024/1024/1024),2);
+ $monthouttotal = round(($monthouttotal/1024/1024/1024),2);
+ if ($showmonth == '2') $dataset[0]='Current%20Month';
+
+ echo '<tr>';
+ echo '<td width="175px" class="listlr"><a href="http://'.$_SERVER['SERVER_NAME'].'/ifbwstats_daily.php?'.$wandataallfile.'&'.$monthdaystart.'&'.$i.'&'.$dataset[0].'">'.str_replace('%20', ' ', $dataset[0]).'</a></td>';
+ echo '<td width="175px" class="listlr">&#8595;'.$monthintotal.'GB</td>';
+ echo '<td width="175px" class="listlr">&#8593;'.$monthouttotal.'GB</td>';
+ echo '<td width="175px" class="listlr">&#8597;'.$total.'GB</td>';
+ echo '</tr>';
+ $monthdaystart = $i + 1;
+ $monthintotal = 0;
+ $monthouttotal = 0;
+ }
+ }
+ echo '</table>';
+ echo '</div>';
+ echo '</td></tr></table>';
+ echo '</div>';
+ unset ($writedata);
+//----------------------------------------end file statistics monthly display----------------------------------------
+}
+//end foreach loop
+echo '</tr></td>';
+echo '</table>';
+
+include("fend.inc");
+echo '</body>';
+echo '</html>';
+?> \ No newline at end of file
diff --git a/pkg_config.7.xml b/pkg_config.7.xml
index 7c5123eb..62605b26 100755
--- a/pkg_config.7.xml
+++ b/pkg_config.7.xml
@@ -1086,5 +1086,16 @@
<required_version>1.2.3</required_version>
<maximum_version>1.2.3</maximum_version>
</package>
+ <package>
+ <name>ifBWStats</name>
+ <website/>
+ <descr>Interface Bandwidth Stats. Tracks data usage on each interface. Helpful if your isp caps your montly data usage. No dependancies (ie rrd).</descr>
+ <category>Diagnostics</category>
+ <config_file>http://192.168.0.5/packages/config/ifbwstats/ifbwstats.xml</config_file>
+ <version>1.0</version>
+ <status>Beta</status>
+ <required_version>1.2.3</required_version>
+ <configurationfile>ifbwstats.xml</configurationfile>
+ </package>
</packages>
</pfsensepkgs>
diff --git a/pkg_config.8.xml b/pkg_config.8.xml
index 8eb39653..557db4b6 100755
--- a/pkg_config.8.xml
+++ b/pkg_config.8.xml
@@ -927,5 +927,16 @@
<config_file>http://www.pfsense.org/packages/config/rrd-summary/rrd-summary.xml</config_file>
<configurationfile>rrd-summary.xml</configurationfile>
</package>
+ <package>
+ <name>ifBWStats</name>
+ <website/>
+ <descr>Interface Bandwidth Stats. Tracks data usage on each interface. Helpful if your isp caps your montly data usage. No dependancies (ie rrd).</descr>
+ <category>Diagnostics</category>
+ <config_file>http://192.168.0.5/packages/config/ifbwstats/ifbwstats.xml</config_file>
+ <version>1.0</version>
+ <status>Beta</status>
+ <required_version>1.2.3</required_version>
+ <configurationfile>ifbwstats.xml</configurationfile>
+ </package>
</packages>
</pfsensepkgs>
diff --git a/pkg_config.8.xml.amd64 b/pkg_config.8.xml.amd64
index 4ec12877..89ea2dae 100755
--- a/pkg_config.8.xml.amd64
+++ b/pkg_config.8.xml.amd64
@@ -945,5 +945,16 @@
<config_file>http://www.pfsense.org/packages/config/rrd-summary/rrd-summary.xml</config_file>
<configurationfile>rrd-summary.xml</configurationfile>
</package>
+ <package>
+ <name>ifBWStats</name>
+ <website/>
+ <descr>Interface Bandwidth Stats. Tracks data usage on each interface. Helpful if your isp caps your montly data usage. No dependancies (ie rrd).</descr>
+ <category>Diagnostics</category>
+ <config_file>http://192.168.0.5/packages/config/ifbwstats/ifbwstats.xml</config_file>
+ <version>1.0</version>
+ <status>Beta</status>
+ <required_version>1.2.3</required_version>
+ <configurationfile>ifbwstats.xml</configurationfile>
+ </package>
</packages>
</pfsensepkgs> \ No newline at end of file