File Coverage

blib/lib/Net/IPAddress/Util.pm
Criterion Covered Total %
statement 236 350 67.4
branch 45 114 39.4
condition 28 69 40.5
subroutine 35 49 71.4
pod 27 27 100.0
total 371 609 60.9


line stmt bran cond sub pod time code
1             package Net::IPAddress::Util;
2              
3 3     3   74186 use strict;
  3         24  
  3         93  
4 3     3   18 use warnings;
  3         8  
  3         83  
5 3     3   67 use 5.010;
  3         10  
6              
7             use overload (
8 3         23 '=' => 'new',
9             '""' => 'str',
10             'cmp' => '_spaceship',
11             '<=>' => '_spaceship',
12             '+' => '_do_add',
13             '-' => '_do_subtract',
14             '<<' => '_shift_left',
15             '>>' => '_shift_right',
16             '&' => '_band',
17             '|' => '_bor',
18             '~' => '_neg',
19 3     3   3182 );
  3         3193  
20              
21 3     3   851 use Carp qw( carp cluck confess );
  3         9  
  3         416  
22 3     3   25 use Exporter qw( import );
  3         8  
  3         125  
23 3     3   1350 use List::MoreUtils qw( pairwise );
  3         47976  
  3         34  
24              
25             our %EXPORT_TAGS = (
26             constr => [qw( IP n32_to_ipv4 )],
27             manip => [qw( explode_ip implode_ip ip_pad_prefix common_prefix prefix_mask ipv4_mask ipv4_flag )],
28             sort => [qw( radix_sort )],
29             compat => [qw( ip2num num2ip validaddr mask fqdn )]
30             );
31              
32             my %EXPORT_OK;
33             for my $k (keys %EXPORT_TAGS) {
34             for my $v (@{$EXPORT_TAGS{ $k }}) {
35             undef $EXPORT_OK{ $v };
36             }
37             }
38              
39             our @EXPORT_OK = keys %EXPORT_OK;
40              
41             $EXPORT_TAGS{ all } = [ @EXPORT_OK ];
42              
43             our $DIE_ON_ERROR = 0;
44             our $PROMOTE_N32 = 1;
45             our $REPAIR_V3_FORMAT = 0;
46             our $WARN_ON_REPAIR = 1;
47              
48             our $VERSION = '4.004';
49              
50             our $fourish = qr/^(?:::ffff:0+:)?(\d+)\.(\d+)\.(\d+)\.(\d+)$/io;
51             our $broken_fourish = qr/^::ffff:(\d+)\.(\d+)\.(\d+)\.(\d+)$/io;
52             our $numberish = qr/^\d+$/o;
53             our $normalish = qr/^([0-9a-f]{32})$/io;
54             our $sixish = qr/^([0-9a-f:]+)(?:\%.*)?$/io;
55              
56             sub _repair_v3_format {
57 0     0   0 my ($old) = @_;
58 0 0 0     0 if (
      0        
59 0         0 !(grep { $_ } @$old[ 0 .. 9 ])
60             && $old->[ 10 ] == 0xff
61             && $old->[ 11 ] == 0xff
62             ) {
63 0 0       0 if ($WARN_ON_REPAIR > 1) {
    0          
64 0         0 local $Carp::Internal{ (__PACKAGE__) };
65 0         0 cluck('Repairing v3.x module data to v4.x data');
66             }
67             elsif ($WARN_ON_REPAIR) {
68 0         0 local $Carp::Internal{ (__PACKAGE__) };
69 0         0 carp('Repairing v3.x module data to v4.x data');
70             }
71 0         0 $old->[ 8 ] = 0xff;
72 0         0 $old->[ 9 ] = 0xff;
73 0         0 $old->[ 10 ] = 0;
74 0         0 $old->[ 11 ] = 0;
75             }
76 0         0 return $old;
77             }
78              
79             sub IP {
80 272     272 1 6965 return Net::IPAddress::Util->new($_[0]);
81             }
82              
83             sub new {
84 1053     1053 1 2138 my $self = shift;
85 1053   33     3557 my $class = ref($self) || $self;
86 1053         2163 my ($address) = @_;
87 1053 50       2220 unless (defined $address) {
88 0         0 return ERROR("Invalid argument undef() provided");
89             }
90 1053         1958 my $normal = [ ];
91 1053 100 100     5779 if (ref($address) eq 'ARRAY' && @$address == 16) {
    100 66        
    100 66        
    100 33        
    50 66        
    100 66        
    50 33        
    100 66        
    50 33        
    0          
92 475         875 $normal = $address;
93             }
94             elsif (ref($address) eq 'ARRAY' && @$address == 4) {
95             # FIXME Principal of least surprise here? Should feeding in 4 values make an IPv4?
96 306         1384 $normal = [ unpack 'C16', pack 'N4', @$address ];
97             }
98 247         1327 elsif (ref $address and eval { $address->isa(__PACKAGE__) }) {
99 247         1038 $normal = [ unpack 'C16', $address->{ address } ];
100             }
101             elsif ($address =~ $fourish) {
102 15         108 $normal = [
103             0, 0, 0, 0,
104             0, 0, 0, 0,
105             0xff, 0xff, 0, 0,
106             $1, $2, $3, $4
107             ];
108             }
109             elsif ($REPAIR_V3_FORMAT && $address =~ $broken_fourish) {
110 0 0       0 if ($WARN_ON_REPAIR > 1) {
    0          
111 0         0 local $Carp::Internal{ (__PACKAGE__) };
112 0         0 cluck('Repairing v3.x module data to v4.x data');
113             }
114             elsif ($WARN_ON_REPAIR) {
115 0         0 local $Carp::Internal{ (__PACKAGE__) };
116 0         0 carp('Repairing v3.x module data to v4.x data');
117             }
118             $normal = [
119 0         0 0, 0, 0, 0,
120             0, 0, 0, 0,
121             0xff, 0xff, 0, 0,
122             $1, $2, $3, $4
123             ];
124             }
125             elsif ($PROMOTE_N32 and $address =~ $numberish and $address >= 0 and $address <= (2 ** 32) - 1) {
126 1         9 $normal = [
127             0, 0, 0, 0,
128             0, 0, 0, 0,
129             0xff, 0xff, 0, 0,
130             unpack('C4', pack('N', $address))
131             ];
132             }
133             elsif ("$address" =~ $normalish) {
134 0         0 my $fresh = $1;
135 0 0       0 eval "require Math::BigInt" or return ERROR("Could not load Math::BigInt: $@");
136 0         0 my $raw = Math::BigInt->from_hex("$fresh");
137 0         0 while ($raw > 0) {
138 0         0 my $word = $raw->copy->band(0xffffffff);
139 0         0 unshift @$normal, unpack('C4', pack('N', $word));
140 0         0 $raw = $raw->copy->brsft(32);
141             }
142 0         0 while (@$normal < 16) {
143 0         0 unshift @$normal, 0;
144             }
145 0         0 eval "no Math::BigInt";
146             }
147             elsif ($address =~ $numberish) {
148 1 50       75 eval "require Math::BigInt" or return ERROR("Could not load Math::BigInt: $@");
149 1         8 my $raw = Math::BigInt->new("$address");
150 1         95 while ($raw > 0) {
151 2         809 my $word = $raw->copy->band(0xffffffff);
152 2         936 unshift @$normal, unpack('C4', pack('N', $word));
153 2         107 $raw = $raw->copy->brsft(32);
154             }
155 1         419 while (@$normal < 16) {
156 8         15 unshift @$normal, 0;
157             }
158 1     1   76 eval "no Math::BigInt";
  1         7  
  1         2  
  1         19  
159             }
160             elsif (
161             $address =~ $sixish
162             and (
163             scalar(grep { /::/o } split(/[[:alnum:]]+/, $address)) == 1
164             or scalar(grep { /[[:alnum:]]+/ } split(/:/, $address)) == 8
165             )
166             ) {
167             # new() from IPv6 address, accepting and ignoring the Scope ID
168 8         30 $address = $1;
169 8         38 my ($lhs, $rhs) = split /::/, $address;
170 8 100       29 $rhs = '' unless defined $rhs;
171 8         21 my $hex = '0' x 32;
172 8         24 $lhs = join '', map { substr('0000' . $_, -4) } split /:/, $lhs;
  15         52  
173 8         31 $rhs = join '', map { substr('0000' . $_, -4) } split /:/, $rhs;
  10         55  
174 8         23 substr($hex, 0, length($lhs)) = $lhs;
175 8         22 substr($hex, - length($rhs), length($rhs)) = $rhs;
176 8         59 my @hex = split //, $hex;
177 8         41 while (@hex) {
178 128         363 push @$normal, hex(join('', splice(@hex, 0, 2)));
179             }
180             }
181             elsif (length($address) == 16) {
182 0         0 $normal = [ unpack('C16', $address) ];
183             }
184             else {
185 0   0     0 return ERROR("Invalid argument `$address', a(n) " . (ref($address) || 'bare scalar') . ' provided');
186             }
187 1053 50       2847 if ($REPAIR_V3_FORMAT) {
188 0         0 $normal = _repair_v3_format($normal);
189             }
190 1053         10444 return bless { address => pack('C16', @$normal) } => $class;
191             }
192              
193             sub is_ipv4 {
194 812     812 1 1372 my $self = shift;
195 812         2644 my @octets = unpack 'C16', $self->{ address };
196             return
197             $octets[ 8 ] == 0xff
198             && $octets[ 9 ] == 0xff
199             && $octets[ 10 ] == 0
200             && $octets[ 11 ] == 0
201 812   66     5668 && (!grep { $_ } @octets[ 0 .. 7 ]);
202             }
203              
204             sub ipv4 {
205 527     527 1 911 my $self = shift;
206 527         4119 return join '.', unpack 'C4', substr($self->{ address }, -4);
207             }
208              
209             sub as_n32 {
210 2     2 1 7 my $self = shift;
211 2         16 return unpack 'N', substr($self->{ address }, -4);
212             }
213              
214             sub as_n128 {
215 1     1 1 3 my $self = shift;
216 1         3 my ($keep) = @_;
217 1         1 my $rv;
218             {
219 1 50       2 eval "require Math::BigInt" or return ERROR("Could not load Math::BigInt: $@");
  1         56  
220 1         22493 my $accum = Math::BigInt->new('0');
221 1         20001 my $factor = Math::BigInt->new('1')->blsft(Math::BigInt->new('32'));
222 1         393 for my $i (map { $_ * 4 } 0 .. 3) {
  4         9  
223 4         339 $accum->bmul($factor);
224 4         306 $accum->badd(Math::BigInt->new('' . unpack 'N', substr($self->{ address }, $i, 4)));
225             }
226 1 50   1   196 eval "no Math::BigInt" unless $keep;
  1         8  
  1         2  
  1         16  
227 1 50       7 $rv = $keep ? $accum : "$accum";
228             }
229 1         49 return $rv;
230             }
231              
232             sub normal_form {
233 24     24 1 73 my $self = shift;
234 24         176 my $hex = join('', map { sprintf('%02x', $_) } unpack('C16', $self->{ address }));
  384         921  
235 24         106 $hex = substr(('0' x 32) . $hex, -32);
236 24         76 return lc $hex;
237             }
238              
239             sub ipv6_expanded {
240 17     17 1 31 my $self = shift;
241 17         39 my $hex = $self->normal_form();
242 17         40 my $rv;
243 17         96 while ($hex =~ /(....)/g) {
244 136 100       288 $rv .= ':' if defined $rv;
245 136         425 $rv .= $1;
246             }
247 17         58 return $rv;
248             }
249              
250             sub ipv6 {
251 18     18 1 35 my $self = shift;
252 18 100       39 if ($self->is_ipv4()) {
253 1         4 return '::ffff:0:'.$self->ipv4();
254             }
255 17         48 my $iv = $self->ipv6_expanded();
256 17   100     75 my $rv = join(':', map { (my $x = $_) =~ s/^0+//; $x ||= '0'; $x } split ':', $iv);
  136         429  
  136         447  
  136         300  
257 17         106 $rv =~ s/[^[:xdigit:]]0(:0)+/::/;
258 17         63 $rv =~ s/::+/::/g;
259 17         33 $rv =~ s/^0::/::/;
260 17         107 return $rv;
261             }
262              
263 0     0 1 0 sub as_str { return str(@_); }
264              
265 0     0 1 0 sub as_string { return str(@_); }
266              
267             sub str {
268 542     542 1 1098 my $self = shift;
269 542 100       1155 if ($self->is_ipv4()) {
270 525         1291 return $self->ipv4();
271             }
272 17         55 return $self->ipv6();
273             }
274              
275             sub _spaceship {
276 216     216   487 my $self = shift;
277 216         499 my ($rhs, $swapped) = @_;
278 216         461 my $lhs = $self->{ address };
279 216         633 $lhs = [ unpack 'N4', $lhs ];
280 216   33     477 $rhs = eval { $rhs->{ address } } || pack('N4', (0, 0, 0, $rhs));
281 216         586 $rhs = [ unpack 'N4', $rhs ];
282 216 50       524 ($lhs, $rhs) = ($rhs, $lhs) if $swapped;
283 216   66     2286 return (1 - (2 * $swapped)) * (
284             $lhs->[ 0 ] <=> $rhs->[ 0 ]
285             || $lhs->[ 1 ] <=> $rhs->[ 1 ]
286             || $lhs->[ 2 ] <=> $rhs->[ 2 ]
287             || $lhs->[ 3 ] <=> $rhs->[ 3 ]
288             );
289             }
290              
291             sub _do_add {
292 16     16   50 my $self = shift;
293 16         50 my ($rhs, $swapped) = @_;
294 16         72 my ($pow, $mask) = $self->_pow_mask;
295 16         57 my $lhs = $self->{ address };
296 16         57 $lhs = [ unpack 'N4', $lhs ];
297 16   33     44 $rhs = eval { $rhs->{ address } } || pack('N4', (0, 0, 0, $rhs));
298 16         118 $rhs = [ unpack 'N4', $rhs ];
299 16 50       66 ($lhs, $rhs) = ($rhs, $lhs) if $swapped;
300 16         58 my @l = reverse @$lhs;
301 16         53 my @r = reverse @$rhs;
302 16         36 my @rv;
303 16         56 for my $digit (0 .. 3) {
304 64         134 my $answer = $l[$digit] + $r[$digit];
305 64 50       142 if ($answer > (2 ** 32) - 1) {
306 0 0       0 $r[$digit + 1] += int($answer / (2 ** 32)) if exists $r[$digit + 1];
307 0         0 $answer = $answer % (2 ** 32);
308             }
309 64         156 push @rv, $answer;
310             }
311 16         96 @rv = $self->_mask_out($pow, $mask, reverse @rv);
312 16         73 my $retval = Net::IPAddress::Util->new(\@rv);
313 16         154 return $retval;
314             }
315              
316             sub _do_subtract {
317 8     8   17 my $self = shift;
318 8         21 my ($rhs, $swapped) = @_;
319 8         24 my ($pow, $mask) = $self->_pow_mask;
320 8         25 my $lhs = $self->{ address };
321 8         25 $lhs = [ unpack 'N4', $lhs ];
322 8   33     21 $rhs = eval { $rhs->{ address } } || pack('N4', (0, 0, 0, $rhs));
323 8         32 $rhs = [ unpack 'N4', $rhs ];
324 8 50       25 ($lhs, $rhs) = ($rhs, $lhs) if $swapped;
325 8         27 my @l = reverse @$lhs;
326 8         18 my @r = reverse @$rhs;
327 8         25 my @rv;
328 8         25 for my $digit (0 .. 3) {
329 32         60 my $answer = $l[$digit] - $r[$digit];
330 32 50       73 if ($answer < 0) {
331 0         0 $answer += (2 ** 32) - 1;
332 0 0       0 $r[$digit + 1] -= 1 if exists $r[$digit + 1];
333             }
334 32         82 push @rv, $answer;
335             }
336 8         30 @rv = $self->_mask_out($pow, $mask, reverse @rv);
337 8         28 my $retval = Net::IPAddress::Util->new(\@rv);
338 8         45 return $retval;
339             }
340              
341             sub _shift_left {
342 0     0   0 my $self = shift;
343 0         0 my ($rhs, $swapped) = @_;
344 0         0 my ($pow, $mask) = $self->_pow_mask;
345 0         0 my @l = reverse unpack('C16', $self->{ address });
346 0         0 my @rv;
347 0         0 for my $octet (0 .. 15) {
348 0         0 $rv[$octet] += $l[$octet] << $rhs;
349 0 0       0 if ($rv[$octet] > 255) {
350 0         0 my $lsb = $rv[$octet] % 256;
351 0 0       0 $rv[$octet + 1] += ($rv[$octet] - $lsb) >> 8 if $octet < 15;
352 0         0 $rv[$octet] = $lsb;
353             }
354             }
355 0         0 @rv = $self->_mask_out($pow, $mask, @rv);
356 0         0 return Net::IPAddress::Util->new(\@rv);
357             }
358              
359             sub _shift_right {
360 0     0   0 my $self = shift;
361 0         0 my ($rhs, $swapped) = @_;
362 0         0 my ($pow, $mask) = $self->_pow_mask;
363 0         0 my @l = unpack('C16', $self->{ address });
364 0         0 my @rv;
365 0         0 for my $octet (0 .. 15) {
366 0         0 $rv[$octet] += $l[$octet] >> $rhs;
367 0 0       0 if (int($rv[$octet]) - $rv[$octet]) {
368 0         0 my $msb = int($rv[$octet]);
369 0         0 my $lsb = $rv[$octet] << $rhs;
370 0         0 $rv[$octet] = $msb;
371 0 0       0 $rv[$octet + 1] += $lsb if $octet < 15;
372             }
373             }
374 0         0 @rv = $self->_mask_out($pow, $mask, unpack('C16', pack('N4', @rv)));
375 0         0 return Net::IPAddress::Util->new(\@rv);
376             }
377              
378             sub _band {
379 141     141   334 my $self = shift;
380 141         347 my ($rhs, $swapped) = @_;
381 141 50       324 ($self, $rhs) = ($rhs, $self) if $swapped;
382 141         326 my $lhs = $self->{ address };
383 141         495 $lhs = [ unpack 'N4', $lhs ];
384 141   33     368 $rhs = eval { $rhs->{ address } } || pack('N4', (0, 0, 0, $rhs));
385 141         382 $rhs = [ unpack 'N4', $rhs ];
386 141 50       353 ($lhs, $rhs) = ($rhs, $lhs) if $swapped;
387 141         337 my @l = @$lhs;
388 141         259 my @r = @$rhs;
389 141         223 my @rv;
390 141         347 for my $hextet (0 .. 3) {
391 564         1152 $rv[$hextet] = $l[$hextet] & $r[$hextet];
392             }
393 141         376 return Net::IPAddress::Util->new(\@rv);
394             }
395              
396             sub _bor {
397 141     141   300 my $self = shift;
398 141         310 my ($rhs, $swapped) = @_;
399 141 50       313 ($self, $rhs) = ($rhs, $self) if $swapped;
400 141         308 my $lhs = $self->{ address };
401 141         403 $lhs = [ unpack 'N4', $lhs ];
402 141   33     313 $rhs = eval { $rhs->{ address } } || pack('N4', (0, 0, 0, $rhs));
403 141         382 $rhs = [ unpack 'N4', $rhs ];
404 141 50       345 ($lhs, $rhs) = ($rhs, $lhs) if $swapped;
405 141         344 my @l = @$lhs;
406 141         284 my @r = @$rhs;
407 141         222 my @rv;
408 141         355 for my $hextet (0 .. 3) {
409 564         1175 $rv[$hextet] = $l[$hextet] | $r[$hextet];
410             }
411 141         406 return Net::IPAddress::Util->new(\@rv);
412             }
413              
414             sub _neg {
415 141     141   287 my $self = shift;
416 141         537 my @n = unpack('C16', $self->{ address });
417 141         369 my @rv = map { 255 - $_ } @n;
  2256         3929  
418 141         431 return Net::IPAddress::Util->new(\@rv);
419             }
420              
421             sub _pow_mask {
422 24     24   53 my $self = shift;
423 24         48 my $pow = 128;
424 24         63 my $mask = pack('N4', 0, 0, 0, 0);
425 24 50       74 if ($self->is_ipv4) {
426 24         54 $pow = 32;
427 24         57 $mask = pack('C16',
428             0, 0, 0, 0,
429             0, 0, 0, 0,
430             0xff, 0xff, 0, 0,
431             0, 0, 0, 0,
432             );
433             }
434 24         95 return ($pow, $mask);
435             }
436              
437             sub _mask_out {
438 24     24   53 my $self = shift;
439 24         75 my ($pow, $mask, @rv) = @_;
440 24         101 my @and = (0, 0, 0, 0);
441 24         77 map { $and[ 4 - $_ ] = 0xffffffff } grep { $pow / $_ >= 32 } (1 .. 4);
  24         85  
  96         333  
442 24         90 my @or = unpack('N4', $mask);
443 24     96   387 @rv = pairwise { $a & $b } @rv, @and;
  96         243  
444 24     96   214 @rv = pairwise { $a | $b } @rv, @or;
  96         239  
445 24         121 return @rv;
446             }
447              
448             sub ipv4_mask {
449 87     87 1 309 return implode_ip(('0' x 64) . ('1' x 16) . ('0' x 16) . ('1' x 32));
450             }
451              
452             sub ipv4_flag {
453 0     0 1 0 return implode_ip(('0' x 64) . ('1' x 16) . ('0' x 48));
454             }
455              
456             sub common_prefix (\@\@) {
457 87     87 1 243 my ($x, $y) = @_;
458 87 50       258 return ERROR("Something isn't right there") unless @$x == @$y;
459 87         156 my @rv;
460 87         290 for my $i (0 .. $#$x) {
461 10856 100       19303 if($x->[$i] eq $y->[$i]) {
462 10775         19979 push @rv, $x->[$i];
463             }
464             else {
465 81         187 last;
466             }
467             }
468 87         2419 return @rv;
469             }
470              
471             sub prefix_mask (\@\@) {
472 87     87 1 225 my ($x, $y) = @_;
473 87 50       240 return ERROR("Something isn't right there") unless @$x == @$y;
474 87         149 my @rv;
475 87         279 for my $i (0 .. $#$x) {
476 10856 100       21019 if($x->[$i] == $y->[$i]) {
477 10775         17204 push @rv, 1;
478             }
479             else {
480 81         175 last;
481             }
482             }
483 87         805 return @rv;
484             }
485              
486             sub ip_pad_prefix (\@) {
487 174     174 1 310 my @array = @{$_[0]};
  174         1856  
488 174         507 for my $i (scalar(@array) .. 127) {
489 722         1197 push @array, 0;
490             }
491 174         2891 return @array;
492             }
493              
494             sub explode_ip {
495 174     174 1 317 my $ip = shift;
496 174         2928 return map { ~~$_ } split //, unpack 'B128', $ip->{ address };
  22272         42286  
497             }
498              
499             sub implode_ip {
500 314     314 1 834 return Net::IPAddress::Util->new([ unpack 'C16', pack 'B128', join '', map { ~~$_ } map { split // } @_ ]);
  40192         78982  
  22412         47003  
501             }
502              
503 0     0 1 0 sub n32_to_ipv4 { local $PROMOTE_N32 = 1; return IP(@_) }
  0         0  
504              
505             sub ERROR {
506 0 0   0 1 0 my $msg = @_ ? shift() : 'An error has occured';
507 0 0       0 if ($DIE_ON_ERROR) {
508 0         0 confess($msg);
509             }
510             else {
511 0 0       0 cluck($msg) if $^W;
512             }
513 0         0 return;
514             }
515              
516             sub radix_sort (\@) {
517             # In theory, a radix sort is O(N), which beats Perl's O(N log N) by
518             # a fair margin. However, it _does_ discard duplicates, so ymmv.
519 0 0   0 1 0 shift if $_[0] eq __PACKAGE__;
520 0         0 my $array = shift;
521 0         0 my $from = [ map { [ unpack 'C16', $_->{ address } ] } @$array ];
  0         0  
522 0         0 my $to;
523 0         0 for (my $i = 15; $i >= 0; $i--) {
524 0         0 $to = [];
525 0         0 for my $card (@$from) {
526 0         0 push @{$to->[ $card->[ $i ] ]}, $card;
  0         0  
527             }
528 0   0     0 $from = [ map { @{$_ // []} } @$to ];
  0         0  
  0         0  
529             }
530 0         0 my @rv = map { IP(pack 'C16', @$_) } @$from;
  0         0  
531 0         0 return @rv;
532             }
533              
534             sub ip2num {
535 0 0   0 1 0 carp('Compatibility function ip2num() is deprecated') if $^W;
536 0         0 my $ip = shift;
537 0         0 my $self = IP($ip);
538 0         0 $self &= ((2 ** 32) - 1);
539 0         0 return $self->as_n32();
540             }
541              
542             sub num2ip {
543 0 0   0 1 0 carp('Compatibility function num2ip() is deprecated') if $^W;
544 0         0 my $num = shift;
545 0         0 my $self = n32_to_ipv4($num);
546 0         0 return $self->str();
547             }
548              
549             sub validaddr {
550 0 0   0 1 0 carp('Compatibility function validaddr() is deprecated') if $^W;
551 0         0 my $ip = shift;
552 0         0 my @octets = split(/\./, $ip);
553 0 0       0 return unless scalar @octets == 4;
554 0         0 for (@octets) {
555 0 0 0     0 return unless defined $_ && $_ >= 0 && $_ <= 255;
      0        
556             }
557 0         0 return 1;
558             }
559              
560             sub mask {
561 0 0   0 1 0 carp('Compatibility function mask() is deprecated') if $^W;
562 0         0 my ($ip, $mask) = @_;
563 0         0 my $self = IP($ip);
564 0         0 my $nm = IP($mask);
565 0         0 return $self & $nm;
566             }
567              
568             sub fqdn {
569 0 0   0 1 0 carp('Compatibility function fqdn() is deprecated') if $^W;
570 0         0 my $dn = shift;
571 0         0 return split /\./, $dn, 2;
572             }
573              
574             1;
575              
576             __END__