NAME

NetAddr::IP - Manages IPv4 and IPv6 addresses and subnets

VERSION

version 4.080_07

SYNOPSIS

use NetAddr::IP qw(Compact Coalesce);
use NetAddr::IP::Util qw(inet_aton);

my $ip = NetAddr::IP->new('192.0.2.1/24');

print $ip->addr, "\n";        # 192.0.2.1
print $ip->mask, "\n";        # 255.255.255.0
print $ip->network, "\n";     # 192.0.2.0/24
print $ip->broadcast, "\n";   # 192.0.2.255/24
print "$ip\n";                # 192.0.2.1/24

if ($ip->within(NetAddr::IP->new('192.0.2.0', 24))) {
    print "within the /24\n";                  # within the /24
}

my $next = $ip + 5;            # 192.0.2.6/24
my @hosts = $ip->hostenum;     # every usable address, 254 of them
my @halves = $ip->split(25);   # 192.0.2.0/25, 192.0.2.128/25

my @merged = Compact(@halves);           # 192.0.2.0/24
my $one    = Coalesce(24, 2, @halves);   # an arrayref holding 192.0.2.0/24

my $v6 = NetAddr::IP->new('2001:db8::1');
print $v6->addr, "\n";         # 2001:DB8:0:0:0:0:0:1
print $v6->cidr, "\n";         # 2001:DB8:0:0:0:0:0:1/128

# from a packed IPv4 address, or leading zeros read as decimal
my $a = NetAddr::IP->new_from_aton(inet_aton('192.0.2.1'));   # 192.0.2.1/32
my $b = NetAddr::IP->new_no('198.051.100.001');               # 198.51.100.1/32

The other entry points are Zeros, Ones, V4mask and V4net, which return 128 bit vectors, and netlimit, described under "FUNCTIONS".

DESCRIPTION

This module provides an object-oriented abstraction on top of IP addresses or IP subnets that allows for easy manipulations. It is compatible with Math::BigInt, and requires perl 5.14 or later.

The internal representation of all IP objects is in 128 bit IPv6 notation. IPv4 and IPv6 objects may be freely mixed: every address carries its family, and a /24 IPv4 subnet and an /24 IPv6 subnet are distinct objects.

Overloaded Operators

Many operators have been overloaded, as described below:

Assignment (=)

Has been optimized to copy one NetAddr::IP object to another very quickly.

->copy()

The assignment (=) operation is only put in to operation when the copied object is further mutated by another overloaded operation. See overload SPECIAL SYMBOLS FOR "use overload" for details.

Calling ->copy() actually creates a new object.

Stringification

An object can be used just as a string. For instance, the following code

my $ip = NetAddr::IP->new('192.0.2.123');
print "$ip\n";

Will print the string 192.0.2.123/32.

Equality

You can test for equality with either eq or ==. The eq operator allows comparison with arbitrary strings as well as NetAddr::IP objects. The following example:

if (NetAddr::IP->new('198.51.100.1','255.255.255.224') eq '198.51.100.1/27')
  { print "Yes\n"; }

will print out "Yes".

Comparison with == requires both operands to be NetAddr::IP objects.

In both cases, a true value is returned if the CIDR representation of the operands is equal.

Comparison via >, <, >=, <=, <=> and cmp

Internally, all network objects are represented in 128 bit format, and the comparison runs on that numeric form. The order is deterministic: the address portion first, then, when the addresses are equal, the numeric value of the masks. Since a longer mask is the larger number, this leads to the counterintuitive result that

/24 > /16

The same order applies to sort:

my @nets = map { NetAddr::IP->new($_) }
    qw(192.0.2.1/32 192.0.2.1/8 192.0.2.1/24 192.0.2.1/16);
print join(', ', sort @nets), "\n";
# 192.0.2.1/8, 192.0.2.1/16, 192.0.2.1/24, 192.0.2.1/32

So the ordering is predictable, but it is not the ordering most people mean by "bigger". To rank netblocks by size, compare the mask lengths directly:

$ip1->masklen <=> $ip2->masklen

Against an operand that is not a NetAddr::IP or NetAddr::IP::Lite object, such as a string, a number or undef, <=> returns undef, as Perl's own <=> does for NaN, and >, <, >= and <= return false, as == does. An undef variable used as that operand stays undef. The cmp operator compares the CIDR text with the operand instead, as eq does, so lt, gt, le and ge agree with eq:

my $ip = NetAddr::IP->new('192.0.2.1');
$ip <=> '192.0.2.1';      # undef
$ip <   '192.0.2.1';      # false
$ip cmp '192.0.2.1/32';   # 0
Addition of a constant (+)

Add a signed integer constant to the address part of a NetAddr object. This operation changes the address part to point so many hosts above the current objects start address. For instance, this code:

print NetAddr::IP->new('198.51.100.1/24') + 5;

will output 198.51.100.6/24. The address wraps around at the broadcast back to the network address, so this code:

print NetAddr::IP->new('198.51.100.1/24') + 255;

outputs 198.51.100.0/24.

Returns a copy of the object when the constant is missing or zero. The constant must be an integer with a magnitude below 2**64; anything else croaks, including a string that is not a number, such as '0x10'. Values above 2**53 must be passed as integers (IV or UV), since a floating point value that large has no unit precision and is rejected.

Subtraction of a constant (-)

The complement of the addition of a constant.

The object must be the left operand. Subtracting an object from a constant (10 - $ip) has no meaning and croaks.

Difference (-)

Returns the difference between the address parts of two NetAddr::IP objects address parts as a 32 bit signed number.

Returns undef if the difference is out of range.

(See range restrictions on Addition above)

Array dereference (@{...})

The array dereference @{$ip} is overloaded and returns the host list, so a NetAddr::IP object can be treated as the addresses it contains:

my $ip = NetAddr::IP->new('192.0.2.0/28');
print scalar @{$ip}, "\n";                # 14
my @hosts = @{$ip};
print "$hosts[0]\n";                       # 192.0.2.1/32
print "$hosts[-1]\n";                      # 192.0.2.14/32

This is hostenum in list form, so the same network and broadcast rule applies: no network or broadcast address, except on a /31, /127, /32 or /128.

Negation and absolute value (- and abs)

Both croak. An address has no meaningful negation, and abs would be the identity at best:

