File Coverage

blib/lib/NetAddr/IP/InetBase.pm
Criterion Covered Total %
statement 52 64 81.2
branch 13 30 43.3
condition 7 48 14.5
subroutine 15 19 78.9
pod 10 10 100.0
total 97 171 56.7


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2             package NetAddr::IP::InetBase;
3              
4 32     32   115 use strict;
  32         39  
  32         911  
5             #use diagnostics;
6             #use lib qw(blib lib);
7              
8 32     32   103 use vars qw($VERSION @EXPORT_OK @ISA %EXPORT_TAGS $Mode);
  32         44  
  32         2338  
9 32     32   15606 use AutoLoader qw(AUTOLOAD);
  32         40509  
  32         152  
10             require Exporter;
11              
12             @ISA = qw(Exporter);
13              
14             $VERSION = do { my @r = (q$Revision: 0.08 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r };
15              
16             @EXPORT_OK = qw(
17             inet_aton
18             inet_ntoa
19             ipv6_aton
20             ipv6_ntoa
21             ipv6_n2x
22             ipv6_n2d
23             inet_any2n
24             inet_n2dx
25             inet_n2ad
26             inet_ntop
27             inet_pton
28             packzeros
29             isIPv4
30             isNewIPv4
31             isAnyIPv4
32             AF_INET
33             AF_INET6
34             fake_AF_INET6
35             fillIPv4
36             );
37              
38             %EXPORT_TAGS = (
39             all => [@EXPORT_OK],
40             ipv4 => [qw(
41             inet_aton
42             inet_ntoa
43             fillIPv4
44             )],
45             ipv6 => [qw(
46             ipv6_aton
47             ipv6_ntoa
48             ipv6_n2x
49             ipv6_n2d
50             inet_any2n
51             inet_n2dx
52             inet_n2ad
53             inet_pton
54             inet_ntop
55             packzeros
56             )],
57             );
58              
59             # prototypes
60             sub inet_ntoa;
61             sub ipv6_aton;
62             sub ipv6_ntoa;
63             sub inet_any2n($);
64             sub inet_n2dx($);
65             sub inet_n2ad($);
66             sub _inet_ntop;
67             sub _inet_pton;
68              
69             my $emulateAF_INET6 = 0;
70              
71 32     32   4968 { no warnings 'once';
  32         45  
  32         11489  
72              
73             *packzeros = \&_packzeros;
74              
75             ## dynamic configuraton for IPv6
76              
77             require Socket;
78              
79             *AF_INET = \&Socket::AF_INET;
80              
81             if (eval { AF_INET6() } ) {
82             *AF_INET6 = \&Socket::AF_INET6;
83             $emulateAF_INET6 = -1; # have it, remind below
84             }
85             if (eval{ require Socket6 } ) {
86             import Socket6 qw(
87             inet_pton
88             inet_ntop
89             );
90             unless ($emulateAF_INET6) {
91             *AF_INET6 = \&Socket6::AF_INET6;
92             }
93             $emulateAF_INET6 = 0; # clear, have it from elsewhere or here
94             } else {
95             unless ($emulateAF_INET6) { # unlikely at this point
96             if ($^O =~ /(?:free|dragon.+)bsd/i) { # FreeBSD, DragonFlyBSD
97             $emulateAF_INET6 = 28;
98             } elsif ($^O =~ /bsd/i) { # other BSD flavors like NetBDS, OpenBSD, BSD
99             $emulateAF_INET6 = 24;
100             } elsif ($^O =~ /(?:darwin|mac)/i) { # Mac OS X
101             $emulateAF_INET6 = 30;
102             } elsif ($^O =~ /win/i) { # Windows
103             $emulateAF_INET6 = 23;
104             } elsif ($^O =~ /(?:solaris|sun)/i) { # Sun box
105             $emulateAF_INET6 = 26;
106             } else { # use linux default
107             $emulateAF_INET6 = 10;
108             }
109 0     0   0 *AF_INET6 = sub { $emulateAF_INET6; };
110             } else {
111             $emulateAF_INET6 = 0; # clear, have it from elsewhere
112             }
113             *inet_pton = \&_inet_pton;
114             *inet_ntop = \&_inet_ntop;
115             }
116              
117             } # end no warnings 'once'
118              
119             sub fake_AF_INET6 {
120 0     0 1 0 return $emulateAF_INET6;
121             }
122              
123             # allow user to choose upper or lower case
124             BEGIN {
125 32     32   304 use vars qw($n2x_format $n2d_format);
  32         50  
  32         1736  
126 32     32   59 $n2x_format = "%x:%x:%x:%x:%x:%x:%x:%x";
127 32         22670 $n2d_format = "%x:%x:%x:%x:%x:%x:%d.%d.%d.%d";
128             }
129              
130             my $case = 0; # default lower case
131              
132 32     32 1 84 sub upper { $n2x_format = uc($n2x_format); $n2d_format = uc($n2d_format); $case = 1; }
  32         58  
  32         50  
133 1     1 1 2 sub lower { $n2x_format = lc($n2x_format); $n2d_format = lc($n2d_format); $case = 0; }
  1         3  
  1         2  
134              
135             sub ipv6_n2x {
136 25128 50   25128 1 38760 die "Bad arg length for 'ipv6_n2x', length is ". length($_[0]) ." should be 16"
137             unless length($_[0]) == 16;
138 25128         197783 return sprintf($n2x_format,unpack("n8",$_[0]));
139             }
140              
141             sub ipv6_n2d {
142 75522 50   75522 1 325997 die "Bad arg length for 'ipv6_n2d', length is ". length($_[0]) ." should be 16"
143             unless length($_[0]) == 16;
144 75522         175073 my @hex = (unpack("n8",$_[0]));
145 75522         80366 $hex[9] = $hex[7] & 0xff;
146 75522         60709 $hex[8] = $hex[7] >> 8;
147 75522         55795 $hex[7] = $hex[6] & 0xff;
148 75522         49420 $hex[6] >>= 8;
149 75522         1976323 return sprintf($n2d_format,@hex);
150             }
151              
152             # if Socket lib is broken in some way, check for overange values
153             #
154             #my $overange = yinet_aton('256.1') ? 1:0;
155             #my $overange = gethostbyname('256.1') ? 1:0;
156              
157             #sub inet_aton {
158             # unless (! $overange || $_[0] =~ /[^0-9\.]/) { # hostname
159             # my @dq = split(/\./,$_[0]);
160             # foreach (@dq) {
161             # return undef if $_ > 255;
162             # }
163             # }
164             # scalar gethostbyname($_[0]);
165             #}
166              
167             sub fillIPv4 {
168 7112     7112 1 6364 my $host = $_[0];
169 7112 50       11251 return undef unless defined $host;
170 7112 100       21155 if ($host =~ /^(\d+)(?:|\.(\d+)(?:|\.(\d+)(?:|\.(\d+))))$/) {
171 7108 50       12714 if (defined $4) {
    0          
    0          
172             return undef unless
173 7108 50 33     105573 $1 >= 0 && $1 < 256 &&
      33        
      33        
      33        
      33        
      33        
      33        
174             $2 >= 0 && $2 < 256 &&
175             $3 >= 0 && $3 < 256 &&
176             $4 >= 0 && $4 < 256;
177 7108         18397 $host = $1.'.'.$2.'.'.$3.'.'.$4;
178             # return pack('C4',$1,$2,$3,$4);
179             # $host = ($1 << 24) + ($2 << 16) + ($3 << 8) + $4;
180             } elsif (defined $3) {
181             return undef unless
182 0 0 0     0 $1 >= 0 && $1 < 256 &&
      0        
      0        
      0        
      0        
183             $2 >= 0 && $2 < 256 &&
184             $3 >= 0 && $3 < 256;
185 0         0 $host = $1.'.'.$2.'.0.'.$3
186             # return pack('C4',$1,$2,0,$3);
187             # $host = ($1 << 24) + ($2 << 16) + $3;
188             } elsif (defined $2) {
189             return undef unless
190 0 0 0     0 $1 >= 0 && $1 < 256 &&
      0        
      0        
191             $2 >= 0 && $2 < 256;
192 0         0 $host = $1.'.0.0.'.$2;
193             # return pack('C4',$1,0,0,$2);
194             # $host = ($1 << 24) + $2;
195             } else {
196 0         0 $host = '0.0.0.'.$1;
197             # return pack('C4',0,0,0,$1);
198             # $host = $1;
199             }
200             # return pack('N',$host);
201             }
202 7112         114910 $host;
203             }
204              
205             sub inet_aton {
206 7108     7108 1 10002 my $host = fillIPv4($_[0]);
207 7108 50       102550 return $host ? scalar gethostbyname($host) : undef;
208             }
209              
210             #sub inet_aton {
211             # my $host = $_[0];
212             # return undef unless defined $host;
213             # if ($host =~ /^(\d+)(?:|\.(\d+)(?:|\.(\d+)(?:|\.(\d+))))$/) {
214             # if (defined $4) {
215             # return undef unless
216             # $1 >= 0 && $1 < 256 &&
217             # $2 >= 0 && $2 < 256 &&
218             # $3 >= 0 && $3 < 256 &&
219             # $4 >= 0 && $4 < 256;
220             # return pack('C4',$1,$2,$3,$4);
221             ## $host = ($1 << 24) + ($2 << 16) + ($3 << 8) + $4;
222             # } elsif (defined $3) {
223             # return undef unless
224             # $1 >= 0 && $1 < 256 &&
225             # $2 >= 0 && $2 < 256 &&
226             # $3 >= 0 && $3 < 256;
227             # return pack('C4',$1,$2,0,$3);
228             ## $host = ($1 << 24) + ($2 << 16) + $3;
229             # } elsif (defined $2) {
230             # return undef unless
231             # $1 >= 0 && $1 < 256 &&
232             # $2 >= 0 && $2 < 256;
233             # return pack('C4',$1,0,0,$2);
234             ## $host = ($1 << 24) + $2;
235             # } else {
236             # return pack('C4',0,0,0,$1);
237             ## $host = $1;
238             # }
239             ## return pack('N',$host);
240             # }
241             # scalar gethostbyname($host);
242             #}
243              
244             my $_zero = pack('L4',0,0,0,0);
245             my $_ipv4mask = pack('L4',0xffffffff,0xffffffff,0xffffffff,0);
246              
247             sub isIPv4 {
248 91081 50   91081 1 135017 if (length($_[0]) != 16) {
249 0   0     0 my $sub = (caller(1))[3] || (caller(0))[3];
250 0         0 die "Bad arg length for $sub, length is ". (length($_[0]) *8) .", should be 128";
251             }
252 91081 50       369148 return ($_[0] & $_ipv4mask) eq $_zero
253             ? 1 : 0;
254             }
255              
256             my $_newV4compat = pack('N4',0,0,0xffff,0);
257              
258             sub isNewIPv4 {
259 0     0 1 0 my $naddr = $_[0] ^ $_newV4compat;
260 0         0 return isIPv4($naddr);
261             }
262              
263             sub isAnyIPv4 {
264 75522     75522 1 208424 my $naddr = $_[0];
265 75522         84279 my $rv = isIPv4($_[0]);
266 75522 50       1595216 return $rv if $rv;
267 0         0 return isNewIPv4($naddr);
268             }
269              
270       0     sub DESTROY {};
271              
272             sub import {
273 64 100   64   113 if (grep { $_ eq ':upper' } @_) {
  352         581  
274 32         107 upper();
275 32         45 @_ = grep { $_ ne ':upper' } @_;
  96         378  
276             }
277 64         23374 NetAddr::IP::InetBase->export_to_level(1,@_);
278             }
279              
280             1;
281              
282             __END__