g_speran has asked for the wisdom of the Perl Monks concerning the following question:

Hello Perl Monks, The code I have below, works fine for all intended purposes of what specifically needs to be accomplish. However, there is one item that i also would like to incorporate but not sure how or if it is possible. Is, there a way below, to incorporate the ability to specify one or more DNS resolvers to resolve the lookups against?

use Net::hostent; use Socket; use Data::Dumper::Simple; $IP='192.168.50.70'; $resolver='192.168.10.99'; Host_IP (); print "\n\n\n\n"; Host_Name ('garytest'); sub Host_IP () { $address=inet_aton($IP); if($hent = gethostbyaddr($address)) { $name = $hent->name; $aliases = $hent->aliases; $RESULT="NSLOOKUP by IP: $IP => $name"; print $RESULT; if (scalar(@{$aliases} > 1)) { $RESULT=" Multiple hostnames are being returned. Correc +t DNS\n"; $RESULT = $RESULT . " \taddress $IP has the following na +mes:\n"; $RESULT = $RESULT . "\t$_\n" for ($name, @{$aliases}); print $RESULT; } }else { $RESULT= "NSLOOKUP by IP: $IP => #### UNRESOLVABLE ####"; print $RESULT; } } sub Host_Name () { $name=shift; if ($hent = gethostbyname($name)) { $name2 = $hent->name; # in case different $addr_ref = $hent->addr_list; @addresses = map { inet_ntoa($_) } @$addr_ref; push(@all_addresses,@addresses); $RESULT= "NSLOOKUP by Name: $name => $name2 => " . join(', ', +sort(@addresses)) ; print $RESULT; if (scalar(@addresses) > 1) { $RESULT="\n Multiple IP Address being returned. Correct + DNS"; print $RESULT; } } else{ $RESULT= "NSLOOKUP by Name: $name => #### UNRESOLVABLE ####"; print $RESULT; } }

Replies are listed 'Best First'.
Re: Specifying a DNS resolver
by Fletch (Bishop) on Apr 03, 2023 at 13:29 UTC

    Presuming some flavour of *NIX the gethostfoo routines are going to go through the libc routines so they're going to use whatever configuration file those honor (nsswitch.conf, resolv.conf, yadda yadda yadda). If you want to customize what you're querying then Net::DNS is probably what you're going to want to look at using.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Re: Specifying a DNS resolver
by haukex (Archbishop) on Apr 03, 2023 at 17:26 UTC
      Request was to make it work with the 2 modules and not use an additional modules I am now doing some testing with the Net::DNS module
Re: Specifying a DNS resolver
by g_speran (Scribe) on Apr 07, 2023 at 02:18 UTC

    So i have taken the advise of using Net::DNS. For simplicity, I have located code on the web and modified it. For the most part I get what i need. I have figured out how to do the name servers, but unfortunately, i don't think it it meets my needs. But I could be missing something. I have specified 2x nameservers. the x.x.50.50 is not online currently. Is there a way using Net:DNS, it would attempt to query the name server, and produce an "error" to the fact of no response, then go to the next nameserver, so on and so forth? If the name server is responding, I would want to display "Name Server - <IP> - followed by all the results". Below is the code I attempted. The "query failed", currently never get executed because the other nameserver is responding

    use warnings; use strict; use Net::DNS; use Data::Dumper::Simple; my $dnsserver; my @resolver; #@resolver=qw[192.168.50.50, 192.168.10.98]; #foreach $dnsserver (@resolver) { #print "Validating Entries against $dnsserver\n"; my $resolver = Net::DNS::Resolver->new( nameservers =>[qw(192.168.50.50 192.168.10.98)], recurse => 0, debug => 1, ); my $ip = "192.168.50.70"; print " ##### Resolver State ##### \n"; $resolver->print; print "\n\n ##### End Resolver State ##### \n"; my $target_ip = join('.', reverse split(/\./, $ip)).".in-addr.arpa +"; my $query = $resolver->query($target_ip, 'PTR'); my $reply = $resolver->search("garytest.fedlab.local"); #warn Dumper(\$query, \$reply); if ($query) { foreach my $answer ($query->answer) { next unless $answer->type eq 'PTR'; print $answer->rdatastr, "\n"; } } else { print "query failed: ", $resolver->errorstring, "\n"; } if ($reply) { foreach my $rr ($reply->answer) { next unless $rr->type eq "A"; print $rr->address, "\n"; } } else { warn "query failed: ", $resolver->errorstring, "\n"; } #}

      What you would need for that is a loop, which is the very thing in your code which has been commented out. Why?

      Sample working solution (data modified to become an SSCCE):

      use warnings; use strict; use Net::DNS; my @resolver = qw[192.168.50.50 8.8.8.8]; for my $dnsserver (@resolver) { print "Validating Entries against $dnsserver\n"; my $resolver = Net::DNS::Resolver->new( nameservers =>[$dnsserver], recurse => 1, debug => 1, ); print " ##### Resolver State ##### \n"; $resolver->print; print "\n\n ##### End Resolver State ##### \n"; my $query = $resolver->query('www.perlmonks.org', 'A'); if ($query) { foreach my $answer ($query->answer) { next unless $answer->type eq 'A'; print $answer->rdatastr, "\n"; } } else { print "query failed: ", $resolver->errorstring, "\n"; next; } }

      🦛

        I commented it out because I was not sure if that was accurate or if there was a function with Net::DNS that was available that I was not aware or able locate searching the web. If doing the loop, as you have indicated and I had in the code is the best/only solution, I am going with it. Thank you for your response and have a great day