File Coverage

blib/lib/DNS/Zone/Record.pm
Criterion Covered Total %
statement 57 121 47.1
branch 19 64 29.6
condition 10 22 45.4
subroutine 8 21 38.1
pod 0 13 0.0
total 94 241 39.0


line stmt bran cond sub pod time code
1             #!/usr/local/bin/perl -w
2             ######################################################################
3             #
4             # DNS/Zone/Record.pm
5             #
6             # $Id: Record.pm,v 1.5 2003/02/04 15:37:35 awolf Exp $
7             # $Revision: 1.5 $
8             # $Author: awolf $
9             # $Date: 2003/02/04 15:37:35 $
10             #
11             # Copyright (C)2001-2003 Andy Wolf. All rights reserved.
12             #
13             # This library is free software; you can redistribute it and/or
14             # modify it under the same terms as Perl itself.
15             #
16             ######################################################################
17              
18             package DNS::Zone::Record;
19              
20 2     2   704 no warnings 'portable';
  2         4  
  2         71  
21 2     2   22 use 5.6.0;
  2         6  
  2         70  
22 2     2   10 use strict;
  2         3  
  2         65  
23 2     2   10 use warnings;
  2         13  
  2         116  
24              
25 2     2   11 use vars qw($AUTOLOAD);
  2         3  
  2         3623  
