Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Net::ftp && IPv6

by gurucubano (Initiate)
on Nov 11, 2014 at 08:57 UTC ( [id://1106790]=perlquestion: print w/replies, xml ) Need Help??

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

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

Replies are listed 'Best First'.
Re: Net::ftp && IPv6
by Loops (Curate) on Nov 11, 2014 at 12:43 UTC

    Hola,

    That whole %eth0 thing is new to me, never seen it used. And if you look at your strace the link-local scope id is still 0. So you're right, the %eth0 isn't being recognized. Try using "ifconfig eth0" to see what its actual scope id is listed as, and use that number after the % instead of "eth0".

      Hello, Thanks for your feedback. The ifconfig shows the interface as:
      $ /sbin/ifconfig eth0 eth0 Link encap:Ethernet HWaddr 00:50:56:B6:53:10 inet addr:10.49.22.20 Bcast:10.49.22.255 Mask:255.255.255. +0 inet6 addr: fe80::250:56ff:feb6:5310/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:12739003 errors:0 dropped:0 overruns:0 frame:0 TX packets:4630164 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:3144021160 (2998.3 Mb) TX bytes:991348328 (945.4 M +b)
      Re/ %eth0: one has to specify in the link-local addr the interface because theoretically all interfaces could have the same addr; and I think, it is fully correct, because the perl script can connect fine and can login; but only the filetransfer does not work; I assume this is somewhere an issue in th Perl methods; if you look for the addr in the strace output, you will see, tehat the $eth0 is used in all places, but only in the last BIND not:
      fgrep fe80::250:56ff:feb6:5310 tr connect(3, {sa_family=AF_INET6, sin6_port=htons(21), inet_pton(AF_INET +6, "fe80::250:56ff:feb6:5310", &sin6_addr), sin6_flowinfo=0, sin6_sco +pe_id=if_nametoindex("eth0")}, 28) = -1 EINPROGRESS (Operation now in + progress) connect(3, {sa_family=AF_INET6, sin6_port=htons(21), inet_pton(AF_INET +6, "fe80::250:56ff:feb6:5310", &sin6_addr), sin6_flowinfo=0, sin6_sco +pe_id=if_nametoindex("eth0")}, 28) = 0 getsockname(3, {sa_family=AF_INET6, sin6_port=htons(47829), inet_pton( +AF_INET6, "fe80::250:56ff:feb6:5310", &sin6_addr), sin6_flowinfo=0, s +in6_scope_id=if_nametoindex("eth0")}, [28]) = 0 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)

      Matthias

        when I do a small change (hardcoded, just for test) in Net/INET6Glue/FTP.pm:
        $ diff /usr/local/sisis-pap/perl5.16.2/lib/site_perl/5.16.2/Net/INET6G +lue/FTP.pm* 30c30 < LocalAddr => $ftp->sockhost, --- > LocalAddr => 'fe80::250:56ff:feb6:5310%eth0'
        the transfer of the data works:
        Net::FTP=GLOB(0x83b0080)<<< 150 Here comes the directory listing. Net::FTP=GLOB(0x83b0080)<<< 226 Directory send OK. file: file file: tr Net::FTP=GLOB(0x83b0080)>>> EPRT |2|fe80::250:56ff:feb6:5310|35672| Net::FTP=GLOB(0x83b0080)<<< 200 EPRT command successful. Consider usin +g EPSV. Net::FTP=GLOB(0x83b0080)>>> RETR file Net::FTP=GLOB(0x83b0080)<<< 150 Opening BINARY mode data connection fo +r file (12 bytes). Net::FTP=GLOB(0x83b0080)<<< 226 File send OK. Net::FTP=GLOB(0x83b0080)>>> QUIT Net::FTP=GLOB(0x83b0080)<<< 221 Goodbye.
        this underpins that somehow on the way down the %eth0 is droped off the $ftp->sockhost;

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1106790]
Approved by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (4)
As of 2024-04-25 22:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found