Skip to content

Instantly share code, notes, and snippets.

@treed
Forked from tene/snmp_traffic.pl
Created April 8, 2009 21:20
Show Gist options
  • Save treed/92050 to your computer and use it in GitHub Desktop.
Save treed/92050 to your computer and use it in GitHub Desktop.
#!/usr/bin/perl -w
use strict;
use Net::SNMP;
use Getopt::Long;
use Data::Dumper;
use lib "/usr/lib/nagios/plugins";
use utils qw (%ERRORS &print_revision);
my $PROGNAME = "check_snmp_traffic";
my $REVISION = "0.9.0";
sub print_usage {
print "Usage:\n";
print " $PROGNAME (-i | -o) [-w <rate>] [-c <rate>] [-h <hostname>] [-C <community>] [-I <interface>] [-t <time>] [-n <number>] [-X] [-B]\n";
print " $PROGNAME [-h | --help]\n";
print " $PROGNAME [-V | --version]\n";
}
sub print_help {
print_revision($PROGNAME, $REVISION);
print "Copyright (c) 2009 Ted Reed\n\n";
print_usage();
print "\n";
print " <rate> Traffic rate must be no more than this fast in bps.\n";
print " (Bps if -B is used.) The default is zero.\n";
print " <hostname> Host to query. Default is localhost.\n";
print " <community> SNMP Community. Default is public.\n";
print " <interface> Given as a numeric index. The default is 1.\n";
print " You may need to investigate to find out what index your\n";
print " device gives the interface you want to query.\n";
print " <time> Duration of the checks, specified in seconds. Default is 30.\n";
print " <number> Number of checks to do. Result is averaged. Default is 3.\n";
print " This cannot be less than 2, for obvious reasons.\n";
print "\n";
print " Use -i or -o to indicate whether the script should query inbound\n";
print " or outbound traffic. If neither is given, -i is assumed.\n";
print " -B is used to change the units to Bps.\n";
print " -X can be used to specify that 64-bit counters should be\n";
print " queried, rather than the 32-bit counters. Consult\n";
print " with your vendor to see if they provide Counter64 support.\n\n";
}
my $opt_warning = 0;
my $opt_critical = 0;
my $opt_version = 0;
my $opt_help = 0;
my $opt_hostname = "localhost";
my $opt_community = "public";
my $opt_interface = "1";
my $opt_inbound = 0;
my $opt_outbound = 0;
my $opt_64bit = 0;
my $opt_bytes = 0;
my $opt_time = 30;
my $opt_checks = 3;
Getopt::Long::Configure('bundling');
GetOptions(
"V" => \$opt_version, "version" => \$opt_version,
"h" => \$opt_help, "help" => \$opt_help,
"w=i" => \$opt_warning, "warning=i" => \$opt_warning,
"c=i" => \$opt_critical, "critical=i" => \$opt_critical,
"H=s" => \$opt_hostname, "hostname=s" => \$opt_hostname,
"C=s" => \$opt_community, "community=s" => \$opt_community,
"I=s" => \$opt_interface, "interface=s" => \$opt_interface,
"i" => \$opt_inbound, "inbound" => \$opt_inbound,
"o" => \$opt_outbound, "outbound" => \$opt_outbound,
"X" => \$opt_64bit, "64bit" => \$opt_64bit,
"B" => \$opt_bytes, "bytes" => \$opt_bytes,
"t=i" => \$opt_time, "time" => \$opt_time,
"n=i" => \$opt_checks, "number" => \$opt_checks);
if ($opt_version) {
print_revision($PROGNAME, $REVISION);
exit $ERRORS{'OK'};
}
if ($opt_help) {
print_help();
exit $ERRORS{'OK'};
}
if ($opt_checks < 2) {
print "TRAFFIC_RATE UNKNOWN: Number of checks requested is less than two.\n";
exit $ERRORS{'UNKNOWN'};
}
my $session = Net::SNMP->session(-hostname => $opt_hostname, -community => $opt_community);
unless (defined($session)) {
print "TRAFFIC_RATE CRITICAL: Unable to connect to $opt_hostname.\n";
exit $ERRORS{'CRITICAL'};
}
my $dir;
my $oid;
unless ($opt_64bit) {
$dir = "10"; # Yes, this makes inbound the default.
$dir = "16" if $opt_outbound;
$oid = "1.3.6.1.2.1.2.2.1.$dir.$opt_interface";
} else {
$dir = "6";
$dir = "10" if $opt_outbound;
$oid = "1.3.6.1.2.1.31.1.1.1.$dir.$opt_interface";
}
sub getTraffic {
my $result = $session->get_request(-varbindlist => [$oid]);
unless (defined($result)) {
print "TRAFFIC_RATE CRITICAL: Error reading oid $oid ", $session->error();
$session->close();
exit $ERRORS{'CRITICAL'};
}
return $result;
}
sub applySlidingWindow($\@$) {
my $size = shift;
my $array = shift;
my $length = @$array;
my $block = shift;
for my $i (1 .. ($length - $size + 1)) {
$block->(@$array[$i, $i - $size + 1]);
}
}
sub sum {
my $ret;
$ret += $_ for @_;
return $ret;
}
my @results;
for (1 .. ($opt_checks - 1)) {
push(@results, [getTraffic()->{$oid}, time()]);
sleep($opt_time / ($opt_checks - 1));
}
push(@results, [getTraffic()->{$oid}, time()]);
my @rates;
applySlidingWindow(2, @results, sub {
my $cur = $_[0][0];
my $prev = $_[1][0];
my $time = $_[0][1] - $_[1][1];
$cur += 2**($opt_64bit ? 64 : 32) if $prev > $cur;
my $rate = ($cur - $prev) / $time;
$rate *= 8 unless $opt_bytes;
push(@rates, $rate);
});
print Dumper(@rates);
my $rates = @rates;
my $rate = sum(@rates)/$rates;
my $condition = "OK";
if ($rate >= $opt_critical) {
$condition = "CRITICAL";
} elsif ($rate >= $opt_warning) {
$condition = "WARNING";
}
printf("TRAFFIC_RATE $condition: %d%s %s\n", $rate, ($opt_bytes ? "Bps" : "bps"), ($opt_outbound ? "outbound" : "inbound"));
$session->close;
exit $ERRORS{$condition};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment