Search code examples
perlipv6getaddrinfo

how to get wildcard address using getaddrinfo


Cross post on : http://www.perlmonks.org/?node_id=988678

I am new to perl. I am trying to fetch all the wildcard interfaces using getaddrinfo (I am using Socket6 (IO:Socket:IP somehow didn't work on my Windows box)), like:

use Socket;
use Socket6;

@res = getaddrinfo('<wildcard>', 3786, AF_UNSPEC, SOCK_STREAM);

while(scalar(@res)>=5){

    ($family, $socktype, $proto, $saddr, $canonname, @res) = @res;
    ($host, $port) = getnameinfo($saddr, NI_NUMERICHOST | NI_NUMERICSERV);
    print ("\nhost= $host port = $port");
}

I am wondering what value should I use for the placeholder , so that I'll get IPv4 as well IPv6 wildcard addresses (0.0.0.0 and ::) in the result, so that I can bind to it independent of the machine I am using (IPv4 or IPv6). In 'c' specifying a null hostname pointer does the job, for perl I tried '', undef but they return loopback addresses.


Solution

  • If it's for local binding, you'll want to supply the AI_PASSIVE hint.

    use strict;
    use warnings;
    
    use Socket qw( :addrinfo SOCK_STREAM );
    
    my ( $err, @res ) = getaddrinfo( undef, 3786, {
      socktype => SOCK_STREAM,
      flags => AI_PASSIVE,
    } );
    die $err if $err;
    
    for my $res ( @res ) {
      my ( $err, $addr, $port ) = getnameinfo( $res->{addr}, NI_NUMERICHOST|NI_NUMERICSERV );
      die $err if $err;
      print "Addr=$addr port=$port\n";
    }
    

    This prints

    $ perl gai.pl
    Addr=0.0.0.0 port=3786
    Addr=:: port=3786
    

    Also, as the author of IO::Socket::IP I'd be keen to know why it didn't work for you - perhaps you could raise it as a bug? https://rt.cpan.org/Dist/Display.html?Queue=IO-Socket-IP