gethostbyaddr#
Look up a host record by its packed IP address.
gethostbyaddr performs a reverse DNS lookup: given a packed binary
address (four bytes for IPv4, sixteen for IPv6) and the matching
address family, it calls the system’s C gethostbyaddr(3) routine and
returns the host record. The typical use case — “whose machine is
this packet from?” — wants the scalar-context form: a single
hostname. The list-context form exposes the full struct hostent:
canonical name, aliases, address family, address length, and every
address the resolver knows for that host.
Synopsis#
my $name = gethostbyaddr $packed_addr, $addrtype;
my ($name, $aliases, $addrtype, $length, @addrs) = gethostbyaddr $packed_addr, $addrtype;
What you get back#
Scalar context — the canonical hostname as a plain string, or
undef if the reverse lookup fails.
List context — a five-element list mirroring the C struct hostent:
$name— the canonical hostname the resolver mapped the address to.$aliases— a space-separated string of alternate names. Single scalar, not a list.$addrtype— the address family of the returned addresses, typicallyAF_INET(2) orAF_INET6(10).$length— the length of each address in bytes (4for IPv4,16for IPv6).@addrs— every address returned for the host, each a packed binary string of$lengthbytes. Often just one, but multi-homed hosts can yield several.
On lookup failure in list context, the return is the empty list.
Global state it touches#
$?— set to the Ch_errnovalue on failure, when the platform exposes it. Test with$? != 0to distinguishHOST_NOT_FOUNDfromTRY_AGAINand similar transient errors.$!— not meaningfully set by DNS failures. Reverse lookups fail viah_errno, noterrno; do not check$!after a failed call.The host database iteration cursor shared with
gethostent,sethostent, andendhostent. A call togethostbyaddrmay reset a cursor left open bygethostent.
Examples#
Scalar form — map a dotted-quad to a hostname:
use Socket;
my $packed = inet_aton("127.0.0.1");
my $name = gethostbyaddr($packed, AF_INET);
print defined $name ? "$name\n" : "no PTR record\n";
Round-trip — forward lookup, then reverse the first address:
use Socket;
my $packed = gethostbyname("www.perl.org");
my $name = gethostbyaddr($packed, AF_INET);
print "$name\n";
Identify the peer on an accepted socket connection:
use Socket;
my $peer = getpeername($sock);
my ($port, $iaddr) = sockaddr_in($peer);
my $host = gethostbyaddr($iaddr, AF_INET);
printf "connection from %s:%d\n", $host // inet_ntoa($iaddr), $port;
List form — every name and address the resolver knows for the host:
use Socket;
my $packed = inet_aton("8.8.8.8");
my ($name, $aliases, $type, $len, @addrs) = gethostbyaddr($packed, AF_INET);
print "canonical: $name\n";
print "aliases: $_\n" for split ' ', $aliases;
print "address: ", inet_ntoa($_), "\n" for @addrs;
By-name interface via the Net::hostent override — accessor methods
instead of positional unpacking:
use Net::hostent;
use Socket;
my $h = gethostbyaddr(inet_aton("127.0.0.1"), AF_INET);
print $h->name, "\n" if $h;
Edge cases#
ADDRis a packed binary string, not a dotted-quad. Passing"127.0.0.1"directly does not work — Perl will call the resolver with nine raw bytes and get nothing useful back. Always go throughSocket::inet_aton,Socket::inet_pton, or an equivalent packer first.ADDRTYPEmust match the address width.AF_INETwants a four-byteADDR;AF_INET6wants sixteen. A mismatch either returnsundefor, on some platforms, reads past the buffer. Use the constant fromSocket, not a hand-typed integer.Check for
undefon the scalar form. A missing PTR record returnsundef, not an empty string. Many addresses on the public internet have no reverse mapping at all.@addrsmay not include the address you queried. The resolver returns the full record for the canonical host, which may contain additional addresses that happen to share the hostname.Scalar context runs the full resolver call anyway. The C routine always populates the whole
hostent; Perl just discards the list. There is no performance advantage to the scalar form beyond clearer code.Reverse of a forward lookup is not guaranteed to round-trip.
gethostbyaddr(gethostbyname($h), AF_INET)may return a different name from$h— reverse DNS maps to the canonical hostname, which often differs from the alias the forward query used.IPv6 support is platform-dependent. Not every libc’s
gethostbyaddr(3)handlesAF_INET6cleanly. For portable dual-stack reverse resolution useSocket::getnameinfo.Thread safety. The underlying C routine keeps per-process static state for the host cursor. Concurrent calls from multiple threads may interleave results. Scripts that need thread-safe reverse resolution should use
Socket::getnameinfo.
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
gethostbyname— the forward lookup: hostname → packed addressgethostent— iterate every entry in the host database instead of looking up one addresssethostent— rewind the host iterator and control whether the file stays open across lookupsSocket::inet_aton— build the packedADDRargument from a dotted-quad stringSocket::inet_ntoa— render a packed address from@addrsback to dotted-quad formSocket::getnameinfo— modern, protocol-agnostic reverse resolver that handles IPv6 and is thread-safe