#!/usr/bin/perl

####################################################################
# nagios: +epn
#
# check_full_arp - nagios plugin 
#
# Copyright (C) 2013 Anthony Bréart
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# Report bugs to:  anthony@kwaoo.com
#
# Tested on Debian
#
####################################################################

use warnings;
use lib "/usr/lib/nagios/plugins";
use utils qw($TIMEOUT %ERRORS &print_revision &support);
use vars qw($PROGNAME);

# Just in case of problems, let's not hang Nagios
$SIG{'ALRM'} = sub {
        print ("ERROR: Plugin took too long to complete (alarm)\n");
        exit $ERRORS{"UNKNOWN"};
};
alarm($TIMEOUT);

$PROGNAME = 'check_full_arp.pl';
$WARNINGPERCENT = '80';
$CRITICALPERCENT = '90';
$GCTHRESHFILE = '/proc/sys/net/ipv4/neigh/default/gc_thresh3';
$SCRIPTVERSION = '1.0';

# Delete each \n and/or \r
sub rntrim($) {
        $string = shift;
        $string =~ s/\r|\n//g;
        return $string;
}

# Get the current number of ARP entries in the table
sub get_number_arp_entries() {
	$arp_numentries=`arp -an|wc -l`;
	rntrim($arp_numentries);
}

# Get the maximum value of ARP entries that can be kept in the table
sub get_max_arp_entries() {
	open(MNAE,$GCTHRESHFILE) || die ("Can't open file $GCTHRESHFILE");

	while (<MNAE>) {
		$arp_maxentries=$_;
	}

	close(MNAE);

	rntrim($arp_maxentries);
}

sub print_usage() {
        print "Usage: \n";
        print "  $PROGNAME [-w | --warning warning_value] [-c | --critical critical_value]\n";
        print "  $PROGNAME [-h | --help]\n";
        print "  $PROGNAME [-v | --version]\n";
}

sub print_help() {
        print_revision($PROGNAME,$SCRIPTVERSION);
        print "Copyright (c) 2013 Bréart Anthony\n";
        print "This program is licensed under the terms of the\n";
        print "GNU General Public License\n(check source code for details)\n";
        print "\n";
        print "Check if the maximum value of ARP entries on any interfaces is not reached.\n";
        print "\n";
	print " -v (--version)      Plugin version\n";
	print " -h (--help)         Usage help\n";
	print " -w (--warning)      Warning - (optional: default value is $WARNINGPERCENT)\n";
	print " -c (--critical)     Critical - (optional: default value is $CRITICALPERCENT)\n";
        print "\n";
        print_usage();
	print "\n";
        support();
}

use Getopt::Long;
&Getopt::Long::config('bundling');
GetOptions(
        "v"     => \$opt_v,           "version"      => \$opt_v,
        "h"     => \$opt_h,           "help"         => \$opt_h,
        "w=s"   => \$WARNINGPERCENT,  "warning=s"    => \$WARNINGPERCENT,
        "c=s"   => \$CRITICALPERCENT, "critical=s"   => \$CRITICALPERCENT,
) or print_usage() && exit(1);

# -h & --help print help
if ($opt_h) { print_help(); exit $ERRORS{'OK'}; }
# -V & --version print version
if ($opt_v) { print_revision($PROGNAME,$SCRIPTVERSION); exit $ERRORS{'OK'}; }

$arp_numentries = get_number_arp_entries();
$arp_maxentries = get_max_arp_entries();

$arp_percent = ($arp_numentries/$arp_maxentries*100);
$arp_percent =~ s/(\.\d{2})\d*/$1/;
$msg = "$arp_numentries/$arp_maxentries ARP entries ($arp_percent%), (levels at $WARNINGPERCENT/$CRITICALPERCENT%)";

if ($arp_numentries > ($arp_maxentries * ($CRITICALPERCENT/100))) {
	$state = 'CRITICAL';
}
else {
	if($arp_numentries > ($arp_maxentries * ($WARNINGPERCENT/100))) {
		$state = 'WARNING';
	}
	else {
		$state = 'OK';
	}
}

print "$state: $msg\n";
exit $ERRORS{$state};
