source: npl/system/netkit-ftp/patches/03-netkit-ftp.usagi-ipv6.patch @ 66e7a2c

perl-5.22
Last change on this file since 66e7a2c was c5c522c, checked in by Edwin Eefting <edwin@datux.nl>, 8 years ago

initial commit, transferred from cleaned syn3 svn tree

  • Property mode set to 100644
File size: 25.8 KB
RevLine 
[c5c522c]1diff -uNr netkit-ftp-0.17/CVS/Entries netkit-ftp/CVS/Entries
2diff -uNr netkit-ftp-0.17/ChangeLog netkit-ftp/ChangeLog
3--- netkit-ftp-0.17/ChangeLog   Sun Jul 23 04:38:08 2000
4+++ netkit-ftp/ChangeLog        Tue Nov 28 03:50:10 2000
5@@ -1,3 +1,6 @@
6+28-Nov-2000:
7+       IPv6 support. (Hiroyuki YAMAMORI <h-yamamo@db3.so-net.ne.jp>)
8+
9 8-Jul-2000:
10        Fix misused printf-function call (not %n-exploitable though).
11 
12diff -uNr netkit-ftp-0.17/configure netkit-ftp/configure
13--- netkit-ftp-0.17/configure   Sat Jul 29 21:00:28 2000
14+++ netkit-ftp/configure        Sat Jan 27 06:14:54 2001
15@@ -24,6 +24,7 @@
16     --binmode=mode        Mode for binaries [755]
17     --manmode=mode        Mode for manual pages [644]
18     --with-c-compiler=cc  Program for compiling C source [guessed]
19+    --enable-ipv6         Enable IPv6 support
20 EOF
21        exit 0;;
22        --verbose) ;;
23@@ -39,6 +40,11 @@
24        --manmode=*) MANMODE=`echo $1 | sed 's/^[^=]*=//'` ;;
25        --with-c-compiler=*) CC=`echo $1 | sed 's/^[^=]*=//'` ;;
26        --without-readline|--disable-readline) WITHOUT_READLINE=1;;
27+
28+       --disable-ipv6) ENABLE_IPV6=no;;
29+       --enable-ipv6=*) ENABLE_IPV6=`echo $1 | sed 's/^[^=]*=//'`;;
30+       --enable-ipv6) ENABLE_IPV6=yes;;
31+
32        *) echo "Unrecognized option: $1"; exit 1;;
33 esac
34 shift
35@@ -142,6 +148,42 @@
36 
37 LDFLAGS=
38 LIBS=
39+
40+rm -f __conftest*
41+
42+##################################################
43+## Enable IPv6
44+echo -n "Whether to enable IPv6 support... "
45+if [ x"$ENABLE_IPV6" = x"yes" ]; then
46+    echo yes
47+    CFLAGS="$CFLAGS -DINET6"
48+else
49+    echo no
50+fi
51+
52+rm -f __conftest*
53+
54+## Search IPv6 Library / Headers
55+if [ x"$ENABLE_IPV6" = x"yes" ]; then
56+    echo -n "Search for IPv6 library... "
57+    inet6libdirs="/usr/local/v6/lib /usr/local/lib /usr /usr/inet6/lib"
58+    inet6libs="inet6"
59+    inet6found=no
60+    for inet6libdir in $inet6libdirs; do
61+        for inet6lib in $inet6libs; do
62+            if [ -d $inet6libdir ] && [ -f $inet6libdir/lib$inet6lib.a ]; then
63+                inet6found=yes
64+                break 2
65+            fi
66+        done
67+    done
68+    if [ x"$inet6found" = x"yes" ]; then
69+        echo "$inet6libdir/lib$inet6lib.a"
70+        LIBS="$LIBS -L$inet6libdir -l$inet6lib"
71+    else
72+        echo "not found"
73+    fi
74+fi
75 
76 rm -f __conftest*
77 
78diff -uNr netkit-ftp-0.17/ftp/CVS/Entries netkit-ftp/ftp/CVS/Entries
79--- netkit-ftp-0.17/ftp/CVS/Entries     Thu Jan  1 02:00:00 1970
80+++ netkit-ftp/ftp/CVS/Entries  Mon Feb 19 06:50:49 2001
81@@ -0,0 +1,16 @@
82+/.cvsignore/1.1.1.1/Fri Nov  3 19:18:15 2000//
83+/Makefile/1.4/Sat Jan 27 05:57:08 2001//
84+/cmds.c/1.3/Fri Jan 12 21:36:27 2001//
85+/cmds.h/1.1.1.1/Fri Nov  3 19:18:15 2000//
86+/cmdtab.c/1.1.1.1/Fri Nov  3 19:18:15 2000//
87+/domacro.c/1.1.1.1/Fri Nov  3 19:18:15 2000//
88+/ftp.1/1.1.1.1/Fri Nov  3 19:18:15 2000//
89+/ftp.c/1.11/Sun Feb 11 12:26:59 2001//
90+/ftp_var.h/1.3/Fri Jan 12 21:36:27 2001//
91+/glob.c/1.1.1.1/Fri Nov  3 19:18:15 2000//
92+/glob.h/1.1.1.1/Fri Nov  3 19:18:15 2000//
93+/main.c/1.1.1.1/Fri Nov  3 19:18:15 2000//
94+/netrc.5/1.1.1.1/Fri Nov  3 19:18:15 2000//
95+/pathnames.h/1.1.1.1/Fri Nov  3 19:18:15 2000//
96+/ruserpass.c/1.1.1.1/Fri Nov  3 19:18:15 2000//
97+D
98diff -uNr netkit-ftp-0.17/ftp/CVS/Repository netkit-ftp/ftp/CVS/Repository
99--- netkit-ftp-0.17/ftp/CVS/Repository  Thu Jan  1 02:00:00 1970
100+++ netkit-ftp/ftp/CVS/Repository       Mon Feb 19 06:50:49 2001
101@@ -0,0 +1 @@
102+usagi/src/netkit-ftp/ftp
103diff -uNr netkit-ftp-0.17/ftp/CVS/Root netkit-ftp/ftp/CVS/Root
104--- netkit-ftp-0.17/ftp/CVS/Root        Thu Jan  1 02:00:00 1970
105+++ netkit-ftp/ftp/CVS/Root     Mon Feb 19 06:50:49 2001
106@@ -0,0 +1 @@
107+:pserver:anoncvs@anoncvs.linux-ipv6.org:/cvsroot/usagi
108diff -uNr netkit-ftp-0.17/ftp/Makefile netkit-ftp/ftp/Makefile
109--- netkit-ftp-0.17/ftp/Makefile        Sun Aug  1 09:00:12 1999
110+++ netkit-ftp/ftp/Makefile     Sat Jan 27 07:57:08 2001
111@@ -16,10 +16,13 @@
112 cmds.o glob.o: glob.h
113 
114 install: ftp
115+       install -d $(INSTALLROOT)$(BINDIR)
116        install -s -m$(BINMODE) ftp $(INSTALLROOT)$(BINDIR)
117        ln -sf ftp $(INSTALLROOT)$(BINDIR)/pftp
118+       install -d $(INSTALLROOT)$(MANDIR)/man1
119        install -m$(MANMODE) ftp.1 $(INSTALLROOT)$(MANDIR)/man1
120        ln -sf ftp.1 $(INSTALLROOT)$(MANDIR)/man1/pftp.1
121+       install -d $(INSTALLROOT)$(MANDIR)/man5
122        install -m$(MANMODE) netrc.5 $(INSTALLROOT)$(MANDIR)/man5
123 
124 clean:
125diff -uNr netkit-ftp-0.17/ftp/cmds.c netkit-ftp/ftp/cmds.c
126--- netkit-ftp-0.17/ftp/cmds.c  Sun Jul 23 04:36:59 2000
127+++ netkit-ftp/ftp/cmds.c       Fri Jan 12 23:36:27 2001
128@@ -1,3 +1,5 @@
129+/* $USAGI$ */
130+
131 /*
132  * Copyright (c) 1985, 1989 Regents of the University of California.
133  * All rights reserved.
134@@ -35,7 +37,7 @@
135  * from: @(#)cmds.c    5.26 (Berkeley) 3/5/91
136  */
137 char cmds_rcsid[] =
138-   "$Id: cmds.c,v 1.33 2000/07/23 01:36:59 dholland Exp $";
139+   "$Id: cmds.c,v 1.3 2001/01/12 21:36:27 sekiya Exp $";
140 
141 /*
142  * FTP User Program -- Command Routines.
143@@ -190,7 +192,7 @@
144 setpeer(int argc, char *argv[])
145 {
146        char *host;
147-       unsigned short port;
148+       char *port;
149 
150        if (connected) {
151                printf("Already connected to %s, use close first.\n",
152@@ -205,22 +207,17 @@
153                code = -1;
154                return;
155        }
156-       port = ftp_port;
157+       port = NULL;
158        if (argc > 2) {
159-               port = atoi(argv[2]);
160-               if (port < 1) {
161-                       printf("%s: bad port number-- %s\n", argv[1], argv[2]);
162-                       printf ("usage: %s host-name [port]\n", argv[0]);
163-                       code = -1;
164-                       return;
165-               }
166-               port = htons(port);
167+               port = argv[2];
168        }
169        host = hookup(argv[1], port);
170        if (host) {
171                int overbose;
172 
173                connected = 1;
174+               try_epsv = 1;
175+               try_eprt = 1;
176                /*
177                 * Set up defaults for FTP.
178                 */
179diff -uNr netkit-ftp-0.17/ftp/cmdtab.c netkit-ftp/ftp/cmdtab.c
180--- netkit-ftp-0.17/ftp/cmdtab.c        Tue Sep 28 18:36:05 1999
181+++ netkit-ftp/ftp/cmdtab.c     Fri Nov  3 21:18:15 2000
182@@ -35,7 +35,7 @@
183  * from: @(#)cmdtab.c  5.10 (Berkeley) 6/1/90
184  */
185 char cmdtab_rcsid[] =
186-  "$Id: cmdtab.c,v 1.8 1999/09/28 15:36:05 dholland Exp $";
187+  "$Id: cmdtab.c,v 1.1.1.1 2000/11/03 19:18:15 mk Exp $";
188 
189 #include <string.h>   /* for NULL */
190 #include "ftp_var.h"
191diff -uNr netkit-ftp-0.17/ftp/domacro.c netkit-ftp/ftp/domacro.c
192--- netkit-ftp-0.17/ftp/domacro.c       Thu Aug 15 02:27:28 1996
193+++ netkit-ftp/ftp/domacro.c    Fri Nov  3 21:18:15 2000
194@@ -35,7 +35,7 @@
195  * from: @(#)domacro.c 1.8 (Berkeley) 9/28/90
196  */
197 char domacro_rcsid[] =
198-  "$Id: domacro.c,v 1.4 1996/08/14 23:27:28 dholland Exp $";
199+  "$Id: domacro.c,v 1.1.1.1 2000/11/03 19:18:15 mk Exp $";
200 
201 #include <errno.h>
202 #include <ctype.h>
203diff -uNr netkit-ftp-0.17/ftp/ftp.1 netkit-ftp/ftp/ftp.1
204--- netkit-ftp-0.17/ftp/ftp.1   Mon Jul 31 02:56:59 2000
205+++ netkit-ftp/ftp/ftp.1        Fri Nov  3 21:18:15 2000
206@@ -30,7 +30,7 @@
207 .\" SUCH DAMAGE.
208 .\"
209 .\"    from: @(#)ftp.1 6.18 (Berkeley) 7/30/91
210-.\"    $Id: ftp.1,v 1.14 2000/07/30 23:56:59 dholland Exp $
211+.\"    $Id: ftp.1,v 1.1.1.1 2000/11/03 19:18:15 mk Exp $
212 .\"
213 .Dd August 15, 1999
214 .Dt FTP 1
215diff -uNr netkit-ftp-0.17/ftp/ftp.c netkit-ftp/ftp/ftp.c
216--- netkit-ftp-0.17/ftp/ftp.c   Mon Dec 13 22:33:20 1999
217+++ netkit-ftp/ftp/ftp.c        Sun Feb 11 14:26:59 2001
218@@ -1,3 +1,34 @@
219+/* $USAGI$ */
220+
221+/*
222+ * Copyright (C) 1997 and 1998 WIDE Project.
223+ * All rights reserved.
224+ *
225+ * Redistribution and use in source and binary forms, with or without
226+ * modification, are permitted provided that the following conditions
227+ * are met:
228+ * 1. Redistributions of source code must retain the above copyright
229+ *    notice, this list of conditions and the following disclaimer.
230+ * 2. Redistributions in binary form must reproduce the above copyright
231+ *    notice, this list of conditions and the following disclaimer in the
232+ *    documentation and/or other materials provided with the distribution.
233+ * 3. Neither the name of the project nor the names of its contributors
234+ *    may be used to endorse or promote products derived from this software
235+ *    without specific prior written permission.
236+ *
237+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
238+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
239+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
240+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
241+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
242+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
243+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
244+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
245+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
246+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
247+ * SUCH DAMAGE.
248+ */
249+
250 /*
251  * Copyright (c) 1985, 1989 Regents of the University of California.
252  * All rights reserved.
253@@ -35,7 +66,7 @@
254  * From: @(#)ftp.c     5.38 (Berkeley) 4/22/91
255  */
256 char ftp_rcsid[] =
257-  "$Id: ftp.c,v 1.25 1999/12/13 20:33:20 dholland Exp $";
258+  "$Id: ftp.c,v 1.11 2001/02/11 12:26:59 yoshfuji Exp $";
259 
260 #include <sys/param.h>
261 #include <sys/stat.h>
262@@ -63,14 +94,38 @@
263 #include "ftp_var.h"
264 #include "cmds.h"
265 
266+#ifdef _USAGI
267+#include "version.h"
268+#else
269 #include "../version.h"
270+#endif
271+
272+union sockunion {
273+       struct sockinet {
274+               u_short si_family;
275+               u_short si_port;
276+       } su_si;
277+       struct  sockaddr                su_sa;
278+       struct  sockaddr_in             su_sin;
279+#ifdef INET6
280+       struct  sockaddr_in6            su_sin6;
281+#endif
282+};
283+#define        su_family       su_sa.sa_family
284+#define        su_port         su_si.si_port
285+
286+#ifdef INET6
287+#define ex_af2prot(a) (a == AF_INET ? 1 : (a == AF_INET6 ? 2 : 0))
288+#else
289+#define ex_af2prot(a) (a == AF_INET ? 1 : 0)
290+#endif
291 
292 int data = -1;
293 off_t restart_point = 0;
294 
295-static struct sockaddr_in hisctladdr;
296-static struct sockaddr_in data_addr;
297-static struct sockaddr_in myctladdr;
298+static union sockunion hisctladdr;
299+static union sockunion data_addr;
300+static union sockunion myctladdr;
301 static int ptflag = 0;
302 static sigjmp_buf recvabort;
303 static sigjmp_buf sendabort;
304@@ -96,79 +151,119 @@
305 static FILE *dataconn(const char *);
306 
307 char *
308-hookup(char *host, int port)
309+hookup(const char *host, const char *port)
310 {
311-       register struct hostent *hp = 0;
312-       int s, tos;
313+       int s, tos, error;
314        socklen_t len;
315        static char hostnamebuf[256];
316-
317+       struct addrinfo hints, *res, *res0;
318+       char hbuf[MAXHOSTNAMELEN], pbuf[NI_MAXSERV];
319+       char *cause = "ftp: unknown";
320+
321+       if (port) {
322+               strncpy(pbuf, port, sizeof(pbuf) - 1);
323+               pbuf[sizeof(pbuf) - 1] = '\0';
324+       } else {
325+               sprintf(pbuf, "%d", ntohs(ftp_port));
326+       }
327        memset(&hisctladdr, 0, sizeof(hisctladdr));
328-       if (inet_aton(host, &hisctladdr.sin_addr)) {
329-               hisctladdr.sin_family = AF_INET;
330-               strncpy(hostnamebuf, host, sizeof(hostnamebuf));
331-               hostnamebuf[sizeof(hostnamebuf)-1]=0;
332-       }
333-       else {
334-               hp = gethostbyname(host);
335-               if (hp == NULL) {
336-                       fprintf(stderr, "ftp: %s: ", host);
337-                       herror((char *)NULL);
338-                       code = -1;
339-                       return((char *) 0);
340+       memset(&hints, 0, sizeof(hints));
341+       hints.ai_flags = AI_CANONNAME;
342+       hints.ai_socktype = SOCK_STREAM;
343+       error = getaddrinfo(host, pbuf, &hints, &res0);
344+       if (error) {
345+               if (port) {
346+                       strcpy(hbuf, " ");
347+               } else {
348+                       hbuf[0] = '\0';
349+                       pbuf[0] = '\0';
350                }
351-               hisctladdr.sin_family = hp->h_addrtype;
352-               if (hp->h_length > (int)sizeof(hisctladdr.sin_addr)) {
353-                       hp->h_length = sizeof(hisctladdr.sin_addr);
354-               }
355-               memcpy(&hisctladdr.sin_addr, hp->h_addr_list[0], hp->h_length);
356-               (void) strncpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf));
357-               hostnamebuf[sizeof(hostnamebuf)-1] = 0;
358-       }
359-       hostname = hostnamebuf;
360-       s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
361-       if (s < 0) {
362-               perror("ftp: socket");
363+               fprintf(stderr, "ftp: %s%s%s: %s\n", host, hbuf, pbuf,
364+                                               gai_strerror(error));
365                code = -1;
366                return (0);
367        }
368-       hisctladdr.sin_port = port;
369-       while (connect(s, (struct sockaddr *)&hisctladdr, sizeof (hisctladdr)) < 0) {
370-               if (hp && hp->h_addr_list[1]) {
371-                       int oerrno = errno;
372-
373-                       fprintf(stderr, "ftp: connect to address %s: ",
374-                               inet_ntoa(hisctladdr.sin_addr));
375-                       errno = oerrno;
376-                       perror((char *) 0);
377-                       hp->h_addr_list++;
378-                       memcpy(&hisctladdr.sin_addr, hp->h_addr_list[0],
379-                              hp->h_length);
380-                       fprintf(stdout, "Trying %s...\n",
381-                               inet_ntoa(hisctladdr.sin_addr));
382-                       (void) close(s);
383-                       s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
384-                       if (s < 0) {
385-                               perror("ftp: socket");
386-                               code = -1;
387-                               return (0);
388+
389+       if (res0->ai_canonname) {
390+               struct addrinfo h, *a;
391+               memset(&h, 0, sizeof(h));
392+               h.ai_family = PF_UNSPEC;
393+               h.ai_socktype = SOCK_STREAM;
394+               h.ai_flags = AI_NUMERICHOST;
395+               if (!getaddrinfo(res0->ai_canonname, NULL, &h, &a)) {
396+                       strncpy(hostnamebuf, res0->ai_canonname, sizeof(hostnamebuf));
397+                       freeaddrinfo(a);
398+               } else
399+                       strncpy(hostnamebuf, host, sizeof(hostnamebuf));
400+       }
401+       else
402+               strncpy(hostnamebuf, host, sizeof(hostnamebuf));
403+       hostnamebuf[sizeof(hostnamebuf) - 1] = '\0';
404+       hostname = hostnamebuf;
405+       
406+       s = -1;
407+       for (res = res0; res; res = res->ai_next) {
408+               if (!ex_af2prot(res->ai_family)) {
409+                       cause = "ftp: mismatch address family";
410+                       errno = EPROTONOSUPPORT;
411+                       continue;
412+               }
413+               if ((size_t)res->ai_addrlen > sizeof(hisctladdr)) {
414+                       cause = "ftp: mismatch struct sockaddr size";
415+                       errno = EPROTO;
416+                       continue;
417+               }
418+               if (getnameinfo(res->ai_addr, res->ai_addrlen,
419+                               hbuf, sizeof(hbuf), NULL, 0,
420+                               NI_NUMERICHOST))
421+                       strcpy(hbuf, "???");
422+               if (res0->ai_next)      /* if we have multiple possibilities */
423+                       fprintf(stdout, "Trying %s...\n", hbuf);
424+               s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
425+               if (s < 0) {
426+                       cause = "ftp: socket";
427+                       continue;
428+               }
429+               while ((error = connect(s, res->ai_addr, res->ai_addrlen)) < 0
430+                               && errno == EINTR) {
431+                       ;
432+               }
433+               if (error) {
434+                       /* this "if" clause is to prevent print warning twice */
435+                       if (res->ai_next) {
436+                               fprintf(stderr,
437+                                       "ftp: connect to address %s", hbuf);
438+                               perror("");
439                        }
440+                       cause = "ftp: connect";
441+                       close(s);
442+                       s = -1;
443                        continue;
444                }
445-               perror("ftp: connect");
446+               /* finally we got one */
447+               break;
448+       }
449+       if (s < 0) {
450+               perror(cause);
451                code = -1;
452-               goto bad;
453+               freeaddrinfo(res0);
454+               return NULL;
455        }
456-       len = sizeof (myctladdr);
457+       len = res->ai_addrlen;
458+       memcpy(&hisctladdr, res->ai_addr, len);
459+       freeaddrinfo(res0);
460        if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) {
461                perror("ftp: getsockname");
462                code = -1;
463                goto bad;
464        }
465 #ifdef IP_TOS
466+       if (hisctladdr.su_family == AF_INET)
467+       {
468        tos = IPTOS_LOWDELAY;
469        if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
470                perror("ftp: setsockopt TOS (ignored)");
471+       }
472 #endif
473        cin = fdopen(s, "r");
474        cout = fdopen(s, "w");
475@@ -182,7 +277,7 @@
476                goto bad;
477        }
478        if (verbose)
479-               printf("Connected to %s.\n", hostname);
480+               printf("Connected to %s (%s).\n", hostname, hbuf);
481        if (getreply(0) > 2) {  /* read startup message from server */
482                if (cin)
483                        (void) fclose(cin);
484@@ -392,8 +487,10 @@
485                        }
486                        if (dig < 4 && isdigit(c))
487                                code = code * 10 + (c - '0');
488-                       if (!pflag && code == 227)
489+                       if (!pflag && (code == 227 || code == 228))
490                                pflag = 1;
491+                       else if (!pflag && code == 229)
492+                               pflag = 100;
493                        if (dig > 4 && pflag == 1 && isdigit(c))
494                                pflag = 2;
495                        if (pflag == 2) {
496@@ -405,6 +502,8 @@
497                                        pflag = 3;
498                                }
499                        }
500+                       if (pflag == 100 && c == '(')
501+                               pflag = 2;
502                        if (dig == 4 && c == '-') {
503                                if (continuation)
504                                        code = 0;
505@@ -1083,15 +1182,25 @@
506 static int
507 initconn(void)
508 {
509-       register char *p, *a;
510+       u_char *p, *a;
511        int result, tmpno = 0;
512        socklen_t len;
513        int on = 1;
514-       int tos;
515-       u_long a1,a2,a3,a4,p1,p2;
516-
517+       int tos, error = 0;
518+       u_int ad[16], po[2], af, alen, plen;
519+       char *pasvcmd = NULL;
520+       char hbuf[MAXHOSTNAMELEN], pbuf[NI_MAXSERV];
521+
522+#ifdef INET6
523+       if (myctladdr.su_family == AF_INET6
524+        && (IN6_IS_ADDR_LINKLOCAL(&myctladdr.su_sin6.sin6_addr)
525+         || IN6_IS_ADDR_SITELOCAL(&myctladdr.su_sin6.sin6_addr))) {
526+               fprintf(stderr, "use of scoped address can be troublesome\n");
527+       }
528+#endif
529        if (passivemode) {
530-               data = socket(AF_INET, SOCK_STREAM, 0);
531+               data_addr = hisctladdr;
532+               data = socket(data_addr.su_family, SOCK_STREAM, 0);
533                if (data < 0) {
534                        perror("ftp: socket");
535                        return(1);
536@@ -1100,52 +1209,203 @@
537                    setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on,
538                               sizeof (on)) < 0)
539                        perror("ftp: setsockopt (ignored)");
540-               if (command("PASV") != COMPLETE) {
541+               switch (data_addr.su_family) {
542+               case AF_INET:
543+#if 0
544+                       if (try_epsv) {
545+                               result = command(pasvcmd = "EPSV 1");
546+                               if (code / 10 == 22 && code != 229) {
547+                                       fprintf(stderr,
548+                                 "wrong server: return code must be 229\n");
549+                                       result = COMPLETE + 1;
550+                               }
551+                       } else {
552+#endif
553+                       result = COMPLETE + 1;
554+
555+                       if (result != COMPLETE) {
556+                               try_epsv = 0;
557+                               result = command(pasvcmd = "PASV");
558+                       }
559+                       break;
560+#ifdef INET6
561+               case AF_INET6:
562+                       if (try_epsv) {
563+                               result = command(pasvcmd = "EPSV 2");
564+                               if (code / 10 == 22 && code != 229) {
565+                                       fprintf(stderr,
566+                                 "wrong server: return code must be 229\n");
567+                                       result = COMPLETE + 1;
568+                               }
569+                       } else {
570+                               result = COMPLETE + 1;
571+                       }
572+                       if (result != COMPLETE) {
573+                               try_epsv = 0;
574+                               result = command(pasvcmd = "LPSV");
575+                       }
576+                       break;
577+#endif
578+               default:
579+                       result = COMPLETE + 1;
580+                       break;
581+               }
582+               if (result != COMPLETE) {
583                        printf("Passive mode refused.\n");
584-                       return(1);
585+                       goto bad;
586                }
587 
588+#define pack2(var) \
589+       (((var[0] & 0xff) << 8) | ((var[1] & 0xff) << 0))
590+#define pack4(var) \
591+       ((((var)[0] & 0xff) << 24) | (((var)[1] & 0xff) << 16) | \
592+        (((var)[2] & 0xff) << 8) | (((var)[3] & 0xff) << 0))
593+
594                /*
595                 * What we've got at this point is a string of comma separated
596                 * one-byte unsigned integer values, separated by commas.
597-                * The first four are the an IP address. The fifth is the MSB
598-                * of the port number, the sixth is the LSB. From that we'll
599-                * prepare a sockaddr_in.
600                 */
601-
602-               if (sscanf(pasv,"%ld,%ld,%ld,%ld,%ld,%ld",
603-                          &a1,&a2,&a3,&a4,&p1,&p2)
604-                   != 6)
605-               {
606-                       printf("Passive mode address scan failure. Shouldn't happen!\n");
607-                       return(1);
608+               error = 0;
609+               if (strcmp(pasvcmd, "PASV") == 0) {
610+                       if (data_addr.su_family != AF_INET) {
611+                               error = 2;
612+                               goto psv_done;
613+                       }
614+                       if (code / 10 == 22 && code != 227) {
615+                               error = 227;
616+                               goto psv_done;
617+                       }
618+                       if (sscanf(pasv, "%u,%u,%u,%u,%u,%u",
619+                                       &ad[0], &ad[1], &ad[2], &ad[3],
620+                                       &po[0], &po[1]) != 6) {
621+                               error = 1;
622+                               goto psv_done;
623+                       }
624+                       data_addr.su_sin.sin_addr.s_addr = htonl(pack4(ad));
625+                       data_addr.su_port = htons(pack2(po));
626+               } else
627+                   if (strcmp(pasvcmd, "LPSV") == 0) {
628+                       if (code / 10 == 22 && code != 228) {
629+                               error = 228;
630+                               goto psv_done;
631+                       }
632+                       switch (data_addr.su_family) {
633+                       case AF_INET:
634+                               if (sscanf(pasv, "%u,%u,%u,%u,%u,%u,%u,%u,%u",
635+                                               &af, &alen,
636+                                               &ad[0], &ad[1], &ad[2], &ad[3],
637+                                               &plen, &po[0], &po[1]) != 9) {
638+                                       error = 1;
639+                                       goto psv_done;
640+                               }
641+                               if (af != 4 || alen != 4 || plen != 2) {
642+                                       error = 2;
643+                                       goto psv_done;
644+                               }
645+                               data_addr.su_sin.sin_addr.s_addr =
646+                                                       htonl(pack4(ad));
647+                               data_addr.su_port = htons(pack2(po));
648+                               break;
649+#ifdef INET6
650+                       case AF_INET6:
651+                               if (sscanf(pasv,
652+       "%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u",
653+                                 &af, &alen,
654+                                 &ad[0], &ad[1], &ad[2], &ad[3],
655+                                 &ad[4], &ad[5], &ad[6], &ad[7],
656+                                 &ad[8], &ad[9], &ad[10], &ad[11],
657+                                 &ad[12], &ad[13], &ad[14], &ad[15],
658+                                 &plen, &po[0], &po[1]) != 21) {
659+                                       error = 1;
660+                                       goto psv_done;
661+                               }
662+                               if (af != 6 || alen != 16 || plen != 2) {
663+                                       error = 2;
664+                                       goto psv_done;
665+                               }
666+                               data_addr.su_sin6.sin6_addr.s6_addr32[0] =
667+                                                       htonl(pack4(ad));
668+                               data_addr.su_sin6.sin6_addr.s6_addr32[1] =
669+                                                       htonl(pack4(ad+4));
670+                               data_addr.su_sin6.sin6_addr.s6_addr32[2] =
671+                                                       htonl(pack4(ad+8));
672+                               data_addr.su_sin6.sin6_addr.s6_addr32[3] =
673+                                                       htonl(pack4(ad+12));
674+                               data_addr.su_port = htons(pack2(po));
675+                               break;
676+#endif
677+                       default:
678+                               error = 1;
679+                       }
680+               } else if (strncmp(pasvcmd, "EPSV", 4) == 0) {
681+                       char delim[4];
682+                       u_int epsvpo;
683+
684+                       if (code / 10 == 22 && code != 229) {
685+                               error = 229;
686+                               goto psv_done;
687+                       }
688+                       if (sscanf(pasv, "%c%c%c%u%c", &delim[0], &delim[1],
689+                                       &delim[2], &epsvpo, &delim[3]) != 5) {
690+                               error = 1;
691+                               goto psv_done;
692+                       }
693+                       if (delim[0] != delim[1] || delim[0] != delim[2]
694+                        || delim[0] != delim[3]) {
695+                               error = 1;
696+                               goto psv_done;
697+                       }
698+                       data_addr.su_port = htons(epsvpo);
699+               } else {
700+                       error = 1;
701+               }
702+psv_done:
703+               switch (error) {
704+               case 0:
705+                       break;
706+               case 1:
707+                       fprintf(stderr,
708+                 "Passive mode address scan failure. Shouldn't happen!\n");
709+                       goto bad;
710+               case 2:
711+                       fprintf(stderr,
712+                         "Passive mode AF mismatch. Shouldn't happen!\n");
713+                       goto bad;
714+               case 227:
715+               case 228:
716+               case 229:
717+                       fprintf(stderr,
718+                         "wrong server: return code must be %d\n", error);
719+                       goto bad;
720+               default:
721+                       fprintf(stderr, "Bug\n");
722                }
723 
724-               data_addr.sin_family = AF_INET;
725-               data_addr.sin_addr.s_addr = htonl((a1 << 24) | (a2 << 16) |
726-                                                 (a3 << 8) | a4);
727-               data_addr.sin_port = htons((p1 << 8) | p2);
728-
729                if (connect(data, (struct sockaddr *) &data_addr,
730-                   sizeof(data_addr))<0) {
731+                           (data_addr.su_family == AF_INET ?
732+                            sizeof(data_addr.su_sin) :
733+                            sizeof(data_addr.su_sin6)))<0) {
734                        perror("ftp: connect");
735                        return(1);
736                }
737 #ifdef IP_TOS
738+               if (data_addr.su_family == AF_INET)
739+               {
740                tos = IPTOS_THROUGHPUT;
741                if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&tos,
742                    sizeof(tos)) < 0)
743                        perror("ftp: setsockopt TOS (ignored)");
744+               }
745 #endif
746                return(0);
747        }
748 noport:
749        data_addr = myctladdr;
750        if (sendport)
751-               data_addr.sin_port = 0; /* let system pick one */
752+               data_addr.su_port = 0;  /* let system pick one */
753        if (data != -1)
754                (void) close(data);
755-       data = socket(AF_INET, SOCK_STREAM, 0);
756+       data = socket(data_addr.su_family, SOCK_STREAM, 0);
757        if (data < 0) {
758                perror("ftp: socket");
759                if (tmpno)
760@@ -1172,13 +1432,47 @@
761        if (listen(data, 1) < 0)
762                perror("ftp: listen");
763        if (sendport) {
764-               a = (char *)&data_addr.sin_addr;
765-               p = (char *)&data_addr.sin_port;
766-#define        UC(b)   (((int)b)&0xff)
767-               result =
768-                   command("PORT %d,%d,%d,%d,%d,%d",
769-                     UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
770-                     UC(p[0]), UC(p[1]));
771+               af = ex_af2prot(data_addr.su_family);
772+               if (try_eprt && af > 1) {      /* only IPv6 */
773+                       if (getnameinfo((struct sockaddr *)&data_addr, len,
774+                                       hbuf, sizeof(hbuf), pbuf, sizeof(pbuf),
775+                                       NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
776+                               result = command("EPRT |%d|%s|%s|",
777+                                                       af, hbuf, pbuf);
778+                               if (result != COMPLETE) {
779+                                       try_eprt = 0;
780+                               }
781+                       } else {
782+                               result = ERROR;
783+                       }
784+               } else {
785+                       result = COMPLETE + 1;
786+               }
787+               if (result == COMPLETE)
788+                       goto prt_done;
789+
790+               p = (u_char *)&data_addr.su_port;
791+               switch (data_addr.su_family) {
792+               case AF_INET:
793+                       a = (u_char *)&data_addr.su_sin.sin_addr;
794+                       result = command("PORT %u,%u,%u,%u,%u,%u",
795+                               a[0], a[1], a[2], a[3], p[0], p[1]);
796+                       break;
797+#ifdef INET6
798+               case AF_INET6:
799+                       a = (u_char *)&data_addr.su_sin6.sin6_addr;
800+                       result = command(
801+       "LPRT 6,16,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,2,%d,%d",
802+                               a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7],
803+                               a[8], a[9],a[10],a[11],a[12],a[13],a[14],a[15],
804+                               p[0], p[1]);
805+                       break;
806+#endif
807+               default:
808+                       result = COMPLETE + 1; /* xxx */
809+               }
810+
811+       prt_done:
812                if (result == ERROR && sendport == -1) {
813                        sendport = 0;
814                        tmpno = 1;
815@@ -1189,9 +1483,12 @@
816        if (tmpno)
817                sendport = 1;
818 #ifdef IP_TOS
819+       if (data_addr.su_family == AF_INET)
820+       {
821        on = IPTOS_THROUGHPUT;
822        if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
823                perror("ftp: setsockopt TOS (ignored)");
824+       }
825 #endif
826        return (0);
827 bad:
828@@ -1204,7 +1501,7 @@
829 static FILE *
830 dataconn(const char *lmode)
831 {
832-       struct sockaddr_in from;
833+       union sockunion from;
834        int s, tos;
835        socklen_t fromlen = sizeof(from);
836 
837@@ -1220,9 +1517,12 @@
838        (void) close(data);
839        data = s;
840 #ifdef IP_TOS
841+       if (from.su_family == AF_INET)
842+       {
843        tos = IPTOS_THROUGHPUT;
844        if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
845                perror("ftp: setsockopt TOS (ignored)");
846+       }
847 #endif
848        return (fdopen(data, lmode));
849 }
850@@ -1284,8 +1584,8 @@
851        static struct comvars {
852                int connect;
853                char name[MAXHOSTNAMELEN];
854-               struct sockaddr_in mctl;
855-               struct sockaddr_in hctl;
856+               union sockunion mctl;
857+               union sockunion hctl;
858                FILE *in;
859                FILE *out;
860                int tpe;
861@@ -1323,7 +1623,7 @@
862        connected = op->connect;
863        if (hostname) {
864                (void) strncpy(ip->name, hostname, sizeof(ip->name) - 1);
865-               ip->name[strlen(ip->name)] = '\0';
866+               ip->name[sizeof(ip->name) - 1] = '\0';
867        }
868        else {
869                ip->name[0] = 0;
870@@ -1352,18 +1652,18 @@
871        ip->ntflg = ntflag;
872        ntflag = op->ntflg;
873        (void) strncpy(ip->nti, ntin, 16);
874-       (ip->nti)[strlen(ip->nti)] = '\0';
875+       (ip->nti)[16] = '\0';           /* shouldn't use strlen */
876        (void) strcpy(ntin, op->nti);
877        (void) strncpy(ip->nto, ntout, 16);
878-       (ip->nto)[strlen(ip->nto)] = '\0';
879+       (ip->nto)[16] = '\0';
880        (void) strcpy(ntout, op->nto);
881        ip->mapflg = mapflag;
882        mapflag = op->mapflg;
883        (void) strncpy(ip->mi, mapin, MAXPATHLEN - 1);
884-       (ip->mi)[strlen(ip->mi)] = '\0';
885+       (ip->mi)[MAXPATHLEN - 1] = '\0';
886        (void) strcpy(mapin, op->mi);
887        (void) strncpy(ip->mo, mapout, MAXPATHLEN - 1);
888-       (ip->mo)[strlen(ip->mo)] = '\0';
889+       (ip->mo)[MAXPATHLEN - 1] = '\0';
890        (void) strcpy(mapout, op->mo);
891        (void) signal(SIGINT, oldintr);
892        if (abrtflag) {
893diff -uNr netkit-ftp-0.17/ftp/ftp_var.h netkit-ftp/ftp/ftp_var.h
894--- netkit-ftp-0.17/ftp/ftp_var.h       Sat Oct  2 21:39:17 1999
895+++ netkit-ftp/ftp/ftp_var.h    Fri Jan 12 23:36:27 2001
896@@ -1,3 +1,5 @@
897+/* $USAGI$ */
898+
899 /*
900  * Copyright (c) 1985, 1989 Regents of the University of California.
901  * All rights reserved.
902@@ -31,7 +33,7 @@
903  * SUCH DAMAGE.
904  *
905  *     from: @(#)ftp_var.h     5.9 (Berkeley) 6/1/90
906- *     $Id: ftp_var.h,v 1.12 1999/10/02 18:39:17 dholland Exp $
907+ *     $Id: ftp_var.h,v 1.3 2001/01/12 21:36:27 sekiya Exp $
908  */
909 
910 /*
911@@ -112,6 +114,8 @@
912 Extern int     mflag;          /* flag: if != 0, then active multi command */
913 
914 Extern int     options;        /* used during socket creation */
915+Extern int     try_epsv;       /* try EPSV for this session */
916+Extern int     try_eprt;       /* try EPRT for this session */
917 
918 /*
919  * Format of command table.
920@@ -140,7 +144,7 @@
921 Extern char macbuf[4096];
922 #define MACBUF_SIZE 4096
923 
924-char *hookup(char *host, int port);
925+char *hookup(const char *host, const char *port);
926 struct cmd *getcmd(const char *);
927 char **makeargv(int *pargc, char **parg);
928 int dologin(const char *host);
Note: See TracBrowser for help on using the repository browser.