#!/usr/bin/perl -w # # Author: Petter Reinholdtsen # Date: 2001-11-09 # # Check /etc/resolv.conf, and make sure the name servers listed are # working. It will ignore entries with '# NAGIOSIGNORE' at the end. use Socket; use vars qw($host $debug $mincount $trycount $testhost $retval $nagiosmsg); $retval = 0; $nagiosmsg = ""; $host = '/usr/bin/host'; $debug = 0; # There should be at least this many servers in the list $mincount = 1; # Try to call host this many times before reporting any bugs $trycount = 3; # Which DNS name to look up $testhost = "www.uio.no"; # Stolen from Logwatch.pm sub canonical_ipv6_address { my @a = split /:/, shift; my @b = qw(0 0 0 0 0 0 0 0); my $i = 0; # comparison is numeric, so we use hex function while (defined $a[0] and $a[0] ne '') {$b[$i++] = hex(shift @a);} @a = reverse @a; $i = 7; while (defined $a[0] and $a[0] ne '') {$b[$i--] = hex(shift @a);} @b; } sub error_with_dns { local ($count, $ip, $error) = @_; # Count 1 = Error # Count 2 = Problem # Count 3-> = Warning if (1 == $count) { $retval = 2; } elsif (2 == $count) { $retval = 1 unless ($retval > 0); } $nagiosmsg .= "
" unless ($nagiosmsg =~ /^$/); $nagiosmsg .= "/etc/resolv.conf: nameserver #$count $ip: $error"; } # Check if there is a DNS server running on the given IP address sub test_dns_server { local ($ip) = @_; local ($name) = ""; print "Checking $1\n" if $debug; # there are other module functions that do this more gracefully # (such as inet_pton), but we can't guarantee that they are available # in every system, so we use the built-in gethostbyaddr. if ($ip =~ /^[\d\.]*$/) { $PackedAddr = pack('C4', split /\./,$ip); $name = gethostbyaddr($PackedAddr,AF_INET()); } elsif ($ip =~ /^[0-9a-zA-Z:]*/) { $PackedAddr = pack('n8', canonical_ipv6_address($ip)); $name = gethostbyaddr($PackedAddr, AF_INET6()); } return "missing in DNS" if ( ! defined $name ); my $try = $trycount; my $delay = 1; # Exponensial backoff for ($try = $trycount; $try; --$try) { print "Running '$host $testhost $ip 2>/dev/null'\n" if $debug; local $lookup = `$host $testhost $ip 2>/dev/null`; print "Reply from host (try=$try):\n $lookup\n" if $debug; if ($lookup =~ /\sA\s+\d/ || $lookup =~ /has address/ || $lookup =~ /domain name pointer/ || $lookup =~ /Name: /) { return undef; # true } print "Sleeping $delay\n" if $debug; sleep $delay; $delay += $delay; } return "no/bad reply from DNS server"; } sub check_etc_resolv_conf { open(RESOLV, "< /etc/resolv.conf") || die "Unable to open /etc/resolv.conf"; local $count = 0; while () { chomp; if (/# NAGIOSIGNORE$/) { # Skip lines marked to be ignored $count++ if (m/^nameserver\s+/); # Count ignored nameservers next; } s/\#.+//; # Skip comments next if (/^\s*$/); # Skip empty lines if (/^nameserver\s+(\S+)/) { $count++; local ($error) = test_dns_server($1); if ( defined $error ) { error_with_dns($count, $1, $error); } } } close(RESOLV); if ($count < $mincount) { $retval = 1 unless $retval > 0; $nagiosmsg .= "
" unless ($nagiosmsg =~ /^$/); $nagiosmsg .= "/etc/resolv.conf: Only $count nameservers in " . "/etc/resolv.conf (low-limit is $mincount)"; } } check_etc_resolv_conf() if ( -f "/etc/resolv.conf" && -x $host ); unless ( -x $host ) { $nagiosmsg .= "$host is missing or not executable, please fix.."; $retval = 1; } if ($nagiosmsg =~ /^$/) { print "/etc/resolv.conf OK\n"; } else { print $nagiosmsg . "\n"; } exit $retval;