File Coverage

blib/lib/NetAddr/IP/InetBase.pm
Criterion Covered Total %
statement 52 65 80.0
branch 13 30 43.3
condition 7 48 14.5
subroutine 15 19 78.9
pod 10 10 100.0
total 97 172 56.4


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2             package NetAddr::IP::InetBase;
3              
4 31     31   266 use strict;
  31         61  
  31         1298  
5             #use diagnostics;
6             #use lib qw(blib lib);
7              
8 31     31   161 use vars qw($VERSION @EXPORT_OK @ISA %EXPORT_TAGS $Mode);
  31         54  
  31         3575  
9 31     31   1090289 use AutoLoader qw(AUTOLOAD);
  31         56498  
  31         192  
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 31     31   7651 { no warnings 'once';
  31         66  
  31         17844  
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 31     31   411 use vars qw($n2x_format $n2d_format);
  31         70  
  31         2361  
126 31     31   159 $n2x_format = "%x:%x:%x:%x:%x:%x:%x:%x";
127 31         41111 $n2d_format = "%x:%x:%x:%x:%x:%x:%d.%d.%d.%d";
128             }
129              
130             my $case = 0; # default lower case
131              
132 31     31 1 100 sub upper { $n2x_format = uc($n2x_format); $n2d_format = uc($n2d_format); $case = 1; }
  31         75  
  31         66  
133 1     1 1 4 sub lower { $n2x_format = lc($n2x_format); $n2d_format = lc($n2d_format); $case = 0; }
  1         2  
  1         3  
134              
135             sub ipv6_n2x {
136 25128 50   25128 1 62855 die "Bad arg length for 'ipv6_n2x', length is ". length($_[0]) ." should be 16"
137             unless length($_[0]) == 16;
138 25128         315797 return sprintf($n2x_format,unpack("n8",$_[0]));
139             }
140              
141             sub ipv6_n2d {
142 75521 50   75521 1 435917 die "Bad arg length for 'ipv6_n2d', length is ". length($_[0]) ." should be 16"
143             unless length($_[0]) == 16;
144 75521         299453 my @hex = (unpack("n8",$_[0]));
145 75521         126154 $hex[9] = $hex[7] & 0xff;
146 75521         98420 $hex[8] = $hex[7] >> 8;
147 75521         102644 $hex[7] = $hex[6] & 0xff;
148 75521         82489 $hex[6] >>= 8;
149 75521         2955817 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 7074     7074 1 10418 my $host = $_[0];
169 7074 50       13782 return undef unless defined $host;
170 7074 100       28684 if ($host =~ /^(\d+)(?:|\.(\d+)(?:|\.(\d+)(?:|\.(\d+))))$/) {
171 7071 50       14653 if (defined $4) {
    0          
    0          
172             return undef unless
173 7071 50 33     130624 $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 7071         24773 $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 7074         16645 $host;
203             }
204              
205             sub inet_aton {
206 7071     7071 1 19343 my $host = fillIPv4($_[0]);
207 7071 50       155148 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 91079 50   91079 1 203793 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 91079 50       541415 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 75521     75521 1 313973 my $naddr = $_[0];
265 75521         138343 my $rv = isIPv4($_[0]);
266 75521 50       2612169 return $rv if $rv;
267 0         0 return isNewIPv4($naddr);
268             }
269              
270 0     0   0 sub DESTROY {};
271              
272             sub import {
273 62 100   62   164 if (grep { $_ eq ':upper' } @_) {
  341         945  
274 31         148 upper();
275 31         63 @_ = grep { $_ ne ':upper' } @_;
  93         509  
276             }
277 62         51326 NetAddr::IP::InetBase->export_to_level(1,@_);
278             }
279              
280             1;
281              
282             __END__