John Rudd wrote:

I'm a prophet now!?

:-)

Hm. So, I'm sure I can figure this out eventually, but does anyone know the right Net::DNS way to extract the TTL?


Net::DNS::RR has a ttl() function.

# perl ttl_test
Lookup: A www.uribl.com
www.uribl.com 591 IN A 209.200.135.149

--------------------------------------------------------

use Net::DNS;

my $res = Net::DNS::Resolver->new;
&lookup('www.uribl.com', 'A');
exit;

sub lookup {
 my ($host, $rr) = @_;
 print "Lookup: $rr $host\n";

 my $packet = $res->send($host, $rr);
 return unless $packet;

 my $header = $packet->header;
 return if ($header->rcode =~ m/NXDOMAIN|SERVFAIL|REFUSED/i);

 my @answer = $packet->answer;
 foreach $a (@answer) {
   my $type = $a->type;
   my $ttl  = $a->ttl;
   if ($type eq 'A') {
     print "$host $ttl IN $a ", $a->address, "\n";
   }
   # support other rr types below...
 }
}


Note that Net::DNS returns the ttl from the answer record, which means if you have a caching nameserver, your ttl may be lower than the value returned from the authoritative nameservers. Pulling a ttl from an SOA wont work either, as ttl can be set per RR. The only proper way to do this is to perform a lookup, set the $res->nameservers() to those from the $packet->authority and re-run the query. That will give you authoritative results, and the ttl will be the proper one.
Something like this...

        @authority = $packet->authority;

        if (scalar @authority) {
          @ns=();  # reset nameservers...
          foreach my $a (@authority) {
            my $type = $a->type;
            my $s = $a->rdatastr;
            if ($type =~ m/ns/i) {
              $s=~s/\.$//;
              push(@ns,$s);
            }
          }
          $res->nameservers(@ns);
        }

Pulling authoritative results can be quite slow, so you may want to alarm it to prevent timeouts from hanging you up.

--
Dallas Engelken
[EMAIL PROTECTED]
http://uribl.com

Reply via email to