3

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.

Sushant
  • 379
  • 3
  • 14

1 Answers1

2

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

LeoNerd
  • 8,344
  • 1
  • 29
  • 36
  • use IO::Socket::IP -register; my $sock = IO::Socket->new( Domain => PF_INET6, LocalHost => "::1", Listen => 1, ) or die "Cannot create socket - $@\n"; print "Created a socket of type " . ref($sock) . "\n"; With the above code, I get following output: c:\Perl\bin>perl c:\iosockip.pl Cannot create socket - no address associated with nodename – Sushant Aug 21 '12 at 11:26
  • Firstly, I suggested an RT ticket, rather than here. Secondly: LocalHost => "::1" will do exactly that, bind it to localhost, presuming there is one. That isn't the wildcard address, which you'd get by LocalHost => "::", which in any case is the default. Furthermore, you didn't specify a port. – LeoNerd Aug 21 '12 at 11:29
  • Thanks for the response, I'll do it with an RT ticket. Just a little background, I missed in my last comment. I am using perl 5.14.2 (ActiveState), then installed Socket, Socket::GetAddrInfo , IO::Socket::IP on it using ppm and just tried a sample program mentioned here : http://search.cpan.org/~pevans/IO-Socket-IP-0.17/lib/IO/Socket/IP.pm (mentioned in last comment); being new to perl I am not sure what I am missing – Sushant Aug 21 '12 at 11:39
  • @res = getaddrinfo('', 3786, AF_UNSPEC, SOCK_STREAM,0, AI_PASSIVE); instead of just getaddrinfo('', 3786, AF_UNSPEC, SOCK_STREAM); (in the question) solved my problem about Socket6 , thanks a lot – Sushant Aug 21 '12 at 12:28
  • Incidentally you probably want to migrate away from Socket6 onto plain Socket, because getaddrinfo() in Socket is now core. – LeoNerd Aug 21 '12 at 13:05
  • Yes, it is better to use the core, but unfortunately getaddrinfo() didn't work for me (maybe some of my bad, I am trying to figure out) on my windows box, though on linux it is working perfectly. I have created https://rt.cpan.org/Public/Bug/Display.html?id=79110 for the same, I would be very happy to use IO::Socket::IP uniformly. – Sushant Aug 21 '12 at 13:37