line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
|
2
|
|
|
|
|
|
|
package Net::IP::RangeCompare; |
3
|
12
|
|
|
12
|
|
539560
|
use strict; |
|
12
|
|
|
|
|
30
|
|
|
12
|
|
|
|
|
454
|
|
4
|
12
|
|
|
12
|
|
3928
|
use Data::Dumper; |
|
12
|
|
|
|
|
46198
|
|
|
12
|
|
|
|
|
682
|
|
5
|
12
|
|
|
12
|
|
72
|
use warnings; |
|
12
|
|
|
|
|
28
|
|
|
12
|
|
|
|
|
423
|
|
6
|
12
|
|
|
12
|
|
62
|
use Carp qw(croak); |
|
12
|
|
|
|
|
21
|
|
|
12
|
|
|
|
|
1193
|
|
7
|
12
|
|
|
12
|
|
67
|
use Scalar::Util qw(looks_like_number blessed); |
|
12
|
|
|
|
|
22
|
|
|
12
|
|
|
|
|
1694
|
|
8
|
12
|
|
|
12
|
|
65
|
use vars qw($error $VERSION @ISA @EXPORT_OK %EXPORT_TAGS %HELPER); |
|
12
|
|
|
|
|
28
|
|
|
12
|
|
|
|
|
1819
|
|
9
|
12
|
|
|
|
|
2258
|
use Data::Range::Compare qw(HELPER_CB |
10
|
|
|
|
|
|
|
key_helper |
11
|
|
|
|
|
|
|
key_start |
12
|
|
|
|
|
|
|
key_end |
13
|
|
|
|
|
|
|
key_generated |
14
|
|
|
|
|
|
|
key_missing |
15
|
|
|
|
|
|
|
key_data |
16
|
|
|
|
|
|
|
add_one |
17
|
|
|
|
|
|
|
sub_one |
18
|
|
|
|
|
|
|
cmp_values |
19
|
|
|
|
|
|
|
sort_largest_range_end_first |
20
|
|
|
|
|
|
|
sort_largest_range_start_first |
21
|
|
|
|
|
|
|
sort_smallest_range_start_first |
22
|
|
|
|
|
|
|
sort_smallest_range_end_first |
23
|
|
|
|
|
|
|
sort_in_consolidate_order |
24
|
|
|
|
|
|
|
sort_in_presentation_order |
25
|
12
|
|
|
12
|
|
13518
|
); |
|
12
|
|
|
|
|
47553
|
|
26
|
12
|
|
|
|
|
2340
|
use Data::IPV4::Range::Parse qw( |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
ALL_BITS |
29
|
|
|
|
|
|
|
MAX_CIDR |
30
|
|
|
|
|
|
|
MIN_CIDR |
31
|
|
|
|
|
|
|
int_to_ip |
32
|
|
|
|
|
|
|
ip_to_int |
33
|
|
|
|
|
|
|
sort_quad |
34
|
|
|
|
|
|
|
sort_notations |
35
|
|
|
|
|
|
|
broadcast_int |
36
|
|
|
|
|
|
|
base_int |
37
|
|
|
|
|
|
|
size_from_mask |
38
|
|
|
|
|
|
|
hostmask |
39
|
|
|
|
|
|
|
cidr_to_int |
40
|
|
|
|
|
|
|
parse_ipv4_cidr |
41
|
|
|
|
|
|
|
parse_ipv4_range |
42
|
|
|
|
|
|
|
parse_ipv4_ip |
43
|
|
|
|
|
|
|
auto_parse_ipv4_range |
44
|
|
|
|
|
|
|
|
45
|
12
|
|
|
12
|
|
13180
|
); |
|
12
|
|
|
|
|
26986
|
|
46
|
|
|
|
|
|
|
|
47
|
12
|
|
|
12
|
|
92
|
use constant key_start_ip =>key_start; |
|
12
|
|
|
|
|
23
|
|
|
12
|
|
|
|
|
790
|
|
48
|
12
|
|
|
12
|
|
176
|
use constant key_end_ip =>key_end; |
|
12
|
|
|
|
|
27
|
|
|
12
|
|
|
|
|
3411
|
|
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
%HELPER=HELPER_CB; |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
$VERSION=4.025; |
53
|
|
|
|
|
|
|
use overload |
54
|
12
|
|
|
|
|
129
|
'""' => \¬ation |
55
|
12
|
|
|
12
|
|
68
|
,'fallback' => 1; |
|
12
|
|
|
|
|
21
|
|
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
require Exporter; |
59
|
|
|
|
|
|
|
@ISA=qw(Exporter Data::Range::Compare ); |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
@EXPORT_OK=qw( |
62
|
|
|
|
|
|
|
hostmask |
63
|
|
|
|
|
|
|
cidr_to_int |
64
|
|
|
|
|
|
|
ip_to_int |
65
|
|
|
|
|
|
|
int_to_ip |
66
|
|
|
|
|
|
|
size_from_mask |
67
|
|
|
|
|
|
|
base_int |
68
|
|
|
|
|
|
|
broadcast_int |
69
|
|
|
|
|
|
|
cmp_int |
70
|
|
|
|
|
|
|
sort_quad |
71
|
|
|
|
|
|
|
sort_notations |
72
|
|
|
|
|
|
|
add_one |
73
|
|
|
|
|
|
|
sub_one |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
sort_ranges |
76
|
|
|
|
|
|
|
sort_largest_first_int_first |
77
|
|
|
|
|
|
|
sort_smallest_last_int_first |
78
|
|
|
|
|
|
|
sort_largest_last_int_first |
79
|
|
|
|
|
|
|
sort_smallest_first_int_first |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
get_overlapping_range |
82
|
|
|
|
|
|
|
get_common_range |
83
|
|
|
|
|
|
|
grep_overlap |
84
|
|
|
|
|
|
|
grep_non_overlap |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
consolidate_ranges |
87
|
|
|
|
|
|
|
range_start_end_fill |
88
|
|
|
|
|
|
|
fill_missing_ranges |
89
|
|
|
|
|
|
|
range_compare |
90
|
|
|
|
|
|
|
compare_row |
91
|
|
|
|
|
|
|
range_compare_force_cidr |
92
|
|
|
|
|
|
|
); |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
%EXPORT_TAGS = ( |
95
|
|
|
|
|
|
|
ALL=>\@EXPORT_OK |
96
|
|
|
|
|
|
|
,HELPER=>[qw( |
97
|
|
|
|
|
|
|
hostmask |
98
|
|
|
|
|
|
|
cidr_to_int |
99
|
|
|
|
|
|
|
ip_to_int |
100
|
|
|
|
|
|
|
int_to_ip |
101
|
|
|
|
|
|
|
sort_quad |
102
|
|
|
|
|
|
|
size_from_mask |
103
|
|
|
|
|
|
|
base_int |
104
|
|
|
|
|
|
|
broadcast_int |
105
|
|
|
|
|
|
|
cmp_int |
106
|
|
|
|
|
|
|
sort_notations |
107
|
|
|
|
|
|
|
add_one |
108
|
|
|
|
|
|
|
sub_one |
109
|
|
|
|
|
|
|
)] |
110
|
|
|
|
|
|
|
,SORT=>[qw( |
111
|
|
|
|
|
|
|
sort_ranges |
112
|
|
|
|
|
|
|
sort_largest_first_int_first |
113
|
|
|
|
|
|
|
sort_smallest_last_int_first |
114
|
|
|
|
|
|
|
sort_largest_last_int_first |
115
|
|
|
|
|
|
|
sort_smallest_first_int_first |
116
|
|
|
|
|
|
|
)] |
117
|
|
|
|
|
|
|
,OVERLAP=>[qw( |
118
|
|
|
|
|
|
|
get_overlapping_range |
119
|
|
|
|
|
|
|
get_common_range |
120
|
|
|
|
|
|
|
grep_overlap |
121
|
|
|
|
|
|
|
grep_non_overlap |
122
|
|
|
|
|
|
|
)] |
123
|
|
|
|
|
|
|
,PROCESS=>[qw( |
124
|
|
|
|
|
|
|
consolidate_ranges |
125
|
|
|
|
|
|
|
range_start_end_fill |
126
|
|
|
|
|
|
|
fill_missing_ranges |
127
|
|
|
|
|
|
|
range_compare |
128
|
|
|
|
|
|
|
compare_row |
129
|
|
|
|
|
|
|
range_compare_force_cidr |
130
|
|
|
|
|
|
|
)] |
131
|
|
|
|
|
|
|
); |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
## compatibilty stuffs |
134
|
|
|
|
|
|
|
*sort_ranges=\&sort_in_consolidate_order; |
135
|
|
|
|
|
|
|
*sort_largest_first_int_first=\&sort_largest_range_start_first; |
136
|
|
|
|
|
|
|
*sort_smallest_last_int_first=\&sort_smallest_range_end_first; |
137
|
|
|
|
|
|
|
*sort_largest_last_int_first =\&sort_largest_range_end_first; |
138
|
|
|
|
|
|
|
*sort_smallest_first_int_first=\&sort_smallest_range_start_first; |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
sub new { |
141
|
228
|
|
|
228
|
1
|
20150
|
my ($s,$start,$end,@args)=@_; |
142
|
228
|
100
|
|
|
|
633
|
return undef unless looks_like_number $start; |
143
|
227
|
100
|
|
|
|
489
|
return undef unless looks_like_number $end; |
144
|
226
|
100
|
|
|
|
440
|
return undef if $start>$end; |
145
|
223
|
|
|
|
|
863
|
$s->SUPER::new(\%HELPER,$start,$end,@args); |
146
|
|
|
|
|
|
|
} |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
sub parse_new_range { |
149
|
88
|
|
|
88
|
1
|
5565
|
my ($s,@args)=@_; |
150
|
88
|
|
|
|
|
101
|
my $string; |
151
|
88
|
100
|
|
|
|
185
|
if($#args >0) { |
152
|
1
|
|
|
|
|
5
|
$string=join ' - ',@args; |
153
|
|
|
|
|
|
|
} else { |
154
|
87
|
100
|
|
|
|
193
|
return undef unless defined($args[0]); |
155
|
86
|
|
|
|
|
95
|
$string=$args[0]; |
156
|
86
|
|
|
|
|
194
|
my $class=blessed($string); |
157
|
86
|
100
|
|
|
|
201
|
if(ref($string)) { |
158
|
47
|
100
|
66
|
|
|
257
|
return $string if $class and $class eq 'Net::IP::RangeCompare'; |
159
|
1
|
50
|
|
|
|
4
|
if($class) { |
160
|
0
|
|
|
|
|
0
|
$string .=''; |
161
|
0
|
0
|
|
|
|
0
|
return undef unless $string=~ m/ |
162
|
|
|
|
|
|
|
^ |
163
|
|
|
|
|
|
|
\d(\.\d{1,3}){0,3} |
164
|
|
|
|
|
|
|
\s*[\/-]\s* |
165
|
|
|
|
|
|
|
\d(\.\d{1,3}){0,3} |
166
|
|
|
|
|
|
|
$ |
167
|
|
|
|
|
|
|
/x; |
168
|
|
|
|
|
|
|
} else { |
169
|
1
|
|
|
|
|
4
|
return undef; |
170
|
|
|
|
|
|
|
} |
171
|
|
|
|
|
|
|
} |
172
|
|
|
|
|
|
|
} |
173
|
40
|
|
|
|
|
122
|
my ($start,$end)=auto_parse_ipv4_range($string); |
174
|
40
|
100
|
|
|
|
1783
|
return undef unless looks_like_number($end); |
175
|
39
|
|
|
|
|
109
|
$s->new($start,$end); |
176
|
|
|
|
|
|
|
} |
177
|
|
|
|
|
|
|
*new_from_ip=\&parse_new_range; |
178
|
|
|
|
|
|
|
*new_from_range=\&parse_new_range; |
179
|
|
|
|
|
|
|
*new_from_cidr=\&parse_new_range; |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
########################################################## |
182
|
|
|
|
|
|
|
# |
183
|
|
|
|
|
|
|
# OO Stubs |
184
|
|
|
|
|
|
|
|
185
|
2108
|
|
|
2108
|
1
|
7146
|
sub first_int () { $_[0]->[key_start_ip] } |
186
|
1160
|
|
|
1160
|
1
|
4827
|
sub last_int () { $_[0]->[key_end_ip] } |
187
|
6
|
|
|
6
|
1
|
1120
|
sub first_ip () { int_to_ip($_[0]->[key_start_ip]) } |
188
|
6
|
|
|
6
|
1
|
1045
|
sub last_ip () { int_to_ip($_[0]->[key_end_ip]) } |
189
|
157
|
|
|
157
|
0
|
16608
|
sub missing () {$_[0]->[key_missing] } |
190
|
2
|
|
|
2
|
0
|
107
|
sub generated () {$_[0]->[key_generated] } |
191
|
0
|
|
|
0
|
1
|
0
|
sub error () { $error } |
192
|
4
|
|
|
4
|
1
|
43
|
sub size () { 1 + $_[0]->last_int - $_[0]->first_int } |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
sub data () { |
195
|
2
|
|
|
2
|
1
|
628
|
my ($s)=@_; |
196
|
|
|
|
|
|
|
# always return the data ref if it exists |
197
|
2
|
100
|
|
|
|
8
|
return $s->[key_data] if ref($s->[key_data]); |
198
|
1
|
|
|
|
|
3
|
$s->[key_data]={}; |
199
|
1
|
|
|
|
|
3
|
$s->[key_data] |
200
|
|
|
|
|
|
|
} |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
sub notation { |
203
|
298
|
|
|
298
|
1
|
6710
|
join ' - ' |
204
|
|
|
|
|
|
|
,int_to_ip($_[0]->first_int) |
205
|
|
|
|
|
|
|
,int_to_ip($_[0]->last_int) |
206
|
|
|
|
|
|
|
} |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
sub get_cidr_notation () { |
209
|
2
|
|
|
2
|
1
|
18
|
my ($s)=@_; |
210
|
2
|
|
|
|
|
4
|
my $n=$s; |
211
|
2
|
|
|
|
|
3
|
my $return_ref=[]; |
212
|
2
|
|
|
|
|
3
|
my ($range,$cidr); |
213
|
2
|
|
|
|
|
6
|
while($n) { |
214
|
3
|
|
|
|
|
29
|
($range,$cidr,$n)=$n->get_first_cidr; |
215
|
3
|
|
|
|
|
19
|
push @$return_ref,$cidr; |
216
|
|
|
|
|
|
|
} |
217
|
2
|
|
|
|
|
12
|
join(', ',@$return_ref); |
218
|
|
|
|
|
|
|
} |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
sub overlap ($) { |
221
|
45
|
|
|
45
|
1
|
320
|
my ($range_a,$range_b)=@_; |
222
|
45
|
|
|
|
|
140
|
my $class=blessed $range_a; |
223
|
45
|
|
|
|
|
100
|
$range_b=$class->parse_new_range($range_b); |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
# return true if range_b's start range is contained by range_a |
226
|
45
|
100
|
100
|
|
|
91
|
return 1 if |
227
|
|
|
|
|
|
|
$range_a->cmp_first_int($range_b)!=1 |
228
|
|
|
|
|
|
|
&& |
229
|
|
|
|
|
|
|
$range_a->cmp_last_int($range_b)!=-1; |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
# return true if range_b's end range is contained by range_a |
232
|
36
|
50
|
66
|
|
|
207
|
return 1 if |
233
|
|
|
|
|
|
|
#$range_a->first_int <=$range_b->last_int |
234
|
|
|
|
|
|
|
cmp_int($range_a->first_int,$range_b->last_int )!=1 |
235
|
|
|
|
|
|
|
&& |
236
|
|
|
|
|
|
|
#$range_a->last_int >=$range_b->last_int; |
237
|
|
|
|
|
|
|
cmp_int($range_a->last_int,$range_b->last_int)!=-1; |
238
|
|
|
|
|
|
|
|
239
|
36
|
100
|
100
|
|
|
187
|
return 1 if |
240
|
|
|
|
|
|
|
#$range_b->first_int <=$range_a->first_int |
241
|
|
|
|
|
|
|
$range_b->cmp_first_int($range_a)!=1 |
242
|
|
|
|
|
|
|
&& |
243
|
|
|
|
|
|
|
#$range_b->last_int >=$range_a->first_int; |
244
|
|
|
|
|
|
|
$range_b->cmp_last_int($range_a)!=-1; |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
# return true if range_b's end range is contained by range_a |
247
|
34
|
100
|
100
|
|
|
174
|
return 1 if |
248
|
|
|
|
|
|
|
#$range_b->first_int <=$range_a->last_int |
249
|
|
|
|
|
|
|
cmp_int($range_b->first_int,$range_a->last_int )!=1 |
250
|
|
|
|
|
|
|
&& |
251
|
|
|
|
|
|
|
#$range_b->last_int >=$range_a->last_int; |
252
|
|
|
|
|
|
|
cmp_int($range_b->last_int,$range_a->last_int)!=-1; |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
# return undef by default |
255
|
|
|
|
|
|
|
undef |
256
|
30
|
|
|
|
|
157
|
} |
257
|
|
|
|
|
|
|
|
258
|
26
|
|
|
26
|
1
|
75
|
sub next_first_int () { add_one($_[0]->last_int) } |
259
|
1
|
|
|
1
|
1
|
378
|
sub previous_last_int () { sub_one($_[0]->first_int) } |
260
|
|
|
|
|
|
|
sub get_first_cidr () { |
261
|
32
|
|
|
32
|
1
|
487
|
my ($s)=@_; |
262
|
32
|
|
|
|
|
90
|
my $class=blessed $s; |
263
|
32
|
|
|
|
|
39
|
my $first_cidr; |
264
|
|
|
|
|
|
|
my $output_cidr; |
265
|
32
|
|
|
|
|
92
|
for(my $cidr=MAX_CIDR;$cidr>-1;--$cidr) { |
266
|
1017
|
|
|
|
|
2386
|
$output_cidr=MAX_CIDR - $cidr; |
267
|
1017
|
|
|
|
|
2031
|
my $mask=cidr_to_int($output_cidr); |
268
|
|
|
|
|
|
|
|
269
|
1017
|
|
|
|
|
10473
|
my $hostmask=hostmask($mask); |
270
|
1017
|
|
|
|
|
4440
|
my $size=size_from_mask($mask); |
271
|
|
|
|
|
|
|
|
272
|
1017
|
100
|
|
|
|
6071
|
next if $s->mod_first_int($size); |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
|
275
|
432
|
|
|
|
|
660
|
my $last_int=$s->first_int + $hostmask; |
276
|
432
|
100
|
|
|
|
685
|
next if cmp_int($last_int,$s->last_int)==1; |
277
|
|
|
|
|
|
|
|
278
|
32
|
|
|
|
|
135
|
$first_cidr=$class->new($s->first_int,$last_int); |
279
|
|
|
|
|
|
|
|
280
|
32
|
|
|
|
|
211
|
last; |
281
|
|
|
|
|
|
|
} |
282
|
32
|
|
|
|
|
61
|
my $cidr_string=join('/',int_to_ip($first_cidr->first_int),$output_cidr); |
283
|
|
|
|
|
|
|
|
284
|
32
|
100
|
|
|
|
333
|
if($first_cidr->cmp_last_int($s)==0) { |
285
|
16
|
|
|
|
|
104
|
return ( $first_cidr ,$cidr_string); |
286
|
|
|
|
|
|
|
} else { |
287
|
|
|
|
|
|
|
return ( |
288
|
16
|
|
|
|
|
92
|
$first_cidr |
289
|
|
|
|
|
|
|
,$cidr_string |
290
|
|
|
|
|
|
|
,$class->new( |
291
|
|
|
|
|
|
|
$first_cidr->next_first_int |
292
|
|
|
|
|
|
|
,$s->last_int |
293
|
|
|
|
|
|
|
) |
294
|
|
|
|
|
|
|
); |
295
|
|
|
|
|
|
|
} |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
} |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
sub is_cidr () { |
300
|
1
|
|
|
1
|
0
|
10
|
my ($s)=@_; |
301
|
1
|
|
|
|
|
3
|
my ($range,$cidr,$next)=$s->get_first_cidr; |
302
|
1
|
50
|
|
|
|
9
|
my $is_cidr=defined($next) ? 0 : 1; |
303
|
1
|
|
|
|
|
49
|
$is_cidr |
304
|
|
|
|
|
|
|
} |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
sub is_range () { |
307
|
1
|
|
|
1
|
0
|
2
|
my ($s)=@_; |
308
|
1
|
|
|
|
|
2
|
my ($range,$cidr,$next)=$s->get_first_cidr; |
309
|
1
|
50
|
|
|
|
11
|
my $is_range=defined($next) ? 1 : 0; |
310
|
1
|
|
|
|
|
7
|
$is_range |
311
|
|
|
|
|
|
|
} |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
sub nth ($) { |
314
|
3
|
|
|
3
|
1
|
682
|
my ($s,$offset)=@_; |
315
|
3
|
|
|
|
|
9
|
my $int=$s->first_int + $offset; |
316
|
3
|
100
|
|
|
|
7
|
return undef if cmp_int($int,$s->last_int)==1; |
317
|
2
|
|
|
|
|
13
|
int_to_ip($int); |
318
|
|
|
|
|
|
|
} |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
sub _internal_ip_list_func ($) { |
321
|
6
|
|
|
6
|
|
12
|
my ($s,$mode)=@_; |
322
|
6
|
|
|
|
|
6
|
my $next=$s; |
323
|
6
|
|
|
|
|
7
|
my @list; |
324
|
|
|
|
|
|
|
my $ip; |
325
|
0
|
|
|
|
|
0
|
my $cidr; |
326
|
6
|
|
|
|
|
207
|
while($next) { |
327
|
15
|
|
|
|
|
125
|
($ip,$cidr,$next)=$next->get_first_cidr; |
328
|
15
|
100
|
|
|
|
144
|
if($mode eq 'first_int') { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
329
|
3
|
|
|
|
|
7
|
push @list,$ip->first_int; |
330
|
|
|
|
|
|
|
} elsif($mode eq 'first_ip') { |
331
|
3
|
|
|
|
|
6
|
push @list,$ip->first_ip; |
332
|
|
|
|
|
|
|
} elsif($mode eq 'last_ip') { |
333
|
3
|
|
|
|
|
7
|
push @list,$ip->last_ip; |
334
|
|
|
|
|
|
|
} elsif($mode eq 'last_int') { |
335
|
3
|
|
|
|
|
5
|
push @list,$ip->last_int; |
336
|
|
|
|
|
|
|
} elsif($mode eq 'netmask_int') { |
337
|
1
|
|
|
|
|
8
|
my ($cidr_int)=($cidr=~ /(\d+)$/); |
338
|
1
|
|
|
|
|
4
|
push @list,cidr_to_int($cidr_int); |
339
|
|
|
|
|
|
|
} elsif($mode eq 'netmask') { |
340
|
2
|
|
|
|
|
12
|
my ($cidr_int)=($cidr=~ /(\d+)$/); |
341
|
2
|
|
|
|
|
7
|
push @list,int_to_ip(cidr_to_int($cidr_int)); |
342
|
|
|
|
|
|
|
} |
343
|
|
|
|
|
|
|
} |
344
|
6
|
|
|
|
|
87
|
@list; |
345
|
|
|
|
|
|
|
} |
346
|
|
|
|
|
|
|
|
347
|
1
|
|
|
1
|
1
|
16
|
sub netmask_int_list { $_[0]->_internal_ip_list_func('netmask_int') } |
348
|
1
|
|
|
1
|
1
|
14
|
sub netmask_list { $_[0]->_internal_ip_list_func('netmask') } |
349
|
1
|
|
|
1
|
1
|
20
|
sub base_list_int () { $_[0]->_internal_ip_list_func('first_int') } |
350
|
1
|
|
|
1
|
1
|
906
|
sub base_list_ip () { $_[0]->_internal_ip_list_func('first_ip') } |
351
|
1
|
|
|
1
|
1
|
958
|
sub broadcast_list_int () { $_[0]->_internal_ip_list_func('last_int') } |
352
|
1
|
|
|
1
|
1
|
850
|
sub broadcast_list_ip () { $_[0]->_internal_ip_list_func('last_ip') } |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
sub enumerate { |
355
|
3
|
|
|
3
|
1
|
27
|
my ($s,$cidr)=@_; |
356
|
3
|
100
|
|
|
|
7
|
$cidr=MAX_CIDR unless $cidr; |
357
|
3
|
|
|
|
|
7
|
my $mask=cidr_to_int($cidr); |
358
|
3
|
|
|
|
|
34
|
my $hostmask=hostmask($mask); |
359
|
3
|
|
|
|
|
10
|
my $n=$s; |
360
|
3
|
|
|
|
|
10
|
my $class=blessed $s; |
361
|
|
|
|
|
|
|
sub { |
362
|
9
|
100
|
|
9
|
|
2163
|
return undef unless $n; |
363
|
|
|
|
|
|
|
#my $cidr_end=($n->first_int & $mask) + $hostmask; |
364
|
6
|
|
|
|
|
83
|
my $cidr_end=broadcast_int($n->first_int , $mask); |
365
|
6
|
|
|
|
|
46
|
my $return_ref; |
366
|
6
|
100
|
|
|
|
12
|
if(cmp_int($cidr_end,$n->last_int)!=-1) { |
367
|
3
|
|
|
|
|
10
|
$return_ref=$n; |
368
|
3
|
|
|
|
|
4
|
$n=undef; |
369
|
|
|
|
|
|
|
} else { |
370
|
3
|
|
|
|
|
14
|
$return_ref=$class->new( |
371
|
|
|
|
|
|
|
$n->first_int |
372
|
|
|
|
|
|
|
,$cidr_end |
373
|
|
|
|
|
|
|
); |
374
|
3
|
|
|
|
|
20
|
$n=$class->new( |
375
|
|
|
|
|
|
|
$return_ref->next_first_int |
376
|
|
|
|
|
|
|
,$n->last_int |
377
|
|
|
|
|
|
|
); |
378
|
|
|
|
|
|
|
} |
379
|
6
|
|
|
|
|
29
|
$return_ref; |
380
|
|
|
|
|
|
|
} |
381
|
3
|
|
|
|
|
16
|
} |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
sub enumerate_size { |
384
|
2
|
|
|
2
|
1
|
16
|
my ($s,$inc)=@_; |
385
|
2
|
|
|
|
|
9
|
my $class=blessed $s; |
386
|
2
|
100
|
|
|
|
7
|
$inc=1 unless $inc; |
387
|
2
|
|
|
|
|
3
|
my $done; |
388
|
|
|
|
|
|
|
sub { |
389
|
8
|
100
|
|
8
|
|
2033
|
return undef if $done; |
390
|
6
|
|
|
|
|
15
|
my $first=$s->first_int; |
391
|
6
|
|
|
|
|
10
|
my $next=$first + $inc; |
392
|
6
|
|
|
|
|
6
|
my $last; |
393
|
6
|
100
|
|
|
|
14
|
if(cmp_int($s->last_int,$next)!=-1) { |
394
|
4
|
|
|
|
|
18
|
$last=$next; |
395
|
|
|
|
|
|
|
} else { |
396
|
2
|
|
|
|
|
43
|
$last=$s->last_int; |
397
|
|
|
|
|
|
|
} |
398
|
6
|
|
|
|
|
17
|
my $new_range=$class->new($first,$last); |
399
|
6
|
100
|
|
|
|
45
|
$done=1 if $s->cmp_last_int($new_range)==0; |
400
|
6
|
|
|
|
|
31
|
$s=$class->new($new_range->next_first_int,$s->last_int); |
401
|
6
|
|
|
|
|
43
|
$new_range; |
402
|
|
|
|
|
|
|
} |
403
|
2
|
|
|
|
|
14
|
} |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
sub cmp_first_int($) { |
406
|
84
|
|
|
84
|
1
|
841
|
my ($s,$cmp)=@_; |
407
|
84
|
|
|
|
|
142
|
cmp_int($s->first_int,$cmp->first_int) |
408
|
|
|
|
|
|
|
} |
409
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
sub cmp_last_int($) { |
411
|
86
|
|
|
86
|
1
|
1342
|
my ($s,$cmp)=@_; |
412
|
86
|
|
|
|
|
161
|
cmp_int($s->last_int,$cmp->last_int) |
413
|
|
|
|
|
|
|
} |
414
|
|
|
|
|
|
|
|
415
|
1017
|
|
|
1017
|
1
|
1667
|
sub mod_first_int ($) { $_[0]->first_int % $_[1] } |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
*cmp_int=\&cmp_values; |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
sub get_common_range { |
420
|
30
|
50
|
|
30
|
1
|
260
|
shift if $_[0] eq 'Net::IP::RangeCompare'; |
421
|
30
|
50
|
|
|
|
83
|
shift if $_[0] eq \%HELPER; |
422
|
30
|
|
|
|
|
39
|
my $ranges=shift; |
423
|
30
|
50
|
|
|
|
64
|
croak 'empty range reference' if $#$ranges==-1; |
424
|
30
|
|
|
|
|
121
|
my $range=Net::IP::RangeCompare->SUPER::get_common_range(\%HELPER,$ranges); |
425
|
30
|
100
|
|
|
|
1565
|
return undef if cmp_values($range->first_int,$range->last_int)==1; |
426
|
29
|
|
|
|
|
176
|
$range; |
427
|
|
|
|
|
|
|
} |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
sub grep_non_overlap { |
430
|
1
|
|
|
1
|
1
|
291
|
my ($range,$list)=@_; |
431
|
1
|
|
|
|
|
4
|
my $result=[]; |
432
|
1
|
|
|
|
|
7
|
my $cmp=Net::IP::RangeCompare->parse_new_range($range); |
433
|
1
|
50
|
|
|
|
11
|
return $result unless defined($cmp); |
434
|
3
|
|
|
|
|
20
|
@$result=(grep { |
435
|
1
|
|
|
|
|
3
|
my $range=Net::IP::RangeCompare->parse_new_range($_); |
436
|
3
|
50
|
|
|
|
25
|
defined($range) ? !$cmp->overlap($range) : 0 |
437
|
|
|
|
|
|
|
} @$list); |
438
|
1
|
|
|
|
|
4
|
$result; |
439
|
|
|
|
|
|
|
} |
440
|
|
|
|
|
|
|
sub grep_overlap { |
441
|
2
|
|
|
2
|
1
|
478
|
my ($range,$list)=@_; |
442
|
2
|
|
|
|
|
5
|
my $result=[]; |
443
|
2
|
|
|
|
|
13
|
my $cmp=Net::IP::RangeCompare->parse_new_range($range); |
444
|
2
|
50
|
|
|
|
171
|
return $result unless defined($cmp); |
445
|
4
|
|
|
|
|
36
|
@$result=(grep { |
446
|
2
|
|
|
|
|
5
|
my $range=Net::IP::RangeCompare->parse_new_range($_); |
447
|
4
|
50
|
|
|
|
40
|
defined($range) ? $cmp->overlap($range) : 0 |
448
|
|
|
|
|
|
|
} @$list); |
449
|
2
|
|
|
|
|
13
|
$result; |
450
|
|
|
|
|
|
|
} |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
sub get_overlapping_range { |
453
|
5
|
100
|
|
5
|
1
|
110
|
shift if $_[0] eq 'Net::IP::RangeCompare'; |
454
|
5
|
100
|
|
|
|
28
|
shift if $_[0] eq \%HELPER; |
455
|
5
|
|
|
|
|
55
|
Net::IP::RangeCompare->SUPER::get_overlapping_range(\%HELPER,@_); |
456
|
|
|
|
|
|
|
} |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
sub consolidate_ranges { |
459
|
22
|
100
|
|
22
|
1
|
382
|
shift if $_[0] eq 'Net::IP::RangeCompare'; |
460
|
22
|
100
|
|
|
|
64
|
shift if $_[0] eq \%HELPER; |
461
|
22
|
|
|
|
|
91
|
Net::IP::RangeCompare->SUPER::consolidate_ranges(\%HELPER,@_) |
462
|
|
|
|
|
|
|
} |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
sub fill_missing_ranges { |
465
|
2
|
50
|
|
2
|
1
|
24
|
shift if $_[0] eq 'Net::IP::RangeCompare'; |
466
|
2
|
50
|
|
|
|
6
|
shift if $_[0] eq \%HELPER; |
467
|
2
|
|
|
|
|
15
|
Net::IP::RangeCompare->SUPER::fill_missing_ranges(\%HELPER,@_); |
468
|
|
|
|
|
|
|
} |
469
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
sub range_start_end_fill { |
471
|
1
|
50
|
|
1
|
1
|
17
|
shift if $_[0] eq 'Net::IP::RangeCompare'; |
472
|
1
|
50
|
|
|
|
5
|
shift if $_[0] eq \%HELPER; |
473
|
1
|
|
|
|
|
11
|
Net::IP::RangeCompare->SUPER::range_start_end_fill(\%HELPER,@_); |
474
|
|
|
|
|
|
|
} |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
sub range_compare { |
477
|
6
|
50
|
|
6
|
1
|
723
|
shift if $_[0] eq 'Net::IP::RangeCompare'; |
478
|
6
|
50
|
|
|
|
19
|
shift if $_[0] eq \%HELPER; |
479
|
6
|
|
|
|
|
36
|
my $sub=Net::IP::RangeCompare->SUPER::range_compare(\%HELPER,@_) ; |
480
|
|
|
|
|
|
|
sub { |
481
|
30
|
|
|
30
|
|
2756
|
my @row=$sub->(); |
482
|
30
|
100
|
|
|
|
875
|
return () unless @row; |
483
|
24
|
|
|
|
|
52
|
return (get_common_range(\@row),@row); |
484
|
|
|
|
|
|
|
} |
485
|
6
|
|
|
|
|
110
|
} |
486
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
sub range_compare_force_cidr { |
488
|
1
|
|
|
1
|
1
|
15
|
my $sub=range_compare(@_); |
489
|
|
|
|
|
|
|
|
490
|
1
|
|
|
|
|
3
|
my ($common,@row)=$sub->(); |
491
|
1
|
|
|
|
|
5
|
my ($cidr,$notation,$next)=$common->get_first_cidr; |
492
|
|
|
|
|
|
|
sub { |
493
|
7
|
100
|
|
7
|
|
47
|
return () unless @row; |
494
|
6
|
|
|
|
|
14
|
my @return_row=($cidr,$notation,@row); |
495
|
6
|
100
|
|
|
|
13
|
if($next) { |
496
|
1
|
|
|
|
|
18
|
($cidr,$notation,$next)=$next->get_first_cidr; |
497
|
|
|
|
|
|
|
} else { |
498
|
5
|
|
|
|
|
7
|
($common,@row)=$sub->(); |
499
|
5
|
100
|
|
|
|
16
|
if(@row) { |
500
|
4
|
|
|
|
|
8
|
($cidr,$notation,$next)=$common->get_first_cidr |
501
|
|
|
|
|
|
|
} else { |
502
|
1
|
|
|
|
|
2
|
$next=undef; |
503
|
|
|
|
|
|
|
} |
504
|
|
|
|
|
|
|
} |
505
|
|
|
|
|
|
|
@return_row |
506
|
6
|
|
|
|
|
35
|
} |
507
|
1
|
|
|
|
|
20
|
} |
508
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
sub compare_row { |
510
|
50
|
100
|
|
50
|
1
|
4288
|
shift if $_[0] eq 'Net::IP::RangeCompare'; |
511
|
50
|
100
|
|
|
|
146
|
shift if $_[0] eq \%HELPER; |
512
|
50
|
|
|
|
|
77
|
my ($ref,$row, $cols)=@_; |
513
|
50
|
100
|
|
|
|
132
|
return Net::IP::RangeCompare->SUPER::init_compare_row(\%HELPER,$ref) |
514
|
|
|
|
|
|
|
unless defined($cols); |
515
|
46
|
|
|
|
|
185
|
Net::IP::RangeCompare->SUPER::compare_row(\%HELPER,$ref,$row, $cols); |
516
|
|
|
|
|
|
|
} |
517
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
=pod |
519
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
=back |
521
|
|
|
|
|
|
|
|
522
|
|
|
|
|
|
|
=cut |
523
|
|
|
|
|
|
|
|
524
|
|
|
|
|
|
|
############################################ |
525
|
|
|
|
|
|
|
# |
526
|
|
|
|
|
|
|
# End of the package |
527
|
|
|
|
|
|
|
1; |
528
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
############################################ |
530
|
|
|
|
|
|
|
# |
531
|
|
|
|
|
|
|
# Helper package |
532
|
|
|
|
|
|
|
package Net::IP::RangeCompare::Simple; |
533
|
|
|
|
|
|
|
|
534
|
12
|
|
|
12
|
|
53498
|
use strict; |
|
12
|
|
|
|
|
39
|
|
|
12
|
|
|
|
|
485
|
|
535
|
12
|
|
|
12
|
|
67
|
use warnings; |
|
12
|
|
|
|
|
20
|
|
|
12
|
|
|
|
|
1203
|
|
536
|
12
|
|
|
12
|
|
150
|
use Carp qw(croak); |
|
12
|
|
|
|
|
22
|
|
|
12
|
|
|
|
|
1007
|
|
537
|
12
|
|
|
12
|
|
63
|
use constant key_sources=>0; |
|
12
|
|
|
|
|
24
|
|
|
12
|
|
|
|
|
834
|
|
538
|
12
|
|
|
12
|
|
60
|
use constant key_columns=>1; |
|
12
|
|
|
|
|
24
|
|
|
12
|
|
|
|
|
875
|
|
539
|
12
|
|
|
12
|
|
67
|
use constant key_compare=>2; |
|
12
|
|
|
|
|
30
|
|
|
12
|
|
|
|
|
651
|
|
540
|
12
|
|
|
12
|
|
66
|
use constant key_changed=>3; |
|
12
|
|
|
|
|
22
|
|
|
12
|
|
|
|
|
14076
|
|
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
sub new { |
543
|
1
|
|
|
1
|
|
347
|
my ($class)=@_; |
544
|
1
|
|
|
|
|
2
|
my $ref=[]; |
545
|
1
|
|
|
|
|
3
|
$ref->[key_sources]={}; |
546
|
1
|
|
|
|
|
2
|
$ref->[key_changed]={}; |
547
|
1
|
|
|
|
|
3
|
$ref->[key_columns]=[]; |
548
|
1
|
|
|
|
|
3
|
$ref->[key_compare]=undef; |
549
|
|
|
|
|
|
|
|
550
|
1
|
|
|
|
|
4
|
bless $ref,$class; |
551
|
|
|
|
|
|
|
} |
552
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
sub add_range ($$) { |
555
|
7
|
|
|
7
|
|
356
|
my ($s,$key,$range)=@_; |
556
|
7
|
50
|
|
|
|
18
|
croak "Key is not defined" unless defined($key); |
557
|
7
|
50
|
|
|
|
12
|
croak "Range is not defined" unless defined($range); |
558
|
|
|
|
|
|
|
|
559
|
7
|
|
|
|
|
16
|
my $obj=Net::IP::RangeCompare->parse_new_range($range); |
560
|
7
|
50
|
|
|
|
50
|
croak "Could not parse: $range" unless $obj; |
561
|
|
|
|
|
|
|
|
562
|
7
|
|
|
|
|
57
|
my $list; |
563
|
|
|
|
|
|
|
|
564
|
7
|
100
|
|
|
|
17
|
if(exists $s->[key_sources]->{$key}) { |
565
|
4
|
|
|
|
|
9
|
$list=$s->[key_sources]->{$key}; |
566
|
|
|
|
|
|
|
} else { |
567
|
3
|
|
|
|
|
8
|
$s->[key_sources]->{$key}=[]; |
568
|
3
|
|
|
|
|
4
|
$list=$s->[key_sources]->{$key}; |
569
|
|
|
|
|
|
|
} |
570
|
7
|
|
|
|
|
10
|
push @$list,$obj; |
571
|
7
|
|
|
|
|
10
|
$s->[key_changed]->{$key}=1; |
572
|
7
|
|
|
|
|
34
|
$obj |
573
|
|
|
|
|
|
|
} |
574
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
sub get_ranges_by_key ($) { |
576
|
2
|
|
|
2
|
|
372
|
my ($s,$key)=@_; |
577
|
2
|
50
|
|
|
|
7
|
croak "key was not defined" unless defined($key); |
578
|
|
|
|
|
|
|
|
579
|
2
|
100
|
|
|
|
8
|
return [@{$s->[key_sources]->{$key}}] |
|
1
|
|
|
|
|
4
|
|
580
|
|
|
|
|
|
|
if exists $s->[key_sources]->{$key}; |
581
|
|
|
|
|
|
|
|
582
|
1
|
|
|
|
|
5
|
return undef; |
583
|
|
|
|
|
|
|
} |
584
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
sub compare_ranges { |
586
|
2
|
|
|
2
|
|
505
|
my ($s,@keys)=@_; |
587
|
2
|
|
|
|
|
7
|
my %exclude=map { ($_,1) } @keys; |
|
1
|
|
|
|
|
4
|
|
588
|
2
|
50
|
|
|
|
4
|
croak "no ranges defined" unless keys %{$s->[key_sources]}; |
|
2
|
|
|
|
|
7
|
|
589
|
|
|
|
|
|
|
|
590
|
2
|
|
|
|
|
3
|
my $columns=$s->[key_columns]; |
591
|
2
|
|
|
|
|
5
|
@$columns=(); |
592
|
2
|
|
|
|
|
3
|
my $compare_ref=[]; |
593
|
2
|
|
|
|
|
3
|
while(my ($key,$ranges)=each %{$s->[key_sources]}) { |
|
8
|
|
|
|
|
22
|
|
594
|
6
|
100
|
|
|
|
18
|
next if exists $exclude{$key}; |
595
|
5
|
|
|
|
|
6
|
push @$columns,$key; |
596
|
5
|
100
|
|
|
|
15
|
$s->[key_sources]->{$key}=Net::IP::RangeCompare::consolidate_ranges($ranges) |
597
|
|
|
|
|
|
|
if $s->[key_changed]->{$key}; |
598
|
5
|
|
|
|
|
33
|
$s->[key_changed]->{$key}=0; |
599
|
5
|
|
|
|
|
10
|
push @$compare_ref,$s->[key_sources]->{$key}; |
600
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
} |
602
|
2
|
50
|
|
|
|
6
|
croak "no ranges defined" if $#$columns==-1; |
603
|
|
|
|
|
|
|
|
604
|
2
|
|
|
|
|
7
|
$s->[key_compare]=Net::IP::RangeCompare::range_compare( |
605
|
|
|
|
|
|
|
$compare_ref |
606
|
|
|
|
|
|
|
,consolidate_ranges=>0 |
607
|
|
|
|
|
|
|
); |
608
|
|
|
|
|
|
|
|
609
|
2
|
|
|
|
|
10
|
1 |
610
|
|
|
|
|
|
|
} |
611
|
|
|
|
|
|
|
|
612
|
|
|
|
|
|
|
sub get_row () { |
613
|
14
|
|
|
14
|
|
125
|
my ($s)=@_; |
614
|
|
|
|
|
|
|
|
615
|
14
|
50
|
|
|
|
19
|
croak "no ranges defined" unless keys %{$s->[key_sources]}; |
|
14
|
|
|
|
|
44
|
|
616
|
|
|
|
|
|
|
|
617
|
|
|
|
|
|
|
#make sure we have something to compare |
618
|
14
|
100
|
|
|
|
38
|
$s->compare_ranges |
619
|
|
|
|
|
|
|
unless $s->[key_compare]; |
620
|
14
|
|
|
|
|
12
|
my %row; |
621
|
14
|
|
|
|
|
23
|
my (@cols)=$s->[key_compare]->(); |
622
|
14
|
100
|
|
|
|
38
|
return () unless @cols; |
623
|
12
|
|
|
|
|
13
|
my $common; |
624
|
|
|
|
|
|
|
|
625
|
12
|
|
|
|
|
13
|
($common,@row{@{$s->[key_columns]}})=@cols; |
|
12
|
|
|
|
|
34
|
|
626
|
|
|
|
|
|
|
|
627
|
12
|
|
|
|
|
62
|
$common,%row |
628
|
|
|
|
|
|
|
|
629
|
|
|
|
|
|
|
} |
630
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
sub get_keys () { |
632
|
0
|
|
|
0
|
|
|
keys %{$_[0]->[key_sources]} |
|
0
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
} |
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
############################################ |
636
|
|
|
|
|
|
|
# |
637
|
|
|
|
|
|
|
# End of the package |
638
|
|
|
|
|
|
|
1; |
639
|
|
|
|
|
|
|
|
640
|
|
|
|
|
|
|
__END__ |