File Coverage

blib/lib/Net/DNS/Method/Hash.pm
Criterion Covered Total %
statement 53 61 86.8
branch 15 26 57.6
condition 15 26 57.6
subroutine 9 11 81.8
pod 0 2 0.0
total 92 126 73.0


line stmt bran cond sub pod time code
1             package Net::DNS::Method::Hash;
2              
3             require 5.005_62;
4 2     2   2474 use strict;
  2         4  
  2         72  
5 2     2   12 use warnings;
  2         4  
  2         55  
6              
7 2     2   10 use Carp;
  2         4  
  2         128  
8 2     2   8799 use Net::DNS;
  2         192003  
  2         221  
9 2     2   18 use Net::DNS::Method;
  2         5  
  2         146  
10 2     2   10 use vars qw($VERSION @ISA $AUTOLOAD);
  2         6  
  2         1526  
11              
12             @ISA = qw(Net::DNS::Method);
13              
14             $VERSION = '2.00';
15              
16             # Default responses
17             our $DEF_ZONE = 'some.com';
18              
19             sub new {
20 2     2 0 701 my $type = shift;
21 2   50     23 my $class = ref($type) || $type || "Net::DNS::Method::Hash";
22              
23 2         5 my $ref = shift;
24              
25 2 50       12 croak "Argument to new() must be a reference to a hash\n"
26             if (ref $ref ne 'HASH');
27              
28 2 50 33     51 my $self =
    50 33        
29             {
30             zone => (defined($ref) && defined($ref->{BaseDomain}) ?
31             lc $ref->{BaseDomain} : $DEF_ZONE),
32             hash => (defined($ref) && defined($ref->{Hash}) ?
33             $ref->{Hash} : {}),
34             };
35            
36 2         14 return bless $self, $class;
37             }
38              
39             sub _match {
40 8     8   338 my $q = lc shift;
41 8         14 my $d = shift;
42              
43 8         43 $q =~ s/\.+$//;
44              
45 8         35 my $pos = index($q, $d);
46              
47 8 100       38 return 1 if $q eq $d;
48 6 50 33     20 return 1 if $pos == 0 and (length($q) <= length($d));
49 6 100       38 return 1 if substr($q, $pos - 1, 1) eq '.';
50 2         10 return 0;
51             }
52              
53             sub ANY {
54 8     8 0 9275 my $self = shift;
55 8         17 my $q = shift;
56 8         12 my $ans = shift;
57              
58 8 100       36 if (_match($q->qname, $self->{zone})) {
59              
60             # warn "match ", $q->qname, "\n";
61              
62 6         24 my $ip = lc substr($q->qname, 0, index($q->qname, $self->{zone}) - 1);
63              
64             # warn "lookup of <$ip>\n";
65              
66 6         138 my $name = $q->qname;
67 6         141 $name =~ s/\.+$//;
68              
69 6 100 100     66 if (exists $self->{hash}->{$ip}
      100        
70             or exists $self->{hash}->{$name}
71             or exists $self->{hash}->{$name . "."})
72             {
73              
74             # warn "found ", $q->qname, "\n";
75              
76             # In this case, we should try to answer
77             # this question...
78              
79 4         5 my $answers = 0;
80              
81             # warn "question ", $q->qname, " resolves to $ip\n";
82             # warn "class ", $q->qclass, "\n";
83             # warn "type ", $q->qtype, "\n";
84              
85 4   66     37 my $set = $self->{hash}->{$ip}
86             || $self->{hash}->{$name}
87             || $self->{hash}->{$name . "."};
88              
89 4 50       14 if (!ref $set) {
90 0         0 $set = [ $set ];
91             }
92            
93 4         7 for my $data (@{$set}) {
  4         9  
94 4         14 my $rr = new Net::DNS::RR $q->qname . " " . $data;
95            
96             # warn "Check against rr type=", $rr->type, " class=",
97             # $rr->class, "\n";
98            
99 4 50 66     4378 if (($q->qtype eq 'ANY' or $rr->type eq $q->qtype)
      33        
100             and $rr->class eq $q->qclass)
101             {
102 4         252 $ans->push('answer', $rr);
103 4         185 ++ $answers;
104             }
105             }
106            
107 4 50       15 if ($answers) { # If we have something to say, we
108             # return success...
109              
110 4         13 $ans->header->rcode('NOERROR');
111 4         3868 return NS_OK | NS_STOP;
112             }
113             }
114             }
115              
116             # warn "NS_FAIL\n";
117 4         15 return NS_FAIL;
118             }
119              
120             sub AUTOLOAD {
121 0     0     my $sub = $AUTOLOAD;
122 0           $sub =~ s/.*:://;
123              
124             # Insure that the called method has an all
125             # uppercase name. This avoids any clash with
126             # future extensions for these handlers, which
127             # will use mixed case or lowercase.
128              
129 0 0         return undef if $sub eq 'DESTROY';
130 0 0         return NS_FAIL unless $sub eq uc $sub;
131              
132 0     0     *$sub = sub { ANY @_; };
  0            
133 0           goto &$sub;
134             }
135              
136             1;
137             __END__