CHips L MINI SHELL

CHips L pro

Current Path : /opt/zabbix_scripts/oldscripts/
Upload File :
Current File : //opt/zabbix_scripts/oldscripts/check_tcptraffic

#!/usr/bin/perl

# check_tcptraffic is a nagios Nagios plugin to monitor the amount of TCP traffic
#
# check_tcptraffic uses the /proc/net/dev Linux entry to compute the
# amount of transferred bytes from the last plugin execution (temporary
# data is stored in the /tmp/check_tcptraffic-iface file)
#
# See  the INSTALL file for installation instructions
#
# Copyright (c) 2010-2011, ETH Zurich.
#
# This module is free software; you can redistribute it and/or modify it
# under the terms of GNU general public license (gpl) version 3.
# See the LICENSE file for details.
#
# RCS information
# enable substitution with:
#   $ svn propset svn:keywords "Id Revision HeadURL Source Date"
#
#   $Id: check_tcptraffic 1285 2012-03-13 15:05:08Z corti $
#   $Revision: 1285 $
#   $HeadURL: https://svn.id.ethz.ch/nagios_plugins/check_tcptraffic/check_tcptraffic $
#   $Date: 2012-03-13 16:05:08 +0100 (Tue, 13 Mar 2012) $

use 5.00800;

use strict;
use warnings;

use Carp;
use English qw(-no_match_vars);
use Nagios::Plugin::Threshold;
use Nagios::Plugin;
use Nagios::Plugin::Range;
use Nagios::Plugin::Getopt;
use Readonly;

################################################################################
# constants

our $VERSION = '2.2.4';

Readonly my $MAX_LONG => 2**32;

# IMPORTANT: Nagios plugins could be executed using embedded perl in this case
#            the main routine would be executed as a subroutine and all the
#            declared subroutines would therefore be inner subroutines
#            This will cause all the global lexical variables not to stay shared
#            in the subroutines!
#
# All variables are therefore declared as package variables...
#

## no critic (ProhibitPackageVars)

use vars qw(
  $help
  $log_file
  $options
  $os_64_bit
  $plugin
  $result
  $status
  $status_msg
  $threshold
  $tmp
);

##############################################################################
# subroutines

use subs qw(verbose);

##############################################################################
# Usage     : debug( "message" )
# Purpose   : writes a debugging message to the console and optionally to the
#             debugging log file
# Returns   : n/a
# Arguments : the debugging message
# Throws    : n/a
# Comments  : n/a
# See also  : n/a
sub debug {

    my $message = shift;

    chomp $message;

    if ( $options->debug() ) {
        print "[DEBUG] $message\n";    ## no critic (RequireCheckedSyscalls)
    }

    if ( $options->debug_log() ) {

        open $log_file, '>>', $options->debug_log()
          or $plugin->nagios_exit( UNKNOWN,
            'Cannot open ' . $options->debug_log() . ": $OS_ERROR" );

        print {$log_file} time
          . " $message\n"
          or $plugin->nagios_exit( UNKNOWN,
            'Cannot write to ' . $options->debug_log() . ": $OS_ERROR" );

        close $log_file
          or $plugin->nagios_exit( UNKNOWN,
            'Cannot close ' . $options->debug_log() . ": $OS_ERROR" );

    }

    return;

}

##############################################################################
# Usage     : running_on_linux()
# Purpose   : check if running on a Linux system
# Returns   : true if running on Linux
# Arguments : n/a
# Throws    : n/a
# Comments  : also checks if the OS is 64 bit capable and sets $os_64_bit
# See also  : n/a
sub running_on_linux {    ## no critic (RequireFinalReturn)

    my $output;
    my $pid;
    my $linux;

    # check the system
    $pid = open $output, q{-|}, 'uname'
      or
      $plugin->nagios_exit( UNKNOWN, "Cannot determine the system: $OS_ERROR" );

    while (<$output>) {
        chomp;
        verbose "running on $_\n";
        $linux = $_ eq 'Linux';

        close $output
          or $plugin->nagios_exit( UNKNOWN, "Cannot close output: $OS_ERROR" );

        # check the OS (32 or 64 bit)
        $pid = open $output, q{-|}, 'uname -m';  ## no critic (RequireBriefOpen)
        if ( !$pid ) {
            carp "Cannot determine if the system is 64 bit capable: $OS_ERROR";
            return $linux;
        }

        while (<$output>) {
            chomp;
            $os_64_bit = ( $_ eq 'x86_64' );
            my $message;
            if ($os_64_bit) {
                $message = '64';
            }
            else {
                $message = '32';
            }
            debug( $message . 'bit system' );
            return $linux;
        }

        carp "Cannot determine if the system is 64 bit capable: $OS_ERROR";
        return $linux;

    }

    $plugin->nagios_exit( UNKNOWN, 'Cannot determine the system' );

}

