NAME
NetAddr::IP::UtilPP - Pure perl implementations of IPv4 and IPv6 address utilities
VERSION
version 4.080_05
SYNOPSIS
use NetAddr::IP::UtilPP qw(
hasbits
shiftleft
addconst
add128
sub128
notcontiguous
ipv4to6
mask4to6
ipanyto6
maskanyto6
ipv6to4
bin2bcd
bcd2bin
);
use NetAddr::IP::InetBase qw(inet_aton ipv6_aton);
# inputs for the calls below
$netaddr = inet_aton('192.0.2.1');
$bits128 = ipv6_aton('2001:db8::1');
$bits1281 = ipv6_aton('2001:db8::2');
$bits1282 = ipv6_aton('2001:db8::1');
$mask128 = ipv6_aton('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00');
$signed_32bit = 1;
$n = 8;
# the family test and the shift
$rv = hasbits($bits128); # true if any bit is set
$bitsXn = shiftleft($bits128, $n); # 8 bits left; no $n returns the input
# arithmetic, carry in scalar context and (carry, result) in list
$carry = addconst($bits128, $signed_32bit);
($carry, $bits128) = addconst($bits128, $signed_32bit);
$carry = add128($bits1281, $bits1282);
($carry, $bits128) = add128($bits1281, $bits1282);
$carry = sub128($bits1281, $bits1282);
($spurious, $cidr) = notcontiguous($mask128);
# widening and narrowing
$ipv6naddr = ipv4to6($netaddr); # ::d.d.d.d
$ipv6naddr = ipanyto6($netaddr); # either family in, 128 bits out
$netaddr = ipv6to4($ipv6naddr); # low 32 bits
# decimal text
$bcdtext = bin2bcd($bits128);
$bits128 = bcd2bin($bcdtext);
DESCRIPTION
NetAddr::IP::UtilPP is the pure Perl implementation of the functions in NetAddr::IP::Util that touch 128 bit strings. In a pure Perl build, NetAddr::IP::Util loads it in place of its XS code, and mode() from NetAddr::IP::Util then reports Pure Perl:
mode() 'CC XS' or 'Pure Perl'
Both implementations croak on a wrong-length argument with the same message, naming the function and both lengths in bits:
Bad arg length for NetAddr::IP::Util::hasbits, length is 40,
should be 128
The message names the function in NetAddr::IP::Util, the module callers normally load, even when this module is called directly. Each entry below says what its function does with a bad argument.
FUNCTIONS
These implement the same operations as NetAddr::IP::Util.
Family test and shift
- $rv = hasbits($bits128);
-
This function returns true if there are one's present in the 128 bit string and false if all the bits are zero.
# i.e. if (hasbits($bits128)) { &do_something; } # or if (hasbits($bits128 & $mask128)) { &do_something; }This allows the implementation of logical functions of the form of:
if ($bits128 & $mask128) { ... input: 128 bit IPv6 string returns: true if any bits are presentCroaks if the argument is not 16 bytes.
- $bitsXn = shiftleft($bits128, $n);
-
input: 128 bit string variable, number of shifts [optional] returns: bits X n shifts NOTE: input bits are returned if $n is not specifiedA negative
$n, or one above$MAX_SHIFTLEFTof 128, croaks, and so does a$bits128that is not 16 bytes.
Arithmetic
- addconst($ipv6naddr, $signed_32con);
-
Add a signed constant to a 128 bit string variable.
input: 128 bit IPv6 string, signed 32 bit integer returns: scalar carry array (carry, result)Croaks if
$ipv6naddris not 16 bytes. - add128($ipv6naddr1, $ipv6naddr2);
-
Add two 128 bit string variables.
input: 128 bit string var1, 128 bit string var2 returns: scalar carry array (carry, result)Croaks if either argument is not 16 bytes.
- sub128($ipv6naddr1, $ipv6naddr2);
-
Subtract two 128 bit string variables.
input: 128 bit string var1, 128 bit string var2 returns: scalar carry array (carry, result)Note: The carry from this operation is the result of adding the one's complement of ARG2 +1 to the ARG1. It is logically NOT borrow.
i.e. if ARG1 >= ARG2 then carry = 1 or if ARG1 < ARG2 then carry = 0Croaks if either argument is not 16 bytes.
- ($spurious, $cidr) = notcontiguous($mask128);
-
This function counts the bit positions remaining in the mask when the rightmost '0's are removed.
input: 128 bit netmask returns true if there are spurious zero bits remaining in the mask false if the mask is contiguous one's, 128 bit cidrCroaks if the argument is not 16 bytes.
Widening and narrowing
- $ipv6naddr = ipv4to6($netaddr);
-
Convert an ipv4 network address into an ipv6 network address.
input: 32 bit network address returns: 128 bit network addressCroaks if the argument is not 4 bytes.
- $ipv6naddr = mask4to6($netaddr);
-
Convert an ipv4 network address into an ipv6 network mask.
input: 32 bit network/mask address returns: 128 bit network/mask addressNOTE: returns the high 96 bits as one's
Croaks if the argument is not 4 bytes.
- $ipv6naddr = ipanyto6($netaddr);
-
Similar to ipv4to6 except that this function takes either an IPv4 or IPv6 input and always returns a 128 bit IPv6 network address.
input: 32 or 128 bit network address returns: 128 bit network addressCroaks if the argument is neither 4 nor 16 bytes.
- $ipv6naddr = maskanyto6($netaddr);
-
Similar to mask4to6 except that this function takes either an IPv4 or IPv6 netmask and always returns a 128 bit IPv6 netmask.
input: 32 or 128 bit network mask returns: 128 bit network maskCroaks if the argument is neither 4 nor 16 bytes.
- $netaddr = ipv6to4($ipv6naddr);
-
Truncate the upper 96 bits of a 128 bit address and return the lower 32 bits. Returns an IPv4 address as returned by inet_aton.
input: 128 bit network address returns: 32 bit inet_aton network addressCroaks if the argument is not 16 bytes.
Decimal strings
- $bcdtext = bin2bcd($bits128);
-
Convert a 128 bit binary string into binary coded decimal text digits.
input: 128 bit string variable returns: string of bcd text digitsCroaks if the argument is not 16 bytes.
- $bits128 = bcd2bin($bcdtxt);
-
Convert a bcd text string to 128 bit string variable
input: string of bcd text digits returns: 128 bit string variableCroaks if the string is empty, is longer than 40 digits, holds a character other than 0 to 9, or is a number too large for 128 bits.
- $bits128 = bcdn2bin($bcdpacked,$ndigits);
-
Convert a packed bcd string into a 128 bit string variable
input: packed bcd string number of digits in string returns: 128 bit string variable
EXPORT_OK
The functions this module can export, all of them also exported by NetAddr::IP::Util. The :all tag imports every one. The first thirteen are documented above; the last five are helpers for the test suite, exported so that this module and the XS build can be compared against each other, and not stable API.
hasbits
shiftleft
addconst
add128
sub128
notcontiguous
ipv4to6
mask4to6
ipanyto6
maskanyto6
ipv6to4
bin2bcd
bcd2bin
comp128
bin2bcdn
bcdn2txt
bcdn2bin
simple_pack
Where bin2bcd returns text digits, simple_pack turns text digits into a packed string, padding to $MAX_BCD_DIGITS first. The inverse of the packing is bcdn2txt, and bcdn2bin turns a packed string back to 128 bits. The last helper, comp128, is published only for testing, because Perl's ~ is faster than calling into the XS routine for a one's complement.
SEE ALSO
NetAddr::IP::Util, NetAddr::IP, NetAddr::IP::Lite
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.