Subject: bin/11858: portal filesystem doesn't support IPv6
To: None <gnats-bugs@gnats.netbsd.org>
From: None <ura@hiru.aoba.yokohama.jp>
List: netbsd-bugs
Date: 12/30/2000 20:53:16
>Number:         11858
>Category:       bin
>Synopsis:       portal filesystem doesn't support IPv6
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sat Dec 30 20:53:00 PST 2000
>Closed-Date:
>Last-Modified:
>Originator:     URA Hiroshi
>Release:        NetBSD-current (2000/11/19)
>Organization:
>Environment:
System: NetBSD satsuki 1.5K NetBSD 1.5K (SATSUKI.MP) #2: Sun Nov 19 21:13:59 JST 2000 ura@satsuki:/usr/local/src/NetBSD/mp/src/sys/arch/i386/compile/SATSUKI.MP i386
Architecture: i386
Machine: i386
>Description:

>How-To-Repeat:

 A sample program is bellow.

#include <stdio.h>
#include <fcntl.h>

int
main(argc, argv)
	int argc;
	char **argv;
{
	int p, pid;
	int c;
	FILE *fp;

	fp = fopen(argv[1], "r+");

	if ((pid = fork()) == 0) {
		while ((c = fgetc(fp)) != EOF) 
			putc(c, stdout);
		exit(0);
	}
	while ((c = getc(stdin)) != EOF)
		fputc(c, fp);
}

 The program output:
% ./a.out /p/tcp/127.0.0.1/daytime
Sun Dec 31 13:51:06 2000
^C

% ./a.out /p/tcp/::1/daytime
^C

>Fix:
  Apply this patch.

Index: Makefile
===================================================================
RCS file: /cvsroot/netbsd/basesrc/sbin/mount_portal/Makefile,v
retrieving revision 1.17
diff -u -u -r1.17 Makefile
--- Makefile	2000/11/06 14:05:54	1.17
+++ Makefile	2000/12/30 23:26:39
@@ -11,6 +11,7 @@
 MOUNT=	${.CURDIR}/../mount
 CPPFLAGS+= -I${.CURDIR}/../../sys -I${MOUNT}
 .PATH:	${MOUNT}
+CPPFLAGS+= -DINET6
 
 .include <bsd.prog.mk>
 .include <bsd.subdir.mk>
Index: pt_tcp.c
===================================================================
RCS file: /cvsroot/netbsd/basesrc/sbin/mount_portal/pt_tcp.c,v
retrieving revision 1.13
diff -u -u -r1.13 pt_tcp.c
--- pt_tcp.c	1998/02/03 03:35:06	1.13
+++ pt_tcp.c	2000/12/30 23:26:39
@@ -78,14 +78,19 @@
 	char port[MAXHOSTNAMELEN];
 	char *p = key + (v[1] ? strlen(v[1]) : 0);
 	char *q;
+	int priv = 0;
+#ifdef INET6
+	struct addrinfo hints, *res, *lres;
+	int failed_socket = 0;
+#else /* ! INET6 */
 	struct hostent *hp;
 	struct servent *sp;
 	struct in_addr **ipp;
 	struct in_addr *ip[2];
 	struct in_addr ina;
 	int s_port;
-	int priv = 0;
 	struct sockaddr_in sain;
+#endif
 
 	q = strchr(p, '/');
 	if (q == 0 || q - p >= sizeof(host))
@@ -112,6 +117,42 @@
 		}
 	}
 
+#ifdef INET6
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_family = PF_UNSPEC;
+	hints.ai_socktype = SOCK_STREAM;
+	hints.ai_protocol = 0;
+	if (getaddrinfo(host, port, &hints, &res) != 0)
+		return(EINVAL);
+
+	for (lres = res; lres; lres = lres->ai_next) {
+		int so;
+
+		if (priv)
+			so = rresvport((int *) 0);
+		else
+			so = socket(lres->ai_family, SOCK_STREAM, 0);
+		if (so < 0) {
+			failed_socket = errno;
+			continue;
+		}
+		failed_socket = 0;
+
+		if (connect(so, lres->ai_addr, lres->ai_addrlen) == 0) {
+			*fdp = so;
+			errno = 0;
+			break;
+		}
+		(void)close(so);
+	}
+
+	if (failed_socket > 0) {
+		errno = failed_socket;
+		syslog(LOG_ERR, "socket: %m");
+	}
+		
+	freeaddrinfo(res);
+#else /* ! INET6 */
 	if (inet_aton(host, &ina) == 0) {
 		hp = gethostbyname(host);
 		if (hp == 0)
@@ -160,6 +201,7 @@
 
 		ipp++;
 	}
+#endif /* INET6 */
 
 	return (errno);
 }
>Release-Note:
>Audit-Trail:
>Unformatted: