File Coverage

blib/lib/Net/Nslookup.pm
Criterion Covered Total %
statement 46 56 82.1
branch 19 34 55.8
condition 11 18 61.1
subroutine 7 8 87.5
pod 0 3 0.0
total 83 119 69.7


line stmt bran cond sub pod time code
1             package Net::Nslookup;
2              
3             # -------------------------------------------------------------------
4             # Net::Nslookup - Provide nslookup(1)-like capabilities
5             # Copyright (C) 2002-2013 darren chamberlain
6             #
7             # This program is free software; you can redistribute it and/or
8             # modify it under the terms of the GNU General Public License as
9             # published by the Free Software Foundation; version 2.
10             #
11             # This program is distributed in the hope that it will be useful, but
12             # WITHOUT ANY WARRANTY; without even the implied warranty of
13             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14             # General Public License for more details.
15             #
16             # You should have received a copy of the GNU General Public License
17             # along with this program; if not, write to the Free Software
18             # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19             # 02111-1307 USA
20             # -------------------------------------------------------------------
21              
22 6     6   5453 use strict;
  6         13  
  6         270  
23 6     6   39 use vars qw($VERSION $DEBUG @EXPORT $TIMEOUT $WIN32);
  6         10  
  6         1193  
24 6     6   46 use base qw(Exporter);
  6         10  
  6         1066  
25              
26             $VERSION = "2.04";
27             @EXPORT = qw(nslookup);
28             $DEBUG = 0 unless defined $DEBUG;
29             $TIMEOUT = 15 unless defined $TIMEOUT;
30             $WIN32 = $^O =~ /win32/i;
31              
32 6     6   32 use Exporter;
  6         8  
  6         6024  
33              
34             my %_methods = qw(
35             A address
36             CNAME cname
37             MX exchange
38             NS nsdname
39             PTR ptrdname
40             TXT rdatastr
41             SOA dummy
42             SRV target
43             );
44              
45             # ----------------------------------------------------------------------
46             # nslookup(%args)
47             #
48             # Does the actual lookup, deferring to helper functions as necessary.
49             # ----------------------------------------------------------------------
50             sub nslookup {
51 15 100   15 0 9959 my $options = isa($_[0], 'HASH') ? shift : @_ % 2 ? { 'host', @_ } : { @_ };
    50          
52 15         39 my ($term, $type, @answers);
53              
54             # Some reasonable defaults.
55 15   50     222 $term = lc ($options->{'term'} ||
56             $options->{'host'} ||
57             $options->{'domain'} || return);
58 15   100     102 $type = uc ($options->{'type'} ||
59             $options->{'qtype'} || "A");
60 15   50     655 $options->{'server'} ||= '';
61 15   100     78 $options->{'recurse'} ||= 0;
62              
63 15 50       62 $options->{'timeout'} = $TIMEOUT
64             unless defined $options->{'timeout'};
65              
66 15 100       54 $options->{'debug'} = $DEBUG
67             unless defined $options->{'debug'};
68              
69 15         32 eval {
70 15     0   391 local $SIG{ALRM} = sub { die "alarm\n" };
  0         0  
71 15 50       177 alarm $options->{'timeout'} unless $WIN32;
72              
73 15   50     61 my $meth = $_methods{ $type } || die "Unknown type '$type'";
74 15         51 my $res = ns($options->{'server'});
75              
76 15 50       65 if ($options->{'debug'}) {
77 0         0 warn "Performing `$type' lookup on `$term'\n";
78             }
79              
80 15 50       102 if (my $q = $res->search($term, $type)) {
81 15 50       217169 if ('SOA' eq $type) {
82 0         0 my $a = ($q->answer)[0];
83 0         0 @answers = (join " ", map { $a->$_ }
  0         0  
84             qw(mname rname serial refresh retry expire minimum));
85             }
86             else {
87 15         89 @answers = map { $_->$meth() } grep { $_->type eq $type } $q->answer;
  27         1028  
  27         397  
88             }
89              
90             # If recurse option is set, for NS, MX, and CNAME requests,
91             # do an A lookup on the result. False by default.
92 15 50 33     1239 if ($options->{'recurse'} &&
      66        
93             (('NS' eq $type) ||
94             ('MX' eq $type) ||
95             ('CNAME' eq $type)
96             )) {
97              
98 6         47 @answers = map {
99 2         7 nslookup(
100             host => $_,
101             type => "A",
102             server => $options->{'server'},
103             debug => $options->{'debug'}
104             );
105             } @answers;
106             }
107             }
108              
109 15 50       932 alarm 0 unless $WIN32;
110             };
111              
112 15 50       159 if ($@) {
113 0 0       0 die "nslookup error: $@"
114             unless $@ eq "alarm\n";
115 0         0 warn qq{Timeout: nslookup("type" => "$type", "host" => "$term")};
116             }
117              
118 15 100       118 return $answers[0] if (@answers == 1);
119 5 50       54 return (wantarray) ? @answers : $answers[0];
120             }
121              
122             {
123             my %res;
124             sub ns {
125 15   50 15 0 76 my $server = shift || "";
126              
127 15 100       54 unless (defined $res{$server}) {
128 6         7679 require Net::DNS;
129 6         782810 import Net::DNS;
130 6         80 $res{$server} = Net::DNS::Resolver->new;
131              
132             # $server might be empty
133 6 50       3600 if ($server) {
134 0 0       0 if (ref($server) eq 'ARRAY') {
135 0         0 $res{$server}->nameservers(@$server);
136             }
137             else {
138 0         0 $res{$server}->nameservers($server);
139             }
140             }
141             }
142              
143 15         57 return $res{$server};
144             }
145             }
146              
147 15     15 0 216 sub isa { &UNIVERSAL::isa }
148              
149             1;
150             __END__