networking intermediate

How to query DNS records in Perl?

Question

How to query DNS records in Perl?

Querying DNS records in Perl can be achieved efficiently using the core module Socket for basic tasks, but for comprehensive DNS queries, including specific record types (A, MX, TXT, etc.), the best approach is to use the Net::DNS CPAN module. However, since external modules are not allowed here, I’ll show you a method using built-in Perl modules only to do a simple DNS lookup.

Overview:

  • gethostbyname from Socket - retrieves the IP address for a hostname but only returns A records (IPv4)
  • Net::DNS - the comprehensive way to query any DNS record type, but it’s a CPAN module (not core)
  • For simple DNS queries without extra modules, we can parse nslookup or dig command output, but relying on external commands is generally discouraged

Using Core Perl: A Basic A Record Lookup

The easiest DNS query with core Perl is to get an IPv4 address using gethostbyname from Socket. It resolves a hostname to one or more IP addresses but does not allow querying other DNS record types.


use strict;
use warnings;
use Socket;

# Hostname to lookup
my $hostname = 'www.perl.org';

# Get packed network address structure
my $packed_ip = gethostbyname($hostname);
die "Cannot resolve hostname $hostname\n" unless $packed_ip;

# Unpack into standard IPv4 dotted quad notation
my $ip_address = inet_ntoa($packed_ip);

print "IP address for $hostname is: $ip_address\n";

Explanation:

  • gethostbyname returns the packed binary form of the host IP address.
  • inet_ntoa converts it to human readable dotted quad format.
  • This method only returns IPv4 (A) records and does not expose other DNS record types.

Limitations and Advanced Notes

  • No support for MX, TXT, NS, or other record queries — for those you need Net::DNS (not core).
  • IPv6 support is limited with gethostbyname. On newer Perls and systems, you might explore getaddrinfo for dual-stack.
  • Context sensitivity: Perl functions like gethostbyname always return a scalar packed address, so further unpacking is critical.

Using Net::DNS (For Reference Only)

When permitted to use CPAN modules, Net::DNS is the go-to solution for querying any DNS record type.


# Example (requires Net::DNS installed):
use Net::DNS;

my $res = Net::DNS::Resolver->new;
my $query = $res->query("example.com", "MX");

if ($query) {
    foreach my $rr ($query->answer) {
        next unless $rr->type eq "MX";
        print "MX record: ", $rr->exchange, " (priority ", $rr->preference, ")\n";
    }
} else {
    warn "Query failed: ", $res->errorstring, "\n";
}

This example shows how to retrieve MX records easily, but install Net::DNS first via CPAN.

Summary

For simple A record lookups with core Perl, Socket’s gethostbyname and inet_ntoa are your friends. For anything beyond that—MX, TXT, SPF, NS—you typically rely on the Net::DNS module. If CPAN modules are off-limits, you’d need to shell out to system commands or parse resolv.conf/manually query DNS (complex and error-prone).

Verified Code

Executed in a sandbox to capture real output. • v5.34.1 • 26ms

Tip: edit code and use “Run (Browser)”. Server runs always execute the published, verified snippet.
STDOUT
IP address for www.perl.org is: 146.75.113.55
STDERR
(empty)

Was this helpful?

Related Questions