Rand Stats

IP::Addr

zef:vrurg

NAME

IP::Addr - dealing with IPv4/IPv6 addresses

SYNOPSIS

my $cidr = IP::Addr.new( "192.0.2.2/27" );
say $cidr;
say $cidr.ip;
for $cidr.network.each -> $ip {
    say $ip;
}

my $cidr6 = IP::Addr.new( "600d::f00d/123" );
say $cidr6;
say $cidr6.ip;

DESCRIPTION

This module provides functionality for working with IPv4/IPv6 addresses.

Module Structure

The main interface is provided by IP::Addr class. Typical class usage is demonstrated in the synopsis. The class is a frontend which tries to determine version of the IP address provided to its constructor and creates corresponding handler object available on its handler attribute. All methods of the handler are available on IP::Addr object via handles trait.

For example, for an arbitrary $ip object of the class $ip.ip call is actually same as calling $ip.handler.ip. Method ip is a universal one for both v4 and v6 addresses and therefore it is not necessary to care about what exact kind of object we're currently dealing with.

Similarly, version-dependant methods are available too but only when corresponding handler is active. For example:

say IP::Addr.new( "192.0.2.2/27" ).broadcast;

is a valid call; while

say IP::Addr.new( "2001:db8::/123" ).broadcast;

will fail with "no method" exception because broadcast is not available for IPv6 addresses.

Glossary

Address forms

Besides of its version each IP address has one more characteristic property: form. It is defined by handler's attribute of the same name: $!form. Particular forms are defined by IP-FORM enum defined in IP::Addr::Common:

Ranged forms

CIDR and ranges are ranged forms contrary to a single IP form.

N-tets

As it is known IP addresses are represented by groups of integers called octets for IPv4 and hextets for IPv6 (there are variations but I chose these two). N-tets is used as a general term for both of them.

METHODS

Constructor

Class constructor new simply re-dispatches its arguments to method set.

set

Str

Returns a valid string representation of the IP object.

gist

Same as Str method.

each

Returns an iterable object which would iterate over IPs contained in the current object starting with selected address (i.e. the one returned by ip method). For ranged forms to iterate over the whole range (from the first-ip to the last-ip) use of method first is recommended:

.say for IP::Addr.new( "192.0.2.3/29" ).each;           # 192.0.2.3/29\n192.0.2.4/29 ...
.say for IP::Addr.new( "192.0.2.3/29" ).first.each;     # 192.0.2.0/29\n192.0.2.1/29 ...

Supply

Similar to each method but returns a Supply object. Same rule about starting with selected IP and use of first method apply.

HANDLER METHODS

This sections documents methods common for both IPv4 and IPv6 handlers.

Notes

For all methods accepting another IP address as a parameter and where descriptions has a statement "same version only" X::IPAddr::TypeCheck exception would be thrown if object with a handler of different version is passed.

Address method parameters could either be IP::Addr instances or string representations.

set

Configures the handler object.

Note In the following subsection $handler notation is used instead of $ip.handler.

addr-len

Returns number of bits for correponding IP version (32 for IPv4 and 128 for IPv6).

n-tets

Returns number of n-tets for the current handler (4 for IPv4 and 8 for IPv6).

version

Returns integer version of the IP object (4 or 6).

ip-classes

Returns list of hashes of reserved IP ranges. Each hash has two keys:

ip

Returns a new IP::Addr object representing just an IP address of the current IP::Addr object.

my $ip = IP::Addr.new( "192.0.2.3/24" );
say $ip;            # 192.0.2.3/24
say $ip.ip;         # 192.0.2.3
say $ip.ip.WHO;     # IP::Addr

prefix

Returns CIDR representation of any form of IP address. For example:

say IP::Addr.new( "192.0.2.3" ).prefix;     # 192.0.2.3/32

For IPv4 handler additional named parameter :mask can be used to use network mask instead of prefix length:

say IP::Addr.new( "192.0.2.3/24" ).prefix( :mask );     # 192.0.2.3/255.255.255.0

first-ip

IP::Addr object for the first IP address in the range. For single IP will be the same as ip method.

last-ip

IP::Addr object for the last IP address in the range. For single IP will be the same as ip method.

network

IP::Addr object of the network current IP object belongs to. Makes real sense for CIDR form only though can be used with any other form too.

mask

Returns string representation of the current IP object mask. Doesn't make much sense for IPv6 addresses because there is officially no such thing for them.

wildcard

Returns string representation of current IP object wildcard. Doesn't make much sense for IPv6 addresses because there is officially no such thing for them.

size

Returns number of IP addresses contained in the current IP::Addr object. For example:

say IP::Addr.new( "192.0.0.0/13" ).size;            # 524288
say IP::Addr.new( "192.0.2.3-192.0.2.23" );         # 21

int-ip

Returns integer value of the IP address.

int-first-ip

Returns integer value of the first IP address in the current IP object.

int-last-ip

Returns integer value of the last IP address in the current IP object.

int-mask

Returns integer value of current IP object mask. Though not defined as such for IPv6 addresses but could be useful in some address arithmetics.

int-wildcard