-$ip;      # cannot negate a NetAddr::IP object
abs $ip;   # cannot take the absolute value of a NetAddr::IP object

To move to another address, add or subtract a constant with the overloaded + and -, or use nth().

Auto-increment

Auto-incrementing a NetAddr::IP object causes the address part to be adjusted to the next host address within the subnet. It will wrap at the broadcast address and start again from the network address.

Auto-decrement

Auto-decrementing a NetAddr::IP object performs exactly the opposite of auto-incrementing it, as you would expect.

Serializing and Deserializing

This module defines hooks to collaborate with Storable for serializing NetAddr::IP objects, through compact and human readable strings. Data frozen as a plain hash, without the hooks, thaws the same way with them in place, because Storable calls the thaw hook only for data the freeze hook wrote. To freeze as a plain hash instead, invoke this module as

use NetAddr::IP ':old_storable';

which removes the hooks, as described under "IMPORT TAGS".

Constructors

->new([$addr, [ $mask|IPv6 ]])
->new4([$addr, [ $mask]])
->new6([$addr, [ $mask]])
->new6FFFF([$addr, [ $mask]])
->new_no([$addr, [ $mask]])
->new_from_aton($netaddr)
->new_cis("$addr $mask")
->new_cis6("$addr $mask")

The constructors new, new4 and new6 create a new address with the supplied address in $addr and an optional netmask $mask, which can be omitted to get a /32 or /128 netmask for IPv4 / IPv6 addresses respectively. All three accept the same notations. The new constructor returns whichever family the input reads as, new4 returns IPv4 or undef, and new6 returns IPv6. See "Numbers and masks" for how each one reads a number and a mask.

The third constructor, new6FFFF, is what makes an IPv4-mapped address, RFC 4291 s2.5.5.2. An IPv4 address, whether dotted, short, a range or a number of up to 32 bits, comes back inside ::ffff:0:0/96, so a /24 becomes a /120. An IPv6 address comes back as new6 gives it: NetAddr::IP->new6FFFF('192.0.2.1'); # 0:0:0:0:0:FFFF:C000:201/128 NetAddr::IP->new6FFFF('192.0.2.0/24'); # 0:0:0:0:0:FFFF:C000:200/120 NetAddr::IP->new6FFFF('2001:db8::1'); # 2001:DB8:0:0:0:0:0:1/128 NetAddr::IP->new6FFFF('::192.0.2.1'); # 0:0:0:0:0:0:C000:201/128

IPv6 text such as ::192.0.2.1 is an IPv6 address, and so are a number wider than 32 bits and the keywords, such as loopback, which new6 reads as IPv6. A host name follows the address it resolves to.

An IPv4 address with a leading zero in any part, such as 192.0.2.010 or 010, is not an address to new: the C library's inet_aton reads 010 as octal 8, and a person reads it as decimal 10. So is the upper bound of a short range, such as 192.0.2.8-011, and a negative number, such as -012. The constructor for that less strict reading is new_no. A part that is not an address once the zeros are removed is still refused. The result, or undef when the text is not an address:

input           new                new_no
192.0.2.1       192.0.2.1/32       192.0.2.1/32
192.0.2.010     undef              192.0.2.10/32
192.0.2.07      undef              192.0.2.7/32
192.0.2.107     192.0.2.107/32     192.0.2.107/32
192.0.2.0107    undef              192.0.2.107/32
010             undef              0.0.0.10/32
192.0.2.0256    undef              undef
192.0.2.8-011   undef              192.0.2.8/30
-012            undef              255.255.255.244/32

Under new_no, 192.0.2.07 is 192.0.2.7, so a typo for 192.0.2.107 succeeds. Likewise 192.0.2.0107 is 192.0.2.107, so an extra zero in front of that address succeeds too. And 010 is 0.0.0.10, the same address as new('10').

IPv6 text is left alone, so 2001:db8::1 is the same address from both constructors, and ::ffff:192.0.2.010 is undef from both. A prefix length is decimal either way, so 192.0.2.0/024 is 192.0.2.0/24 from both. A dotted mask is stripped the same way as an address: new_no('192.0.2.0', '255.255.255.000') is 192.0.2.0/24 and new returns undef.

The new_from_aton constructor takes a packed IPv4 address and assumes a /32 mask. This function replaces the :aton functionality, which reads a packed string as text first and is fundamentally broken. See "DEPRECATED".

The constructors new_cis and new_cis6 accept the common Cisco address notation for address/mask pairs with a space as a separator instead of a slash (/). Both are deprecated in favour of new and new6, which do the same. See "DEPRECATED".

Both ->new6 and ->new_cis6 mark the address as being in ipV6 address space even if the format would suggest otherwise.

print NetAddr::IP->new6('192.0.2.1'), "\n";    # 0:0:0:0:0:0:C000:201/128

Addresses submitted to ->new in ipV6 notation will remain in that notation permanently, whereas the same address in dotted quad notation prints as IPv4:

print NetAddr::IP->new('::192.0.2.1'), "\n";   # 0:0:0:0:0:0:C000:201/128
print NetAddr::IP->new('192.0.2.1'), "\n";     # 192.0.2.1/32

The addr() value is what stringifies as the first part.

The $addr argument can be almost anything that can be resolved to an IP address. It can optionally contain the mask in CIDR notation. A host name is resolved with one getaddrinfo call, so an IPv6 name resolves as well as an IPv4 one. The IPv4 constructor uses an IPv4 answer when there is one. The IPv6 constructor uses an IPv6 answer when there is one, unless that answer is an IPv4-mapped or IPv4-compatible address and an IPv4 answer exists, as for a name with both ::1 and 127.0.0.1.

The prefix notation is understood, with the limitation that the range specified by the prefix must match with a valid subnet.

An IPv6-form mask on an IPv4 address covers all 128 bits, so it needs the 96 leading ones above the address. A mask with 1 to 95 ones returns undef; through new6 the same mask is an IPv6 prefix:

NetAddr::IP->new('192.0.2.4', 'ffff::');    # undef
NetAddr::IP->new6('192.0.2.4', 'ffff::');   # 0:0:0:0:0:0:C000:204/16
NetAddr::IP->new('192.0.2.4',
    'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00');   # 192.0.2.4/24

The same holds for a mask written as a whole number. One that fits in 32 bits is an IPv4 mask. A wider one covers all 128 bits, so it needs the 96 leading ones too. The two long masks below are ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00 and ffff:: written as whole numbers:

