#!/usr/bin/perl -w # nagios: -epn # the above line makes nagios run the script as a separately. # rather than as part of nagios. use POSIX; use lib "/usr/lib/nagios/plugins"; use utils qw(%ERRORS); sub fail_usage { if (scalar @_) { print "$0: error: \n"; map { print " $_\n"; } @_; } print "$0: Usage: \n"; print "$0 [] [ []] \n"; print "$0 [] [-s [-s [-s ]]] \n"; print " options: \n"; print " [-v [-v [-v]]] (verbose) \n"; print " [-t ] (wait this number of seconds) \n"; print " [-f] (fuzzy - ok if one or more of the designated servers answer) \n"; print " [-F] (force (default) - all the designated servers must answer) \n"; print " \n"; exit 3 ; } my $verbose = 0; my %servers=(); my $opt = "-t 5"; my $time = 5; my $force=1; ## for some reason I can't test for empty ARGs in the while loop @ARGV = grep {!/^\s*$/} @ARGV; # examine commandline args while ($ARGV=$ARGV[0]) { my $myarg = $ARGV; if ($ARGV eq '-s') { shift @ARGV; if (!($ARGV = $ARGV[0])) { fail_usage ("$myarg needs an argument"); } if ($ARGV =~ /^-/) { fail_usage ("$myarg must be followed by an argument"); } if (!defined($servers{$ARGV})) { $servers{$ARGV}=1; } } elsif ($ARGV eq '-t') { shift @ARGV; if (!($ARGV = $ARGV[0])) { fail_usage ("$myarg needs an argument"); } if ($ARGV =~ /^-/) { fail_usage ("$myarg must be followed by an argument"); } if ($ARGV !~ /^(\d+)$/) { fail_usage ("$myarg must be followed by an number"); } $time = $1; $opt = "-t $time"; } elsif ($ARGV eq '-f' ) { $force=0; } elsif ($ARGV eq '-F' ) { $force=1; } elsif ($ARGV eq '-h' or $ARGV eq '--help' ) { fail_usage ; } elsif ($ARGV =~ /^-/ ) { fail_usage " invalid option ($ARGV)"; } elsif ($ARGV =~ /^\d+\.\d+\.\d+\.\d+$/) # servers should be ip addresses. I'm not doing detailed checks for this. { if (!defined($servers{$ARGV})) { $servers{$ARGV}=1; } } else { last; } shift @ARGV; } if (scalar @ARGV) { fail_usage "didn't understand arguments: (".join (" ",@ARGV).")"; } my $serversn = scalar keys %servers; if ($verbose > 2) { print "verbosity=($verbose)\n"; print "servers = ($serversn)\n"; if ($serversn) { for my $i (keys %servers) { print "server ($i)\n"; } } } if (!$serversn) { fail_usage "no servers"; } my $responses=0; my $responders=""; my @check_dhcp = qx{/usr/lib/nagios/plugins/check_dhcp -v $opt}; foreach my $value (@check_dhcp) { if ($value =~ /Added offer from server \@ /i){ $value =~ m/(\d+\.\d+\.\d+\.\d+)/i; my $host = $1; # we find a server in our list if (defined($servers{$host})) { $responses++; $responders.="$host "; } else { # we find a rogue DHCP server. Danger Will Robinson! print "SERVICE STATUS:CRITICAL: Rogue DHCP service running on $host"; exit $ERRORS{'CRITICAL'} } } } if ($responses == $serversn) { # we saw all the servers in our list. All is good. print "SERVICE STATUS:OK: $responses of $serversn Expected Responses to DHCP Broadcast"; exit $ERRORS{'OK'}; } if ($responses == 0) { # we found no DHCP responses. print "SERVICE STATUS:CRITICAL: no DHCP service responded"; exit $ERRORS{'CRITICAL'} } # we found less DHCP servers than we should have. Oh Nos! $responders =~ s/ $//; if ($force == 1) { print "SERVICE STATUS:WARNING: $responses of $serversn Responses to DHCP Broadcast. Only ($responders) responded. "; exit $ERRORS{'WARNING'}; } else { print "SERVICE STATUS:OK: $responses of $serversn Responses to DHCP Broadcast. Only ($responders) responded. "; exit $ERRORS{'OK'}; }