Returns integer value of current IP object wildcard. Though not defined as such for IPv6 addresses but could be useful in some address arithmetics.

inc / succ

Increments IP address by 1. For ranged IP forms result of this operation won't be greater than the last IP of the range:

my $ip = IP::Addr.new( "192.0.2.255/24" );
say $ip.inc;                # 192.0.2.255/24

Rerturns current IP::Addr object.

dec / pred

Decrements IP address by 1. For ranged IP forms result of this operation won't be less than the first IP of the range:

my $ip = IP::Addr.new( "192.0.2.0/24" );
say $ip.dec;                # 192.0.2.0/24

Returns current IP::Addr object.

add( Int:D $count )

Shifts IP of the current object by $count positions higher. $count could be negative. For ranged IP form the result of the operation won't leave the range boundaries:

my $ip = IP::Addr.new( "192.0.2.255/24" );
say $ip.add( 10 );              # 192.0.2.255/24
say $ip.add( -300 );            # 192.0.2.0/24

Returns current IP::Addr object.

eq( $addr )

Same version only.

Returns True if current object is equal to $addr.

lt( $addr )

Same version only.

Returns true if the current object is less than $addr.

gt( $addr )

Same version only.

Returns true if the current object is greater than $addr

cmp( $addr )

Same version only.

Returns one of three Order values: Less, Same, or More. For ranges comparison is performed by the selected IP.

contains( $addr )

Same version only.

Returns True if current object contains $addr. Wether the $addr object is the same (e.g. eq method would return True) then it is also considered as contained.

overlaps( $addr )

Same version only.

Returns True if the current object and $addr have at least one common IP address. Useful for starting iteration:

first

Returns a new IP::Addr object whose IP address is the first IP of the current object. Useful for starting iteration.

my $ip = IP::Addr.new( "192.0.2.12/24" );
for $ip.first.each { say $_ }       # 192.0.2.0\n192.0.2.1\n...

See each method.

next

Returns a new IP::Addr object successive to the current object or Nil if current is the last IP of the range.

prev

Returns a new IP::Addr object preceding the current object or Nil if current is the first IP of the range.

next-network

Returns a new IP::Addr object containing network successive to the network of the current object. Valid for CIDR form only. Flips over begining/end of IP range:

$ip = IP::Addr.new( "255.255.255.13/24" );
say $ip.next-network;               # 0.0.0.0/24

prev-network

Returns a new IP::Addr object containing network preceding the network of the current object. Valid for CIDR form only. Flips over the begining of IP range:

$ip = IP::Addr.new( "0.0.0.2/24" );
say $ip.prev-network;               # 255.255.255.0/24

next-range

Returns a new IP::Addr object containing range of the same length successive to the current object. Valid for range form only.

prev-range

Returns a new IP::Addr object containing range of the same length preceding the current object. Valid for range form only.

to-int( @n-tets )

Converts an array of n-tets to integer value corresponding to the current handler's IP version.

to-n-tets( Int:D $addr )

Splits integer represnation of IP address into n-tets corresponding to the current handler's IP version.

info

Returns a hash with information about the current IP object. The hash contains two keys: scope and description. See ip-classes method for more information.

Str

Stringifies current IP object with regard to its form.

OPERATORS

For all supported operators where both operands are addresses at least one of them has to be a IP::Addr object. The other one could be a string representation of an address.

prefix/postfix ++ and prefix/postfix --

Standard Raku operatios working by calling succ/pred methods on IP::Addr object.

infix + ( $addr, $int )

Adds an integer value to the address. The resulting address will never get out of network/range boundaries for objects of corresponding forms. A new IP::Addr object is returned.

$ip2 = $ip1 + 3;

infix - ( $addr, $int )

Deducts an integer value from the address. The resulting address will never get out of network/range boundaries for objects of corresponding forms. A new IP::Addr object is returned.

$ip2 = $ip1 - 3;

infix cmp ( $addr1, $addr2 )

Compares two IP addresses.

given $ip1 cmp $ip2 {
    when Less { say "smaller" }
    when Same { say "same" }
    when More { say "bigger" }
}

infix eqv / infix == ( $addr1, $addr2 )

Checks if two addresses are equal. See handler's eq method.

infix < ( $addr1, $addr2 )

True if $addr1 is less than $addr2. See handler's lt method.

infix <= / infix ≤ ( $addr1, $addr2 )

True if $addr1 is less than or equal to $addr2.

infix > ( $addr1, $addr2 )

True if $addr1 is greater than $addr2. See handler's gt method.

infix >= / infix ≥ ( $addr1, $addr2 )

True $addr1 greater than or equal to $addr2.

infix (cont) / infix ⊇ ( $addr1, $addr2 )

True if $addr1 object contains $addr2. See handler's contains method.

infix ⊆ ( $addr1, $addr2 )

True if $addr1 is contained by $addr2.

CAVEATS

The author doesn't use IPv6 in his setups. All the functionality provided here is developed using information from corresponding Wikipedia pages. Therefore, "here be dragons"©. Please, report back any issue encountered!

SEE ALSO

ChangeLog

AUTHOR

Vadim Belman vrurg@cpan.org