NetAddr::IP->new('192.0.2.4', 4294967040);   # 192.0.2.4/24
NetAddr::IP->new('192.0.2.4',
    '340282366920938463463374607431768211200');   # 192.0.2.4/24
NetAddr::IP->new('192.0.2.4',
    '340277174624079928635746076935438991360');   # undef

Addresses in the packed format returned by inet_aton or gethostbyname are understood only under the deprecated :aton tag, and no mask can be specified for them. Even then a packed string is read as text first and looked up as a host name second, so one whose bytes also spell text comes back as a different address or as undef; see :aton under "DEPRECATED". Use new_from_aton for a packed IPv4 address.

The $addr argument can be any of the following and possibly more...

n.n
n.n/mm
n.n mm
n.n.n
n.n.n/mm
n.n.n mm
n.n.n.n
n.n.n.n/mm        32 bit cidr notation
n.n.n.n mm
n.n.n.n/m.m.m.m
n.n.n.n m.m.m.m
n.n.n.n-n.n.n.n   range notation, with or without spaces at the dash
default, any, broadcast, loopback (keywords, see below)
host, as a mask keyword
x.x.x.x/host
x:x:x/host
0xABCDEF, 0b111111000101011110, (a bcd number)
a netaddr as returned by 'inet_aton', but only with the deprecated
:aton tag, and only when its bytes do not also read as one of these
forms or as a host name; without the tag a packed string returns undef

Any RFC 4291 s2.2 notation

::n.n.n.n
::n.n.n.n/mmm        128 bit cidr notation
::n.n.n.n/::m.m.m.m
::x:x
::x:x/mmm
x:x:x:x:x:x:x:x
x:x:x:x:x:x:x:x/mmm
x:x:x:x:x:x:x:x/m:m:m:m:m:m:m:m with a mask
default, any, loopback, unspecified (keywords, see below)
::x:x/host
0xABCDEF, 0b111111000101011110 within the limits
of perl's number resolution
123456789012  a 'big' bcd number (bigger than perl likes)
and Math::BigInt

A Math::BigInt is read as its decimal text, sign included, so Math::BigInt->new(-5) gives the same result as '-5'. A Math::BigInt NaN or infinity gives undef.

A Fully Qualified Domain Name which returns an ipV4 address or an ipV6 address, embodied in that order. This previously undocumented feature may be disabled with:

use NetAddr::IP qw(:nofqdn);

Surrounding whitespace is ignored on the address and on a separate mask, so a line read from a file needs no chomp:

NetAddr::IP->new("192.0.2.0/24\n");        # 192.0.2.0/24
NetAddr::IP->new("2001:db8::1\r\n");       # 2001:DB8:0:0:0:0:0:1/128
NetAddr::IP->new('192.0.2.0', " 24\n");    # 192.0.2.0/24

The text functions of NetAddr::IP::InetBase and NetAddr::IP::Util do not strip it, so there the string has to be the address and nothing else.

Called with no arguments, 'default' is assumed. An explicit undef argument returns undef, and an empty string returns undef.

Accepted forms in full

The list above is abbreviated. These are the forms worth knowing about, all verified on both builds.

Range and prefix notation, where the prefix has to name a valid subnet:

NetAddr::IP->new('192.0.2.0-192.0.2.255');   # 192.0.2.0/24
NetAddr::IP->new('192.0.2.4-7');             # 192.0.2.4/30
NetAddr::IP->new('192.0.2.');                # 192.0.2.0/24
NetAddr::IP->new('192.0.');                  # 192.0.0.0/16
NetAddr::IP->new('10.');                     # 10.0.0.0/8
NetAddr::IP->new('192.0-3.');                # 192.0.0.0/14

A range has to cover exactly one subnet: its first address has to start the subnet and its last has to end it. Any other range gives undef, in the short form as in the full one:

NetAddr::IP->new('192.0.2.5-6');             # undef
NetAddr::IP->new('192.1-2.');                # undef
NetAddr::IP->new('192.0.2.5-192.0.2.6');     # undef

Short dotted forms change meaning when a mask argument is given, which is the one trap here worth writing out. On its own the short form is a host address; with a mask it is the network of that size:

NetAddr::IP->new('10.1');          # 10.0.0.1/32
NetAddr::IP->new('10.1', 8);       # 10.1.0.0/8
NetAddr::IP->new('10.1.2');        # 10.1.0.2/32
NetAddr::IP->new('10.1.2', 24);    # 10.1.2.0/24

RFC 3986 brackets around an IPv6 literal, which is how a URI carries one:

NetAddr::IP->new('[2001:db8::1]/64');   # 2001:DB8:0:0:0:0:0:1/64
NetAddr::IP->new('[2001:db8::1]');      # 2001:DB8:0:0:0:0:0:1/128

Brackets around an IPv4 literal are not accepted and return undef.

Keywords. The set is not the same for every constructor, which is worth knowing before reaching for one:

NetAddr::IP->new('broadcast');      # 255.255.255.255/32
NetAddr::IP->new('unspecified');    # 0:0:0:0:0:0:0:0/128
NetAddr::IP->new('any');            # 0.0.0.0/0
NetAddr::IP->new('default');        # 0.0.0.0/0
NetAddr::IP->new('loopback');       # 127.0.0.1/8
NetAddr::IP->new('localhost');      # 127.0.0.1/32, via the resolver

The broadcast keyword is IPv4 only: new6('broadcast') returns undef, while new6('unspecified') gives an IPv6 unspecified address. The loopback keyword gives a /8, not a /32. The name localhost is not a keyword at all: it is resolved, so it is undef under :nofqdn and resolver-dependent otherwise. Under new4, unspecified and the ipv6 mask give undef, since both name IPv6 addresses.

Numbers and masks

Text says which family it is in: dotted text such as 192.0.2.1 is IPv4, and text with a colon such as 2001:db8::1 is IPv6. A number does not, so the constructor decides:

input                  new         new4        new6
IPv4 text              IPv4        IPv4        IPv6, ::a.b.c.d
IPv6 text              IPv6        undef       IPv6
::ffff:a.b.c.d text    IPv6        IPv4        IPv6
number below 2**32     IPv4        IPv4        IPv6
number from 2**32      IPv6        undef       IPv6
negative number        IPv4        IPv4        undef

