#!/usr/bin/perl
 
#-----------------------------------------------------------------------
# calculate_traffic.cgi
#
# $Id: calculate_traffic.cgi,v 1.7 1999/04/02 07:57:08 mrtg Exp $
#
# This cgi takes a log file name, a start date, and an
# end date as the three mandatory values passed to the script.
# It returns the total Octets In and Out from that interface
# between those two dates, inclusive.  The start date and 
# end date MUST be specified as: MM-DD-YYYY-HH:MM, and the
# start date MUST be earlier than the end date.
#-----------------------------------------------------------------------
 
#-----------------------------------------------------------------------
# GLOBALS
 
use strict;
use Time::Local;

require 5.004;
 
$| = 1 ;
 
my($DEBUG)     = 0;

my($topdir)    = "/";

my($datestr)   = "";
my($start_date)= "";
my($end_date)  = "";
my($logfile)   = "";

#-----------------------------------------------------------------------
 
#-----------------------------------------------------------------------
sub errorexit {
   print ("$0:  Error:  @_.\n");
   exit(21);
}
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
sub scale {
   my ($bits) = @_;
   ($bits =~ /^[\d.]+$/) or return "ERROR";
   my ($units) = "bps";
   foreach my $unit ("Kbps", "Mbps", "Gbps", "Tbps") {
      last unless ($bits / 1024 > 1);
      $bits = $bits / 1024;
      $units = $unit;
   }
   return sprintf "%0.2f %s", $bits, $units;
}
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
sub get_args {
   my($logfile,$start,$end,$start_str,$end_str);
   unless( $#ARGV == 2 ) {
      my($name) = `basename $0` ;
      $name =~ s/\s+//g ;
      print STDERR "usage: $name <logfile> <start_date> <end_date>\n" ;
      print STDERR "   where <start_date> and <end_date> are in the\n";
      print STDERR "   format: MM-DD-YYYY-HH:MM\n";
      exit(1) ;
   }
   $logfile = $ARGV[0];
   if (! -r $logfile) {
      &errorexit("Couldn't read $logfile: $!");
   }
   $start_str = $ARGV[1];
   $end_str = $ARGV[2];
   if (($start_str eq "") || ($end_str eq "")) {
      &errorexit("Sorry, null dates NOT allowed!");
   }
   $start_str =~ m/^(\d\d)\-(\d\d)\-(\d\d\d\d)\-(\d\d)\:(\d\d)$/ or
      &errorexit("You specified an invalid start date: $start_str");
   $start = timelocal(0,$5,$4,$2,$1-1,$3);
   $end_str =~ m/^(\d\d)\-(\d\d)\-(\d\d\d\d)\-(\d\d)\:(\d\d)$/ or
      &errorexit("You specified an invalid end date: $end_str");
   $end = timelocal(0,$5,$4,$2,$1-1,$3);
   if ($start > $end) {
      # just swap them, don't complain
      my($tmp_date) = $start;
      $start = $end;
      $end = $tmp_date;
   }
   return($logfile,$start,$end);
}
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
sub print_params {
   my($log,$start,$end) = @_ if @_;
   my($start_str, $end_str);
   $start_str = scalar localtime($start);
   $end_str = scalar localtime($end);
   print STDOUT "<html><head><title>Total stats from $start_str till $end_str </title></head>";
   print STDOUT "<body align='center' bgcolor='#ffffff'><table border=1><tr><td>";
   print STDOUT "Logfile: $log\n";
   print STDOUT "</td></tr><tr><td>";
   print STDOUT "Start time: $start_str\n";
   print STDOUT "</td></tr><tr><td>";
   print STDOUT "End time: $end_str\n";
   print STDOUT "</td></tr>";
}
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
sub get_totals {
   my($logfile,$start,$end) = @_ if @_;
   my($itot,$otot,$interval) = (0,0,0);
   my($aline,$curr_date,$avg_in,$avg_out,$pin,$pout);
   # File is in reverse, from end to start, so we count down...
   my($prev_date) = time;
   open(LOG,"$logfile") or &errorexit("Couldn't open $logfile: $!");
   while (<LOG>) {
      $aline = $_;
      chomp($aline);
      ($curr_date,$avg_in,$avg_out,$pin,$pout) = split(' ',$aline);
      $interval = $prev_date - $curr_date; 
      $prev_date = $curr_date;
      next if ($curr_date > $end);
      next if ($curr_date < $start);
      $itot = $itot + ($avg_in * $interval);
      $otot = $otot + ($avg_out * $interval);
      print STDOUT "IN: $avg_in * $interval = $itot\tOUT: $avg_out * $interval = $otot\n" if ($DEBUG);
   }
   return($itot,$otot);
}
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
sub print_totals {
   my($in,$out,$interval) = @_ if @_;
   my($inm,$outm) = @_ if @_;
	$inm = $in/1024/1024 ; 
	$outm = $out/1024/1024 ;

   print STDOUT "<tr><td>";
   printf STDOUT "Total Megabytes in: %0.2f %s MB<br>\n", $inm ;
   printf STDOUT "Total Megabytes out: %0.2f %s MB \n", $outm ;
   print STDOUT "</td></tr>";

   print STDOUT "<tr><td>";
   print STDOUT "Average = 24 hour average<br>" ;
	my($a_in) = &scale($in*8/$interval);
	my($a_out) = &scale($out*8/$interval);
   print "Average traffic in: $a_in <br>\n";
   print STDOUT "Average traffic out: $a_out \n"; 
   print STDOUT "</td></tr>";

   print STDOUT "<tr><td>";
   print STDOUT "Average workday = 22days/month * 8 hours = 176 hours<br>" ;
	my($aw_in) = &scale((($in*8/$interval)*720)/176);
   printf STDOUT "Average workday traffic in: $aw_in<br>\n";
	my($aw_out) = &scale((($out*8/$interval)*720)/176);
   printf STDOUT "Average workday traffic out: $aw_out<br>\n"; 
	my($aw_tot) = &scale(((($in*8/$interval)*720)/176)+((($out*8/$interval)*720)/176));
   printf STDOUT "Average workday traffic total: $aw_tot<br>\n"; 
   print STDOUT "</td></tr>";
   print STDOUT "</table></body></html>";


}
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
# MAIN

($logfile,$start_date,$end_date) = &get_args;
&print_params($logfile,$start_date,$end_date);

my($interval) = $end_date - $start_date;

my($in_tot,$out_tot) = &get_totals($logfile,$start_date,$end_date);
&print_totals($in_tot,$out_tot,$interval);
#-----------------------------------------------------------------------
#
