File Coverage

blib/lib/App/Manoc/IPAddress/IPv4Network.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package App::Manoc::IPAddress::IPv4Network;
2             #ABSTRACT: IPv4 Networks
3              
4              
5 1     1   3070 use Moose;
  1         2  
  1         6  
6              
7             our $VERSION = '2.99.2'; ##TRIAL VERSION
8              
9 1     1   5641 use namespace::autoclean;
  1         2  
  1         16  
10              
11 1     1   53 use Moose::Util::TypeConstraints;
  1         2  
  1         9  
12 1     1   2057 use App::Manoc::Utils::IPAddress qw(check_addr netmask2prefix prefix2netmask_i);
  0            
  0            
13             use App::Manoc::IPAddress::IPv4;
14              
15             use overload ( '""' => sub { shift->_stringify() }, );
16              
17              
18             has 'address' => (
19             is => 'ro',
20             isa => 'App::Manoc::IPAddress::IPv4',
21             required => 1,
22             writer => '_set_address',
23             );
24              
25             sub _address_i {
26             $_[0]->address->numeric();
27             }
28              
29              
30             has 'prefix' => (
31             is => 'ro',
32             isa => subtype( 'Int' => where { $_ >= 0 && $_ <= 32 } ),
33             required => 1,
34             );
35              
36             has '_netmask_i' => (
37             is => 'ro',
38             isa => 'Int',
39             lazy => 1,
40             init_arg => undef,
41             builder => '_build_netmask_i',
42             );
43              
44             sub _build_netmask_i {
45             prefix2netmask_i( $_[0]->prefix );
46             }
47              
48              
49             has 'netmask' => (
50             is => 'ro',
51             isa => 'App::Manoc::IPAddress::IPv4',
52             lazy => 1,
53             init_arg => 1,
54             builder => '_build_netmask'
55             );
56              
57             sub _build_netmask {
58             App::Manoc::IPAddress::IPv4->new( numeric => $_[0]->_netmask_i );
59             }
60              
61             has '_broadcast_i' => (
62             is => 'ro',
63             isa => 'Int',
64             lazy => 1,
65             init_arg => undef,
66             builder => '_build_broadcast_i',
67             );
68              
69             sub _build_broadcast_i {
70             $_[0]->_address_i | ~$_[0]->_netmask_i;
71             }
72              
73              
74             has 'broadcast' => (
75             is => 'ro',
76             isa => 'App::Manoc::IPAddress::IPv4',
77             lazy => 1,
78             init_arg => undef,
79             builder => '_build_broadcast',
80             );
81              
82             sub _build_broadcast {
83             App::Manoc::IPAddress::IPv4->new( numeric => $_[0]->_broadcast_i );
84             }
85              
86             has _first_host_i => (
87             is => 'ro',
88             isa => 'Int',
89             lazy => 1,
90             init_arg => undef,
91             builder => '_build_first_host_i',
92             );
93              
94             sub _build_first_host_i {
95             $_[0]->_address_i + 1;
96             }
97              
98              
99             has first_host => (
100             is => 'ro',
101             isa => 'App::Manoc::IPAddress::IPv4',
102             lazy => 1,
103             init_arg => undef,
104             builder => '_build_first_host',
105             );
106              
107             sub _build_first_host {
108             App::Manoc::IPAddress::IPv4->new( numeric => $_[0]->_first_host_i );
109             }
110              
111             has _last_host_i => (
112             is => 'ro',
113             isa => 'Int',
114             lazy => 1,
115             init_arg => undef,
116             builder => '_build_last_host_i'
117             );
118              
119             sub _build_last_host_i {
120             $_[0]->_broadcast_i - 1;
121             }
122              
123              
124             has last_host => (
125             is => 'ro',
126             isa => 'App::Manoc::IPAddress::IPv4',
127             lazy => 1,
128             init_arg => undef,
129             builder => '_build_last_host',
130             );
131              
132             sub _build_last_host {
133             App::Manoc::IPAddress::IPv4->new( numeric => $_[0]->_last_host_i );
134             }
135              
136              
137             has wildcard => (
138             is => 'ro',
139             isa => 'App::Manoc::IPAddress::IPv4',
140             lazy => 1,
141             init_arg => undef,
142             builder => '_build_wildcard'
143             );
144              
145             sub _build_wildcard {
146             my $self = shift;
147             my $prefix = $self->prefix;
148             my $addr = $prefix ? ( ( 1 << ( 32 - $prefix ) ) - 1 ) : 0xFFFFFFFF;
149             return App::Manoc::IPAddress::IPv4->new( numeric => $addr );
150             }
151              
152              
153             has num_hosts => (
154             is => 'ro',
155             isa => 'Int',
156             lazy => 1,
157             init_arg => undef,
158             builder => '_build_num_hosts'
159             );
160              
161             sub _build_num_hosts {
162             return $_[0]->_last_host_i - $_[0]->_first_host_i + 1;
163             }
164              
165              
166             sub contains_address {
167             my ( $self, $address ) = @_;
168              
169             blessed($address) and
170             $address->isa('App::Manoc::IPAddress::IPv4') and
171             $address = $address->numeric;
172              
173             return ( $address & $self->_netmask_i ) == $self->_address_i;
174             }
175              
176             around BUILDARGS => sub {
177             my $orig = shift;
178             my $class = shift;
179              
180             if ( @_ == 2 ) {
181             my $address = shift;
182             if ( !ref($address) ) {
183             check_addr($address) and
184             $address = App::Manoc::IPAddress::IPv4->new($address);
185             }
186             my $prefix = shift;
187             if ( blessed($prefix) && $prefix->isa('App::Manoc::IPAddress::IPv4') ) {
188             $prefix = $prefix->padded;
189             }
190             check_addr($prefix) and $prefix = netmask2prefix($prefix);
191             return $class->$orig(
192             address => $address,
193             prefix => $prefix,
194             );
195             }
196             else {
197             return $class->$orig(@_);
198             }
199             };
200              
201             sub BUILD {
202             my $self = shift;
203              
204             my $address_i = $self->address->numeric;
205             my $prefix = $self->prefix;
206             my $wildcard_i = $prefix ? ( ( 1 << ( 32 - $prefix ) ) - 1 ) : 0xFFFFFFFF;
207              
208             if ( ( $address_i & $wildcard_i ) != 0 ) {
209             my $new_address_i = $address_i & prefix2netmask_i($prefix);
210             $self->_set_address( App::Manoc::IPAddress::IPv4->new( numeric => $new_address_i ) );
211             }
212             }
213              
214             sub _stringify {
215             my $self = shift;
216             return $self->address->unpadded . "/" . $self->prefix;
217             }
218              
219             __PACKAGE__->meta->make_immutable;
220             1;
221              
222             # Local Variables:
223             # mode: cperl
224             # indent-tabs-mode: nil
225             # cperl-indent-level: 4
226             # cperl-indent-parens-as-block: t
227             # End:
228              
229             __END__
230              
231             =pod
232              
233             =head1 NAME
234              
235             App::Manoc::IPAddress::IPv4Network - IPv4 Networks
236              
237             =head1 VERSION
238              
239             version 2.99.2
240              
241             =head1 SYNOPSIS
242              
243             my $net = App::Manoc::IPAddress::IPv4Network->new('192.168.1.0', '24');
244             # same as App::Manoc::IPAddress::IPv4Network->new('10.10.0.0', '255.255.0.0');
245              
246             print "$net"; # prints 192.168.1.0/24
247              
248             $net->address; # returns '192.168.1.0'
249             $net->prefix; # returns '24'
250             $net->netmask; # returns '255.255.255.0'
251             $net->broadcast; # returns 192.168.1.255'
252             $net->first_host; # returns '192.168.1.1',
253             $net->last_host; # returns '192.168.1.254'
254             $net->wildcard; # returns '0.0.0.255'
255              
256             $net->contains_address( App::Manoc::IPAddress::IPv4->new('192.168.1.5') );
257              
258             =head1 DESCRIPTION
259              
260             A class for IPv4 networks.
261              
262             =head1 ATTRIBUTES
263              
264             =head2 address
265              
266             =head2 prefix
267              
268             =head2 netmask
269              
270             =head2 broadcast
271              
272             =head2 first_host
273              
274             =head2 last_host
275              
276             =head2 wildcard
277              
278             =head2 num_hosts
279              
280             =head1 METHODS
281              
282             =head2 contains_address($address)
283              
284             Return 1 if the address is part of this network.
285              
286             =head1 AUTHORS
287              
288             =over 4
289              
290             =item *
291              
292             Gabriele Mambrini <gmambro@cpan.org>
293              
294             =item *
295              
296             Enrico Liguori
297              
298             =back
299              
300             =head1 COPYRIGHT AND LICENSE
301              
302             This software is copyright (c) 2017 by Gabriele Mambrini.
303              
304             This is free software; you can redistribute it and/or modify it under
305             the same terms as the Perl 5 programming language system itself.
306              
307             =cut