Under new4, IPv4-mapped text such as ::ffff:192.0.2.1 is the IPv4 address it carries, when its prefix is 96 bits or longer. A host name takes the family of its answer, so new4 gives undef for a name with no IPv4 address. Since new reads a number below 2**32 as IPv4, it cannot make an IPv6 address inside ::/96, such as ::1, from a number; new6 can.

A number is a whole decimal number such as 3221225985, a 0x or 0b literal of up to 32 bits such as 0xc0000201, or a Math::BigInt. A decimal number or a Math::BigInt goes up to 2**128 - 1. On its own a number is the address with that value:

NetAddr::IP->new('3221225985');    # 192.0.2.1/32
NetAddr::IP->new('4294967296');    # 0:0:0:0:0:1:0:0/128
NetAddr::IP->new4('4294967296');   # undef
NetAddr::IP->new6('1');            # 0:0:0:0:0:0:0:1/128

With a prefix length, new and new4 read a number from 0 to 255 as the first octet, the short form of 10.0.0.0/8, and a larger number as the address value. Under new6 the number is always the address value, and the prefix length is an IPv6 one:

NetAddr::IP->new('10', 8);     # 10.0.0.0/8
NetAddr::IP->new('300', 24);   # 0.0.1.44/24
NetAddr::IP->new6('10', 8);    # 0:0:0:0:0:0:0:A/8
NetAddr::IP->new6('10', 64);   # 0:0:0:0:0:0:0:A/64

A mask written as a whole number above 128 is a raw mask, the form numeric returns. With a raw mask the number is always the address value:

NetAddr::IP->new('10', 4294967040);   # 0.0.0.10/24

A negative number counts down from 2**32, so -1 is 255.255.255.255. Both new and new4 accept -1 to -4294967296, and new6 refuses a negative number:

NetAddr::IP->new('-1');    # 255.255.255.255/32
NetAddr::IP->new6('-1');   # undef

A mask is read for the family of the address:

mask                      IPv4 address          IPv6 address
prefix length 0 to 32     IPv4 prefix           IPv6 prefix
prefix length 33 to 128   undef                 IPv6 prefix
dotted, 255.255.255.0     IPv4 mask             96 plus its length
IPv6 form, ffff::         needs the 96          IPv6 mask
                          leading ones
whole number above 128    32 bits, or 128       128 bits
                          with the 96 leading
                          ones
host                      /32                   /128
default, any              /0                    /0
loopback                  /8                    /128
broadcast                 /32                   undef
unspecified               undef                 /128

Under new6, IPv4 text becomes ::a.b.c.d. A prefix length or a dotted mask on it is read as an IPv4 one and gains 96, and any other mask is read as for an IPv6 address:

NetAddr::IP->new6('192.0.2.1', 24);         # 0:0:0:0:0:0:C000:201/120
NetAddr::IP->new6('192.0.2.1', 'ffff::');   # 0:0:0:0:0:0:C000:201/16
NetAddr::IP->new6('192.0.2.1', 'host');     # 0:0:0:0:0:0:C000:201/128

Address and mask

->addr()

Returns a scalar with the address part of the object as an IPv4 or IPv6 text string as appropriate. This is useful for printing or for passing the address part of the NetAddr::IP object to other components that expect an IP address. If the object is an ipV6 address or was created using ->new6($ip) it will be reported in ipV6 hex format otherwise it will be reported in dot quad format only if it resides in ipV4 address space.

->mask()

Returns a scalar with the mask as an IPv4 or IPv6 text string as described above.

->masklen()

Returns a scalar the number of one bits in the mask.

->bits()

Returns the width of the address in bits. Normally 32 for v4 and 128 for v6.

->version()

Returns the version of the address or subnet. Currently this can be either 4 or 6.

->cidr()

Returns a scalar with the address and mask in CIDR notation. A NetAddr::IP object stringifies to the result of this function. (see comments about ->new6() and ->addr() for output formats)

->aton()

Returns the address part of the NetAddr::IP object in the same format as the inet_aton() or ipv6_aton function respectively. If the object was created using ->new6($ip), the address returned will always be in ipV6 format, even for addresses in ipV4 address space.

Boundaries

->network()

Returns a new object referring to the network address of a given subnet. A network address has all zero bits where the bits of the netmask are zero. Normally this is used to refer to a subnet.

The netmask is carried over from the object it was called on, so a /24 gives a /24 and a /32 gives a /32. Use addr() for the network address on its own, and cidr() for it in slash notation.

->broadcast()

Returns a new object referring to the broadcast address of a given subnet. The broadcast address has all ones in all the bit positions where the netmask has zero bits. This is normally used to address all the hosts in a given subnet.

->first()

Returns a new object representing the first usable IP address within the subnet (ie, the first host address).

->last()

Returns a new object representing the last usable IP address within the subnet (ie, one less than the broadcast address).

->range()

Returns a scalar with the base address and the broadcast address separated by a dash and spaces. This is called range notation.

Numeric forms

->numeric()

When called in a scalar context, will return a numeric representation of the address part of the IP address. When called in an array context, it returns a list of two elements. The first element is as described, the second element is the numeric representation of the netmask.

This method is essential for serializing the representation of a subnet.

Passing both values back rebuilds the object. The new6 constructor rebuilds an IPv6 object, including ::/0 and ::1/0. The new4 constructor and new rebuild an IPv4 object when the numeric mask is above 128. A numeric mask of 0 is still prefix length 0, so 0.0.0.5/0 comes back as 5.0.0.0/0. The new constructor reads the values of an IPv6 object inside ::/96, such as ::1, as IPv4:

my $ip = NetAddr::IP->new6('::1');
print NetAddr::IP->new6($ip->numeric), "\n";   # 0:0:0:0:0:0:0:1/128
print NetAddr::IP->new($ip->numeric), "\n";    # 0.0.0.1/32

The ipV6 value has more digits than a Perl number holds, so ==, <=> and sort on two numeric() results compare them as floats and call distinct addresses equal:

my $x = NetAddr::IP->new('2001:db8::1');
my $y = NetAddr::IP->new('2001:db8::2');
print scalar $x->numeric, "\n";   # 42540766411282592856903984951653826561
print $x->numeric == $y->numeric ? 'same' : 'different';
# same, though the addresses differ in the last digit