26              
27             my $VERSION = '0.85';
28             my $REVISION = sprintf("%d.%02d", q$Revision: 1.5 $ =~ /(\d+)\.(\d+)/);
29              
30             my %fields = (
31             OS => undef,
32             CPU => undef,
33             TTL => undef,
34             TYPE => undef,
35             TEXT => undef,
36             CNAME => undef,
37             EMAIL => undef,
38             RETRY => undef,
39             SERIAL => undef,
40             EXPIRE => undef,
41             DOMAIN => undef,
42             COMMENT => undef,
43             ADDRESS => undef,
44             NSERVER => undef,
45             REFRESH => undef,
46             MINIMUM => undef,
47             PROTOCOL => undef,
48             SERVICES => undef,
49             EXCHANGE => undef,
50             PREFERENCE => undef,
51             );
52              
53             ###
54             # Default type is '' and represents a
55             # comment. All other data is optional.
56             # When omitted TTL defaults to 0.
57             ###
58             sub new {
59 17     17 0 38 my($pkg, $ttl, $type, $data) = @_;
60 17   33     65 my $class = ref($pkg) || $pkg;
61              
62 17         36 my $self = {
63             '_ID' => undef,
64             };
65            
66 17   100     53 $self->{'TYPE'} = $type || '';
67 17   100     46 $self->{'TTL'} = $ttl || 0;
68              
69 17 100       82 if($type eq 'IN A') {
    50          
    50          
    100          
    100          
    50          
    100          
    50          
    50          
70 2         1111 $self->{'ADDRESS'} = $data;
71             }
72             elsif($type eq 'IN CNAME') {
73 0         0 $self->{'CNAME'} = lc $data;
74 0         0 $self->{'CNAME'} =~ s/\.$//;
75             }
76             elsif($type eq 'IN HINFO') {
77             (
78 0         0 $self->{'CPU'},
79             $self->{'OS'}
80             ) = split /\s+/, $data;
81             }
82             elsif($type eq 'IN MX') {
83 8         33 ($self->{'PREFERENCE'}, $self->{'EXCHANGE'}) = split /\s+/, $data;
84 8         21 $self->{'PREFERENCE'} = lc $self->{'PREFERENCE'};
85 8         16 $self->{'EXCHANGE'} = lc $self->{'EXCHANGE'};
86 8         30 $self->{'EXCHANGE'} =~ s/\.$//;
87             }
88             elsif($type eq 'IN NS') {
89 2         6 $self->{'NSERVER'} = lc $data;
90 2         13 $self->{'NSERVER'} =~ s/\.$//;
91             }
92             elsif($type eq 'IN PTR') {
93 0         0 $self->{'DOMAIN'} = lc $data;
94 0         0 $self->{'DOMAIN'} =~ s/\.$//;
95             }
96             elsif($type eq 'IN SOA') {
97 1         12 $data =~ s/\(|\)//g;
98              
99             (
100 1         11 $self->{'NSERVER'},
101             $self->{'EMAIL'},
102             $self->{'SERIAL'},
103             $self->{'REFRESH'},
104             $self->{'RETRY'},
105             $self->{'EXPIRE'},
106             $self->{'MINIMUM'}
107             ) = split /\s+/, $data;
108              
109 1         5 $self->{'NSERVER'} = lc $self->{'NSERVER'};
110 1         5 $self->{'NSERVER'} =~ s/\.$//;
111              
112 1         3 $self->{'EMAIL'} = lc $self->{'EMAIL'};
113 1         3 $self->{'EMAIL'} =~ s/\.$//;
114              
115 1         2 $self->{'SERIAL'} = lc $self->{'SERIAL'};
116 1         2 $self->{'REFRESH'} = lc $self->{'REFRESH'};
117 1         3 $self->{'RETRY'} = lc $self->{'RETRY'};
118 1         2 $self->{'EXPIRE'} = lc $self->{'EXPIRE'};
119 1         2 $self->{'MINIMUM'} = lc $self->{'MINIMUM'};
120             }
121             elsif($type eq 'IN TXT') {
122 0         0 $self->{'TEXT'} = $data;
123             }
124             elsif($type eq 'IN WKS') {
125             (
126 0         0 $self->{'ADDRESS'},
127             $self->{'PROTOCOL'},
128             $self->{'SERVICES'}
129             ) = split /\s+/, $data;
130             }
131             else {
132 4         13 $self->{'COMMENT'} = $data;
133 4         6 $self->{'TYPE'} = '';
134             }
135              
136 17         44 bless $self, $class;
137              
138 17         54 return $self;
139             }
140              
141             # The id shall only be used to search if
142             # the backend allows to use ids more
143             # efficiently. Setting this attribute
144             # should only be done when reading/writing
145             # from/to the backend (e.g. database)
146             ########################################
147             sub id {
148 0     0 0 0 my($self, $id) = @_;
149            
150 0 0       0 $self->{'_ID'} = $id if($id);
151            
152 0         0 return($self->{'_ID'});
153             }
154              
155             sub data {
156 0     0 0 0 my($self) = @_;
157              
158 0         0 my $type = $self->type();
159              
160 0 0       0 if($type eq 'IN SOA') {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
161             return(
162 0         0 $self->nserver() . ". " .
163             $self->email() . ". " .
164             $self->serial() . " " .
165             $self->refresh() . " " .
166             $self->retry() . " " .
167             $self->expire() . " " .
168             $self->minimum()
169             );
170             }
171             elsif($type eq 'IN A') {
172             return(
173 0         0 $self->address()
174             );
175             }
176             elsif($type eq 'IN NS') {
177             return(
178 0         0 $self->nserver() . "."
179             );
180             }
181             elsif($type eq 'IN MX') {
182             return(
183 0         0 $self->preference() . " " .
184             $self->exchange() . "."
185             );
186             }
187             elsif($type eq 'IN CNAME') {
188             return(
189 0         0 $self->cname() . "."
190             );
191             }
192             elsif($type eq 'IN HINFO') {
193             return(
194 0         0 $self->cpu() . " " .
195             $self->os()
196             );
197             }
198             elsif($type eq 'IN PTR') {
199             return(
200 0         0 $self->domain()
201             );
202             }
203             elsif($type eq 'IN TXT') {
204             return(
205 0         0 $self->text()
206             );
207             }
208             elsif($type eq 'IN WKS') {
209             return(
210 0         0 $self->address() . " " .
211             $self->protocol() . " " .
212             $self->services()
213             );
214             }
215             else {
216             return(
217 0         0 "; " . $self->comment()
218             );
219             }
220              
221 0         0 return undef;
222             }
223              
224             sub dump {
225 0     0 0 0 my($self, $label, $format, $ttl_default) = @_;
226              
227 0 0       0 my $ttlstring = ($self->ttl() == $ttl_default) ? '' : $self->ttl();
228            
229 0 0       0 if($self->type() eq 'IN SOA') {
    0          
230 0         0 printf "$format %s IN SOA %s. %s. \(\n", $label, $ttlstring, $self->nserver(), $self->email();
231 0         0 printf "$format %s ; Serial\n" , '', $self->serial();
232 0         0 printf "$format %s ; Refresh\n", '', $self->refresh();
233 0         0 printf "$format %s ; Retry\n" , '', $self->retry();
234 0         0 printf "$format %s ; Expire\n" , '', $self->expire();
235 0         0 printf "$format %s ; Minimum\n", '', $self->minimum();
236 0         0 printf "$format \)", '';
237 0 0       0 print " " if($self->comment());
238             }
239             elsif($self->type() ne '') {
240 0         0 my $out_format = "$format %s %-9s %s";
241 0         0 printf $out_format, $label, $ttlstring, $self->type(), $self->data();
242 0 0       0 print " " if($self->comment());
243             }
244              
245 0 0       0 print "; " . $self->comment() if($self->comment());
246 0         0 print "\n";
247              
248 0         0 return $self;
249             }
250              
251             sub toXML {
252 0     0 0 0 my($self) = @_;
253 0         0 my $result;
254              
255 0         0 $result .= qq(\n);
256 0         0 $result .= qq() . $self->ttl() . qq(\n);
257 0         0 $result .= qq() . $self->type() . qq(\n);
258 0         0 $result .= qq() . $self->data() . qq(\n);
259 0         0 $result .= qq(\n);
260            
261 0         0 return $result;
262             }
263              
264             sub debug {
265 0     0 0 0 my($self) = @_;
266            
267 0         0 eval {
268 2     2   24 use Data::Dumper;
  2         5  
  2         1538  
269            
270 0         0 print Dumper($self);
271             };
272            
273 0         0 return $self;
274             }
275              
276             sub AUTOLOAD {
277 37     37   55 my($self, $value) = @_;
278 37 50       86 my $type = ref($self) or die "$self is not an object";
279              
280 37         50 my $name = $AUTOLOAD;
281 37         984 $name =~ s/.*://;
282 37         58 $name =~ tr/a-z/A-Z/;
283            
284 37 50       82 die "Can't access `$name' field in class $type" unless (exists $fields{$name});
285              
286 37 50 33     379 if(($name eq 'CNAME') ||
      33        
      33        
      33        
287             ($name eq 'EMAIL') ||
288             ($name eq 'DOMAIN') ||
289             ($name eq 'NSERVER') ||
290             ($name eq 'EXCHANGE')
291             ) {
292 0         0 $value = lc $value;
293             }
294            
295 37 100       69 if ($value) {
296 2 50 33     10 if(($name eq 'TYPE') || ($name eq 'COMMENT')) {
297 0         0 die "Read-only attribute `$name' in class $type";
298             }
299            
300 2         10 return $self->{$name} = $value;
301             } else {
302 35         297 return $self->{$name};
303             }
304             }
305              
306 0     0     sub DESTROY {
307             }
308              
309             sub check {
310 0     0 0   my($self) = @_;
311            
312             #unless(isipaddr($self->{address})) {}
313             #unless(isrealhost($self->{cname}) {}
314             #0 <= $self->{preference} <= 65535
315             #unless(isrealhost{$self->{exchange}) {}
316             #unless(isrealhost{$self->{nserver}) {}
317             #unless(isrealhost{$self->{domain}) {}
318             #unless(isrealhost{$self->{nserver}) {}
319             #unless(isemail($self->{email}) {}
320             # 0 <= $self->{serial} <= 4294967295
321             #unless(abs($self->{serial}) == $self->{serial}) {}
322             #unless($self->{serial} > 1995000000) {}
323             # 0 <= $self->{refresh} <= 4294967295
324             # 0 <= $self->{retry} <= 4294967295
325             # 0 <= $self->{expire} <= 4294967295
326             # 0 <= $self->{minimum} <= 4294967295
327              
328 0           return undef;
329             }
330              
331             sub isipaddr {
332 0     0 0   /^(\s+)\.(\s+)\.(\s+)\.(\s+)\.$/;
333             }
334              
335             sub isreverseip {
336 0     0 0   /\.in-addr\.arpa$/i;
337             }
338              
339 0     0 0   sub isrealhost {
340             #test for existance
341             #might use ping and/or dig
342             }
343              
344             sub isemail {
345 0     0 0   /[\w\-]+\@([\w\-]+\.)+[\w\-]+/;
346             }
347              
348             sub is32bit {
349 0 0   0 0   ($_[0] >= 0) && ($_[0] <= 4294967295);
350             }
351              
352             sub is16bit {
353 0 0   0 0   ($_[0] >= 0) && ($_[0] <= 65535);
354             }
355              
356             1;
357              
358             __END__