Notes:
- getnameinfo() gets a hostname and a service name, so it's not exactly the same as gethostbyaddr()
- although the docs imply you need to enter a port, that's just to get the local service name. If you set it as undef then you can ignore any service
# 1, old deprecated way
use Socket; # gethostbyaddr, inet_aton, AF_INET
sub ip_address_to_host {
my ( $self, $ip_address ) = @_;
my ($hostname) = gethostbyaddr(
inet_aton($ip_address),
AF_INET,
);
return $hostname;
}
# 2, newer better way
use Socket qw(AF_INET inet_pton getnameinfo sockaddr_in);
sub ip_address_to_host {
my ( $self, $ip_address ) = @_;
my $port = undef;
my $socket_address = sockaddr_in($port, inet_pton(AF_INET, $ip_address));
my $flags = 0;
my $xflags = 0;
my ($error, $hostname, $servicename) = getnameinfo($socket_address, $flags, $xflags);
return $hostname;
}
# 3, best way - that only uses DNS and not /etc/hosts first
use Net::DNS;
sub ip_address_to_host {
my ( $self, $ip_address ) = @_;
my $res = Net::DNS::Resolver->new;
my $target_ip = join('.', reverse split(/\./, $ip_address)).".in-addr.arpa";
my $query = $res->query("$target_ip", "PTR") // return;
my $answer = ($query->answer)[0] // return;
my $hostname = $answer->rdatastr;
return $hostname;
}
# 4, the code golf way (no validation) - by Mark B
perl -le 'use Net::DNS::Resolver; print ((Net::DNS::Resolver->new()->query("10.232.32.158","PTR")->answer)[0]->ptrdname);'