Compare the objects directly, since both operators are overloaded, or use ->bigint():

print $x == $y ? 'same' : 'different';     # different
print $x <=> $y;                            # -1
print $x->bigint == $y->bigint ? 'same' : 'different';   # different
->bigint()

When called in scalar context, will return a Math::BigInt representation of the address part of the IP address. When called in an array context, it returns a list of two elements, The first element is as described, the second element is the Math::BigInt representation of the netmask.

Text forms

->short()

Returns the address part in a short or compact notation.

(ie, 10.0.0.1 becomes 10.1).

Works with both, V4 and V6.

->canon()

Returns the address part in canonical notation as a string. For ipV4, this is dotted quad, and is the same as the return value from "->addr()". For ipV6 it follows RFC 5952 sections 4.1 to 4.3: leading zeros dropped, the longest run of zero groups shortened to ::, the first of two equal runs shortened, and lowercase. It is the same as the LOWER CASE value returned by "->short()", except that an IPv4-mapped address, in ::ffff:0:0/96, comes back in the RFC 5952 section 5 mixed form:

canon ->new('::ffff:192.0.2.1')    ::ffff:192.0.2.1
canon ->new6FFFF('192.0.2.1')      ::ffff:192.0.2.1

The other prefixes with an IPv4 address in the low 32 bits stay in hex, as Python's ipaddress prints them: the IPv4-compatible ::/96 that RFC 4291 deprecates, the IPv4-translated ::ffff:0:0:0/96 of RFC 2765, which RFC 6145 obsoletes, and the NAT64 64:ff9b::/96 of RFC 6052:

canon ->new6('192.0.2.1')          ::c000:201
canon ->new('::ffff:0:192.0.2.1')  ::ffff:0:c000:201
canon ->new('64:ff9b::192.0.2.1')  64:ff9b::c000:201

Neither ->re() nor ->re6() matches the mixed form, so neither matches what canon gives for a mapped address.

->full()

Returns the address part in FULL notation for ipV4 and ipV6 respectively.

i.e. for ipV4
  0000:0000:0000:0000:0000:0000:127.0.0.1

for ipV6
  0000:0000:0000:0000:0000:0000:0000:0000

To force ipV4 addresses into full ipV6 format use:

->full6()

Returns the address part in FULL ipV6 notation

->full6m()

Returns the mask part in FULL ipV6 notation

->prefix()

Returns a scalar with the address and mask in ipV4 prefix representation. This is useful for some programs, which expect its input to be in this format.

The range encoded starts at first(), not at network(), so it includes the broadcast address:

print NetAddr::IP->new('192.0.2.4/30')->prefix();   # 192.0.2.5-7
print NetAddr::IP->new('192.0.2.0/24')->prefix();   # 192.0.2.
print NetAddr::IP->new('192.0.2.0/20')->prefix();   # 192.0.0-15.
print NetAddr::IP->new('192.0.2.9/32')->prefix();   # 192.0.2.9

Returns undef for an IPv6 address.

->nprefix()

Just as ->prefix(), but does not include the broadcast address.

->wildcard()

When called in a scalar context, returns the wildcard bits corresponding to the mask, in dotted-quad or ipV6 format as applicable.

When called in an array context, returns a two-element array. The first element, is the address part. The second element, is the wildcard translation of the mask.

Containment

$me->contains($other)

Returns true when $me completely contains $other. False is returned otherwise and undef is returned if $me and $other are not both NetAddr::IP or NetAddr::IP::Lite objects.

$me->within($other)

The complement of ->contains(). Returns true when $me is completely contained within $other, undef if $me and $other are not both NetAddr::IP or NetAddr::IP::Lite objects.

An IPv4 object and an IPv6 object never contain each other, even when the IPv6 address is the IPv4 address in ::a.b.c.d or ::ffff:a.b.c.d form. Compare ->addr() of the two to see why: they print as different addresses.

->is_rfc1918()

Returns true when $me is an RFC 1918 address.

10.0.0.0     -  10.255.255.255  (10/8 prefix)
172.16.0.0   -  172.31.255.255  (172.16/12 prefix)
192.168.0.0  -  192.168.255.255 (192.168/16 prefix)
->is_local()

Returns true when $me is a local network address.

i.e.    ipV4    127.0.0.0 - 127.255.255.255
or      ipV6    === ::1
or      ipV6    ::127.0.0.0 - ::127.255.255.255
or      ipV6    ::ffff:127.0.0.0 - ::ffff:127.255.255.255

An IPv4 loopback address held in an IPv6 object, whether from new6 or as a mapped address, is local, the same as its IPv4 form.

Splitting

->split($bits,[optional $bits1,$bits2,...])

Similar to ->splitref above but returns the list rather than a list reference. You may not want to use this if a large number of objects is expected.

->splitref($bits,[optional $bits1,$bits2,...])

Returns a reference to a list of objects, representing subnets of bits mask produced by splitting the original object, which is left unchanged. Note that $bits must be longer than the original mask in order for it to be splittable.

Croaks when the plan does not fit or a mask is malformed, rather than returning undef:

NetAddr::IP->new('192.0.2.0/24')->splitref(16);
# netmask error: overrange or spurious bits

The plan does not fit when one of its elements is shorter than the original mask, or has no room left when its turn comes. On a /24, splitref(24, 25) croaks because the /24 leaves no room for the /25, and so does splitref(25, 25, 25). A plan whose elements add up to less than the original is not an error, since the last element repeats until the object is full, and neither is a last element too large for the space left, which is filled with smaller pieces from the plan, as described below. A $bits equal to the original mask returns the network as the only piece. A plan that fits returns every piece:

my $p = NetAddr::IP->new('192.0.2.0/24')->splitref(25);
# 192.0.2.0/25  192.0.2.128/25

ERROR conditions:

->splitref will DIE with the message 'netlimit exceeded'
  if the number of return objects exceeds 'netlimit'.
  See function 'netlimit' above (default 2**16 or 65536 nets).

->splitref will DIE with the message 'netmask error: overrange
  or spurious bits' when bits or the (bits list) will not fit
  within the original object.

->splitref will DIE with the same message if a supplied ipV4,
  ipV6, or NetAddr mask is inappropriately formatted.

The bits argument may be a CIDR mask, a dot quad or ipV6 string or a NetAddr::IP object. If bits is missing, the object is split for into all available addresses within the ipV4 or ipV6 object ( auto-mask of CIDR 32, 128 respectively ).

