#!/usr/bin/perl

#################################################
# Traffic Grapher add on for Cricket.
# Written by Dave Kelly (dkelly@inav.net)
# v1.3.
#
# 1/11/01 - Changed 'exists' to 'defined', because 'exists' is deprecated.
#           Thanks to Dan Spray for pointing this out (cpdans@conpoint.com)
#
#################################################


# Directory where this program resides
$rootdir = "/home/cricket/cricket/util";

# Name of the dbm file that hold rollovers and previous values
$dbmfile = $rootdir."/traffic.dbm";

# Upper threshold of the counter on the router before it rolls over
$rollthresh = 4294967296;


# Open this for use globally by everything in the script
dbmopen(%traffic, $dbmfile, 0666);


# This really needs better, or in fact, any, error handling.
if ($ARGV[0] eq "listall")
{
  &listall;
}
elsif ($ARGV[0] eq "reset")
{
  &reset;
}
elsif ($ARGV[0] eq "update")
{
  $name = $ARGV[1];
  $ip = $ARGV[2];
  $community = $ARGV[3];
  $inoid = $ARGV[4];
  $outoid = $ARGV[5];

  &update;
}
else
{
  print "Usage:\n";
  print "  traffic reset\n";
  print "  traffic update <name> <IP> <SNMP_community> <INCOMING_OID> <OUTGOING_OID>\n";
}

dbmclose(%traffic);

sub listall
{
  foreach $port (sort keys(%traffic))
  {
    local($myport) = $port;
    $myport =~ s/\w*\://;
    local($portlist);
    push(@portlist, $myport);
  }
  local($last) = 0;
  local($newvaluein) = 0;
  local($newvalueout) = 0;
  foreach $port (sort @portlist)
  {
    if ($port ne $last)		# Need this to keep from processing keys more than once
    {
      #
      # This gets spit out to stdout, and could easily be piped to an email via a cron as so:
      # traffic reset | mail -s "Period End usage report" address@domain.com
      #
      $newvaluein = (($rollthresh * $traffic{'rolloverin:'.$port}) + $traffic{'lastin:'.$port}) - $traffic{'offsetin:'.$port};
      $newvalueout = (($rollthresh * $traffic{'rolloverout:'.$port}) + $traffic{'lastout:'.$port}) - $traffic{'offsetout:'.$port};

      print "Period end summary for $port:\n";
#      print "Last reported incoming byte count: $traffic{'lastin:'.$port}\n";
#      print "Last reported outgoing byte count: $traffic{'lastout:'.$port}\n";
#      print "Incoming bytes rollover count: $traffic{'rolloverin:'.$port}\n";
#      print "Outgoing bytes rollover count: $traffic{'rolloverout:'.$port}\n";
      print "TOTAL INCOMING BYTES SINCE LAST RESET: $newvaluein\n";
      print "TOTAL OUTGOING BYTES SINCE LAST RESET: $newvalueout\n";
      print "\n\n\n";
      $last = $port;
    }
  }
}

sub reset
{
  foreach $port (sort keys(%traffic))
  {
    local($myport) = $port;
    $myport =~ s/\w*\://;
    local($portlist);
    push(@portlist, $myport);
  }
  local($last) = 0;
  local($newvaluein) = 0;
  local($newvalueout) = 0;
  foreach $port (sort @portlist)
  {
    if ($port ne $last)		# Need this to keep from processing keys more than once
    {
      #
      # This gets spit out to stdout, and could easily be piped to an email via a cron as so:
      # traffic reset | mail -s "Period End usage report" address@domain.com
      #
      $newvaluein = (($rollthresh * $traffic{'rolloverin:'.$port}) + $traffic{'lastin:'.$port}) - $traffic{'offsetin:'.$port};
      $newvalueout = (($rollthresh * $traffic{'rolloverout:'.$port}) + $traffic{'lastout:'.$port}) - $traffic{'offsetout:'.$port};

      print "Period end summary for $port:\n";
#      print "Last reported incoming byte count: $traffic{'lastin:'.$port}\n";
#      print "Last reported outgoing byte count: $traffic{'lastout:'.$port}\n";
#      print "Incoming bytes rollover count: $traffic{'rolloverin:'.$port}\n";
#      print "Outgoing bytes rollover count: $traffic{'rolloverout:'.$port}\n";
      print "TOTAL INCOMING BYTES SINCE LAST RESET: $newvaluein\n";
      print "TOTAL OUTGOING BYTES SINCE LAST RESET: $newvalueout\n";
      print "\n\n\n";
      &resetentry($port);
      $last = $port;
    }
  }
}



sub resetentry
{
  local($port) = @_;
  
  $traffic{"rolloverin:".$port} = "0";
  $traffic{"rolloverout:".$port} = "0";
  $traffic{"lastin:".$port} = "0";
  $traffic{"lastout:".$port} = "0";

  local($portval) = `snmpget $traffic{'ip:'.$port} $traffic{'community:'.$port} $traffic{'inoid:'.$port}`;
  $portval =~ s/.*\=\ //;
  chomp($portval);
  $traffic{"offsetin:".$port} = $portval;

  local($portval) = `snmpget $traffic{'ip:'.$port} $traffic{'community:'.$port} $traffic{'outoid:'.$port}`;
  $portval =~ s/.*\=\ //;
  chomp($portval);
  $traffic{"offsetout:".$port} = $portval;
}



sub update
{
  # We need to store these because they're used whenever we reset.
  $traffic{'ip:'.$name} = $ip;
  $traffic{'community:'.$name} = $community;
  $traffic{'inoid:'.$name} = $inoid;
  $traffic{'outoid:'.$name} = $outoid;

  if (!defined($traffic{'lastin:'.$name}))	# Assume that if this isn't here, we need to initialize (reset) to zero
  {
    &resetentry($name);
  }

  local($newbytesin) = `snmpget $ip $community $inoid`;
  local($newbytesout) = `snmpget $ip $community $outoid`;

  $newbytesin =~ s/.*\=\ //;
  chomp($newbytesin);

  $newbytesout =~ s/.*\=\ //;
  chomp($newbytesout);

  if ($newbytesin < $traffic{'lastin:'.$name})   #increment rollover
  {
    $traffic{'rolloverin:'.$name} = $traffic{'rolloverin:'.$name} + 1;
  }
  local($newvaluein) = (($rollthresh * $traffic{'rolloverin:'.$name}) + $newbytesin) - $traffic{'offsetin:'.$name};
    
  if ($newbytesout < $traffic{'lastout:'.$name})   #increment rollover
  {
    $traffic{'rolloverout:'.$name} = $traffic{'rolloverout:'.$name} + 1;
  }
  local($newvalueout) = (($rollthresh * $traffic{'rolloverout:'.$name}) + $newbytesout) - $traffic{'offsetout:'.$name};

  print "$newvaluein incoming bytes\n";
  print "$newvalueout outgoing bytes\n\n";

  $traffic{'lastin:'.$name} = $newbytesin;
  $traffic{'lastout:'.$name} = $newbytesout;
}