##############################################################################
# Usage     : whoami()
# Purpose   : retrieve the user runnging the process
# Returns   : username
# Arguments : n/a
# Throws    : n/a
# Comments  : n/a
# See also  : n/a
sub whoami {

    my $output;

    my $pid = open $output, q{-|}, 'whoami'    ## no critic (RequireBriefOpen)
      or
      $plugin->nagios_exit( UNKNOWN, "Cannot determine the user: $OS_ERROR" );

    while (<$output>) {
        chomp;
        debug("user $_");
        return $_;
    }

    $plugin->nagios_exit( UNKNOWN, 'Cannot determine the user' );

    return;

}

##############################################################################
# Usage     : write_timer($data_in, $data_out)
# Purpose   : writes the time and transmit data to the temporary file
# Returns   : n/a
# Arguments : n/a
# Throws    : n/a
# Comments  : n/a
# See also  : n/a
sub write_timer {

    my $in  = shift;
    my $out = shift;

    my $TMP;    # file handler

    my $dbg_message = "writing to $tmp";

    if ( !open $TMP, q{>}, $tmp ) {    ## no critic (RequireBriefOpen)
        debug("error: $OS_ERROR");
        $plugin->nagios_exit( UNKNOWN, "Cannot initialize timer: $OS_ERROR" );
    }

    my $line = time . " $in $out\n";
    print {$TMP} $line;                ## no critic (RequireCheckedSyscalls)
    debug("$dbg_message: $line");

    close $TMP
      or $plugin->nagios_exit( UNKNOWN, "Cannot close timer: $OS_ERROR" );

    return;

}

##############################################################################
# Usage     : read_proc('eth0')
# Purpose   : reads information about an interface in the proc file system
# Returns   : an hash containing the interface info
# Arguments : iface : interface name
# Throws    : n/a
# Comments  : n/a
# See also  : n/a
sub read_proc {

    my $iface = shift;

    my %data;

    my $found = 0;
    my $in;
    my $out;
    my $time;

    my $IN;     # file descriptor
    my $TMP;    # file descriptor

    my $dev_file = '/proc/net/dev';

    open $IN, q{<}, $dev_file    ## no critic (RequireBriefOpen)
      or $plugin->nagios_exit( UNKNOWN, "Cannot open $dev_file: $OS_ERROR" );

    while (<$IN>) {

        chomp;

        if (/:/mxs) {

         # /proc/net/dev format
         #
         # bytes:      The total number of bytes of data transmitted or received
         #             by the interface.
         # packets:    The total number of packets of data transmitted or
         #             received by the interface.
         # errs:       The total number of transmit or receive errors detected
         #             by the device driver.
         # drop:       The total number of packets dropped by the device driver.
         # fifo        The number of FIFO buffer errors.
         # frame:      The number of packet framing errors.
         # compressed: The number of compressed packets transmitted or received
         #             by the device driver.
         # multicast:  The number of multicast frames transmitted or received by
         #             the device driver.

     # hack: some kernels now put some whitespace between the colon and bytes in
            s/:\s+/:/mxs;

            my (
                $combined,      $packets_in,   $errs_in,
                $drop_in,       $fifo_in,      $frame_in,
                $compressed_in, $multicast_in, $bytes_out,
                $packets_out,   $errs_out,     $drop_out,
                $fifo_out,      $frame_out,    $compressed_out,
                $multicast_out
            ) = split;

            my ( $name, $bytes_in ) = split /:/mxs, $combined;

            if ( $name eq $options->interface() ) {

                $found = 1;

                $data{combined}       = $combined;
                $data{packets_in}     = $packets_in;
                $data{errs_in}        = $errs_in;
                $data{drop_in}        = $drop_in;
                $data{fifo_in}        = $fifo_in;
                $data{frame_in}       = $frame_in;
                $data{compressed_in}  = $compressed_in;
                $data{multicast_in}   = $multicast_in;
                $data{bytes_out}      = $bytes_out;
                $data{packets_out}    = $packets_out;
                $data{errs_out}       = $errs_out;
                $data{drop_out}       = $drop_out;
                $data{fifo_out}       = $fifo_out;
                $data{frame_out}      = $frame_out;
                $data{compressed_out} = $compressed_out;
                $data{multicast_out}  = $multicast_out;
                $data{bytes_in}       = $bytes_in;

                # get the time difference
                if ( $options->reset() || !open $TMP, q{<}, $tmp )
                {    ## no critic (RequireBriefOpen)
                    write_timer( $bytes_in, $bytes_out );
                    $plugin->nagios_exit( UNKNOWN, 'Initializing timer' );
                }

                while (<$TMP>) {
                    chomp;
                    ( $time, $in, $out ) = split;
                    $data{diff} = time - $time;
                    $data{in}   = $in;
                    $data{out}  = $out;
                    debug("reading old data: $time $in $out after $data{diff}");
                }

                close $TMP
                  or $plugin->nagios_exit( UNKNOWN,
                    "Cannot close $tmp: $OS_ERROR" );

                write_timer( $bytes_in, $bytes_out );

                last;

            }

        }

    }

    if ( !$found ) {
        $plugin->nagios_exit( UNKNOWN,
            'Interface ' . $options->interface() . ' not found' );
    }

    close $IN
      or $plugin->nagios_exit( UNKNOWN, "Cannot close $dev_file: $OS_ERROR" );

    return %data;

}