With optional additional bits list, the original object is split into parts sized based on the list. NOTE: a short list will replicate the last item. If the last item is too large to for what remains of the object after splitting off the first parts of the list, a "best fits" list of remaining objects will be returned based on an increasing sort of the CIDR values of the bits list.

i.e.

my $ip     = NetAddr::IP->new('192.0.2.0/24');
my $objptr = $ip->splitref(28, 29, 28, 29, 26);

has split plan 28 29 28 29 26 26 26 28
and returns this list of objects

192.0.2.0/28
192.0.2.16/29
192.0.2.24/28
192.0.2.40/29
192.0.2.48/26
192.0.2.112/26
192.0.2.176/26
192.0.2.240/28

NOTE: that /26 replicates twice beyond the original request and /28 fills the remaining return object requirement.

->rsplit($bits,[optional $bits1,$bits2,...])

Similar to ->rsplitref above but returns the list rather than a list reference. You may not want to use this if a large number of objects is expected.

->rsplitref($bits,[optional $bits1,$bits2,...])

The method ->rsplitref is the same as ->splitref above except that the split plan is applied to the original object in reverse order.

i.e.

my $ip     = NetAddr::IP->new('192.0.2.0/24');
my $objptr = $ip->rsplitref(28, 29, 28, 29, 26);

has split plan 28 26 26 26 29 28 29 28
and returns this list of objects

192.0.2.0/28
192.0.2.16/26
192.0.2.80/26
192.0.2.144/26
192.0.2.208/29
192.0.2.216/28
192.0.2.232/29
192.0.2.240/28

Set operations

Call each of these on an object, NetAddr::IP or NetAddr::IP::Lite, which joins the list, or call the function Compact or Coalesce on the list alone. A call on the class name, such as NetAddr::IP->coalesce(24, 2, @list), croaks.

$me->compact($addr1, $addr2, ...)
@compacted_object_list = Compact(@object_list)

Given a list of objects (including $me), this method will compact all the addresses and subnets into the largest (ie, least specific) subnets possible that contain exactly all of the given objects.

Note that if fed with the same IP subnets multiple times, a more "correct" approach has been adopted and only one address would be returned.

Note that $me and all $addr's must be NetAddr::IP or NetAddr::IP::Lite objects.

IPv4 and IPv6 objects are compacted separately. The returned list holds the IPv4 results followed by the IPv6 results. The objects passed in are not modified; the results are new objects.

$me->compactref(\@list)
$list_ref = Compact(\@list)

As usual, a faster version of ->compact() that returns a reference to a list. Note that this method takes a reference to a list instead.

With no list, $me->compactref() compacts $me alone, as $me->compactref([]) and $me->compact() do.

Note that $me must be a NetAddr::IP or NetAddr::IP::Lite object.

$me->coalesce($masklen, $number, @list_of_subnets)
$arrayref = Coalesce($masklen,$number,@list_of_subnets)

Will return a reference to list of NetAddr::IP subnets of $masklen mask length, when $number or more addresses from @list_of_subnets are found to be contained in said subnet.

Subnets from @list_of_subnets with a mask shorter than $masklen are passed "as is" to the return list.

Subnets from @list_of_subnets with a mask exactly equal to $masklen are passed "as is" to the return list, as their network address. They are not counted towards $number, so an equal length subnet is returned exactly once whatever $number is set to, and is never dropped for failing to reach it.

Subnets from @list_of_subnets with a mask longer than $masklen have their address count added towards $number. The count is the size of the subnet, so a /25 counts 128 and a /32 counts 1. An address held by more than one of these subnets is counted once: two copies of 192.0.2.1/32 count 1, and 192.0.2.0/30 with 192.0.2.1/32 inside it counts 4.

Called as a method, the array will include $me.

The returned list is in address order within each address family. A list holding both IPv4 and IPv6 subnets is coalesced separately for each family, with the same $masklen applied to each, and the IPv4 results come before the IPv6 results. The mask length $masklen must fit the address width of every argument, so a $masklen above 32 with any IPv4 argument is an error.

Hosts

->num()

Returns the number of usable addresses in the subnet: the host count, excluding the network and broadcast addresses. A /31 or /127 counts as 2 usable addresses per RFC 3021, and a /32 or /128 counts as 1:

print NetAddr::IP->new('192.0.2.0/31')->num();     # 2
print NetAddr::IP->new('2001:db8::/127')->num();   # 2
print NetAddr::IP->new('192.0.2.0/30')->num();     # 2
print NetAddr::IP->new('192.0.2.0/28')->num();     # 14
print NetAddr::IP->new('192.0.2.1/32')->num();     # 1

To use the old behavior for ->nth($index) and ->num():

use NetAddr::IP qw(:old_nth);

WARNING:

The module will calculate and return a numeric string for network ranges as large as 2**128. These values are TEXT strings and perl can treat them as integers for numeric calculations.

Perl on 32 bit platforms only handles integer numbers up to 2**32 and on 64 bit platforms to 2**64.

If you wish to manipulate numeric strings returned by NetAddr::IP that are larger than 2**32 or 2**64, respectively, you must load additional modules such as Math::BigInt, bignum or some similar package to do the integer math.

->nth($index)

Returns a new object representing the n-th usable IP address within the subnet (ie, the n-th host address). If no address is available (for example, when the network is too small for $index hosts), undef is returned.

See "DEPRECATED" and the Changes file for the change, and the :old_nth tag for the old behaviour.

To use the old behavior for ->nth($index) and ->num():

use NetAddr::IP qw(:old_nth);

old behavior:
NetAddr::IP->new('192.0.2.0/32')->nth(0) == undef
NetAddr::IP->new('192.0.2.0/32')->nth(1) == undef
NetAddr::IP->new('192.0.2.0/31')->nth(0) == undef
NetAddr::IP->new('192.0.2.0/31')->nth(1) == 192.0.2.1/31
NetAddr::IP->new('192.0.2.0/30')->nth(0) == undef
NetAddr::IP->new('192.0.2.0/30')->nth(1) == 192.0.2.1/30
NetAddr::IP->new('192.0.2.0/30')->nth(2) == 192.0.2.2/30
NetAddr::IP->new('192.0.2.0/30')->nth(3) == 192.0.2.3/30

