NAME
NetAddr::IP::InetBase - IPv4 and IPv6 address parsing and formatting utilities
VERSION
version 4.080_07
SYNOPSIS
use NetAddr::IP::InetBase qw(fillIPv4 inet_any2n inet_aton inet_n2dx
inet_ntoa ipv6_aton ipv6_n2x);
my $packed = inet_aton('192.0.2.1');
print length($packed), "\n"; # 4
print inet_ntoa($packed), "\n"; # 192.0.2.1
print ipv6_n2x(ipv6_aton('2001:db8::1')), "\n"; # 2001:db8:0:0:0:0:0:1
print inet_n2dx(inet_any2n('192.0.2.1')), "\n"; # 192.0.2.1
print fillIPv4('192.0.2'), "\n"; # 192.0.0.2
NetAddr::IP::InetBase::lower(); # case, see IMPORT TAGS
NetAddr::IP::InetBase::upper();
DESCRIPTION
The NetAddr::IP::InetBase module is the pure Perl layer that converts IPv4 and IPv6 addresses between binary and text. Everything here is pure Perl on every host. Both NetAddr::IP::Util and the XS build take these functions from it rather than reimplementing them. The function inet_ntop calls core Socket, which calls the platform C library. See "Core Socket".
A binary address here is called packed below, as opposed to text. It comes in two sizes. The IPv4 form, $V4_PACKED_BYTES bytes, is what inet_aton returns. The 16 byte form, $V6_PACKED_BYTES, is what ipv6_aton returns, and inet_any2n returns it for both families, with an IPv4 address in the low 32 bits.
The IPv6 functions accept every text form in RFC 4291 s2.2:
x:x:x:x:x:x:x:x
x:x:x:x:x:x:d.d.d.d
::x:x:x
::x:d.d.d.d
::ffff:d.d.d.d
Each d is decimal, 0 to 255, without a leading zero. No part of an IPv4 address takes one, in a tail or on its own, so ::ffff:192.0.2.010, 192.0.2.010 and 010.1 are not addresses: the C library's inet_aton reads 010 as octal 8, and a person reads it as decimal 10.
The whole string has to be the address. Surrounding whitespace, a trailing newline included, makes it text that is not one, and inet_aton returns undef for it without asking gethostbyname. The constructor, NetAddr::IP->new, strips surrounding whitespace before it reads an address.
Text that is not an address is not an error. Four functions, inet_aton, ipv6_aton, inet_any2n and inet_pton, return undef for it. A binary argument of the wrong length is an error, and each entry below says which functions croak on one.
A binary argument is measured in bytes, as the XS functions of NetAddr::IP::Util measure one. A string upgraded to UTF-8 is read as the bytes it holds. A string with a character above 0xFF cannot be read as bytes, and every function that croaks on a wrong length croaks on it, with Wide character in and the full name of the function that measures the argument.
FUNCTIONS
Text to binary
- $netaddr = inet_aton($dotquad);
-
Convert a dot-quad IP address into an IPv4 packed network address.
input: IP address i.e. 192.0.2.1 returns: packed network address, or undefShort forms follow the BSD
inet_atonconvention, not RFC 791:127.1is 127.0.0.1 and192.0.2is 192.0.0.2. Its octal reading of a leading zero does not:192.0.2.010returns undef. A literal does not callgethostbyname. Other text does, and that function keeps one static buffer, so two threads resolving names at once can swap answers. Returns undef for an octet above 255, for text with whitespace, and for text that does not resolve. - $bits128 = ipv6_aton($ipv6_text);
-
Takes an IPv6 address in any of the RFC 4291 s2.2 text forms and returns a 128 bit binary RDATA string. Returns undef if the text is not a valid address.
input: ipv6 text returns: 128 bit RDATA string, or undef - $ipv6naddr = inet_any2n($dotquad or $ipv6_text);
-
This function converts a text IPv4 or IPv6 address in text format in any standard notation into a 128 bit IPv6 string address. It prefixes any dot-quad address (if found) with '::' and passes it to ipv6_aton.
input: dot-quad or RFC 4291 s2.2 address returns: 128 bit IPv6 string, or undefReturns undef if the text is not an address, including a bare number such as
10, which has no colon and is no dotted quad. An empty or undefined argument is read as::, the all-zero address. - $netaddr = inet_pton($AF_family,$text_addr);
-
This function takes an IP address in IPv4 or IPv6 text format and converts it into binary format. The type of IP address conversion is controlled by the FAMILY argument.
Returns undef for text that is not an address of that family, and croaks on a family other than
AF_INETandAF_INET6.NOTE:
inet_ptonreads the text itself rather than calling the platforminet_pton, so every host reads it alike. For IPv4,inet_pton(AF_INET, ...)takes only four decimal parts from 0 to 255, each without a leading zero, and nothing after them. It returns undef for a short form such as127.1, for a host name, and for an undefined address. By contrast,inet_atonaccepts the short form and the host name.
Binary to text
- $dotquad = inet_ntoa($netaddr);
-
Convert a packed IPv4 network address to a dot-quad IP address.
input: packed network address returns: IP address i.e. 192.0.2.1Croaks if the argument is not 4 bytes.
- $ipv6text = ipv6_ntoa($ipv6naddr);
-
Convert a 128 bit binary IPv6 address to the compressed RFC 5952 s4 text representation.
input: 128 bit RDATA string returns: ipv6 textCroaks if the argument is not 16 bytes.
This is inet_ntop(AF_INET6,$ipv6naddr). An address with an IPv4 address in the low 32 bits is printed by the platform
inet_ntop. On glibc that is mixed notation,::ffff:192.0.2.1. A different C library can print a different form. See the notes on inet_ntop below.No method of NetAddr::IP or NetAddr::IP::Lite calls this function. Stringification goes through ipv6_n2x, which is pure Perl on every host.
- $hex_text = ipv6_n2x($bits128);
-
Takes an IPv6 RDATA string and returns an 8 segment IPv6 hex address
input: 128 bit RDATA string returns: x:x:x:x:x:x:x:x Note: this function does NOT compress adjacent strings of 0:0:0:0 into the :: format - $dec_text = ipv6_n2d($bits128);
-
Takes an IPv6 RDATA string and returns a mixed hex - decimal IPv6 address with the 6 uppermost chunks in hex and the lower 32 bits in dot-quad representation.
input: 128 bit RDATA string returns: x:x:x:x:x:x:d.d.d.d Note: this function does NOT compress adjacent strings of 0:0:0:0 into the :: format - $dotquad or $hex_text = inet_n2dx($ipv6naddr);
-
This function does the right thing and returns the text for either a dot-quad IPv4 or a hex notation IPv6 address.
input: 128 bit IPv6 string returns: ddd.ddd.ddd.ddd or x:x:x:x:x:x:x:x Note: this function does NOT compress adjacent strings of 0:0:0:0 into the :: formatCroaks if the argument is not 16 bytes.
- $dotquad or $dec_text = inet_n2ad($ipv6naddr);
-
This function does the right thing and returns the text for either a dot-quad IPv4 or a hex::decimal notation IPv6 address.
input: 128 bit IPv6 string returns: ddd.ddd.ddd.ddd or x:x:x:x:x:x:ddd.ddd.ddd.ddd Note: this function does NOT compress adjacent strings of 0:0:0:0 into the :: formatCroaks if the argument is not 16 bytes.
- $text_addr = inet_ntop($AF_family,$netaddr);
-
This function takes an IP address in binary format and converts it into text format. The type of IP address conversion is controlled by the FAMILY argument.
NOTE: inet_ntop ALWAYS returns lowercase characters.
For IPv4,
inet_ntop(AF_INET, ...)isinet_ntoa. For IPv6,inet_ntop(AF_INET6, ...)is the platforminet_ntop. An address with an IPv4 address in the low 32 bits is printed in that library's form. On glibc:address text ::ffff:192.0.2.1 ::ffff:192.0.2.1 ::ffff:0:0 ::ffff:0.0.0.0 ::192.0.2.1 ::192.0.2.1A different C library can print a different form. The difference is confined to the mapped prefix ::ffff:0:0/96 and the deprecated compatible prefix ::/96. Everything else agrees, including zero run compression, which of two equal runs is shortened, a single zero group, leading zeros and case.
- $hex_text = packzeros($hex_text);
-
Shortens an eight-group IPv6 hex address by substituting :: for the longest run of zero groups, per RFC 5952 s4.2.1. Where two runs are equally long the first is shortened, s4.2.3, and a run of one zero group is never shortened at all, s4.2.2. The result is always lowercase, RFC 5952 s4.3, whatever the case setting.
print packzeros('0:0:0:0:0:ffff:c000:201'); # ::ffff:c000:201 print packzeros('2001:db8:0:1:1:1:1:1'); # 2001:db8:0:1:1:1:1:1 print packzeros('2001:db8:0:0:1:0:0:1'); # 2001:db8::1:0:0:1 print packzeros('2001:db8:0:1:1:0:0:1'); # 2001:db8:0:1:1::1 print packzeros('2001:0DB8:0:1:2:3:4:5'); # 2001:db8:0:1:2:3:4:5
Family tests
- $rv = isIPv4($bits128);
-
This function returns true if there are no on bits present in the IPv6 portion of the 128 bit string and false otherwise.
i.e. the address must be of the form - ::d.d.d.dwhich is the RFC 4291 s2.5.5.1 IPv4-compatible prefix
::/96, deprecated by that RFC.Croaks if the argument is not 16 bytes. The message names
isIPv4, orisNewIPv4orisAnyIPv4when the argument came in through one of them. - $rv = isNewIPv4($bits128);
-
This function returns true if the 128 bit string is an IPv4-mapped address, of the form
::ffff:d.d.d.dwhich is the RFC 4291 s2.5.5.2 prefix
::ffff:0:0/96. Croaks if the argument is not 16 bytes. - $rv = isAnyIPv4($bits128);
-
This function returns true if the 128 bit string has an IPv4 address in the low 32 bits, of either form
::d.d.d.d or ::ffff:d.d.d.dwhich is the union of the RFC 4291 s2.5.5.1 compatible prefix and the s2.5.5.2 mapped prefix. Croaks if the argument is not 16 bytes.
Address family
- $constant = AF_INET;
-
Returns the system value for AF_INET, taken from Socket.
- $constant = AF_INET6;
-
Returns the value for AF_INET6, taken from Socket.
use NetAddr::IP::InetBase qw(AF_INET AF_INET6); print AF_INET(), ' ', AF_INET6(), "\n"; # 2, then the platform value - $false = fake_AF_INET6;
-
Deprecated. Returns 0 on every host, because
AF_INET6always comes from Socket, and warns in thedeprecatedcategory. See "DEPRECATED".
Short IPv4 text
- $ip_filled = fillIPv4($shortIP);
-
Expands a short IPv4 text address to the four part form, padding the missing octets with zeros. This follows the BSD
inet_atonconvention for padding and is not RFC 791. Unlike BSD, every part must fit in an octet, so300gives undef rather than 0.0.1.44.input: short or full IPv4 text returns: the four part form, or undef print fillIPv4('192.0.2.1'), "\n"; # 192.0.2.1 print fillIPv4('192.0.2'), "\n"; # 192.0.0.2 print fillIPv4('192.0'), "\n"; # 192.0.0.0 print fillIPv4('10'), "\n"; # 0.0.0.10An argument that does not look like a short or full IPv4 address is returned unchanged, so a hostname passes straight through, and an octet out of range gives undef:
print fillIPv4('example.com'), "\n"; # example.com print defined(fillIPv4('256.1.1.1')) ? 'defined' : 'undef', "\n"; # undef print defined(fillIPv4('300')) ? 'defined' : 'undef', "\n"; # undefThe argument is text, not a packed address. A packed string does not match, so it is returned unchanged too.
Case
- NetAddr::IP::InetBase::lower();
-
Return IPv6 strings in lowercase. This is the default only when NetAddr::IP::InetBase is loaded on its own. The module NetAddr::IP::Util loads this one with the :upper tag, so a program that loads NetAddr::IP::Util, NetAddr::IP::Lite or NetAddr::IP gets uppercase output unless it calls lower() or imports :lower from NetAddr::IP::Lite, NetAddr::IP, or this module.
- NetAddr::IP::InetBase::upper();
-
Return IPv6 strings in uppercase.
The case setting is one package-wide variable. Calling lower() or upper(), or importing :lower or :upper from this module, NetAddr::IP::Lite, or NetAddr::IP, changes the output for every user of these modules in the running program, not only the caller. The last call wins. Those tags are not accepted by NetAddr::IP::Util. Call its lower() or upper().
The default may be set to uppercase when the module is loaded by importing the tag
:upper:use NetAddr::IP::InetBase qw(:upper);
EXPORTS
Nothing is exported by default.
EXPORT_OK
inet_aton inet_ntoa ipv6_aton ipv6_ntoa
ipv6_n2x ipv6_n2d inet_any2n inet_n2dx
inet_n2ad inet_pton inet_ntop packzeros
isIPv4 isNewIPv4 isAnyIPv4 AF_INET
AF_INET6 fake_AF_INET6 fillIPv4
IMPORT TAGS
:all-
Every name in "EXPORT_OK".
:ipv4-
inet_aton inet_ntoa fillIPv4 :ipv6-
ipv6_aton ipv6_ntoa ipv6_n2x ipv6_n2d inet_any2n inet_n2dx inet_n2ad inet_pton inet_ntop packzeros :lowerand:upper-
The case tags. If both are given,
:upperwins, whichever order they are in. See "THE CASE POLICY".
DEPRECATED
Everything listed here is deprecated and will be removed in version 5.
fake_AF_INET6-
Returned the
AF_INET6value this module guessed from the operating system's name on a perl whose Socket had none. Every supported perl's Socket hasAF_INET6, so nothing is guessed and it returns 0. CallAF_INET6for the value.
THE CASE POLICY
The case of IPv6 text output is one package global, not a setting per object or per module, so it applies to every user of the library in the process. Two consequences worth stating plainly.
This module defaults to lowercase:
use NetAddr::IP::InetBase qw(ipv6_aton ipv6_n2x);
my $bits128 = ipv6_aton('2001:db8::1');
print ipv6_n2x($bits128); # 2001:db8:0:0:0:0:0:1
Importing :upper from this module switches it:
use NetAddr::IP::InetBase qw(:upper ipv6_aton ipv6_n2x);
my $bits128 = ipv6_aton('2001:db8::1');
print ipv6_n2x($bits128); # 2001:DB8:0:0:0:0:0:1
Loading NetAddr::IP::Util does the same, because that module imports :upper from here as it loads. Passing :upper or :lower on a use NetAddr::IP::Util line dies. Both NetAddr::IP::Lite and NetAddr::IP accept the tags.
And once set, an unrelated package importing :lower changes it back for everyone:
use NetAddr::IP;
package Other;
use NetAddr::IP::Lite qw(:lower);
package main;
print NetAddr::IP->new('2001:db8::1')->addr, "\n"; # 2001:db8:0:0:0:0:0:1
Under ithreads each thread has its own copy of the setting. A thread starts with the case in force when it was created, and upper() or lower() in one thread does not change another.
Whether uppercase or lowercase should be the default, and whether the setting should be process-wide at all, is an open question: see GH#7.
Three functions ignore the setting entirely and are always lowercase: packzeros, which follows RFC 5952 s4.3, and ipv6_ntoa and inet_ntop, which follow the platform inet_ntop.
Core Socket
The constants AF_INET and AF_INET6 and the function inet_ntop come from core Socket. Socket6 is not used. The inet_pton here reads the text itself, because C libraries differ in the IPv4 text they accept.
For an IPv4 address, inet_ntop is inet_ntoa. For an IPv6 address, inet_ntop is the platform function, so an address with an IPv4 address in the low 32 bits follows that C library. On glibc the mapped form is ::ffff:192.0.2.1.
SEE ALSO
NetAddr::IP, NetAddr::IP::Lite, NetAddr::IP::Util
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.