line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Data::IPV4::Range::Parse; |
2
|
|
|
|
|
|
|
|
3
|
6
|
|
|
6
|
|
199398
|
use strict; |
|
6
|
|
|
|
|
13
|
|
|
6
|
|
|
|
|
219
|
|
4
|
6
|
|
|
6
|
|
42
|
use warnings; |
|
6
|
|
|
|
|
15
|
|
|
6
|
|
|
|
|
247
|
|
5
|
6
|
|
|
6
|
|
34
|
use Carp qw(croak); |
|
6
|
|
|
|
|
15
|
|
|
6
|
|
|
|
|
510
|
|
6
|
6
|
|
|
6
|
|
42
|
use vars qw(@ISA %EXPORT_TAGS @EXPORT_OK $VERSION @EXPORT); |
|
6
|
|
|
|
|
11
|
|
|
6
|
|
|
|
|
1260
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
$VERSION = '1.05'; |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
require Exporter; |
11
|
|
|
|
|
|
|
@ISA = qw(Exporter); |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
@EXPORT_OK=qw( |
14
|
|
|
|
|
|
|
ALL_BITS |
15
|
|
|
|
|
|
|
MAX_CIDR |
16
|
|
|
|
|
|
|
MIN_CIDR |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
sort_quad |
19
|
|
|
|
|
|
|
sort_notations |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
int_to_ip |
22
|
|
|
|
|
|
|
ip_to_int |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
parse_ipv4_cidr |
25
|
|
|
|
|
|
|
parse_ipv4_ip |
26
|
|
|
|
|
|
|
parse_ipv4_range |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
broadcast_int |
29
|
|
|
|
|
|
|
base_int |
30
|
|
|
|
|
|
|
size_from_mask |
31
|
|
|
|
|
|
|
hostmask |
32
|
|
|
|
|
|
|
cidr_to_int |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
auto_parse_ipv4_range |
35
|
|
|
|
|
|
|
); |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
%EXPORT_TAGS = ( |
38
|
|
|
|
|
|
|
ALL=>\@EXPORT_OK |
39
|
|
|
|
|
|
|
,CONSTANTS=>[qw( |
40
|
|
|
|
|
|
|
ALL_BITS |
41
|
|
|
|
|
|
|
MAX_CIDR |
42
|
|
|
|
|
|
|
MIN_CIDR |
43
|
|
|
|
|
|
|
)] |
44
|
|
|
|
|
|
|
,PARSE_RANGE=>[qw( |
45
|
|
|
|
|
|
|
parse_ipv4_cidr |
46
|
|
|
|
|
|
|
parse_ipv4_ip |
47
|
|
|
|
|
|
|
parse_ipv4_range |
48
|
|
|
|
|
|
|
auto_parse_ipv4_range |
49
|
|
|
|
|
|
|
)] |
50
|
|
|
|
|
|
|
,PARSE_IP=>[qw( |
51
|
|
|
|
|
|
|
int_to_ip |
52
|
|
|
|
|
|
|
ip_to_int |
53
|
|
|
|
|
|
|
)] |
54
|
|
|
|
|
|
|
,SORT=>[qw( |
55
|
|
|
|
|
|
|
sort_quad |
56
|
|
|
|
|
|
|
sort_notations |
57
|
|
|
|
|
|
|
)] |
58
|
|
|
|
|
|
|
,COMPUTE_FROM_INT=>[ qw( |
59
|
|
|
|
|
|
|
broadcast_int |
60
|
|
|
|
|
|
|
base_int |
61
|
|
|
|
|
|
|
size_from_mask |
62
|
|
|
|
|
|
|
hostmask |
63
|
|
|
|
|
|
|
cidr_to_int |
64
|
|
|
|
|
|
|
)] |
65
|
|
|
|
|
|
|
); |
66
|
|
|
|
|
|
|
|
67
|
6
|
|
|
6
|
|
35
|
use constant ALL_BITS=>0xffffffff; |
|
6
|
|
|
|
|
11
|
|
|
6
|
|
|
|
|
712
|
|
68
|
6
|
|
|
6
|
|
29
|
use constant MAX_CIDR=>32; |
|
6
|
|
|
|
|
14
|
|
|
6
|
|
|
|
|
286
|
|
69
|
6
|
|
|
6
|
|
34
|
use constant MIN_CIDR=>0; |
|
6
|
|
|
|
|
10
|
|
|
6
|
|
|
|
|
7979
|
|
70
|
|
|
|
|
|
|
|
71
|
2
|
100
|
|
2
|
1
|
11
|
sub int_to_ip ($) { shift if $#_>0;join '.',unpack('C4',(pack('N',$_[0]))) } |
|
2
|
|
|
|
|
22
|
|
72
|
35
|
100
|
|
35
|
1
|
103
|
sub ip_to_int ($) { shift if $#_>0;unpack('N',pack('C4',split(/\./,$_[0]))) } |
|
35
|
|
|
|
|
258
|
|
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
sub sort_quad ($$) { |
75
|
4
|
|
|
4
|
1
|
25
|
my ($ip_a,$ip_b)=@_; |
76
|
4
|
|
|
|
|
9
|
ip_to_int($ip_a) <=> ip_to_int($ip_b) |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
sub sort_notations ($$) { |
80
|
2
|
|
|
2
|
1
|
959
|
my ($a_start,$a_end,$b_start,$b_end)=map { auto_parse_ipv4_range($_) } @_; |
|
4
|
|
|
|
|
13
|
|
81
|
2
|
50
|
|
|
|
7
|
croak 'cannot parse notation a or b' |
82
|
|
|
|
|
|
|
unless defined($b_end); |
83
|
2
|
|
|
|
|
3
|
my $ab_cmp=($a_start<=>$b_start); |
84
|
2
|
100
|
|
|
|
622
|
return $ab_cmp if $ab_cmp!=0; |
85
|
1
|
|
|
|
|
3
|
$a_end <=> $b_end |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
sub broadcast_int ($$) { |
89
|
8
|
100
|
|
8
|
1
|
52
|
shift if $#_>1; |
90
|
8
|
|
|
|
|
45
|
base_int($_[0],$_[1]) + hostmask($_[1]) |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
|
93
|
16
|
100
|
|
16
|
1
|
78
|
sub base_int ($$) { shift if $#_>1;$_[0] & $_[1] } |
|
16
|
|
|
|
|
52
|
|
94
|
2
|
100
|
|
2
|
1
|
8
|
sub size_from_mask ($) { shift if $#_>0;1 + hostmask($_[0] ) } |
|
2
|
|
|
|
|
6
|
|
95
|
12
|
100
|
|
12
|
1
|
582
|
sub hostmask ($) { shift if $#_>0;ALL_BITS & (~(ALL_BITS & $_[0])) } |
|
12
|
|
|
|
|
64
|
|
96
|
|
|
|
|
|
|
sub cidr_to_int ($) { |
97
|
39
|
50
|
|
39
|
1
|
128
|
shift if $#_>0; |
98
|
39
|
|
|
|
|
48
|
my ($cidr)=@_; |
99
|
39
|
|
|
|
|
59
|
my $shift=MAX_CIDR -$cidr; |
100
|
39
|
50
|
|
|
|
72
|
return undef unless defined($cidr); |
101
|
39
|
50
|
|
|
|
191
|
return undef unless $cidr=~ /^\d{1,2}$/s; |
102
|
39
|
50
|
33
|
|
|
202
|
return undef if $cidr>MAX_CIDR or $cidr
|
103
|
39
|
100
|
|
|
|
829
|
return 0 if $shift==MAX_CIDR; |
104
|
38
|
|
|
|
|
158
|
ALL_BITS & (ALL_BITS << $shift) |
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
sub parse_ipv4_cidr { |
108
|
6
|
|
|
6
|
1
|
13
|
my $notation=$_[$#_]; |
109
|
6
|
|
|
|
|
34
|
$notation=~ s/(^\s+|\s+$)//g; |
110
|
|
|
|
|
|
|
return () |
111
|
6
|
50
|
|
|
|
46
|
unless($notation=~ / |
112
|
|
|
|
|
|
|
^\d{1,3}(\.\d{1,3}){0,3} |
113
|
|
|
|
|
|
|
\s*\/\s* |
114
|
|
|
|
|
|
|
\d{1,3}(\.\d{1,3}){0,3}$ |
115
|
|
|
|
|
|
|
/x); |
116
|
6
|
|
|
|
|
36
|
my ($ip,$mask)=split /\s*\/\s*/,$notation; |
117
|
6
|
|
|
|
|
16
|
my $ip_int=ip_to_int($ip); |
118
|
6
|
|
|
|
|
14
|
my $mask_int; |
119
|
|
|
|
|
|
|
|
120
|
6
|
50
|
33
|
|
|
49
|
if($mask=~ /\./) { |
|
|
50
|
|
|
|
|
|
121
|
|
|
|
|
|
|
# we know its quad notation |
122
|
0
|
|
|
|
|
0
|
$mask_int=ip_to_int($mask); |
123
|
|
|
|
|
|
|
} elsif($mask>=MIN_CIDR && $mask<=MAX_CIDR) { |
124
|
6
|
|
|
|
|
17
|
$mask_int=cidr_to_int($mask); |
125
|
|
|
|
|
|
|
} else { |
126
|
0
|
|
|
|
|
0
|
$mask_int=ip_to_int($mask); |
127
|
|
|
|
|
|
|
} |
128
|
6
|
|
|
|
|
21
|
my $first_int=base_int($ip_int , $mask_int); |
129
|
6
|
|
|
|
|
16
|
my $last_int=broadcast_int( $first_int,$mask_int); |
130
|
|
|
|
|
|
|
|
131
|
6
|
|
|
|
|
31
|
($first_int,$last_int) |
132
|
|
|
|
|
|
|
} |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
sub parse_ipv4_range { |
135
|
5
|
|
|
5
|
1
|
31
|
my $range=$_[$#_]; |
136
|
5
|
50
|
|
|
|
17
|
return () unless defined($range); |
137
|
|
|
|
|
|
|
# lop off start and end spaces |
138
|
5
|
|
|
|
|
33
|
$range=~ s/(^\s+|\s+$)//g; |
139
|
|
|
|
|
|
|
|
140
|
5
|
50
|
|
|
|
39
|
return () unless $range=~ / |
141
|
|
|
|
|
|
|
^\d{1,3}(\.\d{1,3}){0,3} |
142
|
|
|
|
|
|
|
\s*-\s* |
143
|
|
|
|
|
|
|
\d{1,3}(\.\d{1,3}){0,3}$ |
144
|
|
|
|
|
|
|
/x; |
145
|
|
|
|
|
|
|
|
146
|
5
|
|
|
|
|
27
|
my ($start,$end)=split /\s*-\s*/,$range; |
147
|
5
|
|
|
|
|
18
|
( ip_to_int($start) ,ip_to_int($end)) |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
sub parse_ipv4_ip { |
152
|
3
|
|
|
3
|
1
|
6
|
my $ip=$_[$#_]; |
153
|
3
|
50
|
|
|
|
8
|
return () unless defined($ip); |
154
|
|
|
|
|
|
|
|
155
|
3
|
|
|
|
|
9
|
( ip_to_int($ip) ,ip_to_int($ip)) |
156
|
|
|
|
|
|
|
} |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
sub auto_parse_ipv4_range { |
159
|
7
|
|
|
7
|
1
|
14
|
my $source=$_[$#_]; |
160
|
7
|
100
|
|
|
|
39
|
return parse_ipv4_cidr($source) if $source=~ /\//; |
161
|
3
|
100
|
|
|
|
17
|
return parse_ipv4_range($source) if $source=~ /-/; |
162
|
1
|
|
|
|
|
3
|
return parse_ipv4_ip($source); |
163
|
|
|
|
|
|
|
} |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
1; |
166
|
|
|
|
|
|
|
__END__ |