1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
#!/usr/bin/perl -w
#------------------------------------------------------------------------------
# Usage: mresolv2 [ -t timeout ] [ file... ]
#
# Reads IP addresses and issues non-blocking DNS queries. Answers are
# sent to standard output in RR format:
#
# 1.1.168.192.in-addr.arpa. 86400 IN PTR host1.example.com.
#
# 1.2.168.192.in-addr.arpa. 86400 IN CNAME 1.0-16.2.168.192.in-addr.arpa.
# 1.0-16.2.168.192.in-addr.arpa. 86400 IN PTR host2.example.com.
#
# Michael Fuhr
# mike@fuhr.org
#
# Copyright (c) 1999-2000 Michael Fuhr. All rights reserved. This program
# is free software; you can redistribute it and/or modify it under the same
# terms as Perl itself.
#
# $Id: mresolv2,v 1.3 2000/11/24 17:14:40 mfuhr Exp mfuhr $
#------------------------------------------------------------------------------
use IO::Socket;
use IO::Select;
use Net::DNS;
use Getopt::Std;
use strict;
use constant DEFAULT_TIMEOUT => 30;
use constant DEFAULT_NAMESERVER => "127.0.0.1";
use constant DEFAULT_PORT => 53;
use constant DEFAULT_SRCADDR => "0.0.0.0";
use constant DEFAULT_SRCPORT => 0;
$| = 1;
#------------------------------------------------------------------------------
# Get the timeout or use a reasonable default.
#------------------------------------------------------------------------------
my $progname = $0;
$progname =~ s!.*/!!;
my %opt;
getopts("t:", \%opt);
my $timeout = defined($opt{"t"}) ? $opt{"t"} : DEFAULT_TIMEOUT;
die "$progname: invalid timeout: $timeout\n" if $timeout < 0;
#------------------------------------------------------------------------------
# Create a socket pointing at the default nameserver.
#------------------------------------------------------------------------------
my $sock = IO::Socket::INET->new(Proto => "udp");
die "couldn't create socket: $!" unless $sock;
my $sockaddr_src = sockaddr_in(DEFAULT_SRCPORT, inet_aton(DEFAULT_SRCADDR));
$sock->bind($sockaddr_src) or die "can't bind socket: $!";
my $res = Net::DNS::Resolver->new;
my $ns = $res->nameservers ? ($res->nameservers)[0] : DEFAULT_NAMESERVER;
my $sockaddr_dst = sockaddr_in(DEFAULT_PORT, inet_aton($ns));
my $sel = IO::Select->new;
$sel->add($sock);
#------------------------------------------------------------------------------
# Read IP addresses and send queries.
#------------------------------------------------------------------------------
my $pending = 0;
while (<>) {
chomp;
next unless /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/;
my $ip = "$4.$3.$2.$1.in-addr.arpa";
my $packet = Net::DNS::Packet->new($ip, "PTR");
$sock->send($packet->data, 0, $sockaddr_dst) or die "send: $ip: $!";
++$pending;
while ($sel->can_read(0)) {
--$pending;
my $buf = "";
$sock->recv($buf, 512) or die "recv: $!";
next unless $buf;
my $ans = Net::DNS::Packet->new(\$buf);
next unless $ans;
foreach my $rr ($ans->answer) {
$rr->print;
if ($rr->type eq "CNAME") {
my $cname = $rr->cname;
my $packet = Net::DNS::Packet->new($cname, "PTR");
$sock->send($packet->data, 0, $sockaddr_dst)
or die "send: $cname: $!";
++$pending;
}
}
}
}
#------------------------------------------------------------------------------
# Wait for outstanding requests until all are complete or we've timed out.
#------------------------------------------------------------------------------
while ($pending > 0 && $sel->can_read($timeout)) {
--$pending;
my $buf = "";
$sock->recv($buf, 512) or die "recv: $!";
next unless $buf;
my $ans = Net::DNS::Packet->new(\$buf);
next unless $ans;
foreach my $rr ($ans->answer) {
$rr->print;
if ($rr->type eq "CNAME") {
my $cname = $rr->cname;
my $packet = Net::DNS::Packet->new($cname, "PTR");
$sock->send($packet->data, 0, $sockaddr_dst)
or die "send: $cname: $!";
++$pending;
}
}
}
|