##############################################################################
# Usage     : verbose("some message string", $optional_verbosity_level);
# Purpose   : write a message if the verbosity level is high enough
# Returns   : n/a
# Arguments : message : message string
#             level   : options verbosity level
# Throws    : n/a
# Comments  : n/a
# See also  : n/a
sub verbose {

    # arguments
    my $message = shift;
    my $level   = shift;

    if ( !defined $message ) {
        $plugin->nagios_exit( UNKNOWN,
            q{Internal error: not enough parameters for 'verbose'} );
    }

    if ( !defined $level ) {
        $level = 0;
    }

    debug($message);

    if (   $level < $options->verbose()
        || $options->debug() )
    {
        print $message;    ## no critic (RequireCheckedSyscalls)
    }

    return;

}

##############################################################################
# main
#

################
# Initialization

$os_64_bit  = 0;
$plugin     = Nagios::Plugin->new( shortname => 'TCPTRAFFIC' );
$status     = 0;
$status_msg = q{};

########################
# Command line arguments

$options = Nagios::Plugin::Getopt->new(
    usage   => 'Usage: %s [OPTIONS]',
    version => $VERSION,
    url     => 'https://trac.id.ethz.ch/projects/nagios_plugins',
    blurb   => 'Monitors the amount of traffic on a given interface',
);

$options->arg(
    spec => 'critical|c=s',
    help =>
      'Exit with CRITICAL status if traffic is outside of the specified range',
    required => 1,
);

$options->arg(
    spec => 'warning|w=s',
    help =>
      'Exit with WARNING status if traffic is outside of the specified range',
    required => 1,
);

$options->arg(
    spec     => 'interface|i=s',
    help     => 'network interface to monitor',
    required => 1,
);

$options->arg(
    spec     => 'speed|s=i',
    help     => 'speed (in Mbit/s)',
    required => 1,
);

$options->arg(
    spec => 'reset|r',
    help => 'initialize counter',
);

$options->arg(
    spec     => 'debug',
    help     => 'debugging output',
    required => 0,
);

$options->arg(
    spec     => 'debug_log=s',
    help     => 'generates a log with debugging information',
    required => 0,
);

$options->getopts();

###############
# Sanity checks

if ( $options->debug_log() && ( !-w $options->debug_log() ) ) {
    $plugin->nagios_exit( UNKNOWN, $options->debug_log() . ' is not writable' );
}
debug('------------------------------------------');

if ( !running_on_linux() ) {
    $plugin->nagios_exit( UNKNOWN, 'Not running on a Linux system' );
}

# parse the critical and warning ranges
my $critical_range =
  Nagios::Plugin::Range->parse_range_string( $options->critical() );
if ( !( $critical_range && $critical_range->is_set() ) ) {
    $plugin->nagios_exit( UNKNOWN, 'Could not parse "critical"' );
}

