File Coverage

blib/lib/DNS/BL/cmds/punch.pm
Criterion Covered Total %
statement 27 54 50.0
branch 0 18 0.0
condition 0 3 0.0
subroutine 9 10 90.0
pod 1 1 100.0
total 37 86 43.0


line stmt bran cond sub pod time code
1             package DNS::BL::cmds::punch;
2              
3 1     1   1815 use DNS::BL;
  1         3  
  1         30  
4              
5 1     1   37 use 5.006001;
  1         4  
  1         41  
6 1     1   6 use strict;
  1         2  
  1         100  
7 1     1   7 use warnings;
  1         3  
  1         56  
8              
9 1     1   7 use NetAddr::IP;
  1         2  
  1         24  
10 1     1   158 use DNS::BL::cmds;
  1         3  
  1         39  
11 1     1   5 use DNS::BL::Entry;
  1         2  
  1         34  
12              
13 1     1   6 use vars qw/@ISA/;
  1         2  
  1         55  
14              
15             @ISA = qw/DNS::BL::cmds/;
16              
17 1     1   6 use Carp;
  1         3  
  1         600  
18              
19             our $VERSION = '0.00_01';
20             $VERSION = eval $VERSION; # see L
21              
22             # Preloaded methods go here.
23              
24             =pod
25              
26             =head1 NAME
27              
28             DNS::BL::cmds::punch - Punch holes in entries within the database
29              
30             =head1 SYNOPSIS
31              
32             use DNS::BL::cmds::punch;
33              
34             =head1 DESCRIPTION
35              
36             This module implements the B command, used to punch holes in
37             existing DNSBL entries managed by L. The general syntax of
38             this command, is as follows
39              
40             punch hole
41              
42             where each argument has the following function:
43              
44             =over 4
45              
46             =item Bip-addressE>
47              
48             Specifies which IP address or network this command refers
49             to. Essentially, anything that L will understand. Entries
50             falling entirely within this range, will be deleted. Entries that
51             partially overlap with the given range, will be fragmented.
52              
53             =back
54              
55             This functionality is provided by the following method:
56              
57             =over
58              
59             =item C<-Eexecute()>
60              
61             See L for information on this method's general purpose
62             and calling convention.
63              
64             This method implements the behavior specified above.
65              
66             =cut
67              
68             sub execute
69             {
70 0     0 1   my $bl = shift;
71 0           my $command = shift;
72 0           my %args = @_;
73              
74 0           my @r = __PACKAGE__->arg_check($bl, 'punch', $command,
75             [ qw/hole/ ], \%args);
76 0 0         return wantarray ? (@r) : $r[0]
    0          
77             if $r[0] != &DNS::BL::DNSBL_OK;
78            
79 0           my $e = new DNS::BL::Entry;
80 0           my $ip;
81              
82             return wantarray ?
83 0 0 0       (&DNS::BL::DNSBL_ESYNTAX(),
    0          
84             "'punch' requires a valid 'hole' IP address")
85             : &DNS::BL::DNSBL_ESYNTAX()
86             unless exists $args{hole} and
87             $ip = new NetAddr::IP $args{hole};
88              
89 0           $e->addr($args{hole});
90              
91             # First, find out wether any space is covered by our hole. In
92             # this case, remove it
93              
94 0           @r = $bl->erase($e);
95              
96             # Now, find entries that cover our hole.
97              
98 0           @r = $bl->match($e);
99 0           shift @r;
100 0           shift @r;
101              
102             # For each entry, split it progressively...
103 0           while (my $r = shift @r)
104             {
105 0           my @t = $bl->erase($r);
106 0 0         if ($r->addr->masklen < $e->addr->masklen)
107             { # Split and keep...
108 0           my @p = $r->addr->split($r->addr->masklen + 1);
109 0           for my $p (@p)
110             {
111 0 0         if ($p->contains($e->addr))
112             {
113 0           my $c = $r->clone;
114 0           $c->addr($p);
115 0           push @r, $c;
116             }
117             else
118             {
119 0           my $c = $r->clone;
120 0           $c->addr($p);
121 0           my @t = $bl->write($c);
122             return wantarray ?
123 0 0         ($t[0], "'" . __PACKAGE__
    0          
124             . "' failed on add $p (" . $r->addr
125             . " dropped): $t[1]") : $t[0]
126             if $t[0] != &DNS::BL::DNSBL_OK;
127             }
128             }
129             }
130             }
131              
132 0 0         return wantarray ? (&DNS::BL::DNSBL_OK, "Hole punched") :
133             &DNS::BL::DNSBL_OK;
134             };
135              
136             1;
137             __END__