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
.\" The Regents of the University of California. All rights reserved.
@ -671,7 +671,7 @@ recommended.
.Pp
When running on IPv6, connection from IPv4 mapped address
.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.
.Pp
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.
@ -109,7 +109,7 @@ __COPYRIGHT(
#if 0
static char sccsid[] = "@(#)ftpd.c 8.5 (Berkeley) 4/28/95";
#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 /* not lint */
@ -342,9 +342,38 @@ main(argc, argv)
syslog(LOG_ERR, "getpeername (%s): %m",argv[0]);
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
&& 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) {
if ((cp = strchr(line, '\n')) != NULL)
*cp = '\0';
@ -355,11 +384,7 @@ main(argc, argv)
reply(530,
"Connection from IPv4 mapped address is not supported.");
exit(0);
}
addrlen = sizeof(ctrl_addr);
if (getsockname(0, (struct sockaddr *)&ctrl_addr, &addrlen) < 0) {
syslog(LOG_ERR, "getsockname (%s): %m",argv[0]);
exit(1);
#endif
}
#ifdef IP_TOS
if (family == AF_INET) {
@ -1137,7 +1162,7 @@ dataconn(name, size, mode)
sizebuf[0] = '\0';
if (pdata >= 0) {
union sockunion from;
int s, fromlen = ctrl_addr.su_len;
int s, fromlen = sizeof(from);
(void) alarm(curclass.timeout);
s = accept(pdata, (struct sockaddr *)&from, &fromlen);