Note that in each case, the broadcast address is represented in the output set and that the 'zero'th index is always undef.

new behavior:
NetAddr::IP->new('192.0.2.0/32')->nth(0) == 192.0.2.0/32
NetAddr::IP->new('192.0.2.1/32')->nth(0) == 192.0.2.1/32
NetAddr::IP->new('192.0.2.0/31')->nth(0) == 192.0.2.0/31
NetAddr::IP->new('192.0.2.0/31')->nth(1) == 192.0.2.1/31
NetAddr::IP->new('192.0.2.0/30')->nth(0) == 192.0.2.1/30
NetAddr::IP->new('192.0.2.0/30')->nth(1) == 192.0.2.2/30
NetAddr::IP->new('192.0.2.0/30')->nth(2) == undef

Note that a /32 net always has 1 usable address while a /31 has exactly two usable addresses for point-to-point addressing. The first index (0) returns the address immediately following the network address except for a /31 or /127 when it return the network address.

->hostenum()

Returns the list of hosts within a subnet. The network and broadcast addresses are left out, except on a /31 or /127, which gives both, and on a /32 or /128, which gives its one address. So a /28 gives 14 hosts and a /30 gives 2.

ERROR conditions:

->hostenum will DIE with the message 'netlimit exceeded'
  if the number of return objects exceeds 'netlimit'.
  See function 'netlimit' above (default 2**16 or 65536 nets).
->hostenumref()

Faster version of ->hostenum(), returning a reference to a list.

NOTE: hostenum and hostenumref report two (2) useable hosts in a /31 or /127 point-to-point network (RFC 3021), the same as first, last, nth and num. Versions before 4.080 reported zero hosts unless the :rfc3021 tag was imported, so the tag is no longer needed and is deprecated. See "DEPRECATED".

Regular expressions

->re()

Returns a Perl regular expression that will match an IP address within the given subnet. Defaults to ipV4 notation. For an IPv6 object, including one built from text such as ::1, and for an address that is not in ipV4 space, it returns the ipV6 regex of ->re6.

->re6()

Returns a Perl regular expression that will match an IP address within the given subnet. Always returns an ipV6 regex.

The regex matches the address written in full or with one :: run, with or without leading zeros in each group. Case is ignored. It does not match the dotted quad forms ::192.0.2.1 or ::ffff:192.0.2.1. Like the IPv4 regex of ->re, it does not match inside a longer address, so the regex for 2001:db8::1/128 does not match 2001:db8::10 or 2001:db8:2001:db8::1. Anchor the regex when matching a whole string:

my $re = NetAddr::IP->new('2001:db8::/32')->re6;
print "in\n" if '2001:db8::1' =~ /^$re$/;

The regex reads a hex digit and a colon before the address, or a dot and a digit after it, as part of a longer address. So it does not match src:2001:db8::1, where the label ends in a hex digit, or 2001:db8::1.443, where a port follows a dot.

Both ->re and ->re6 return a non-capturing group, so that embedding either one in a larger pattern does not change the numbering of the caller's own capture groups. Wrap the result yourself if you want the matched text:

my $ip   = NetAddr::IP->new('2001:db8::/32');
my $text = 'addr=2001:db8::1 port=443';
my $re   = $ip->re6;
if ($text =~ /addr=($re)\s/) { print "matched $1\n" }   # matched 2001:db8::1

IMPORT TAGS

Every tag here is process-wide: it changes behaviour for the whole program, not for one object, and each is shown where it applies. Under ithreads each thread has its own copy; see "THREADS".

:lower and :upper

By default the library returns IPv6 text in uppercase. Import :lower for lowercase, which RFC 5952 s4.3 recommends:

use NetAddr::IP qw(:lower);

use NetAddr::IP qw(:upper);   # pin it, whatever the default becomes

If both are given, :upper wins, whichever order they are in:

use NetAddr::IP qw(:lower :upper);
print NetAddr::IP->new('2001:db8::1')->addr, "\n";   # 2001:DB8:0:0:0:0:0:1
use NetAddr::IP qw(:upper :lower);
print NetAddr::IP->new('2001:db8::1')->addr, "\n";   # 2001:DB8:0:0:0:0:0:1

Note that :lower and :upper set $NetAddr::IP::InetBase::Upper, true for uppercase, shared by NetAddr::IP, NetAddr::IP::Lite, NetAddr::IP::Util and NetAddr::IP::InetBase. Importing either tag in one module changes the output of every other module in the same program. The last import wins.

:nofqdn

Turn off resolving a fully qualified domain name in the constructor, which is otherwise done for you. The switch is $NetAddr::IP::Lite::NoFQDN. See "THREADS".

use NetAddr::IP qw(:nofqdn);
:old_storable

Make Storable freeze objects as a plain hash, as it did before this module had its own Storable hooks, instead of as a CIDR string:

use NetAddr::IP qw(:old_storable);

Data frozen as a plain hash thaws the same with or without this tag, because Storable calls the thaw hook only for data the freeze hook wrote.

This deletes the Storable hooks for the whole program, or for the calling thread under ithreads (see "THREADS"), and has no variable, so it cannot be scoped with local. Once the hooks are gone, data frozen with them no longer thaws there, and thaw dies with a message that starts "No STORABLE_thaw defined for objects of class NetAddr::IP".

:old_nth

Restore the pre-4.00 nth() and num() behaviour, which counted the broadcast address and had a undef zeroth index. The switch is $NetAddr::IP::Lite::Old_nth. See "THREADS".

use NetAddr::IP qw(:old_nth);

The tags :aton and :rfc3021 are listed under "DEPRECATED".

THREADS

The library keeps no state that threads share. Its functions hold nothing between calls, so several threads can call them at the same time.

The settings that change behaviour are package state: the :lower and :upper tags with upper() and lower(), and :nofqdn, :old_nth, :old_storable, :aton and netlimit(). Under ithreads each thread has its own copy. A thread starts with the settings in force when it was created, and a change made afterwards stays in the thread that made it. Within one thread they are still process-wide, as described under "IMPORT TAGS". With local, a change to one of these variables lasts to the end of the block, and the previous value returns there, including after die:

