File: mresolv2

package info (click to toggle)
libnet-dns-perl 0.19-0.1
  • links: PTS
  • area: main
  • in suites: woody
  • size: 544 kB
  • ctags: 323
  • sloc: perl: 5,191; makefile: 54
file content (130 lines) | stat: -rwxr-xr-x 3,977 bytes parent folder | download
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;
        }
    }
}