in reply to loop ending b4 I want it to

As an alternative to FunkyMonk's suggestion (essentially echoed by jasonk), you may want to keep your "sub nsqry" to answer just a single Name lookup.

If this is the case, you need to add one more loop :

for my $key (keys %AoH) { for my $domain qw(ns7.xxx.com wrnadc02.xx.xxxxxx.com) { nsqry($domain, $_ ) for @{$AoH{$key}} ; } }
By the way, your %AoH is really a HASH whose VALUES are Array-refs, and would probably be better named as "HoA".

I imagine (Having written similar functionality myself), that you may eventually want to associate the domain name with the IP-address when you find it. Your current data structure will make that association very complicated. Here is my suggested structure/code:

my @domain = ( {NAME => 'ns7.xxx.com', IPLIST => []} # IP +LIST gets populated dynamically, as discovered , {NAME => 'wrnadc02.xx.xxxxxx.com', IPLIST => []} ); my %IPinfo; # This will be a HoH for (qw (10.220.84.30 10.220.84.51 10.220.84.52 10.220.84.54 ...){ $IPinfo{$_}= {DOMAININDEX => undef, TYPE => "CLIENT"}; } .... OUTER: for my $ip (keys %IPinfo){ for my $domidx (0..$#domain){ my $ptr = nsquery($domain[$domidx]->{NAME}, $ip) ; # Assumi +ng "nsquery" has been modified to return the info next unless $ptr; # No change, if $ptr is empty $IPinfo{$ip}{DOMAININDEX} = $domidx; # Forward ref from IP +to DOMAIN $IPinfo{$ip}{PTR} = $ptr; push @{$domain[$domidx]->{IPLIST}}, $ip; # Keep a list of I +P's that live in this domain next OUTER; # we bail after the first domain found (More ef +ficient) } }

     "As you get older three things happen. The first is your memory goes, and I can't remember the other two... " - Sir Norman Wisdom

Replies are listed 'Best First'.
Re^2: loop ending b4 I want it to
by mikejones (Scribe) on Oct 28, 2007 at 06:43 UTC
    yes you are right...I would like to match the domain names with the IP lookup, however I do not want to skip the second lookup if any IP is found in the 1st domain because I want to see if an IP is in both domains. When you said "Assuming "nsqry" has been modified to return the info," I became confused in trying to modify the sub. Will you help?
    #!/usr/bin/perl use strict; use warnings; use Carp; use Net::DNS; use Data::Dumper; my @domain = ( { NAME => 'ns7.pyxis.com', IPLIST => [] } , ## Autovivification { NAME => 'wrnadc02.na.alarismed.com', IPLIST => [] } ) ; my %IPinfo; # HoH for my $IP (qw ( 10.220.84.30 10.220.84.51 10.220.84.52 10.220.84.54 10.220.84.55 10.220.84.56 10.220.84.57 10.220.84.58 10.220.84.59 10.220.84.60 10.220.84.61 10.220.84.62 10.220.84.64 10.220.84.65 10.220.84.70 10.220.84.71 10.220.84.72 10.220.84.73 10.220.84.74 )) { $IPinfo{$IP} = {DOMAININDEX => undef, TYPE => "CLIENT" } ; } for my $ip (keys %IPinfo) { for my $domids (0..$#domain) { my $ptr = nsqry($domain[$domids]->{NAME}, $ip) ; next unless $ptr ; # No change, if $ptr is empty $IPinfo{$ip}{DOMAININDEX} = $domids ; $IPinfo{$ip}{PTR} = $ptr ; push @{$domain[$domids]->{IPLIST}}, $ip ; } } sub nsqry { my ( $nssvr, @clients ) = @_ ; my $res = Net::DNS::Resolver->new ( nameservers => [$nssvr], recurse => 1, ## do recursive lookups retry => 1, debug => 0, ) ; for my $client (@clients) { my $query = $res->search($client) ; if ($query) { for my $rr ($query->answer) { next unless ($rr->type eq "PTR"); print $rr->ptrdname, "\n" ; } } else { warn "query failed: ", $res->errorstring, "\n" ; } } } print Dumper(\@domain); $VAR1 = [ { 'NAME' => 'ns7.pyxis.com', 'IPLIST' => [] }, { 'NAME' => 'wrnadc02.na.alarismed.com', 'IPLIST' => [] } ];
      It is not clear what you are trying to achieve.

      Your code shows attempts to explicitly specify domain name servers. Some issues that leave your approach and objectives hazy are:

      • You explicitly specify Name SERVERS, not domain names. This is OK, if all you want are PTR records.
      • 'wrnadc02.na.alarismed.com' does not seem to exist. In fact the "na" subdomain does not seem to exist
      • "alarismed.com" seems to have the same name server(s) as "pyxis.com", so the reason for specifying different Name servers is not clear.
      • You are re-creating a new $res object for each query.
      If your "sub nsqry" works as you expect, the only change necessary is to "return $rr->ptrdname" after (or instead of) printing it.On failure, "return undef".

      You can also use a modified example from the Net::DNS docs:

      sub new-nsqry{ my ($res, $IP) = @_; # Note: $res is created OUTSIDE the sub ... my $query = $res->query($IP, "PTR"); if ($query) { foreach $rr (grep { $_->type eq 'PTR' } $query->answer) { print $rr->ptrdname, " : $IP\n"; return $rr->ptrdname; } return undef; } else { warn "query failed for $IP: ", $res->errorstring, "\n"; return undef; } }

           "As you get older three things happen. The first is your memory goes, and I can't remember the other two... " - Sir Norman Wisdom

        I am trying to achieve lookups for each IP in each nameserver, telling me success or no success.

        We can disregard your first three bullet points, but the fourth yes I should only need to create one object. But since I have two nameservers, I need to lookup all these IPs twice, once in each nameserver. So do I still need one object? If so how do I dereference it? This code right below works, but no sure how to implement in the $res object code?

        #for my $ns (@namesvr) { # for my $keys (sort keys %$ns) { # print "$keys => $ns->{$keys}\n"; # } # print "\n"; #} #exit;

        #!/usr/bin/perl use strict; use warnings; use Carp; use Net::DNS; use Data::Dumper; ## AoH my @namesvr = ( { NAME => 'ns#.xxxx.com', IPLIST => [] } , +## Autovivification { NAME => 'wrnaxxxx.xx.xxxxx.com', IPLIST => [] } ) ; #print Dumper(\@namesvr);exit; my %IPinfo; ## HoH for my $IP (qw ( 10.220.84.30 10.220.84.51 10.220.84.52 10.220.84.54 10.220.84.55 10.220.84.56 10.220.84.57 10.220.84.58 )) { $IPinfo{$IP} = {DOMAININDEX => undef, TYPE => "CLIEN +T" } ; } our ( $res, $IP ) ; for my $ns (@namesvr) { for my $keys (sort keys %$ns) { $res = Net::DNS::Resolver->new ( nameservers => [$ns->{$keys}], recurse => 1, ## do recursive lookups retry => 1, debug => 0, ); } } for my $ip (keys %IPinfo) { for my $ids (0..$#namesvr) { my $ptr = nsqry($namesvr[$ids]->{NAME}, $ip) ; # nsqry has bee +n modified to return the info next unless $ptr ; # No change, if $ptr is empty $IPinfo{$ip}{DOMAININDEX} = $ids ; # Forward ref from IP to DO +MAIN $IPinfo{$ip}{PTR} = $ptr ; push @{$namesvr[$ids]->{IPLIST}}, $ip ; # Keep a list of IP's +that live in this domain } } sub nsqry { ( $res, $IP ) = @_ ; my $query = $res->query($IP, 'PTR') ; if ($query) { for my $rr ($query->answer) { next unless ($rr->type eq 'PTR') ; ## skip record if not e +q PTR ## print $rr->ptrdname ; return $rr->ptrdname ; } return undef ; } else { carp "query failed for $IP: ", $res->errorstring, "\n" ; return undef ; } }