Network info

gethostbyname#

Look up a host record by DNS name.

gethostbyname resolves a hostname to its IP address(es) and canonical record by calling the system’s C gethostbyname(3) routine. The typical use case — “give me the packed IP of this host” — wants the scalar-context form and nothing more. The list-context form exposes the full host record: canonical name, aliases, address family, address length, and every address on file.

Synopsis#

my $packed_ip = gethostbyname $name;
my ($name, $aliases, $addrtype, $length, @addrs) = gethostbyname $name;

What you get back#

Scalar context — the first IP address as a packed binary string (four bytes for IPv4, sixteen for IPv6), or undef if the lookup fails. Convert to a dotted-quad with Socket::inet_ntoa:

use Socket;
my $packed = gethostbyname("www.perl.org");
my $dotted = inet_ntoa($packed) if defined $packed;

List context — a five-element list mirroring the C struct hostent:

  • $name — the canonical hostname.

  • $aliases — a space-separated string of alternate names.

  • $addrtype — the address family, 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 name, each a packed binary string of $length bytes.

On lookup failure in list context, the return is the empty list.

Global state it touches#

  • $? — set to the C h_errno value on failure, when the platform exposes it. Test with $? != 0 to distinguish “no such host” (HOST_NOT_FOUND) from “try again” (TRY_AGAIN) and similar.

  • The host database iteration cursor shared with gethostent, sethostent, and endhostent. A call to gethostbyname may reset a cursor left open by gethostent.

Examples#

Scalar form — the common case:

use Socket;
my $packed = gethostbyname("localhost");
defined $packed or die "cannot resolve localhost: $!";
print inet_ntoa($packed), "\n";      # 127.0.0.1

List form — enumerate every address for a multi-homed host:

use Socket;
my ($name, $aliases, $type, $len, @addrs) = gethostbyname("www.example.com");
for my $addr (@addrs) {
    print inet_ntoa($addr), "\n";
}

Unpack an IPv4 address by hand, without Socket:

my $packed = gethostbyname("127.0.0.1");
my ($a, $b, $c, $d) = unpack("W4", $packed);
print "$a.$b.$c.$d\n";               # 127.0.0.1

Forward then reverse — resolve a name, then look the address back up:

use Socket;
my $packed = gethostbyname("www.perl.org");
my $back   = gethostbyaddr($packed, AF_INET);
print "$back\n";

By-name interface via the Net::hostent override — accessor methods instead of positional unpacking:

use Net::hostent;
my $h = gethostbyname("www.perl.org");
print $h->name, " ", join(",", @{$h->aliases}), "\n";

Edge cases#

  • Always call in scalar context when you want “the IP”. The list-context form is never what a quick resolver wants and allocates four extra return values. The upstream docs flag this explicitly: “Make sure gethostbyname is called in SCALAR context and that its return value is checked for definedness.”

  • Check for undef on the scalar form. A failed lookup returns undef, not an empty string. A literal 0.0.0.0 address, by contrast, is a valid four-byte packed string and stringifies to the zero byte sequence, not to undef.

  • @addrs may be empty in list context even when the first four return values are defined — some resolvers produce a record with no addresses. Always iterate, don’t index [0] blindly.

  • Aliases are one scalar, not a list. $aliases is a single space-separated string. Split on whitespace if you need a list.

  • Numeric IP strings are accepted. Passing "127.0.0.1" returns the packed form of that address without a DNS round-trip — the resolver short-circuits numeric input.

  • IPv6. gethostbyname queries only the IPv4 (AF_INET) address family. For dual-stack resolution use Socket::getaddrinfo, which returns records for every address family the host offers.

  • 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 resolution should use Socket::getaddrinfo.

  • h_errno vs $!. DNS failures set h_errno (exposed via $?), not errno / $!. Checking $! after a failed gethostbyname is meaningless.

Differences from upstream#

Fully compatible with upstream Perl 5.42.

See also#

  • gethostbyaddr — the reverse lookup: packed address → host record

  • gethostent — iterate every entry in the host database instead of looking up one name

  • sethostent — rewind the host iterator and control whether the file stays open across lookups

  • Socket::inet_ntoa — turn the packed scalar-context result into a dotted-quad string

  • Socket::inet_aton — the pure name-to-packed helper when you don’t need the full host record

  • unpack — decode the packed address manually when Socket is not available