Net::IPAM::Block - A library for reading, formatting, sorting and converting IP-blocks.
use Net::IPAM::Block; # parse and normalize $cidr = Net::IPAM::Block->new('10.0.0.0/255.0.0.0') // die 'wrong format,'; $cidr = Net::IPAM::Block->new('10.0.0.0/8') // die 'wrong format,'; $range = Net::IPAM::Block->new('fe80::2-fe80::e') // die 'wrong format,'; $host = Net::IPAM::Block->new('2001:db8::1') // die 'wrong format,';
A block is an IP-network or IP-range, e.g.
192.168.0.1/255.255.255.0 # network, with IP mask 192.168.0.1/24 # network, with CIDR mask ::1/128 # network, with CIDR mask 10.0.0.3-10.0.17.134 # range 2001:db8::1-2001:db8::f6 # range
The parsed block is represented as an object with:
base last mask # if block is a CIDR, otherwise undef
This representation is fast sortable without conversions to/from the different IP versions.
$b = Net::IPAM::Block->new('fe80::/10');
new() parses the input as CIDR, range or address (or IP object, see below) and returns the Net::IPAM::Block object.
Example for valid input strings:
2001:db8:dead::/38 10.0.0.0/8 10.0.0.0/255.0.0.0 2001:db8::1-2001:db8::ff00:35 192.168.2.3-192.168.7.255
If a begin-end range can be represented as a CIDR, new() calculates the netmask and returns the range as CIDR block with a proper mask.
Plain IP addresses as input strings or objects are converted to /32 or /128 CIDRs.
0.0.0.0 => 0.0.0.0/32 ::ffff:127.0.0.1 => 127.0.0.1/32 :: => ::/128 Net::IPAM::IP->new('1.2.3.4') => 1.2.3.4/32 $range = Net::IPAM::Block->new('10.2.0.17-10.3.67.255') // die 'wrong block format,'; $range = Net::IPAM::Block->new('fe80::-fe80::1234') // die 'wrong block format,'; $cidr_24 = Net::IPAM::Block->new('10.0.0.0/24') // die 'wrong block format,'; $cidr_32 = Net::IPAM::Block->new('192.168.0.1') // die 'wrong block format,'; $cidr_128 = Net::IPAM::Block->new('2001:db8::1') // die 'wrong block format,'; $cidr_128 = Net::IPAM::Block->new( Net::IPAM::IP->new('2001:db8::1') // die 'wrong IP format,' );
Returns undef on illegal input.
$v = $b->version
Returns 4 or 6.
Returns the block in canonical form.
say Net::IPAM::Block->new('fe80::aa/10')->to_string; # fe80::/10 say Net::IPAM::Block->new('1.2.3.4-1.2.3.36')->to_string; # 1.2.3.4-1.2.3.36 say Net::IPAM::Block->new('127.0.0.1')->to_string; # 127.0.0.1/32
Stringification is overloaded with "to_string"
my $b = Net::IPAM::Block->new('fe80::/10'); say $b; # fe80::/10
$b->is_cidr
Returns true if the block is a CIDR.
Net::IPAM::Block->new('fe80::aa/10')->is_cidr # true Net::IPAM::Block->new('1.2.3.1-1.2.3.2')->is_cidr # false
@cidrs = $b->cidrsplit
Returns the next 2 cidrs splitted from block.
Net::IPAM::Block->new('0.0.0.0/7')->cidrsplit # 0.0.0.0/8 1.0.0.0/8 Net::IPAM::Block->new('fe80::/12')->cidrsplit # fe80::/13 fe88::/13
Returns undef if cidr mask is at maximum or if block is no CIDR.
@cidrs = $b->to_cidrs
Returns a list of Net::IPAM::Block objects as true CIDRs, representing the range.
Net::IPAM::Block->new('17.0.0.1-17.0.0.2')->to_cidrs # 17.0.0.1/32 17.0.0.2/32 Net::IPAM::Block->new('fe80::aa-fe80::ac')->to_cidrs # fe80::aa/127 fe80::ac/128 Net::IPAM::Block->new('1.2.3.0-1.2.3.101')->to_cidrs # 1.2.3.0/26 1.2.3.64/27 1.2.3.96/30 1.2.3.100/31
If the range is a CIDR, just returns the CIDR:
Net::IPAM::Block->new('10.0.0.0/8')->to_cidrs # 10.0.0.0/8 Net::IPAM::Block->new('::1')->to_cidrs # ::1/128
$ip = $b->base
Returns the base IP, as Net::IPAM::IP object.
$b = Net::IPAM::Block->new('fe80::ffff/10'); say $b->base; # fe80::/10
$ip = $b->last
Returns the last IP, as Net::IPAM::IP object.
$b = Net::IPAM::Block->new('10.0.0.0/30') say $b->last; # 10.0.0.3
$ip = $b->mask
Returns the netmask as Net::IPAM::IP object.
$b = Net::IPAM::Block->new('10.0.0.0/24') say $b->mask if defined $b->mask; # 255.255.255.0
The mask is only defined for real CIDR blocks.
Example:
1.2.3.4 => mask is /32 = 255.255.255.255 ::1 => mask is /128 = ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 10.0.0.0-10.0.0.15 => mask is /28 = 255.255.255.240 ::-::f => mask is /124 = ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0 10.0.0.0/24 => mask is /24 = 255.255.255.0 fe80::/10 => mask is /10 = ffc0:0000:0000:0000:0000:0000:0000:0000 10.0.0.0-10.0.0.13 => mask is undef ::-::5 => mask is undef
$ip = $b->hostmask
Returns the hostmask as Net::IPAM::IP object.
$b = Net::IPAM::Block->new('10.0.0.0/24') say $b->mask; # 255.255.255.0 say $b->hostmask; # 0.0.0.255 $b = Net::IPAM::Block->new('fe80::/10') say $b->mask; # ffc0:: say $b->hostmask; # 3f:ffff:ffff:ffff:ffff:ffff:ffff:ffff
The hostmask is only defined for real CIDR blocks.
bitlen returns the minimum number of bits to represent a range from base to last
bitlen
$n = $b->bitlen
obvious for CIDR blocks:
$b = Net::IPAM::Block->new('10.0.0.0/24') say $b->bitlen; # 32 - 24 = 8 bit $b = Net::IPAM::Block->new('::/0'); say $b->bitlen; # 128 - 0 = 128 bit
not so obvious for ranges:
$b = Net::IPAM::Block->new('2001:db8::affe-2001:db8::cafe'); say $b->bitlen; # 15 bit (at least)
iter returns the next IP in block, starting with base and stopping at last. Returns undef after last.
iter
$b = Net::IPAM::Block->new('2001:db8::affe-2001:db8::cafe'); while ( my $ip = $b->iter ) { say $ip; } OUTPUT: 2001:db8::affe 2001:db8::afff 2001:db8::b000 2001:db8::b001 ... 2001:db8::cafb 2001:db8::cafc 2001:db8::cafd 2001:db8::cafe
$a->cmp($b)
Compares two IP blocks:
print $this->cmp($other); @sorted_blocks = sort { $a->cmp($b) } @unsorted_blocks;
cmp() returns -1, 0, +1:
0 if $a == $b, -1 if $a is v4 and $b is v6 +1 if $a is v6 and $b is v4 -1 if $a->base < $b->base +1 if $a->base > $b->base -1 if $a->base == $b->base and $a->last > $b->last # $a is super-set of $b +1 if $a->base == $b->base and $a->last < $b->last # $a is sub-set of $b
$a->is_disjunct_with($b)
Returns true if the blocks are disjunct
a |----------| b |---| a |------| b |---| print "a and b are disjunct" if $a->is_disjunct_with($b)
$a->overlaps_with($b)
Returns true if the blocks overlap.
a |-------| b |------| a |------| b |-------| a |----| b |---------| a |---------| b |----|
$a->contains($b)
Returns true if block a contains block b. a and b may NOT coincide.
if ( $a->contains($b) ) { print "block a contains block b\n"; } a |-----------------| |-----------------| |-----------------| b |------------| |------------| |------------|
The argument may also be a Net::IPAM::IP address object.
if ( $a->contains($ip) ) { print "block a contains ip\n"; }
@diff = $outer->diff(@inner)
Returns all blocks in outer block, minus the inner blocks.
my $outer = Net::IPAM::Block->new("192.168.2.0/24"); my @inner = ( Net::IPAM::Block->new("192.168.2.0/26"), Net::IPAM::Block->new("192.168.2.240-192.168.2.249"), ); my @diff = $outer->diff(@inner); # diff: [192.168.2.64-192.168.2.239, 192.168.2.250-192.168.2.255]
DEPRECATED: find_free_cidrs() is deprecated in favor of diff(), maybe followed by to_cidrs() @free = $outer->find_free_cidrs(@inner)
Returns all free cidrs within given block, minus the inner blocks.
my $outer = Net::IPAM::Block->new("192.168.2.0/24"); my @inner = ( Net::IPAM::Block->new("192.168.2.0/26"), Net::IPAM::Block->new("192.168.2.240-192.168.2.249"), ); my @free = $outer->find_free_cidrs(@inner); # outer: 192.168.2.0/24 - inner: [192.168.2.0/26 192.168.2.240-192.168.2.249] # free: [192.168.2.64/26 192.168.2.128/26 192.168.2.192/27 192.168.2.224/28 192.168.2.250/31 192.168.2.252/30]
@agg = aggregate(@blocks)
Returns the minimal number of blocks spanning the range of input blocks.
If CIDRs are required, use the following idiom:
@cidrs = map { $_->to_cidrs } aggregate(@blocks);
Net::IPAM::Block overloads the following operators.
my $bool = !!$block;
Always true.
my $str = "$block";
Alias for "to_string".
Karl Gaissmaier, <karl.gaissmaier(at)uni-ulm.de>
<karl.gaissmaier(at)uni-ulm.de>
Please report any bugs or feature requests to bug-net-ipam-block at rt.cpan.org, or through the web interface at https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Net-IPAM-Block. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
bug-net-ipam-block at rt.cpan.org
You can find documentation for this module with the perldoc command.
perldoc Net::IPAM::Block
You can also look for information at:
on github
TODO
Net::IPAM::IP Net::IPAM::Tree
This software is copyright (c) 2020 by Karl Gaissmaier.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
To install Net::IPAM::Block, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Net::IPAM::Block
CPAN shell
perl -MCPAN -e shell install Net::IPAM::Block
For more information on module installation, please visit the detailed CPAN module installation guide.