--- name: gethostbyaddr signature: 'gethostbyaddr ADDR, ADDRTYPE' since: 5.0 status: documented categories: ["Network info"] --- ```{index} single: gethostbyaddr; Perl built-in ``` *[Network info](../perlfunc-by-category)* # 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 ```perl 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`](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, typically `AF_INET` (`2`) or `AF_INET6` (`10`). - `$length` — the length of each address in bytes (`4` for IPv4, `16` for IPv6). - `@addrs` — every address returned for the host, each a packed binary string of `$length` bytes. 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 - [`$?`](../perlvar) — set to the C `h_errno` value on failure, when the platform exposes it. Test with `$? != 0` to distinguish `HOST_NOT_FOUND` from `TRY_AGAIN` and similar transient errors. - [`$!`](../perlvar) — not meaningfully set by DNS failures. Reverse lookups fail via `h_errno`, not `errno`; do not check [`$!`](../perlvar) after a failed call. - The host database iteration cursor shared with [`gethostent`](gethostent), [`sethostent`](sethostent), and [`endhostent`](endhostent). A call to `gethostbyaddr` may reset a cursor left open by [`gethostent`](gethostent). ## Examples Scalar form — map a dotted-quad to a hostname: ```perl 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: ```perl 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: ```perl 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: ```perl 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: ```perl use Net::hostent; use Socket; my $h = gethostbyaddr(inet_aton("127.0.0.1"), AF_INET); print $h->name, "\n" if $h; ``` ## Edge cases - **`ADDR` is 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 through [`Socket::inet_aton`](../../Socket/inet_aton), [`Socket::inet_pton`](../../Socket/inet_pton), or an equivalent packer first. - **`ADDRTYPE` must match the address width.** `AF_INET` wants a four-byte `ADDR`; `AF_INET6` wants sixteen. A mismatch either returns [`undef`](undef) or, on some platforms, reads past the buffer. Use the constant from [`Socket`](../../Socket), not a hand-typed integer. - **Check for [`undef`](undef) on the scalar form.** A missing PTR record returns [`undef`](undef), not an empty string. Many addresses on the public internet have no reverse mapping at all. - **`@addrs` may 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)` handles `AF_INET6` cleanly. For portable dual-stack reverse resolution use [`Socket::getnameinfo`](../../Socket/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`](../../Socket/getnameinfo). ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`gethostbyname`](gethostbyname) — the forward lookup: hostname → packed address - [`gethostent`](gethostent) — iterate every entry in the host database instead of looking up one address - [`sethostent`](sethostent) — rewind the host iterator and control whether the file stays open across lookups - [`Socket::inet_aton`](../../Socket/inet_aton) — build the packed `ADDR` argument from a dotted-quad string - [`Socket::inet_ntoa`](../../Socket/inet_ntoa) — render a packed address from `@addrs` back to dotted-quad form - [`Socket::getnameinfo`](../../Socket/getnameinfo) — modern, protocol-agnostic reverse resolver that handles IPv6 and is thread-safe