Subject: pkg/13308: chat/icb IPv6 support
To: None <gnats-bugs@gnats.netbsd.org>
From: None <itojun@itojun.org>
List: netbsd-bugs
Date: 06/26/2001 01:22:10
>Number:         13308
>Category:       pkg
>Synopsis:       chat/icb IPv6 support
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    pkg-manager
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Mon Jun 25 09:21:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Jun-ichiro itojun Hagino
>Release:        1.5W
>Organization:
	itojun.org
>Environment:
System: NetBSD starfruit.itojun.org 1.5W NetBSD 1.5W (STARFRUIT) #506: Mon Jun 18 12:19:27 JST 2001 itojun@starfruit.itojun.org:/usr/home/itojun/NetBSD/src/sys/arch/i386/compile/STARFRUIT i386
Architecture: i386
Machine: i386
>Description:
	i'm posting it here, since i'm not sure who maintains icb these days.
	if you are the maintainer of icb itself (not the pkgsrc) contact me.

	the patch is useful when:
	- icb server start supporting IPv6
	- contacting IPv4 icb server from IPv6 icb client, over protocol
	  translator
>How-To-Repeat:
>Fix:
	the patch requires getaddrinfo/getnameinfo (= 1.5 or later).

diff -u -r -x CVS ./murgil/contoport.c /home/itojun/work/kame-apps/icb/murgil/contoport.c
--- ./murgil/contoport.c	Sat Feb 25 06:19:40 1995
+++ /home/itojun/work/kame-apps/icb/murgil/contoport.c	Thu Nov  9 11:08:05 2000
@@ -12,44 +12,47 @@
 #include "ipcf.h"
 #include "externs.h"
 
-struct in_addr *_getaddress();
-
 connecttoport(host_name, port_number)
 char *host_name;
 int port_number;
 {
-	int s;
-	struct sockaddr_in saddr;
-	struct in_addr *addr;
+	int s, error;
+	struct addrinfo hints, *res, *res0;
+	char sbuf[NI_MAXSERV];
+	char hbuf[NI_MAXHOST];
 
 	fprintf(stderr,"Trying to connect to port %d of host %s.\n", port_number,
 				host_name);
 
 	/* get the client host inet address */
-	if ((addr = _getaddress(host_name)) == 0) {
-		fail = "can't lookup server INET address";
-		return(-1);
+	snprintf(sbuf, sizeof(sbuf), "%d", port_number);
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_family = PF_UNSPEC;
+	hints.ai_socktype = SOCK_STREAM;
+	error = getaddrinfo(host_name, sbuf, &hints, &res0);
+	if (error) {
+		fail = gai_strerror(error);
+		return -1;
 	}
-
-	/* insert hostname into address */
-	bzero((char *) &saddr, sizeof(saddr));
-	bcopy((char *) addr, (char *) &saddr.sin_addr, 4);
-
-	/* fill in socket domain and port number */
-	saddr.sin_family = AF_INET;
-	saddr.sin_port = htons((u_short)port_number);
-
-	/* create a socket */
-	if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-		fail = "couldn't create socket";
-		fprintf(stderr,"icb: couldn't connect to %s server.\n",host_name);
-		return(-1);
+	s = -1;
+	for (res = res0; res; res = res->ai_next) {
+		getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
+		    NULL, 0, NI_NUMERICHOST);
+		s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+		if (s < 0)
+			continue;
+		if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
+			close(s);
+			s = -1;
+			continue;
+		}
+		break;
 	}
