line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Net::DHCP::Config::Utilities; |
2
|
|
|
|
|
|
|
|
3
|
3
|
|
|
3
|
|
170677
|
use 5.006; |
|
3
|
|
|
|
|
25
|
|
4
|
3
|
|
|
3
|
|
13
|
use strict; |
|
3
|
|
|
|
|
21
|
|
|
3
|
|
|
|
|
64
|
|
5
|
3
|
|
|
3
|
|
14
|
use warnings; |
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
92
|
|
6
|
3
|
|
|
3
|
|
1259
|
use Net::CIDR::Overlap; |
|
3
|
|
|
|
|
41501
|
|
|
3
|
|
|
|
|
950
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
=head1 NAME |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
Net::DHCP::Config::Utilities - Utility for helping generate configs for DHCP servers and manage subnets. |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
=head1 VERSION |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
Version 0.1.0 |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=cut |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
our $VERSION = '0.2.0'; |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
=head1 SYNOPSIS |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
Please note that this only supports IPv4 currently. |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
use Net::DHCP::Config::Utilities; |
26
|
|
|
|
|
|
|
use Net::DHCP::Config::Utilities::INI_loader; |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
my $dhcp_util = Net::DHCP::Config::Utilities->new; |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
# load stuff from a file |
31
|
|
|
|
|
|
|
my $loader = Net::DHCP::Config::Utilities::INI_loader->new( $dhcp_util ); |
32
|
|
|
|
|
|
|
eval{ |
33
|
|
|
|
|
|
|
$loader->load_file( $file ); |
34
|
|
|
|
|
|
|
}; |
35
|
|
|
|
|
|
|
if ( $@ ){ |
36
|
|
|
|
|
|
|
# do something upon error |
37
|
|
|
|
|
|
|
die( $@ ); |
38
|
|
|
|
|
|
|
} |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
# create and add a new subnet |
41
|
|
|
|
|
|
|
my $options={ |
42
|
|
|
|
|
|
|
base=>'10.0.0.0', |
43
|
|
|
|
|
|
|
mask=>'255.255.255.0', |
44
|
|
|
|
|
|
|
dns=>'10.0.0.1 , 10.0.10.1', |
45
|
|
|
|
|
|
|
desc=>'a example subnet', |
46
|
|
|
|
|
|
|
}; |
47
|
|
|
|
|
|
|
my $subnet = Net::DHCP::Config::Utilities::Subnet->new( $options ); |
48
|
|
|
|
|
|
|
eval{ |
49
|
|
|
|
|
|
|
$dhcp_util->subnet_add( $subnet ); |
50
|
|
|
|
|
|
|
}; |
51
|
|
|
|
|
|
|
if ( $@ ){ |
52
|
|
|
|
|
|
|
# do something upon error |
53
|
|
|
|
|
|
|
die( $@ ); |
54
|
|
|
|
|
|
|
} |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
my @subnets=$dhcp_util->subnet_list; |
57
|
|
|
|
|
|
|
print "Subnets:\n".join("\n", @subnets)."\n"; |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
=head1 METHODS |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
=head2 new |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
This iniates the object. No arguments are taken |
64
|
|
|
|
|
|
|
and this will always succeed. |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
my $dhcp_util = Net::DHCP::Config::Utilities->new; |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
=cut |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
sub new { |
71
|
3
|
|
|
3
|
1
|
6785
|
my $self={ |
72
|
|
|
|
|
|
|
nco=>Net::CIDR::Overlap->new, |
73
|
|
|
|
|
|
|
subnets=>{}, |
74
|
|
|
|
|
|
|
}; |
75
|
3
|
|
|
|
|
367
|
bless $self; |
76
|
|
|
|
|
|
|
|
77
|
3
|
|
|
|
|
14
|
return $self; |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
=head2 subnet_add |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
This adds a new L object, provided |
83
|
|
|
|
|
|
|
it does not over lap any existing ones. If the same base/mask has been |
84
|
|
|
|
|
|
|
added previously, the new will over write the old. |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
One object is taken and that is the L |
87
|
|
|
|
|
|
|
to add. |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
This will die upon failure. |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
eval{ |
92
|
|
|
|
|
|
|
$dhcp_util->subnet_add( $subnet ); |
93
|
|
|
|
|
|
|
}; |
94
|
|
|
|
|
|
|
if ( $@ ){ |
95
|
|
|
|
|
|
|
die( $@.' prevented the subnet from being added' ); |
96
|
|
|
|
|
|
|
} |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
=cut |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
sub subnet_add{ |
101
|
8
|
|
|
8
|
1
|
12
|
my $self=$_[0]; |
102
|
8
|
|
|
|
|
10
|
my $subnet=$_[1]; |
103
|
|
|
|
|
|
|
|
104
|
8
|
50
|
|
|
|
22
|
if ( ref( $subnet ) ne 'Net::DHCP::Config::Utilities::Subnet' ){ |
105
|
0
|
|
|
|
|
0
|
die( 'No subnet specified or not a Net::DHCP::Config::Utilities::Subnet' ); |
106
|
|
|
|
|
|
|
} |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
# check if it already exists |
109
|
8
|
|
|
|
|
22
|
my $base=$subnet->base_get; |
110
|
8
|
|
|
|
|
21
|
my $mask=$subnet->mask_get; |
111
|
8
|
100
|
|
|
|
24
|
if ( defined( $self->{subnets}{$base} ) ){ |
112
|
1
|
|
|
|
|
3
|
my $current_mask=$self->{subnets}{$base}->mask_get; |
113
|
|
|
|
|
|
|
# if it already exists with a different mask, don't readd it |
114
|
1
|
50
|
|
|
|
4
|
if ( $mask ne $current_mask ){ |
115
|
0
|
|
|
|
|
0
|
die ( '"'.$base.'" already exists with the mask "'.$current_mask.'" can not readd it with the mask "'.$mask.'"' ); |
116
|
|
|
|
|
|
|
} |
117
|
1
|
|
|
|
|
8
|
$self->{subnets}{$base}=$subnet; |
118
|
1
|
|
|
|
|
4
|
return 1; |
119
|
|
|
|
|
|
|
} |
120
|
|
|
|
|
|
|
|
121
|
7
|
|
|
|
|
20
|
my $cidr=$subnet->cidr; |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
# make sure this subnet does not overlap with any existing ones |
124
|
7
|
|
|
|
|
11
|
eval{ |
125
|
7
|
|
|
|
|
27
|
$self->{nco}->compare_and_add( $cidr, 0, 0 ); |
126
|
|
|
|
|
|
|
}; |
127
|
7
|
100
|
|
|
|
6814
|
if ( $@ ){ |
128
|
1
|
|
|
|
|
6
|
die( '"'.$cidr.'" overlaps one or more exists subnets... '.$@ ); |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
|
131
|
6
|
|
|
|
|
14
|
$self->{subnets}{$base}=$subnet; |
132
|
|
|
|
|
|
|
|
133
|
6
|
|
|
|
|
16
|
return 1; |
134
|
|
|
|
|
|
|
} |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
=head2 subnet_get |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
This returns the requested the subnet. |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
One option is taken and that is the base of the subnet desired. |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
If the requested subnet is not found, this will die. |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
The returned value is a L |
145
|
|
|
|
|
|
|
object. |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
my $subnet=$dhcp_util->subnet_get; |
148
|
|
|
|
|
|
|
if ( $@ ){ |
149
|
|
|
|
|
|
|
die( $@ ); |
150
|
|
|
|
|
|
|
} |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
=cut |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
sub subnet_get{ |
155
|
2
|
|
|
2
|
1
|
4
|
my $self=$_[0]; |
156
|
2
|
|
|
|
|
5
|
my $base=$_[1]; |
157
|
|
|
|
|
|
|
|
158
|
2
|
50
|
|
|
|
5
|
if (! defined( $base ) ){ |
159
|
0
|
|
|
|
|
0
|
die( 'No base specified' ); |
160
|
|
|
|
|
|
|
} |
161
|
|
|
|
|
|
|
|
162
|
2
|
50
|
|
|
|
5
|
if ( !defined( $self->{subnets}{ $base } ) ){ |
163
|
0
|
|
|
|
|
0
|
die( '"'.$base.'" does not exist' ); |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
|
166
|
2
|
|
|
|
|
5
|
return $self->{subnets}{ $base }; |
167
|
|
|
|
|
|
|
} |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
=head2 subnet_list |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
Returns a list of the subnet bases. |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
my @subnets=$dhcp_util->subnet_list; |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
=cut |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
sub subnet_list{ |
178
|
1
|
|
|
1
|
1
|
3
|
return keys( %{ $_[0]->{subnets} } ); |
|
1
|
|
|
|
|
11
|
|
179
|
|
|
|
|
|
|
} |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
=head1 AUTHOR |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
Zane C. Bowers-Hadley, C<< >> |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
=head1 BUGS |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
Please report any bugs or feature requests to C, or through |
188
|
|
|
|
|
|
|
the web interface at L. I will be notified, and then you'll |
189
|
|
|
|
|
|
|
automatically be notified of progress on your bug as I make changes. |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
=head1 SUPPORT |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
perldoc Net::DHCP::Config::Utilities |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
You can also look for information at: |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=over 4 |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker (report bugs here) |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
L |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
L |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
=item * CPAN Ratings |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
L |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
=item * Search CPAN |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
L |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
=item * Git Repository |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
L |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
=back |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
=head1 LICENSE AND COPYRIGHT |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
This software is Copyright (c) 2019 by Zane C. Bowers-Hadley. |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
This is free software, licensed under: |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
The Artistic License 2.0 (GPL Compatible) |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
=cut |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
1; # End of Net::DHCP::Config::Utilities |