Subject: Re: $REMOTEHOST
To: None <itojun@iijlab.net>
From: =?iso-2022-jp?B?GyRCR19LXBsoQiAbJEJIJRsoQg==?= <Hajimu UMEMOTO>
List: tech-net
Date: 06/14/2000 20:47:20
----Next_Part(Wed_Jun_14_20:47:20_2000_499)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

>>>>> On Wed, 14 Jun 2000 14:50:06 +0900
>>>>> Jun-ichiro itojun Hagino <itojun@iijlab.net> said:

itojun> 	who configures environment variable "REMOTEHOST"?

Tcsh does.

itojun> 	the handling of variable needs some fix, since it will truncate
itojun> 	things after first colon, and therefore will chop IPv6 address off.
itojun> 	(happens when you remote-login over IPv6)

There is no good solution to treat raw IPv6 address.  This is due to
shortage of UT_HOSTSIZE.  Further worse, X DISPLAY uses `:' and it
conflict with IPv6 address syntax.
I'm using the change attached for workaround.  I sent some part of it
to the auther.


----Next_Part(Wed_Jun_14_20:47:20_2000_499)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Description: tcsh-ipv6.diff
Content-Disposition: attachment; filename="tcsh-ipv6.diff"

Index: tcsh/tc.func.c
diff -u tcsh/tc.func.c.orig tcsh/tc.func.c
--- tcsh/tc.func.c.orig	Sun Jun 11 07:20:52 2000
+++ tcsh/tc.func.c	Tue Jun 13 03:03:52 2000
@@ -81,6 +81,9 @@
 static	int	 tildecompare	__P((struct tildecache *, struct tildecache *));
 static  Char    *gethomedir	__P((Char *));
 #ifdef REMOTEHOST
+#ifdef INET6
+#include <utmp.h>
+#endif
 static	sigret_t palarm		__P((int));
 static	void	 getremotehost	__P((void));
 #endif /* REMOTEHOST */
@@ -2040,14 +2043,34 @@
 getremotehost()
 {
     const char *host = NULL;
+#ifdef INET6
+    struct sockaddr_storage saddr;
+    int len = sizeof(struct sockaddr_storage);
+    static char hbuf[NI_MAXHOST];
+#else
     struct hostent* hp;
     struct sockaddr_in saddr;
     int len = sizeof(struct sockaddr_in);
+#endif
 #if defined(UTHOST) && !defined(HAVENOUTMP)
     char *sptr = NULL;
 #endif
 
     if (getpeername(SHIN, (struct sockaddr *) &saddr, &len) != -1) {
+#ifdef INET6
+#if 0
+	int flag = 0;
+#else
+	int flag = NI_NUMERICHOST;
+#endif
+
+#ifdef NI_WITHSCOPEID
+	flag |= NI_WITHSCOPEID;
+#endif
+	getnameinfo((struct sockaddr *)&saddr, len, hbuf, sizeof(hbuf),
+		    NULL, 0, flag);
+	host = hbuf;
+#else
 #if 0
 	if ((hp = gethostbyaddr((char *)&saddr.sin_addr, sizeof(struct in_addr),
 				AF_INET)) != NULL)
@@ -2055,6 +2078,7 @@
 	else
 #endif
 	    host = inet_ntoa(saddr.sin_addr);
+#endif
     }
 #if defined(UTHOST) && !defined(HAVENOUTMP)
     else {
@@ -2062,14 +2086,58 @@
 	char *name = utmphost();
 	/* Avoid empty names and local X displays */
 	if (name != NULL && *name != '\0' && *name != ':') {
+	    struct in_addr addr;
+
 	    /* Look for host:display.screen */
+	    /*
+	     * There is conflict with IPv6 address and X DISPLAY.  So,
+	     * we assume there is no IPv6 address in utmp and don't
+	     * touch here.
+	     */
 	    if ((sptr = strchr(name, ':')) != NULL)
 		*sptr = '\0';
-	    /* Leave IP address as is */
-	    if (isdigit(*name))
+	    /* Leave IPv4 address as is */
+	    if (inet_aton(name, &addr))
 		host = name;
 	    else {
 		if (sptr != name) {
+#ifdef INET6
+		    char *s, *domain;
+		    char dbuf[MAXHOSTNAMELEN], cbuf[MAXHOSTNAMELEN];
+		    struct addrinfo hints, *res = NULL;
+
+		    memset(&hints, 0, sizeof(hints));
+		    hints.ai_family = PF_UNSPEC;
+		    hints.ai_socktype = SOCK_STREAM;
+		    hints.ai_flags = AI_PASSIVE | AI_CANONNAME;
+		    if (strlen(name) < UT_HOSTSIZE) {
+			if (getaddrinfo(name, NULL, &hints, &res) != 0)
+			    res = NULL;
+		    } else if (gethostname(dbuf, sizeof(dbuf) - 1) == 0 &&
+			       (domain = strchr(dbuf, '.')) != NULL) {
+			for (s = strchr(name, '.');
+			     s != NULL; s = strchr(s + 1, '.')) {
+			    if (*(s + 1) != '\0' &&
+				(ptr = strstr(domain, s)) != NULL) {
+				len = s - name;
+				if (len + strlen(ptr) >= sizeof(cbuf))
+				    break;
+				strncpy(cbuf, name, len);
+				strcpy(cbuf + len, ptr);
+				if (getaddrinfo(cbuf, NULL, &hints, &res) != 0)
+				    res = NULL;
+				break;
+			    }
+			}
+		    }
+		    if (res != NULL) {
+			if (res->ai_canonname != NULL) {
+			    strncpy(hbuf, res->ai_canonname, sizeof(hbuf));
+			    host = hbuf;
+			}
+			freeaddrinfo(res);
+		    }
+#else
 		    if ((hp = gethostbyname(name)) == NULL) {
 			/* Try again eliminating the trailing domain */
 			if ((ptr = strchr(name, '.')) != NULL) {
@@ -2081,6 +2149,7 @@
 		    }
 		    else
 			host = hp->h_name;
+#endif
 		}
 	    }
 	}

----Next_Part(Wed_Jun_14_20:47:20_2000_499)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Description: My Signature
Content-Disposition: attachment; filename=".signature-world"

Hajimu UMEMOTO @ Internet Mutual Aid Society Yokohama, Japan
ume@mahoroba.org  ume@bisd.hitachi.co.jp  ume@FreeBSD.org
http://www.imasy.org/~ume/

----Next_Part(Wed_Jun_14_20:47:20_2000_499)----