#!/usr/local/bin/perl # # Check on a dhcp sharenet's address utilization. # # Check if the cache file is up to date. If not get a new copy from # metal1's web server. Then search it for the reading. # # by Doke Scott, 2013.8.29 # # $Header: /opt/home/doke/work/nagios/RCS/check_dhcp_leases,v 1.10 2014/04/23 22:05:07 doke Exp $ use vars qw( $cachedir $cachetime $cachefile $remoteurl ); $remoteurl = "http://metal1.nss/cgi-bin/nss/dhcp_leases_last"; $cachetime = 4 * 60; # seconds cache is good for $cachedir = "/var/tmp"; $cachefile = "$cachedir/dhcp-leases.cache.$>"; # effective uid $ENV{PATH} = "/usr/sfw/bin:/usr/local/bin:/usr/bin"; ################## use warnings; use strict; use Getopt::Long; use Fcntl ':flock'; use vars qw( $sharednet $crit_used $warn_used $force $verbose $help ); $crit_used = 95; # percent $warn_used = 90; # percent $force = 0; $verbose = 0; $help = 0; ############### sub usage { my( $rc ) = @_; print "Usage: $0 -s -c n critical at n percent used -w n warn at n percent used -f force updating dhcp info cache file -v verbose -h help \n"; exit $rc; } Getopt::Long::Configure ("bundling"); GetOptions( 's=s' => \$sharednet, 'c=i' => \$crit_used, 'w=i' => \$warn_used, 'f' => \$force, 'v+' => \$verbose, 'h' => \$help, ); &usage( 0 ) if ( $help ); &usage( 3 ) if ( ! $sharednet ); get_reading( $sharednet ); print "no data found for $sharednet\n"; exit 3; # unknown ################# sub get_reading { my( $sharednet ) = @_; my( $sharednet2, $pub_used, $pub_total, $pub_percent, $pri_used, $pri_total, $pri_percent ); check_cache(); if ( ! open( fH, $cachefile ) ) { print "can't open $cachefile: $!\n"; exit 3; } #file: 20080902-19:17 # #sharednet0.0 - 311/502 (62.0%), 33/251 (13.1%) # 128.175.0.0: 128.175.0.2...128.175.0.252 # 128.175.169.0: 128.175.169.2...128.175.169.252 while ( ) { $verbose > 1 && print ">$_"; chomp; unless ( m!^ \s* ([\w\d\.]+) \s+ - \s+ (\d+)/(\d+) \s+ \(([\d\.]+)%\), \s+ (\d+)/(\d+) \s+ \(([\d\.]+)%\) \s* $!xi ) { next; } ( $sharednet2, $pub_used, $pub_total, $pub_percent, $pri_used, $pri_total, $pri_percent ) = ( $1, $2, $3, $4, $5, $6, $7 ); $verbose > 1 && print ">$sharednet2, $pub_used, $pub_total, $pub_percent, $pri_used, $pri_total, $pri_percent\n"; if ( $sharednet2 eq $sharednet ) { printf "%s: %s/%d %0.1f%% public used, %s/%d %0.1f%% private used" . " | sharednet=%s, public=%d;%d;%0.1f, private=%d;%d;%0.1f\n", $sharednet2, $pub_used, $pub_total, $pub_percent, $pri_used, $pri_total, $pri_percent, $sharednet2, $pub_used, $pub_total, $pub_percent, $pri_used, $pri_total, $pri_percent; if ( $pub_percent > $crit_used || $pri_percent > $crit_used ) { exit 2; # critical } elsif ( $pub_percent > $warn_used || $pri_percent > $warn_used ) { exit 1; # warning } else { exit 0; # ok } } } close fH; } sub check_cache { my( $url, $cmd, $i ); $verbose && print "checking cache file\n"; foreach $i ( 1 .. 10 ) { my( $dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks ) = stat( $cachefile ); if ( ! -e _ || ( time() - $mtime ) > $cachetime || -s _ < 200 || $force ) { # refresh_cache; $verbose && print "refreshing cache file\n"; if ( ! open( lockH, "+>>$cachefile.new" ) ) { $verbose && warn "can't open new cache file to lock it: $!\n"; sleep 1; next; } if ( ! flock( lockH, LOCK_EX | LOCK_NB ) ) { $verbose && warn "can't lock new cache file, $cachefile.new: $!\n"; close lockH; sleep 1; next; } unlink $cachefile; $url = $remoteurl; $cmd = "wget -q -O '$cachefile' '$url'"; $verbose && print "cmd: $cmd\n"; system( $cmd ); if ( -s $cachefile > 200 ) { # success $verbose && print "successfully refreshed cache file\n"; flock( lockH, LOCK_UN ); close lockH; return; } # failed $verbose && print "couldn't refresh $cachefile\n"; flock( lockH, LOCK_UN ); close lockH; # loop around to try again } } }