NAME
Net::IPAM::Block - A library for reading, formatting, sorting and converting IP-blocks.
SYNOPSIS
use Net::IPAM::Block;
# parse and normalize
my $cidr = Net::IPAM::Block->new('10.0.0.0/24') // die 'wrong format,';
my $range = Net::IPAM::Block->new('fe80::2-fe80::e') // die 'wrong format,';
my $host = Net::IPAM::Block->new('2001:db8::1') // die 'wrong format,';
DESCRIPTION
A block is an IP-network or IP-range, e.g.
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.
METHODS
new
$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
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_ip.
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.
version
$v = $b->version
Returns 4 or 6.
to_string
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
is_cidr
$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
cidrsplit
@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.
to_cidrs
@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
base
$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
last
$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
mask
$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
hostmask
$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.
cmp
$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
is_disjunct_with
$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)
overlaps_with
$a->overlaps_with($b)
Returns true if the blocks overlap.
a |-------|
b |------|
a |------|
b |-------|
a |----|
b |---------|
a |---------|
b |----|
contains
$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";
}
find_free_cidrs
@cidrs = $outer->find_free_cidrs(@inner)
Returns all free CIDR blocks (of max possible bitlen) within given CIDR, minus the inner CIDR blocks. Croaks if inner blocks are no subset of (or not equal to) outer block.
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]
FUNCTIONS
aggregate
@cidrs = aggregate(@blocks)
Returns the minimal number of CIDRs spanning the range of input blocks.
AUTHOR
Karl Gaissmaier, <karl.gaissmaier(at)uni-ulm.de>
BUGS
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.
SUPPORT
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
SEE ALSO
LICENSE AND COPYRIGHT
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.