Source Code
packet_count
  Prev   Next
#!/usr/local/bin/perl
#
#  packet_count             Maintain a log of packet throughput
#
# Usage:   packet_count
#       
# Cron:    0,10,20,30,40,50 * * * *        /usr/local/etc/syswatch/bin/packet_count
#
# Save data in: /var/log/packet_count/day.<#>
#
#
# Conventions:      vi:tabstop=4
#
#       Globals    are in  MixedCaseWithNoUnderscores like this.
#       locals     are in  all_lower_case_with_underscores
#       CONSTANTS  are in  ALL_CAPS
#       fcn_names  are in  all_lower_case_with_underscores
#
# Originally written: Apr, 1996
# Last update:        Sep, 2001
#       

$DATE_ARG__DAY_WITH_LEADING_ZERO    = "%d";     # "03"

$OnMac      = ! -e '/etc/passwd';
$SW_HOME    = '/usr/local/etc/syswatch';
$SW_HOME    = '' if( $OnMac );
$NETSTAT    = '/bin/netstat';
$DATE       = '/bin/date';
$DayOfMonth = `$DATE +$DATE_ARG__DAY_WITH_LEADING_ZERO` if( ! $OnMac );
$DayOfMonth = '3'         if(   $OnMac );
$TheLogFile = "/var/log/packet_count/day.$DayOfMonth";
$Debug      = $ARGV[ 0 ] eq '-d';
$Verbose    = $ARGV[ 0 ] eq '-v';


#
# The "last time" file, which keeps the info
# from our last run, so we can compute what
# happened in between then and now.
#
$TheLastTimeInfoFile    = "$SW_HOME/config/PacketCount.last";
    $Last_Time              = 0;
    $Curr_Time              = 0;
    $WHEN_KEYWORD           = 'when';

    $Last_PacketsSent       = 0;
    $Curr_PacketsSent       = 0;
    $PACKETS_SENT_KEYWORD   = 'IP packets sent';
#   $PACKETS_SENT_PATTERN   = 'packets sent from this host';
    $PACKETS_SENT_PATTERN   = 'requests sent out';

    $Last_PacketsRcvd       = 0;
    $Curr_PacketsRcvd       = 0;
    $PACKETS_RCVD_KEYWORD   = 'IP packets rcvd';
#   $PACKETS_RCVD_PATTERN   = 'packets for this host';
    $PACKETS_RCVD_PATTERN   = 'total packets received';
    
    $Last_Connections       = 0;
    $Curr_Connections       = 0;
    $CONNECTIONS_KEYWORD    = 'TCP connection accepts';
#   $CONNECTIONS_PATTERN    = 'connection accepts';
    $CONNECTIONS_PATTERN    = 'active connections openings';


#
# main
#   
    &get_cur_values();
    &reset_log_file()   if( &is_start_of_new_day() );
    &log_values() if( &get_last_time_info() );
    do update_last_time_info();
    
    exit( 0 );
#
# end main
#


#
# reset_log_file
#
# Clear the log file and put the single header
# line in it.
#
sub reset_log_file
{
    local ( $hdr ) = "# Through Seconds Sent pkts   Rcvd pkts   Connections TCP Packets TCP Bytes   TCP Retrans Packets TCP Retrans Bytes\n";
    open( LOG, "> $TheLogFile" ) || &fatal_error( "Can't open $TheLogFile" );
    print LOG $hdr;
    close( LOG );
}


#
# is_start_of_new_day
#
# Is it now the start of a new day? Hour == 0 & min < 2: yes
#
sub is_start_of_new_day
{
    local ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = localtime( time );
    
    return 1 if( $hour == 0 && $min <= 2 );
    return 0;
}



#
# get_cur_values()
#
# Get the current totals from the OS
#
sub get_cur_values
{
    local ( $stats );
#   $stats = `$NETSTAT -s` if( ! $OnMac );
    $stats = `$NETSTAT -i` if( ! $OnMac );
#print "stats=$stats\n";
    $stats = &read_in_contents_of_file( "netstat -s" ) if( $OnMac );
    
    $Curr_Time = time;
    $Curr_Date = `$DATE` if( ! $OnMac );
    $Curr_Date = 'Thu Apr  3 11:15:36 PST 1997 ' if( $OnMac );
    chop( $Curr_Date );
    
    $stats =~ /([0-9]*) $PACKETS_SENT_PATTERN/;
    $Curr_PacketsSent = int( $1 );
    
    $stats =~ /([0-9]*) $PACKETS_RCVD_PATTERN/;
    $Curr_PacketsRcvd = int( $1 );
    
    $stats =~ /([0-9]*) $CONNECTIONS_PATTERN/;
    $Curr_Connections = int( $1 );

    dbg("$Curr_Date: sent=$Curr_PacketsSent, rcvd=$Curr_PacketsRcvd\n");
}


