NAME
Net::IPAddress::Util - Version-agnostic representation of an IP address
VERSION
Version 4.004
SYNOPSIS
use Net::IPAddress::Util qw( IP );
my $ipv4 = IP('192.168.0.1');
my $ipv46 = IP('::ffff:0:192.168.0.1');
my $ipv6 = IP('fe80::1234:5678:90ab');
print "$ipv4\n"; # 192.168.0.1
print "$ipv46\n"; # 192.168.0.1
print "$ipv6\n"; # fe80::1234:5678:90ab
print $ipv4->normal_form() . "\n"; # 0000000000000000ffff0000c0a80001
print $ipv46->normal_form() . "\n"; # 0000000000000000ffff0000c0a80001
print $ipv6->normal_form() . "\n"; # fe8000000000000000001234567890ab
for (my $ip = IP('192.168.0.0'); $ip <= IP('192.168.0.255'); $ip++) {
# do something with $ip
}
DESCRIPTION
The goal of the Net::IPAddress::Util modules is to make IP addresses easy to deal with, regardless of whether they're IPv4 or IPv6, and regardless of the source (and destination) of the data being manipulated. The module Net::IPAddress::Util is for working with individual addresses, Net::IPAddress::Util::Range is for working with individual ranges of addresses, and Net::IPAddress::Util::Collection is for working with collections of addresses and/or ranges.
COMPATIBILITY NOTICE
Version 4.x of this module broke compatibility with v3.x, specifically in cases where IPv4 addresses were formatted as IPv6 addresses (either string or numeric).
Version 5.x can read and write addresses in both legacy v3.x and v4.x formats.
The default output format in v5.x for representing IPv4 addresses as IPv6 is compatible with v3.x, and is known as non-SIIT mode. To use v4.x representation, either pass in a truthy falue to the SIIT
parameter at construction time, or calll the SIIT()
method on constructed objects. To transform an SIIT formatted object to non-SIIT format, call the SIIT()
object method with a defined false value.
Rationale
The reason for switching back to the v3.x non-SIIT format is simply that SIIT seems to be encountered far less often in the wild.
GLOBAL VARIABLES
$Net::IPAddress::Util::DIE_ON_ERROR
Set to a true value to make errors confess()
. Set to a false value to make errors cluck()
. Defaults to false.
$Net::IPAddress::Util::PROMOTE_N32
Set to a true value to make new() assume that bare 32-bit (or smaller) numbers are supposed to represent IPv4 addresses, and promote them accordingly (i.e. to do implicitly what n32_to_ipv4() does). Set to a false value to make new() treat all bare numbers as 128-bit numbers representing IPv6 addresses. Defaults to false.
EXPORTABLE FUNCTIONS
- explode_ip
- implode_ip
-
Transform an IP address to and from an array of 128 bits, MSB-first.
- common_prefix
-
Given two bit arrays (as provided by
explode_ip
), return the truncated bit array of the prefix bits those two arrays have in common.
- prefix_mask
-
Given two bit arrays (as provided by
explode_ip
), return a truncated bit array of ones of the same length as the sharedcommon_prefix
of the two arrays.
- ip_pad_prefix
-
Take a truncated bit array, and right-pad it with zeroes to the appropriate length.
- ipv4_mask
-
Returns a bitmask that can be ANDed against an IP to pull out only the IPv4-relevant bits, that is the N32 portion with the 0xffff appended to its front.
- ipv4_flag
-
Returns a bitmask that can be ORed onto an N32 to make it a proper "IPv4 stored as IPv6" N128.
- radix_sort
-
Given an array of objects, sorts them in ascending order, faster than Perl's built-in sort command.
For those who understand the math, a radix sort is
O(N)
instead ofO(N log N)
(the speed of Perl's builtin sort()), but it does discard duplicates, so ymmv. There are also (rare) corner cases in which radix_sort() can chew up so much RAM that it causes paging / swapping, which will slow down the process dramatically.
COMPATIBILITY API
- ip2num
- num2ip
- validaddr
- mask
- fqdn
-
These functions are exportable to provide a functionally-identical API to that provided by Net::IPAddress. They will cause warnings to be issued if they are called, to help you in your transition to Net::IPAddress::Util, if indeed that's what you're doing -- and I can't readily imagine any other reason you'd want to export them from here (as opposed to from Net::IPAddress) unless that's indeed what you're doing.
EXPORT TAGS
:constr
Exports IP() and n32_to_ipv4(), both useful for creating objects based on arbitrary external data.
:manip
Exports the functions for low-level "bit-twiddling" of addresses. You very probably don't need these unless you're writing your own equivalent of the Net::IPAddress::Util::Range or Net::IPAddress::Util::Collection modules.
:sort
Exports radix_sort()
. You only need this if you're dealing with large arrays of Net::IPAddress::Util objects, and runtime is of critical concern.
:compat
Exports the Compatibility API functions listed above.
:all
Exports all exportable functions.
CONSTRUCTORS
new
Create a new Net::IPAddress::Util object, based on a well-formed IPv4 or IPv6 address string (e.g. '192.168.0.1' or 'fe80::1234:5678:90ab'), or based on what is known by this module as the "normal form", a 32-digit hex number (without the leading '0x').
There are a number of acceptable arguments to new()
, though it does always take a single argument.
- 16-element ARRAYREF
-
Creates an IPv6 object from 16 unsigned octets in network (big-endian) order.
- 4-element ARRAYREF
-
Creates an IPv6 object from 4 unsigned 32-bit network-order integers, supplied in network order.
- An existing Net::IPAddress::Util object (equivalently, call as an object method)
-
Creates a non-destructive clone of the object.
- A well-formed IPv4 or IPv6 string (including SIIT "IPv4 in IPv6" notation)
-
Examples are
1.2.3.4
,::ffff:0:1.2.3.4
,1:2::3:4
. Note that for IPv6 flavor strings, the scope ID (if any) is silently discarded. Note also that this behavior is subject to change. If you feel strongly, go to CPAN RT and file a ticket. - An unsigned 32-bit integer Perl value
-
Iff the $PROMOTE_N32 package variable is set, creates an IPv4 object.
Actually, since all objects of this class are underlyingly IPv6, creates an "IPv4 in IPv6" representation of the IPv4 address. This is a very minor technical point, but I don't want the reader going away with incorrect assumptions about the way this module works.
- An unsigned 128-bit integer Perl value (or a string holding a decimal representation of one, or a Math::BigInt object containing one)
-
Creates an IPv6 object, treating the number as network-order.
- A 32-character hex string (case insensitive)
-
Creates an IPv6 object. NB this may be especially useful when you're using the output of the
normal_form
method (e.g. for round-tripping to a database). - A non-encoded sequence of 16 bytes in Perl string form
-
Creates an IPv6 object. Be especially sure that use of this argument form is performed correctly. You MUST, for instance,
utf8::downgrade
anddecode
your string before providing it. No effort is made to check or ensure anything about Unicode flagging or semantics. This is probably a bug, and is likely to be fixed in some future version (unless you can find a case for it being a security bug, in which case go directly to CPAN RT, please, and I'll fix it ASAP).
IP
The exportable function IP() is a shortcut for Net::IPAddress::Util->new().
my $xyzzy = Net::IPAddress::Util->new($foo);
my $plugh = IP($foo); # Exactly the same thing, but with less typing
n32_to_ipv4
The exportable function n32_to_ipv4() converts an IPv4 address in "N32" format (i.e. a network-order 32-bit number) into an Net::IPAddress::Util object representing the same IPv4 address.
OVERLOADS
This module overloads a number of operators (cmp, <=>, &, |, ~, +, -, <<, >>) in hopefully obvious ways. One perhaps non-obvious overload is that cmp performs apparently "numeric" order comparison (the same as <=>) instead of strict string comparison. To understand why, picture it as comparing the normal_form
of the addresses stringwise (rather than the as_str
form).
OBJECT METHODS
is_ipv4
Returns true if this object represents an IPv4 address.
ipv4
Returns the dotted-quad representation of this object, or an error if it is not an IPv4 address, for instance '192.168.0.1'.
as_n32
Returns the "N32" representation of this object (that is, a 32-bit number in network order) if this object represents an IPv4 address, or an error if it does not.
as_n128
Returns the "N128" representation of this object (that is, a 128-bit number in network order).
You may supply one optional argument. If this argument is true, the return value will be a Math::BigInt object (allowing quickish and easy math involving two such return values), otherwise (if it is false (the default)), then the N128 number will be returned as a bare string. If your platform can handle math with unsigned 128-bit integers, or if you will not be doing math on the results, then I strongly recommend the latter (default / false) option for performance reasons. In the true-argument case, you're advised to stringify the Math::BigInt math results as soon as is practical for performance reasons -- Math::BigInt is not "CPU free".
ipv6
Returns the canonical IPv6 string representation of this object, for instance 'fe80::1234:5678:90ab' or '::ffff:0:192.168.0.1'.
ipv6_expanded
Returns the IPv6 string representation of this object, without compressing extraneous zeroes, for instance 'fe80:0000:0000:0000:0000:1234:5678:90ab'.
normal_form
Returns the value of this object as a zero-padded 32-digit hex string, without the leading '0x', suitable (for instance) for storage in a database, or for other purposes where easy, fast sorting is desirable, for instance 'fe8000000000000000001234567890ab'.
'""'
str
as_str
as_string
If this object is an IPv4 address, it stringifies to the result of ipv4
, else it stringifies to the result of ipv6
.
INTERNAL FUNCTIONS
- ERROR
-
Either confess()es or cluck()s the passed string based on the value of $Net::IPAddress::Util::DIE_ON_ERROR, and if possible returns undef.
TODO
What is the correct thing to do when new
is given a flat 16-character string with its Unicode flag set?
LICENSE
May be redistributed and/or modified under terms of the Artistic License v2.0.
AUTHOR
PWBENNETT -- paul(dot)w(dot)bennett(at)gmail.com
THANKS
Thanks to Dave "Autarch" Rolsky for discovering the potential security issue that motivated me to finally dust off the v5.x prototype and make the tests work (and implement the fix to the discovered security issue).