anslookup.pl
1 | #!/usr/bin/perl
2 | # anslookup.pl v1.43
3 | # Authoritative nslookup by Boris 'pi' Piwinger <3.14@piology.org>
4 | unless (@ARGV) {print "\nUsage: anslookup.pl [-type ...] hostname [hostname ...]\n type: whatever you would like to ask (like A, CNAME, NS, MX etc.)\n default: -A -CNAME\n -ANY shows everything\n\n";exit;}
5 | my%opt;
6 | while (substr($ARGV[0],0,1) eq "-")
7 | {$opt{uc(substr(shift,1,8))}=1;}
8 | if ($opt{"ANY"}) {$opt{"NS"}=1;$opt{"A"}=1;$opt{"CNAME"}=1;$opt{"MX"}=1;$opt{"TXT"}=1;$opt{"SOA"}=1;}
9 | unless (%opt) {%opt=qw(A 1 CNAME 1)}
10 | my%mainopt=%opt;
11 | my$ip='(?:[01]?\d\d?|2[0-4]\d|25[0-5])'; # one byte of an IP-address
12 | $ip="($ip)\.($ip)\.($ip)\.($ip)"; # complete IP-address
13 | use Net::DNS;
14 | my$res=Net::DNS::Resolver->new;
15 | srand;
16 | my$defaultNS=$res->send(".","NS");
17 | my@defaultNS=$defaultNS->answer ? $defaultNS->answer : $defaultNS->authority;
18 | $defaultNS=$defaultNS[rand(@defaultNS)]->nsdname; # Ask God
19 | #my($defaultNS)=$res->nameservers; # Ask your local dealer
20 | print "DNS-Server to resolve TLDs: $defaultNS\n";
21 | while (my$host=shift) {
22 | %opt=%mainopt;
23 | $host=~s/\.$//;
24 | print "\nQuerying $host:\n";
25 | unless ($host=~/^(?:[a-zA-Z0-9\/-]+\.)*[a-zA-Z0-9\/-]+$/) {print " No host name.\n";next;}
26 | if ($host=~/^$ip$/) {$host="$4.$3.$2.$1.IN-ADDR.ARPA"}
27 | if ($host=~/\.IN-ADDR\.ARPA$/i) {
28 | %opt=("PTR",1);
29 | } else {undef($opt{"PTR"})}
30 | $res->nameservers($defaultNS);
31 | &FINDNS($host,"(?:[a-zA-Z0-9-]+)"," ");
32 | }
33 |
34 | sub FINDNS {
35 | my($host,$re,$indent)=@_;
36 | if ($host=~/($re|^.*\.IN-ADDR\.ARPA)$/) {
37 | my$subhost=$1;
38 | # Try to find name server for $subhost.
39 | if (my$query=$res->send($subhost.".", $opt{"PTR"} ? "PTR" : "NS")) {
40 | my$i=0;
41 | foreach my $rr ($query->answer ? $query->answer : $query->authority) {
42 | next unless ($rr->type eq "NS");
43 | next if (lc($rr->name) ne lc($subhost) && ! $opt{"PTR"});
44 | $i++;
45 | print "$indent$subhost-NS: ", $rr->nsdname, "\n";
46 | my($olddns)=$res->nameservers($rr->nsdname);
47 | return 1 if (&FINDNS($host,"(?:[a-zA-Z0-9-]+\\.)".$re,$indent." "));
48 | $res->nameservers($olddns);
49 | }
50 | return 1 if ($i); # No answer available, stop anyway.
51 | }
52 | # No nameserver found, lookup host.
53 | return 1 if (&RESOLVEHOST($host,$indent));
54 | } else { # $subhost eq $host
55 | return 1 if (&RESOLVEHOST($host,$indent));
56 | }
57 | }
58 |
59 | sub RESOLVEHOST {
60 | if (my$query=$res->send($_[0].".","ANY")) {
61 | my$done=0;
62 | foreach my $rr ($query->answer ? $query->answer : $query->authority) {
63 | if ($rr->type eq "NS" && $opt{"NS"}) {
64 | print $_[1]."DNS server for $_[0]: ", $rr->nsdname, "\n";
65 | $done=1;
66 | } elsif ($rr->type eq "A" && $opt{"A"}) {
67 | print $_[1]."Address of $_[0]: ", $rr->address, "\n";
68 | $done=1;
69 | } elsif ($rr->type eq "CNAME" && ($opt{"CNAME"} || $opt{"PTR"})) {
70 | print $_[1]."$_[0] is an alias of: ", $rr->cname, "\n";
71 | $done=1;
72 | } elsif ($rr->type eq "MX" && $opt{"MX"}) {
73 | print $_[1]."Mail for $_[0] handled (pri=".$rr->preference.") by: ", $rr->exchange, "\n" ;
74 | $done=1;
75 | } elsif ($rr->type eq "TXT" && $opt{"TXT"}) {
76 | print $_[1]."DNS text for $_[0]: ", $rr->txtdata, "\n";
77 | $done=1;
78 | } elsif ($rr->type eq "SOA" && $opt{"SOA"}) {
79 | print $_[1]."SOA for $_[0]:\n";
80 | print $_[1]." primary nameserver: ".$rr->mname."\n";
81 | print $_[1]." person responsible for this zone: ".$rr->rname."\n";
82 | print $_[1]." serial number: ".$rr->serial."\n";
83 | print $_[1]." refresh interval: ".$rr->refresh."\n";
84 | print $_[1]." retry interval: ".$rr->retry."\n";
85 | print $_[1]." expire interval: ".$rr->expire."\n";
86 | print $_[1]." minimum (default) TTL: ".$rr->minimum."\n";
87 | $done=1;
88 | } elsif ($rr->type eq "PTR" && $opt{"PTR"}) {
89 | print $_[1]."Host name for $_[0]: ". $rr->ptrdname."\n";
90 | $done=1;
91 | } elsif ($opt{$rr->type}||$opt{"ANY"}) {
92 | print $_[1];
93 | $rr->print;
94 | $done=1;
95 | }
96 | }
97 | unless ($done) {
98 | if ($res->errorstring eq "NXDOMAIN") {
99 | print $_[1]."$_[0] does not exist (NXDOMAIN).\n";
100 | } else {
101 | print $_[1]."$_[0]: No answer for your question.\n";
102 | return 0;
103 | }
104 | }
105 | return 1;
106 | } elsif ($res->errorstring eq "NXDOMAIN" || $res->errorstring eq "NOERROR") {
107 | print $_[1]."$_[0] does not exist (".$res->errorstring.").\n";
108 | return 1;
109 | } else {
110 | print $_[1]."Cannot resolve host $_[0]: ", $res->errorstring, "\n";
111 | return 0;
112 | }
113 | }

© Boris 'pi' Piwinger,
June 3, 2004