swissknife has asked for the wisdom of the Perl Monks concerning the following question:

Dear Experts

i am trying to get the IP address returned by the API getaddrinfo(). i have no experience with Socket module but i found some code online and giving a try. i use the following code.

#!/usr/bin/perl use Socket; my $server = shift @ARGV; my $pip = gethostbyname($server); my $IP_add = inet_ntoa($pip); print $IP_add;

this returns the IP address of the server passed as argument.

but when i try to print the value of $pip, it returns nothing and if i try to pass the $server directly instead of $pip it gives me error. i am not able to understand when $pip has nothing in it, it works but if i pass $server which has name of server in it it gives error.

could someone explain?

Replies are listed 'Best First'.
Re: perl and getaddrinfo API
by Athanasius (Archbishop) on Apr 20, 2016 at 11:23 UTC

    Hello swissknife,

    If you display the contents of $pip using Data::Dump, say, you’ll see that it actually contains four bytes:

    #! perl use strict; use warnings; use Socket; use Data::Dump; my $server = shift @ARGV; my $pip = gethostbyname($server); dd $pip; my $IP_add = inet_ntoa($pip); print $IP_add;

    Output:

    21:17 >perl 1602_SoPW.pl perlmonks.pair.com "\xD1\xC5{\x99" 209.197.123.153 21:17 >

    If these bytes don’t appear when you print $pip, that’s likely because they happen to be unprintable.

    BTW, the documentation for Socket mentions that gethostbyname is a legacy subroutine.

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      Thanks for pointing out to problem. about the legacy subroutine i tried the new codes.
      use Socket qw(:addrinfo SOCK_RAW); my ($err, @res) = getaddrinfo($hostname, "", {socktype => SOCK_RAW}); die "Cannot getaddrinfo - $err" if $err; while( my $ai = shift @res ) { my ($err, $ipaddr) = getnameinfo($ai->{addr}, NI_NUMERICHOST, NIx +_NOSERV); die "Cannot getnameinfo - $err" if $err; print "$ipaddr\n"; }

      copied from http://perldoc.perl.org/Socket.html#(%24err%2c-%40result)-%3d-getaddrinfo-%24host%2c-%24service%2c-%5b%24hints%5d

      it gives me error "addrinfo not defined in %Socket::EXPORT_TAGS

      perl i am using is 5.8.4. is this because of perl version i am using? or it is something else?

        Perl 5.8 is very old. Whether that’s the problem I don’t know; but when I add a line defining $hostname to the code you posted:

        #! perl use strict; use warnings; use Socket qw(:addrinfo SOCK_RAW); my $hostname = 'perlmonks.pair.com'; my ($err, @res) = getaddrinfo($hostname, "", { socktype => SOCK_RAW }) +; die "Cannot getaddrinfo - $err" if $err; while (my $ai = shift @res) { my ($err, $ipaddr) = getnameinfo($ai->{addr}, NI_NUMERICHOST, NIx_ +NOSERV); die "Cannot getnameinfo - $err" if $err; print "$ipaddr\n"; }

        it works correctly on my system:

        22:41 >perl 1602_SoPW.pl 209.197.123.153 22:42 >

        (Windows 8.1 64-bit, Strawberry Perl 5.22.1, Socket v2.021.)

        Hope that helps,

        Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

        Yes, the old Perl version is the problem. The core Socket module didn't start supporting IPv6 (and the address family independent routines get*info()) until at least 5.14 or so.

        Socket is now dual-lived so you can get the latest copy from CPAN, but not sure how a new version of Socket will work on such an old Perl.

        You could try Socket6 and / or Socket::GetAddrInfo. I've used in the past and the API was a bit different than the "standard" supplied directly in the new Socket module versions.

Re: perl and getaddrinfo API
by trippledubs (Deacon) on Apr 20, 2016 at 12:53 UTC
    my @ip = map { hex($_) } map { /(..)/g } unpack("H*",$pip); print join '.',@ip;
    Since the system call gethostbyname results in a C struct, it can be unpacked.