local $NetAddr::IP::InetBase::Upper = 0;   # lowercase IPv6 text
local $NetAddr::IP::Lite::NoFQDN    = 1;   # do not resolve a name
local $NetAddr::IP::Lite::Old_nth   = 1;   # pre-4.00 nth() and num()
local $NetAddr::IP::netlimit        = 20;  # see L</netlimit>

The :old_storable tag deletes the Storable hooks and has no variable, so it cannot be scoped.

use threads;
use NetAddr::IP;

NetAddr::IP::Util::lower();
my $child = threads->create(
    sub { return "" . NetAddr::IP->new('2001:db8::ab') }
);
NetAddr::IP::Util::upper();
print $child->join, "\n";                       # 2001:db8:0:0:0:0:0:ab/128
print NetAddr::IP->new('2001:db8::ab'), "\n";   # 2001:DB8:0:0:0:0:0:AB/128

FUNCTIONS

netlimit

use NetAddr::IP qw(netlimit);
netlimit 20;

Sets the maximum number of nets beyond which the library will return an error, as a power of 2. The default is $DEFAULT_NETLIMIT_EXP, or 2**16 = 65536 nets. Each 2**16 consumes roughly 4 MB, so 2**20 is about 64 MB and 2**24 about 1 GB.

Returns the new limit, 2**$n, or undef if the request was ignored. Anything below the default of 16 or above the maximum of 24 is ignored, as is a non-numeric argument:

netlimit(20);   # 1048576
netlimit(16);   # 65536, the default
netlimit(24);   # 16777216, the maximum
netlimit(10);   # undef, below the default
netlimit(25);   # undef, above the maximum

Past this limit, hostenum() and hostenumref() die with netlimit exceeded rather than returning a partial list.

The exponent is kept in $NetAddr::IP::netlimit. With local, a change lasts to the end of one block, and the previous value returns there, including after die:

my $ip = NetAddr::IP->new('192.0.2.0/24');
{
    local $NetAddr::IP::netlimit = 20;
    $ip->split(32);
}

Zeros, Zero, Ones, V4mask and V4net

use NetAddr::IP qw(Ones V4mask V4net Zeros);
use NetAddr::IP::Util qw(ipv6_n2x);

print ipv6_n2x(Zeros()), "\n";    # 0:0:0:0:0:0:0:0
print ipv6_n2x(Ones()), "\n";     # FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
print ipv6_n2x(V4mask()), "\n";   # FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:0:0
print ipv6_n2x(V4net()), "\n";    # 0:0:0:0:0:0:FFFF:FFFF

Each returns a 128 bit string, the form an object keeps its address and mask in. The first is all zero bits and the second all one bits. The IPv4 pair, V4mask and V4net, has ones above the low 32 bits and in them respectively. Another name for Zeros is Zero.

EXPORT_OK

Compact
Coalesce
Zeros
Zero
Ones
V4mask
V4net
netlimit

DEPRECATED

Everything listed here is deprecated and will be removed in version 5.

:aton

Enables ->new() to accept a raw packed address of four or sixteen bytes, and stops it stripping surrounding whitespace from a string of four or sixteen bytes, which may be a packed address that begins or ends with a whitespace byte. Plain inet_aton notation is accepted without this tag.

The length of the string does not mark it as packed. Every text form listed under "Constructors" is tried first, then a host name lookup, and the string is read as packed only when all of them fail. A packed address whose bytes also spell text comes back as that text, or as undef:

string   packed address   result of new() under :aton
"1 23"   49.32.50.51      1.0.0.0/23, an address and a mask
"a bc"   97.32.98.99      undef, a mask that is not valid
"1234"   49.50.51.52      0.0.4.210/32, a decimal integer
"1.23"   49.46.50.51      1.0.0.23/32, a short dotted form
"0x1f"   48.120.49.102    0.0.0.31/32, a hex literal
"::1f"   58.58.49.102     0:0:0:0:0:0:0:1F/128, IPv6 text

Strings of digits with dots, hyphens, or an x or b after a leading zero can read as integers, short dotted forms, ranges and hex or binary literals. A space, tab, newline, carriage return, vertical tab, form feed or slash between two runs of letters, digits, dots, colons and hyphens splits the string into an address and a mask.

Any byte 0x3A, an ASCII colon, sends the string to the IPv6 text parser. Unless the whole string is IPv6 text, as in the last row above, the result is undef. Packed IPv4 addresses with an octet of 58, such as 192.0.2.58, fall into this group, as does 2001:db8::3a packed into sixteen bytes.

A string made only of ASCII letters, digits, dots, hyphens and underscores is looked up as a host name before it is read as packed. A packed address such as 109.97.105.108, the bytes "mail", makes the call wait for the resolver. If the name resolves, the answer is returned in place of the packed address.

The order also affects text. A four or sixteen character string that is not valid text and does not resolve, a mistyped host name for example, can come back as the address its bytes spell instead of undef.

Use new_from_aton for a packed IPv4 address: it reads every four byte string as packed and makes no lookup. There is no replacement for the packed sixteen byte case.

use NetAddr::IP qw(:aton);
:rfc3021

Imports successfully and does nothing. Versions before 4.080 reported zero usable hosts in a /31 or /127 unless this tag was imported; hostenum and hostenumref now always report two, the same as first, last, nth and num. Importing it warns.

use NetAddr::IP qw(:rfc3021);   # no longer needed
new_cis and new_cis6

Accept the Cisco address and mask notation, with a space separator in place of a slash. Both ->new() and ->new6() do the same.

->new('192.0.2.0 24')       in place of   ->new_cis('192.0.2.0 24')
->new6('::192.0.2.0 120')   in place of   ->new_cis6('::192.0.2.0 120')

NOTES / BUGS ... FEATURES

On Windows and Cygwin a plain perl Makefile.PL builds pure Perl, with no C toolchain, and --xs asks for the XS build. Elsewhere, macOS included, it builds the XS when a C compiler works. The choice is made in inc/MakeMaker/header.pl. The build steps are in README.md, and mode() reports which mode is running.

AUTHORS

  • Dean Hamstead <dean@fragfest.com.au>

  • Luis E. Muñoz <luismunoz@cpan.org>

  • Michael Robinton <michael@bizsystems.com>

COPYRIGHT AND LICENSE

This software is Copyright (c) 2026 by Dean Hamstead, Luis E. Muñoz, Michael Robinton.

This is free software, licensed under:

The MIT (X11) License

The full text of the license can be found in the LICENSE file included with this distribution.