my $warning_range =
  Nagios::Plugin::Range->parse_range_string( $options->warning() );
if ( !( $warning_range && $warning_range->is_set() ) ) {
    $plugin->nagios_exit( UNKNOWN, 'Could not parse "warning"' );
}

# check the speed (depending on the counter size in bits)

my $max_check_time;    # in seconds

# size    max (bytes)  max (bits)       max (Mbits)
# -----------------------------------------------------------
# 64 bit  2^32         2^64*8 -> 2^67   2^67 / 1024^2 -> 2^47
# 32 bit  2^32         2^32*8 -> 2^35   2^38 / 1024^2 -> 2^15

#<<<
if ($os_64_bit) {
    $max_check_time = int( ( 2**47 - 1 ) / $options->speed() ); ## no critic (ProhibitMagicNumbers)
}
else {
    $max_check_time = int( ( 2**15 - 1 ) / $options->speed() ); ## no critic (ProhibitMagicNumbers)
}
#>>>
verbose
  "the counters can hold data for $max_check_time seconds before overflow\n";

$threshold = Nagios::Plugin::Threshold->set_thresholds(
    warning  => $warning_range,
    critical => $critical_range,
);

$tmp = '/tmp/check_tcptraffic_status-' . $options->interface() . whoami();

########################
# Check the proc entry

my %data = read_proc( $options->interface() );

if ( $data{diff} > $max_check_time ) {

    verbose 'the time from last check ('
      . $data{diff}
      . 's) is greater than the maximum check time allowed with speed '
      . $options->speed() . ' ('
      . $max_check_time
      . "s): sleeping 1s to gather data again\n";

    # time difference is > max_check_time
    # since the counter could overflow
    # we reeinitilize the timer and
    # we perform a 1s check

    write_timer( $data{bytes_in}, $data{bytes_out} );

    sleep 1;

    %data = read_proc( $options->interface() );

}

if ( $data{diff} == 0 ) {

    # round up
    $data{diff} = 1;

}

my $traffic_in;
my $traffic_out;

# in

if ( $data{bytes_in} >= $data{in} ) {
    $traffic_in = int( ( $data{bytes_in} - $data{in} ) / $data{diff} );
    debug(
        "IN: $traffic_in = int( ( $data{bytes_in} - $data{in} ) / $data{diff} )"
    );
}
else {

    # the old value is larger than the new one: the counter overflowed
    $traffic_in =
      int( ( $MAX_LONG - $data{in} + $data{bytes_in} ) / $data{diff} );
    debug(
"IN (overflow): $traffic_in = int( ( $MAX_LONG - $data{in} + $data{bytes_in} ) / $data{diff} )"
    );
}

# out

if ( $data{bytes_out} >= $data{out} ) {
    $traffic_out = int( ( $data{bytes_out} - $data{out} ) / $data{diff} );
    debug(
"OUT: $traffic_out = int( ( $data{bytes_out} - $data{out} ) / $data{diff} )"
    );
}
else {

    # the old value is larger than the new one: the counter overflowed
    $traffic_out =
      int( ( $MAX_LONG - $data{out} + $data{bytes_out} ) / $data{diff} );
    debug(
"OUT (overflow): $traffic_out = int( ( $MAX_LONG - $data{out} + $data{bytes_out} ) / $data{diff} )"
    );
}

my $traffic = $traffic_in + $traffic_out;
debug("TOT: $traffic = $traffic_in + $traffic_out");

$plugin->add_perfdata(
    label     => 'TOTAL',
    value     => sprintf( '%.0f', $traffic ),
    uom       => 'B',
    threshold => $threshold,
);

$plugin->add_perfdata(
    label => 'IN',
    value => sprintf( '%.0f', $traffic_in ),
    uom   => 'B',
);

$plugin->add_perfdata(
    label => 'OUT',
    value => sprintf( '%.0f', $traffic_out ),
    uom   => 'B',
);

$plugin->add_perfdata(
    label => 'TIME',
    value => sprintf( '%.0f', $data{diff} ),
    uom   => 'B',
);

$plugin->nagios_exit( $threshold->get_status($traffic),
    $options->interface() . q{ } . sprintf( '%.0f', $traffic ) . ' bytes/s' );

1;

Copyright 2K16 - 2K18 Indonesian Hacker Rulez