#!/usr/bin/perl
#
# check_traffic v 0.90b - Nagios(r) network traffic monitor plugin
#
# Copyright (c) 2003 Adrian Wieczorek, <ads (at) irc.pila.pl>
#
# Send me bug reports, questions and comments about this plugin.
# Latest version of this software: http://adi.blink.pl/nagios
#
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307

$VERSION      = "0.90b";

$ENV{'PATH'}='';
$ENV{'BASH_ENV'}=''; 
$ENV{'ENV'}=''; 

$TRAFFIC_FILE = "/tmp/traffic";

# SNMP stuff:
$SNMPWALK     = "/usr/bin/snmpwalk";
$SNMPGET      = "/usr/bin/snmpget";
$COMMUNITY    = "public";

# RRD support:
$WITH_RRD     = 1;
$RRDTOOL      = "/usr/bin/rrdtool";
$DB_PATH      = "/usr/local/nagios/check_traffic-$VERSION/db";



my %STATUS_CODE = (  'UNKNOWN'  => '-1',
                     'OK'       => '0',
		     'WARNING'  => '1',
		     'CRITICAL' => '2'   );
							    
my ($in_bytes,$out_bytes) = 0;
my $warn_usage = 85;
my $crit_usage = 98;

if ($#ARGV == -1) { print_usage(); }

sub print_usage()
{
 print "Usage: check_traffic -H host -i if_number -b if_max_speed [-r if_description] [ -w warn ] [ -c crit ]\n\n";
 print "Options:\n";
 print " -H --host STRING or IPADDRESS\n";
 print "   Check interface on the indicated host.\n";
 print " -i --interface INTEGER\n";
 print "   Interface number assigned by SNMP agent.\n";
 print " -b --bps INTEGER\n";
 print "   Interface maximum speed in bytes per second.\n";
 print " -r --rrd STRING\n";
 print "   Interface description used to store values in correct RRD file.\n";
 print " -w --warning INTEGER\n";
 print "   % of bandwidth usage necessary to result in warning status\n";
 print " -c --critical INTEGER\n";
 print "   % of bandwidth usage necessary to result in critical status\n";
 exit($STATUS_CODE{"UNKNOWN"});
}

# - Initial arguments parsing
ARG:
while ($ARGV[0] =~ /^-/ ) 
{
 if ( $ARGV[0] =~/^-H|^--host/ ) 
 {
  $host_address = $ARGV[1];
  shift @ARGV;
  shift @ARGV;
  next ARG;
 }
 if ( $ARGV[0] =~/^-i|^--interface/ ) 
 {
  $iface_number = $ARGV[1];
  shift @ARGV;
  shift @ARGV;
  next ARG;
 }
 if ( $ARGV[0] =~/^-r|^--rrd/ ) 
 {
  $iface_descr = $ARGV[1];
  shift @ARGV;
  shift @ARGV;
  next ARG;
 }
 if ( $ARGV[0] =~/^-b|^--bps/ ) 
 {
  $iface_speed = $ARGV[1];
  shift @ARGV;
  shift @ARGV;
  next ARG;
 }
 if ( $ARGV[0] =~/^-w|^--warning/ ) 
 {
  $warn_usage = $ARGV[1];
  shift @ARGV;
  shift @ARGV;
  next ARG;
 }
 if ( $ARGV[0] =~/^-c|^--critical/ ) 
 {
  $crit_usage = $ARGV[1];
  shift @ARGV;
  shift @ARGV;
  next ARG;
 }
 print "Unknown flag: $ARGV[0]\n";
 exit($STATUS_CODE{"UNKNOWN"});
}

if((!$host_address) or (!$iface_number) or (!$iface_speed) or ($WITH_RRD and !$iface_descr)) 
{ 
 print_usage();
}

$_ = `$SNMPGET -v 1 $host_address -c $COMMUNITY interfaces.ifTable.ifEntry.ifInOctets.$iface_number`;

m/(\d*)\s$/;
$in_bytes = $1;

$_ = `$SNMPGET -v 1 $host_address -c $COMMUNITY interfaces.ifTable.ifEntry.ifOutOctets.$iface_number`;

m/(\d*)\s$/;
$out_bytes = $1;

open(FILE,"<".$TRAFFIC_FILE."_if".$iface_number."_".$host_address);
while($row = <FILE>)
{
 @last_values = split(":",$row);
 $last_check_time = $last_values[0];
 $last_in_bytes = $last_values[1];
 $last_out_bytes = $last_values[2];
}
close(FILE);

$update_time = time;

open(FILE,">".$TRAFFIC_FILE."_if".$iface_number."_".$host_address) or die "Can't open $TRAFFIC_FILE for writing: $!";
print FILE "$update_time:$in_bytes:$out_bytes";
close(FILE);

if($WITH_RRD)
{
 $db_file = $host_address."_".$iface_descr.".rrd";
 `$RRDTOOL update $DB_PATH/$db_file $update_time:$in_bytes:$out_bytes`;
}

$in_traffic = sprintf("%.2f",($in_bytes-$last_in_bytes)/(time-$last_check_time));
$out_traffic = sprintf("%.2f",($out_bytes-$last_out_bytes)/(time-$last_check_time));

$in_usage = sprintf("%.1f",($in_traffic*100)/$iface_speed);
$out_usage = sprintf("%.1f",($out_traffic*100)/$iface_speed);


if($in_traffic > 1024) 
{
 $in_traffic = sprintf("%.2f",$in_traffic/1024);
 $in_prefix = "k";
 if($in_traffic > 1024)
 {
  $in_traffic = sprintf("%.2f",$in_traffic/1024);
  $in_prefix = "M";
 }
}

if($out_traffic > 1024) 
{
 $out_traffic = sprintf("%.2f",$out_traffic/1024);
 $out_prefix = "k";
 if($out_traffic > 1024)
 {
  $out_traffic = sprintf("%.2f",$out_traffic/1024);
  $out_prefix = "M";
 }
}

$in_bytes = sprintf("%.2f",($in_bytes/1024)/1024);
$out_bytes = sprintf("%.2f",($out_bytes/1024)/1024);

print "Total RX Bytes: $in_bytes MB, Total TX Bytes: $out_bytes MB<br>";
print "Average Traffic: $in_traffic ".$in_prefix."B/s (".$in_usage."%) in, $out_traffic ".$out_prefix."B/s (".$out_usage."%) out";

if(($in_usage > $crit_usage) or ($out_usage > $crit_usage))
{
 print "<br>CRITICAL: (".$crit_usage."%) bandwidth utilization.\n";
 exit($STATUS_CODE{"CRITICAL"});
}

if(($in_usage > $warn_usage) or ($out_usage > $warn_usage))
{
 print "<br>WARNING: (".$warn_usage."%) bandwidth utilization.\n";
 exit($STATUS_CODE{"WARNING"});
}


exit($STATUS_CODE{"OK"});
