Hello,
I have to use Net::FTP to pull out data of an IPv6 (and IPv4) FTP-server; the used code is:
#!/usr/local/bin/perl
use Net::INET6Glue;
use Net::FTP;
$username='anonymous';
$password='sisis@oclc.org';
$directory='pub';
$filename='file';
$ipaddr='::1';
# $ipaddr='fe80::250:56ff:feb6:5310%eth0';
$ftp = Net::FTP->new($ipaddr, Debug=>1, Passive=>1)
or die "Can't connect: $@\n";
$ftp->login($username, $password)
or die "Couldn't login\n";
$ftp->cwd($directory)
or die "Couldn't change directory\n";
@lines = $ftp->ls()
or die "Couldn't list dir\n";
foreach $file (@lines) {
print "file: $file\n";
}
$ftp->get($filename)
or die "Couldn't get $filename\n";
$ftp->quit()
or die "Couldn't quit\n";
exit;
If the above code is executed with localhost addr ::1, it works fine, both in Passive mode and no-Passive mode:
./ftp.pl
Net::FTP>>> Net::FTP(2.77)
Net::FTP>>> Exporter(5.66)
Net::FTP>>> Net::Cmd(2.29)
Net::FTP>>> IO::Socket::INET(1.33)
Net::FTP>>> IO::Socket(1.34)
Net::FTP>>> IO::Handle(1.33)
Net::FTP=GLOB(0x83b0060)<<< 220 FTP on srV41pl2ap01dxoh
Net::FTP=GLOB(0x83b0060)>>> USER anonymous
Net::FTP=GLOB(0x83b0060)<<< 331 Please specify the password.
Net::FTP=GLOB(0x83b0060)>>> PASS ....
Net::FTP=GLOB(0x83b0060)<<< 230 Login successful.
Net::FTP=GLOB(0x83b0060)>>> CWD pub
Net::FTP=GLOB(0x83b0060)<<< 250 Directory successfully changed.
Net::FTP=GLOB(0x83b0060)>>> EPSV
Net::FTP=GLOB(0x83b0060)<<< 229 Entering Extended Passive Mode (|||400
+81|)
Net::FTP=GLOB(0x83b0060)>>> NLST
Net::FTP=GLOB(0x83b0060)<<< 150 Here comes the directory listing.
Net::FTP=GLOB(0x83b0060)<<< 226 Directory send OK.
file: file
file: tr
Net::FTP=GLOB(0x83b0060)>>> EPSV
Net::FTP=GLOB(0x83b0060)<<< 229 Entering Extended Passive Mode (|||400
+94|)
Net::FTP=GLOB(0x83b0060)>>> RETR file
Net::FTP=GLOB(0x83b0060)<<< 150 Opening BINARY mode data connection fo
+r file (12 bytes).
Net::FTP=GLOB(0x83b0060)<<< 226 File send OK.
Net::FTP=GLOB(0x83b0060)>>> QUIT
Net::FTP=GLOB(0x83b0060)<<< 221 Goodbye.
However if I use the so called link-local addr fe80::250:56ff:feb6:5310%eth0 with the interface name %eth0 at the end, the transfer of the directory content hangs in Passive mode:
./ftp.pl
Net::FTP>>> Net::FTP(2.77)
Net::FTP>>> Exporter(5.66)
Net::FTP>>> Net::Cmd(2.29)
Net::FTP>>> IO::Socket::INET(1.33)
Net::FTP>>> IO::Socket(1.34)
Net::FTP>>> IO::Handle(1.33)
Net::FTP=GLOB(0x83b0050)<<< 220 FTP on srV41pl2ap01dxoh
Net::FTP=GLOB(0x83b0050)>>> USER anonymous
Net::FTP=GLOB(0x83b0050)<<< 331 Please specify the password.
Net::FTP=GLOB(0x83b0050)>>> PASS ....
Net::FTP=GLOB(0x83b0050)<<< 230 Login successful.
Net::FTP=GLOB(0x83b0050)>>> CWD pub
Net::FTP=GLOB(0x83b0050)<<< 250 Directory successfully changed.
Net::FTP=GLOB(0x83b0050)>>> EPSV
Net::FTP=GLOB(0x83b0050)<<< 229 Entering Extended Passive Mode (|||400
+57|)
Net::FTP=GLOB(0x83b0050)>>> NLST
and in non-Passive mode it gives an error:
./ftp.pl
Net::FTP>>> Net::FTP(2.77)
Net::FTP>>> Exporter(5.66)
Net::FTP>>> Net::Cmd(2.29)
Net::FTP>>> IO::Socket::INET(1.33)
Net::FTP>>> IO::Socket(1.34)
Net::FTP>>> IO::Handle(1.33)
Net::FTP=GLOB(0x83b0050)<<< 220 FTP on srV41pl2ap01dxoh
Net::FTP=GLOB(0x83b0050)>>> USER anonymous
Net::FTP=GLOB(0x83b0050)<<< 331 Please specify the password.
Net::FTP=GLOB(0x83b0050)>>> PASS ....
Net::FTP=GLOB(0x83b0050)<<< 230 Login successful.
Net::FTP=GLOB(0x83b0050)>>> CWD pub
Net::FTP=GLOB(0x83b0050)<<< 250 Directory successfully changed.
Can't call method "sockdomain" on an undefined value at /usr/local/sis
+is-pap/perl5.16.2/lib/site_perl/5.16.2/Net/INET6Glue/FTP.pm line 33.
It seems that at the end of the story the %eth0 at the end of the address is missed somewhere in the Perl methods (I watched the proc with strace):
bind(4, {sa_family=AF_INET6, sin6_port=htons(0), inet_pton(AF_INET6, "
+fe80::250:56ff:feb6:5310", &sin6_addr), sin6_flowinfo=0, sin6_scope_i
+d=0}, 28) = -1 EINVAL (Invalid argument)
All this is with Perl 5.16.2
Any ideas? Thanks in advance.
Matthias