#
# get_last_time_info()
#
# Get the info from the last time we ran.
# Rtn TRUE if we got it, FALSE if it wasn't
# there or was out of date, etc.
#
sub get_last_time_info
{
    dbg("No 'last time file' ($TheLastTimeInfoFile)\n")  if( ! -e $TheLastTimeInfoFile );

    return 0 if( ! -e $TheLastTimeInfoFile );
    
    local ( $last_info ) = &read_in_contents_of_file( $TheLastTimeInfoFile );
    
    $last_info =~ /$WHEN_KEYWORD    ([0-9]*)/;
    $Last_Time = int( $1 );
    
    $last_info =~ /$PACKETS_SENT_KEYWORD    ([0-9]*)/;
    $Last_PacketsSent = int( $1 );
    
    $last_info =~ /$PACKETS_RCVD_KEYWORD    ([0-9]*)/;
    $Last_PacketsRcvd = int( $1 );
    
    $last_info =~ /$CONNECTIONS_KEYWORD ([0-9]*)/;
    $Last_Connections = int( $1 );
    
    return 0 if( $Last_Time == 0 || $Last_PacketsSent == 0 || $Last_PacketsRcvd == 0
              || $Last_Connections == 0 );
    return 1;
}


#
# update_last_time_info()
#
# Write our current numbers so we can use them next time
#
sub update_last_time_info
{
    return if( $Debug );
    
    open( LTI, "> $TheLastTimeInfoFile" ) || &fatal_error( "Can't open $TheLastTimeInfoFile" );
    
    print LTI "$WHEN_KEYWORD    $Curr_Time\n";
    print LTI "$PACKETS_SENT_KEYWORD    $Curr_PacketsSent\n";
    print LTI "$PACKETS_RCVD_KEYWORD    $Curr_PacketsRcvd\n";
    print LTI "$CONNECTIONS_KEYWORD $Curr_Connections\n";
    
    close( LTI );

    dbg("Updating last time info with 'Curr_*' values\n");
}


#
# log_values()
#
# Calc and save the values in the log
#
sub log_values
{
    #
    # If we've rebooted since we last ran then the
    # counters will be reset and so the "last" values
    # are no longer valid. Also, true if we've reset
    # the date.
    #
    return if( $Curr_Time        <= $Last_Time
            || $Curr_PacketsSent <  $Last_PacketsSent
            || $Curr_PacketsRcvd <  $Last_PacketsRcvd
            || $Curr_Connections <  $Last_Connections
             );
    
    local ( $n_secs ) = $Curr_Time        - $Last_Time;
    local ( $n_sent ) = $Curr_PacketsSent - $Last_PacketsSent;
    local ( $n_rcvd ) = $Curr_PacketsRcvd - $Last_PacketsRcvd;
    local ( $n_conn ) = $Curr_Connections - $Last_Connections;
    
    local ( $hdr ) = "# Through #seconds    Sent pkts   Rcvd pkts   # Connections\n";
    local ( $ln ) = "$Curr_Date $n_secs $n_sent $n_rcvd $n_conn\n";
    
    if( ! $Debug )
    {
        open( LOG, ">> $TheLogFile" ) || &fatal_error( "Can't open $TheLogFile" );
        print LOG $hdr if( -z $TheLogFile );
        print LOG $ln;
        close( LOG );
    }
    
    print $hdr . $ln if( $OnMac || $Debug );
}



# ------------------ Utils -------------------

#
# fatal_error
#
#   Exit with this message. We want to make sure to
#   remove our lock file, so we can run again.
#
sub fatal_error
{
    local ( $msg ) = @_;
    print STDERR "$msg\n";
    exit;
}


#
# read_in_contents_of_file
#
#   Return the contents of this file in a string.
#
sub read_in_contents_of_file
{
    local ( $file_name ) = @_;
    local ( $file_conts );
    
    if( $OnMac )
    {
        open( SRC, $file_name ) || &fatal_error( "Can't open $file_name" );
        
        while( <SRC> )
        {
            $file_conts = $file_conts . $_;
        }
        
        close( SRC );
    }
    else
    {
        $file_conts = `cat $file_name`;
    }
    return $file_conts;
}

#
# dbg()
#
sub dbg
{
    local ( $msg ) = @_;

    print $msg  if( $Debug || $Verbose );
}