#!/opt/csw/bin/perl
#
use warnings;
use strict;
# -------- USED PERL MODILES
use Net::Nslookup; #http://search.cpan.org/~darren/Net-Nslookup-2.01/lib/Net/Nslookup.pm
use Net::Ping; # http://search.cpan.org/~smpeters/Net-Ping-2.36/lib/Net/Ping.pm
# ---------- GET SORTED LIST OF HOSTS FROM netgroup FILE
# define files
my $netgroup = "netgroup.nis"; # example: file nis-master:/var/yp/src/netgroup
my $netgrouponlyip = "netgroup-only-ip"; # file has only IPs taken from netgroup.nis
my $netgrouponlyhostname = "netgroup-only-hostname"; # file has only hostnames taken from netgroup.nis
# open file for reading
open (NG, "< $netgroup") or die "Can't open file $netgroup: $!" ; #open file for reading
my @netgroup = <NG>; # store file in array
close (NG) or die "Can't close file $netgroup: $!" ; # and close the file
# open file for writing
open (LH, "> hosts.list") or die "Can't open hosts.list: $!";
foreach my $netgroup (@netgroup)
{
# remove comments, blank lines, lines without hosts (there is no user, domain in netgroup file)
# store lines as array, in scalar context grep returns number of times expresion is true
my @line = grep !/^#|^$/, grep /\(.*,,\)/, $netgroup;
# $line is scalar, list of hosts in one line
foreach my $line (@line)
{
# select lines with hosts, ignore lines with only netgroups
$line =~ s/\(//g;
$line =~ s/,,\)//g;
# remove netgroup name
$line =~ s/^\S+\s+// ; #\S any nonwhitespace character
$line =~ s/\s+/\n/g ; # replace whitespace with new line
print LH "$line" ;
}
}
close LH or die "Can't close hosts.list: $!";
# sort hostnames
open (LH, "< hosts.list") or die "Can't open hosts.list: $!";
open (SLH, "> sort.hosts.list") or die "Can't open sort.hosts.list: $!";
my @hostlines = <LH>;
@hostlines = sort(@hostlines);
foreach my $hostline (@hostlines)
{
print SLH "$hostline";
}
close(LH) or die "Can't close hosts.list: $!";
close(SLH) or die "Can't close sort.hosts.list: $!";
rename("hosts.list", "hosts.list.orig");
rename("sort.hosts.list", "hosts.list");
# ---------- DEVIDE netgroup FILE TO netgroup-only-ip AND netgroup-only-hostname
open (HOSTL, "< hosts.list") or die "Can't open hosts.list: $!";
my @ipline = <HOSTL>;
close HOSTL or die "Can't close hosts.list: $!";
open (IP, "> $netgrouponlyip") or die "Can't open file $netgrouponlyip: $!";
open (NOIP, "> $netgrouponlyhostname") or die "Can't open file $netgrouponlyhostname: $!";
foreach my $ipline (@ipline)
{
if ( $ipline =~ m/^\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b$/ )
{
print IP "$ipline";
}
else
{
print NOIP "$ipline";
}
}
close IP or die "Can't close $netgrouponlyip: $!";
print "File $netgrouponlyip created - contains only IP from netgroup. \n" ;
close NOIP or die "Can't close $netgrouponlyhostname: $!";
print "File $netgrouponlyhostname created - contains only hostnames from netgroup. \n" ;
# -------------- CHECK DNS/PING AND CREATE FILES netgroup.problem.dns, netgroup.problem.ping, netgroup.ok
open (LH, "< $netgrouponlyhostname") or die "Can't open file $netgrouponlyhostname: $!";
my @machines = <LH>; # store file in array and close file
close (LH) or die "Can't close file $netgrouponlyhostname: $!";
open (DNSPROBLEM, "> netgroup.problem.dns") or die "Can't open netgroup.problem.dns: $!";
open (PINGPROBLEM, "> netgroup.problem.ping") or die "Can't open netgroup.problem.ping: $!";
open (OK, "> netgroup.ok") or die "Can't open netgroup.ok: $!";
foreach my $machine (@machines)
{
chomp($machine);
print " \n----------- $machine \n";
if ( my $ip = nslookup( domain => "$machine", type => 'A' ) )
{
if ( my $fqdn = nslookup ( domain => $ip, type => 'PTR' ) )
{
if ( $machine ne $fqdn )
{
# original name differs from resolved IP, check is it problem or name is alias
if ( my $realmachine = nslookup ( domain => "$machine", type => 'CNAME' ) )
{
# OK: original name is alias, continue with ping test
print "ALIAS: $machine" . "\n" . "IP: $ip" . "\n" . "REALNAME: $realmachine \n";
my $p = Net::Ping->new();
if ( $p->ping($realmachine) )
{
print "PING OK: $realmachine \n";
# print to netgroup.ok
print OK "$machine (alias for $realmachine) \n";
}
else
{
print "PING PROBLEM: $realmachine \n";
# print to netgroup.problem.ping
print PINGPROBLEM "$machine (alias for $realmachine) \n";
}
$p->close();
}
else
{
# PROBLEM: original name differs from resolved IP
print "ORIG: $machine" . "\n" . "IP: $ip" . "\n" . "PTR_Problem: $machine differs from resolved IP ($fqdn) \n";
# print to netgroup.problem.dns
print DNSPROBLEM "$machine (differs from resolved IP: $fqdn) \n";
}
}
else
{
# OK: original name is same as resolved IP, continue with ping test
print "ORIG: $machine" . "\n" . "IP: $ip" . "\n" . "PTR_Resolv: $fqdn \n" ;
my $p = Net::Ping->new();
if ( $p->ping($machine) )
{
print "PING OK: $machine \n";
# print to netgroup.ok
print OK "$machine \n";
}
else
{
print "PING PROBLEM: $machine \n";
# print to netgroup.problem.ping
print PINGPROBLEM "$machine \n";
}
$p->close();
}
}
else
{
# PROBLEM: IP is resolved, but reverse lookup failes
print "Can't find FQDN from $ip \n";
# print to netgroup.problem.dns
print DNSPROBLEM "$machine (Can't find FQDN from $ip) \n";
}
}
else
{
# PROBLEM: original name can't resolve to IP
print "Can't find IP of $machine \n";
# print to netgroup.problem.dns
print DNSPROBLEM "$machine (Can't find IP) \n";
}
}
close (DNSPROBLEM) or die "Can't close netgroup.problem.dns: $!";
close (PINGPROBLEM) or die "Can't close netgroup.problem.ping: $!";
close (OK) or die "Can't close netgroup.ok: $!";
exit 0
|