summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authoritojun <itojun@NetBSD.org>1999-07-27 15:41:49 +0000
committeritojun <itojun@NetBSD.org>1999-07-27 15:41:49 +0000
commit542bd3ceb5dc783b76e762e3b97d36665dbcd36d (patch)
tree1021bcad61ab34655de5572a553c2b12f2a02712 /libexec
parentb0c1735026ecb1919c5721cce2aacfd0ffd060fa (diff)
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
Diffstat (limited to 'libexec')
-rw-r--r--libexec/ftpd/ftpd.84
-rw-r--r--libexec/ftpd/ftpd.c43
2 files changed, 36 insertions, 11 deletions
diff --git a/libexec/ftpd/ftpd.8 b/libexec/ftpd/ftpd.8
index 2ebb90317ee..13b469ffc55 100644
--- a/libexec/ftpd/ftpd.8
+++ b/libexec/ftpd/ftpd.8
@@ -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
diff --git a/libexec/ftpd/ftpd.c b/libexec/ftpd/ftpd.c
index 011cf2020ea..6834368d8bc 100644
--- a/libexec/ftpd/ftpd.c
+++ b/libexec/ftpd/ftpd.c
@@ -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);