handle IPv4 TCP control connection, toward AF_INET6 socket.

this happens when you have the following line in inetd.conf,
but not with tcp4 line:
>>>ftp  stream tcp6 nowait root /usr/libexec/ftpd ftpd -ll
This commit is contained in:
itojun 1999-07-27 15:41:49 +00:00
parent b0c1735026
commit 542bd3ceb5
2 changed files with 36 additions and 11 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: ftpd.8,v 1.39 1999/07/11 20:03:41 itojun Exp $ .\" $NetBSD: ftpd.8,v 1.40 1999/07/27 15:41:49 itojun Exp $
.\" .\"
.\" Copyright (c) 1985, 1988, 1991, 1993 .\" Copyright (c) 1985, 1988, 1991, 1993
.\" The Regents of the University of California. All rights reserved. .\" The Regents of the University of California. All rights reserved.
@ -671,7 +671,7 @@ recommended.
.Pp .Pp
When running on IPv6, connection from IPv4 mapped address When running on IPv6, connection from IPv4 mapped address
.Pq IPv4 connection to IPv6 socket .Pq IPv4 connection to IPv6 socket
is not supported yet. is not very stable.
Please run two daemons, one for IPv4 and one for IPv6. Please run two daemons, one for IPv4 and one for IPv6.
.Pp .Pp
Don't create Don't create

View File

@ -1,4 +1,4 @@
/* $NetBSD: ftpd.c,v 1.67 1999/07/02 05:52:14 itojun Exp $ */ /* $NetBSD: ftpd.c,v 1.68 1999/07/27 15:41:49 itojun Exp $ */
/* /*
* Copyright (C) 1997 and 1998 WIDE Project. * Copyright (C) 1997 and 1998 WIDE Project.
@ -109,7 +109,7 @@ __COPYRIGHT(
#if 0 #if 0
static char sccsid[] = "@(#)ftpd.c 8.5 (Berkeley) 4/28/95"; static char sccsid[] = "@(#)ftpd.c 8.5 (Berkeley) 4/28/95";
#else #else
__RCSID("$NetBSD: ftpd.c,v 1.67 1999/07/02 05:52:14 itojun Exp $"); __RCSID("$NetBSD: ftpd.c,v 1.68 1999/07/27 15:41:49 itojun Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
@ -342,9 +342,38 @@ main(argc, argv)
syslog(LOG_ERR, "getpeername (%s): %m",argv[0]); syslog(LOG_ERR, "getpeername (%s): %m",argv[0]);
exit(1); exit(1);
} }
/*XXX*/ addrlen = sizeof(ctrl_addr);
if (getsockname(0, (struct sockaddr *)&ctrl_addr, &addrlen) < 0) {
syslog(LOG_ERR, "getsockname (%s): %m",argv[0]);
exit(1);
}
if (his_addr.su_family == AF_INET6 if (his_addr.su_family == AF_INET6
&& IN6_IS_ADDR_V4MAPPED(&his_addr.su_sin6.sin6_addr)) { && IN6_IS_ADDR_V4MAPPED(&his_addr.su_sin6.sin6_addr)) {
#if 1
/*
* IPv4 control connection arrived to AF_INET6 socket.
* I hate to do this, but this is the easiest solution.
*/
union sockunion tmp_addr;
tmp_addr = his_addr;
memset(&his_addr, 0, sizeof(his_addr));
his_addr.su_sin.sin_family = AF_INET;
his_addr.su_sin.sin_len = sizeof(his_addr.su_sin);
memcpy(&his_addr.su_sin.sin_addr,
&tmp_addr.su_sin6.sin6_addr.s6_addr32[3],
sizeof(his_addr.su_sin.sin_addr));
his_addr.su_sin.sin_port = tmp_addr.su_sin6.sin6_port;
tmp_addr = ctrl_addr;
memset(&ctrl_addr, 0, sizeof(ctrl_addr));
ctrl_addr.su_sin.sin_family = AF_INET;
ctrl_addr.su_sin.sin_len = sizeof(ctrl_addr.su_sin);
memcpy(&ctrl_addr.su_sin.sin_addr,
&tmp_addr.su_sin6.sin6_addr.s6_addr32[3],
sizeof(ctrl_addr.su_sin.sin_addr));
ctrl_addr.su_sin.sin_port = tmp_addr.su_sin6.sin6_port;
#else
while (fgets(line, sizeof(line), fd) != NULL) { while (fgets(line, sizeof(line), fd) != NULL) {
if ((cp = strchr(line, '\n')) != NULL) if ((cp = strchr(line, '\n')) != NULL)
*cp = '\0'; *cp = '\0';
@ -355,11 +384,7 @@ main(argc, argv)
reply(530, reply(530,
"Connection from IPv4 mapped address is not supported."); "Connection from IPv4 mapped address is not supported.");
exit(0); exit(0);
} #endif
addrlen = sizeof(ctrl_addr);
if (getsockname(0, (struct sockaddr *)&ctrl_addr, &addrlen) < 0) {
syslog(LOG_ERR, "getsockname (%s): %m",argv[0]);
exit(1);
} }
#ifdef IP_TOS #ifdef IP_TOS
if (family == AF_INET) { if (family == AF_INET) {
@ -1137,7 +1162,7 @@ dataconn(name, size, mode)
sizebuf[0] = '\0'; sizebuf[0] = '\0';
if (pdata >= 0) { if (pdata >= 0) {
union sockunion from; union sockunion from;
int s, fromlen = ctrl_addr.su_len; int s, fromlen = sizeof(from);
(void) alarm(curclass.timeout); (void) alarm(curclass.timeout);
s = accept(pdata, (struct sockaddr *)&from, &fromlen); s = accept(pdata, (struct sockaddr *)&from, &fromlen);