File Coverage

blib/lib/Net/DNS.pm
Criterion Covered Total %
statement 68 68 100.0
branch 22 22 100.0
path n/a
condition n/a
subroutine 17 17 100.0
pod 13 13 100.0
total 120 120 100.0


line stmt bran path cond sub pod time code
1               package Net::DNS;
2                
3 88       88   8399108 use strict;
  88           132  
  88           2765  
4 88       88   336 use warnings;
  88           154  
  88           9574  
5                
6               our $VERSION;
7               $VERSION = '1.55';
8               $VERSION = eval {$VERSION};
9               our $SVNVERSION = (qw$Id: DNS.pm 2051 2026-06-11 14:06:42Z willem $)[2];
10                
11                
12               =head1 NAME
13                
14               Net::DNS - Perl Interface to the Domain Name System
15                
16               =head1 SYNOPSIS
17                
18               use Net::DNS;
19               my $resolver = Net::DNS::Resolver->new(...);
20               my $response = $resolver->send(...);
21                
22               =head1 DESCRIPTION
23                
24               Net::DNS is a collection of Perl modules that act as a Domain Name System
25               (DNS) resolver. It allows the programmer to perform DNS queries that are
26               beyond the capabilities of "gethostbyname" and "gethostbyaddr".
27                
28               The programmer should be familiar with the structure of a DNS packet
29               and the zone file presentation format described in RFC1035.
30                
31               =cut
32                
33                
34 88       88   39229 use integer;
  88           1246  
  88           414  
35                
36 88       88   3170 use base qw(Exporter);
  88           196  
  88           87794  
37               our @EXPORT = qw(SEQUENTIAL UNIXTIME YYYYMMDDxx
38               yxrrset nxrrset yxdomain nxdomain rr_add rr_del
39               mx rr rrsort);
40                
41                
42               local $SIG{__DIE__};
43               require Net::DNS::Resolver;
44               require Net::DNS::Packet;
45               require Net::DNS::RR;
46               require Net::DNS::Update;
47                
48                
49 1       1 1 112549 sub version { return $VERSION; }
50                
51                
52               #
53               # rr()
54               #
55               # Usage:
56               # @rr = rr('example.com');
57               # @rr = rr('example.com', 'A', 'IN');
58               # @rr = rr($res, 'example.com' ... );
59               #
60               sub rr {
61 7       7 1 3196 my @arg = @_;
62 7 100         56 my $res = ( ref( $arg[0] ) ? shift @arg : Net::DNS::Resolver->new() );
63                
64 7           35 my $reply = $res->query(@arg);
65 7 100         50 my @list = $reply ? $reply->answer : ();
66 7           143 return @list;
67               }
68                
69                
70               #
71               # mx()
72               #
73               # Usage:
74               # @mx = mx('example.com');
75               # @mx = mx($res, 'example.com');
76               #
77               sub mx {
78 4       4 1 1257 my @arg = @_;
79 4 100         22 my @res = ( ref( $arg[0] ) ? shift @arg : () );
80 4           14 my ( $name, @class ) = @arg;
81                
82               # This construct is best read backwards.
83               #
84               # First we take the answer section of the packet.
85               # Then we take just the MX records from that list
86               # Then we sort the list by preference
87               # We do this into an array to force list context.
88               # Then we return the list.
89                
90 3           18 my @list = sort { $a->preference <=> $b->preference }
91 4           15 grep { $_->type eq 'MX' } &rr( @res, $name, 'MX', @class );
  6           33  
92 4           58 return @list;
93               }
94                
95                
96               #
97               # rrsort()
98               #
99               # Usage:
100               # @prioritysorted = rrsort( "SRV", "priority", @rr_array );
101               #
102               sub rrsort {
103 12       12 1 4234 my @arg = @_;
104 12           36 my $rrtype = uc shift @arg;
105 12           31 my ( $attribute, @rr ) = @arg; ## NB: attribute is optional
106 12 100         61 ( @rr, $attribute ) = @arg if ref($attribute) =~ /^Net::DNS::RR/;
107                
108 12           29 my @extracted = grep { $_->type eq $rrtype } @rr;
  89           254  
109 12 100         47 return @extracted unless scalar @extracted;
110 10           77 my $func = "Net::DNS::RR::$rrtype"->get_rrsort_func($attribute);
111 10           53 my @sorted = sort $func @extracted;
112 10           73 return @sorted;
113               }
114                
115                
116               #
117               # Auxiliary functions to support policy-driven zone serial numbering.
118               #
119               # $successor = $soa->serial(SEQUENTIAL);
120               # $successor = $soa->serial(UNIXTIME);
121               # $successor = $soa->serial(YYYYMMDDxx);
122               #
123                
124 3       3 1 14 sub SEQUENTIAL { return (undef) }
125                
126 1       1 1 6 sub UNIXTIME { return CORE::time; }
127                
128               sub YYYYMMDDxx {
129 2       2 1 65 my ( $dd, $mm, $yy ) = (localtime)[3 .. 5];
130 2           14 return 1900010000 + sprintf '%d%0.2d%0.2d00', $yy, $mm, $dd;
131               }
132                
133                
134               #
135               # Auxiliary functions to support dynamic update.
136               #
137                
138               sub yxrrset {
139 5       5 1 1287 my @arg = @_;
140 5           26 my $rr = Net::DNS::RR->new(@arg);
141 5           15 $rr->ttl(0);
142 5 100         14 $rr->class('ANY') unless $rr->rdata;
143 5           25 return $rr;
144               }
145                
146               sub nxrrset {
147 2       2 1 589 my @arg = @_;
148 2           24 my $rr = Net::DNS::RR->new(@arg);
149 2           7 return Net::DNS::RR->new(
150               name => $rr->name,
151               type => $rr->type,
152               class => 'NONE'
153               );
154               }
155                
156               sub yxdomain {
157 2       2 1 435 my @arg = @_;
158 2           4 my ( $domain, @etc ) = map {split} @arg;
  3           9  
159 2 100         10 my $rr = Net::DNS::RR->new( scalar(@etc) ? @arg : ( name => $domain ) );
160 2           7 return Net::DNS::RR->new(
161               name => $rr->name,
162               type => 'ANY',
163               class => 'ANY'
164               );
165               }
166                
167               sub nxdomain {
168 2       2 1 669 my @arg = @_;
169 2           4 my ( $domain, @etc ) = map {split} @arg;
  3           11  
170 2 100         12 my $rr = Net::DNS::RR->new( scalar(@etc) ? @arg : ( name => $domain ) );
171 2           7 return Net::DNS::RR->new(
172               name => $rr->name,
173               type => 'ANY',
174               class => 'NONE'
175               );
176               }
177                
178               sub rr_add {
179 4       4 1 1162 my @arg = @_;
180 4           18 my $rr = Net::DNS::RR->new(@arg);
181 4 100         16 $rr->{ttl} = 86400 unless defined $rr->{ttl};
182 4           13 return $rr;
183               }
184                
185               sub rr_del {
186 3       3 1 1604 my @arg = @_;
187 3           7 my ( $domain, @etc ) = map {split} @arg;
  3           16  
188 3 100         26 my $rr = Net::DNS::RR->new( scalar(@etc) ? @arg : ( name => $domain, type => 'ANY' ) );
189 3 100         13 $rr->class( $rr->rdata ? 'NONE' : 'ANY' );
190 3           11 $rr->ttl(0);
191 3           11 return $rr;
192               }
193                
194                
195               1;
196               __END__