File Coverage

blib/lib/Net/DNS/RR/NSEC.pm
Criterion Covered Total %
statement 129 129 100.0
branch 18 18 100.0
path n/a
condition 9 9 100.0
subroutine 23 23 100.0
pod 8 10 100.0
total 187 189 100.0


line stmt bran path cond sub pod time code
1               package Net::DNS::RR::NSEC;
2                
3 14       14   470619 use strict;
  14           24  
  14           438  
4 14       14   48 use warnings;
  14           21  
  14           1049  
5               our $VERSION = (qw$Id: NSEC.pm 2002 2025-01-07 09:57:46Z willem $)[2];
6                
7 14       14   67 use base qw(Net::DNS::RR);
  14           29  
  14           1637  
8                
9                
10               =head1 NAME
11                
12               Net::DNS::RR::NSEC - DNS NSEC resource record
13                
14               =cut
15                
16 14       14   70 use integer;
  14           19  
  14           86  
17                
18 14       14   424 use Net::DNS::DomainName;
  14           28  
  14           448  
19 14       14   62 use Net::DNS::Parameters qw(:type);
  14           24  
  14           21584  
20                
21                
22               sub _decode_rdata { ## decode rdata from wire-format octet string
23 1       1   1 my ( $self, $data, $offset ) = @_;
24                
25 1           1 my $limit = $offset + $self->{rdlength};
26 1           4 ( $self->{nxtdname}, $offset ) = Net::DNS::DomainName->decode( $data, $offset );
27 1           2 $self->{typebm} = substr $$data, $offset, $limit - $offset;
28 1           2 return;
29               }
30                
31                
32               sub _encode_rdata { ## encode rdata as wire-format octet string
33 20       20   32 my $self = shift;
34                
35 20           52 my $nxtdname = $self->{nxtdname};
36 20           67 return join '', $nxtdname->encode(), $self->{typebm};
37               }
38                
39                
40               sub _format_rdata { ## format rdata portion of RR string.
41 3       3   9 my $self = shift;
42                
43 3           5 my $nxtdname = $self->{nxtdname};
44 3           6 return ( $nxtdname->string(), $self->typelist );
45               }
46                
47                
48               sub _parse_rdata { ## populate RR from rdata in argument list
49 40       40   92 my ( $self, @argument ) = @_;
50                
51 40           107 $self->nxtdname( shift @argument );
52 40           98 $self->typelist(@argument);
53 40           85 return;
54               }
55                
56                
57               sub _defaults { ## specify RR attribute default values
58 5       5   10 my $self = shift;
59                
60 5           22 $self->_parse_rdata('.');
61 5           11 return;
62               }
63                
64                
65               sub nxtdname {
66 44       44 1 76 my ( $self, @value ) = @_;
67 44           75 for (@value) { $self->{nxtdname} = Net::DNS::DomainName->new($_) }
  42           146  
68 44 100         176 return $self->{nxtdname} ? $self->{nxtdname}->name : undef;
69               }
70                
71                
72               sub typelist {
73 244       244 1 9107 my ( $self, @argument ) = @_;
74                
75 244 100   100     732 if ( scalar(@argument) || !defined(wantarray) ) {
76 229           558 $self->{typebm} = &_type2bm(@argument);
77 229           497 return;
78               }
79                
80 15           42 my @type = &_bm2type( $self->{typebm} );
81 15 100         85 return wantarray ? (@type) : "@type";
82               }
83                
84                
85               sub typemap {
86 126       126 1 537 my ( $self, $type ) = @_;
87                
88 126           257 my $number = typebyname($type);
89 126           189 my $window = $number >> 8;
90 126           168 my $bitnum = $number & 255;
91                
92 126     100     307 my $typebm = $self->{typebm} || return;
93 125           167 my @bitmap;
94 125           204 my $index = 0;
95 125           283 while ( $index < length $typebm ) {
96 125           435 my ( $block, $size ) = unpack "\@$index C2", $typebm;
97 125           464 $bitmap[$block] = unpack "\@$index xxa$size", $typebm;
98 125           369 $index += $size + 2;
99               }
100                
101 125     100     1224 my @bit = split //, unpack 'B*', ( $bitmap[$window] || return );
102 124           834 return $bit[$bitnum];
103               }
104                
105                
106               sub match {
107 8       8 1 1630 my ( $self, $qname ) = @_;
108 8           20 my $name = Net::DNS::DomainName->new($qname)->canonical;
109 8           19 return $name eq $self->{owner}->canonical;
110               }
111                
112                
113               sub covers {
114 29       29 1 142 my ( $self, $qname ) = @_;
115 29           82 my $name = join chr(0), reverse Net::DNS::DomainName->new($qname)->_wire;
116 29           68 my $this = join chr(0), reverse $self->{owner}->_wire;
117 29           64 my $next = join chr(0), reverse $self->{nxtdname}->_wire;
118 29           63 foreach ( $name, $this, $next ) {tr /\101-\132/\141-\172/}
  87           108  
119                
120 29 100         65 return ( $name cmp $this ) + ( "$next\001" cmp $name ) == 2 unless $next gt $this;
121 23           100 return ( $name cmp $this ) + ( $next cmp $name ) == 2;
122               }
123                
124                
125               sub encloser {
126 42       42 1 4527 my ( $self, $qname ) = @_;
127 42           74 my @label = Net::DNS::Domain->new($qname)->label;
128                
129 42           76 my @owner = $self->{owner}->label;
130 42           38 my $depth = scalar(@owner);
131 42           39 my $next;
132 42           49 while ( scalar(@label) > $depth ) {
133 36           46 $next = shift @label;
134               }
135                
136 42 100         69 return unless defined $next;
137                
138 20           30 my $nextcloser = join( '.', $next, @label );
139 20 100         45 return if lc($nextcloser) ne lc( join '.', $next, @owner );
140                
141 12           14 $self->{nextcloser} = $nextcloser;
142 12           21 $self->{wildcard} = join( '.', '*', @label );
143 12           31 return $self->owner;
144               }
145                
146                
147 2       2 1 8 sub nextcloser { return shift->{nextcloser}; }
148                
149 2       2 1 8 sub wildcard { return shift->{wildcard}; }
150                
151                
152               ########################################
153                
154               sub _type2bm {
155 229       229   421 my @typelist = @_;
156 229           321 my @typearray;
157 229           425 foreach my $typename ( map { split() } @typelist ) {
  291           843  
158 302           628 my $number = typebyname($typename);
159 302           432 my $window = $number >> 8;
160 302           455 my $bitnum = $number & 255;
161 302           403 my $octet = $bitnum >> 3;
162 302           383 my $bit = $bitnum & 7;
163 302           782 $typearray[$window][$octet] |= 0x80 >> $bit;
164               }
165                
166 229           466 my $bitmap = '';
167 229           292 my $window = 0;
168 229           364 foreach (@typearray) {
169 234 100         543 if ( my $pane = $typearray[$window] ) {
170 214 100         626 my @content = map { $_ || 0 } @$pane;
  844           2268  
171 214           881 $bitmap .= pack 'CC C*', $window, scalar(@content), @content;
172               }
173 234           485 $window++;
174               }
175                
176 229           847 return $bitmap;
177               }
178                
179                
180               sub _bm2type {
181 15       15   141 my @empty;
182 15     100     39 my $bitmap = shift || return @empty;
183                
184 13           17 my $index = 0;
185 13           19 my $limit = length $bitmap;
186 13           14 my @typelist;
187                
188 13           27 while ( $index < $limit ) {
189 13           50 my ( $block, $size ) = unpack "\@$index C2", $bitmap;
190 13           28 my $typenum = $block << 8;
191 13           33 foreach my $octet ( unpack "\@$index xxC$size", $bitmap ) {
192 69           76 my $i = $typenum += 8;
193 69           72 my @name;
194 69           112 while ($octet) {
195 155           152 --$i;
196 155 100         268 unshift @name, typebyval($i) if $octet & 1;
197 155           642 $octet = $octet >> 1;
198               }
199 69           112 push @typelist, @name;
200               }
201 13           58 $index += $size + 2;
202               }
203                
204 13           43 return @typelist;
205               }
206                
207                
208               sub typebm { ## historical
209 1       1 0 4 my ( $self, @typebm ) = @_; # uncoverable pod
210 1           2 for (@typebm) { $self->{typebm} = $_ }
  1           2  
211 1           5 $self->_deprecate('prefer $rr->typelist() or $rr->typemap()');
212 1           5 return $self->{typebm};
213               }
214                
215               sub covered { ## historical
216 1       1 0 10 my ( $self, @argument ) = @_; # uncoverable pod
217 1           3 return $self->covers(@argument);
218               }
219                
220               ########################################
221                
222                
223               1;
224               __END__