-
-	/* connect it to the server inet address */
-	if (connect(s, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) {
+	freeaddrinfo(res0);
+	if (s < 0) {
 		fail = "couldn't connect to server (not running?)";
-		fprintf(stderr,"icb: couldn't connect to %s server.\n",host_name);
+		fprintf(stderr,"icb: couldn't connect to %s server.\n",
+		    host_name);
 		return(-1);
 	}
 
diff -u -r -x CVS ./murgil/getrname.c /home/itojun/work/kame-apps/icb/murgil/getrname.c
--- ./murgil/getrname.c	Tue Jun 26 01:18:59 2001
+++ /home/itojun/work/kame-apps/icb/murgil/getrname.c	Sun Jul 16 19:40:00 2000
@@ -12,41 +12,23 @@
 getremotename(s)
 int s;			/* connected socket fd */
 {
-	static char rname[24];
-	struct hostent *host;
-#if defined(linux) || defined(__NetBSD__)
-#define PEER_CAST (struct sockaddr *)
-#define HOST_CAST (char *)
+	static char hbuf[NI_MAXHOST];
+	struct sockaddr_storage rs;
+	int rs_size = sizeof(rs);
+#ifdef NI_WITHSCOPEID
+	const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
 #else
-#define PEER_CAST
-#define HOST_CAST
+	const int niflags = NI_NUMERICHOST;
 #endif
-	struct sockaddr_in rs;
-	int rs_size = sizeof(rs);
-/* temporary hack */
-char *debug_c;
-long debug_l, inet_addr();
-	char *inet_ntoa();
 
 	/* get address of remote user */
-	if (getpeername(s, PEER_CAST &rs, &rs_size) < 0) {
+	if (getpeername(s, (struct sockaddr *) &rs, &rs_size) < 0) {
 		perror("server: getpeername failed");
 		return(NULL);
 	}
-/* temporary hack */
-	debug_c = inet_ntoa(rs.sin_addr);
-	debug_l = inet_addr(debug_c);
-
-	/* get hostname from table */
-	if ((host = gethostbyaddr(HOST_CAST &rs.sin_addr.s_addr,
-	  sizeof(rs.sin_addr.s_addr), AF_INET)) == 0) {
-#ifdef NEVER
-/* temporary hack */
-	if ((host = gethostbyaddr(&debug_l, sizeof(debug_l), AF_INET)) == 0) {
-		/* not there, return address in numerical format */
-		sprintf(rname, "[%s]", inet_ntoa(debug_l));
-#endif
-		return(inet_ntoa(rs.sin_addr.s_addr));
-	} else
-		return(char *)(host->h_name);
+	if (getnameinfo((struct sockaddr *) &rs, rs_size, hbuf, sizeof(hbuf),
+	    NULL, 0, niflags) == 0)
+		return hbuf;
+	else
+		return "?";
 }
diff -u -r -x CVS ./murgil/makeport.c /home/itojun/work/kame-apps/icb/murgil/makeport.c
--- ./murgil/makeport.c	Sat Feb 25 06:19:42 1995
+++ /home/itojun/work/kame-apps/icb/murgil/makeport.c	Sun Jul 16 19:40:00 2000
@@ -19,36 +19,42 @@
 char *host_name;
 int port_number;
 {
-	struct sockaddr_in saddr;
-	struct hostent *hp;
+	struct addrinfo hints, *res, *res0;
+	int error;
 	int one = 1;
 	int s;
+	char sbuf[NI_MAXSERV];
 
-	/* get the server host inet address */
-	if ((hp = gethostbyname(host_name)) < (struct hostent *) 0) {
-		fail = "makenewport: gethostbyname";
-		return(-1);
+	snprintf(sbuf, sizeof(sbuf), "%d", port_number);
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_family = PF_UNSPEC;
+	hints.ai_socktype = SOCK_STREAM;
+	hints.ai_flags = AI_PASSIVE;
+
+	error = getaddrinfo(host_name, sbuf, &hints, &res);
+	if (error) {
+		fail = gai_strerror(error);
+		return -1;
 	}
 
-	/* insert host_name into address */
-	bzero((char *) &saddr, sizeof(saddr));
-	bcopy(hp->h_addr, (char *) &saddr.sin_addr, hp->h_length);
+	s = -1;
+	for (res = res0; res; res = res->ai_next) {
+		s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+		if (s < 0)
+			continue;
 
-	/* fill in socket domain and port number */
-	saddr.sin_family = hp->h_addrtype;
-	saddr.sin_port = htons(port_number);
+		if (bind(s, res->ai_addr, res->ai_addrlen) < 0) {
+			close(s);
+			s = -1;
+			continue;
+		}
 
-	/* create a socket */
-	if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-		fail = "makenewport: gethostbyname";
-		return(-1);
+		break;
 	}
-
-	/* bind it to the inet address */
-	if (bind(s, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) {
-		fail = "makenewport: bind";
-		perror("perror says:");
-		return(-1);
+	freeaddrinfo(res0);
+	if (s < 0) {
+		fail = "couldn't make a new listening socket";
+		return -1;
 	}
 
 	/* start listening for connections */
>Release-Note:
>Audit-Trail:
>Unformatted: