Index: bind8/src/bin/Makefile
diff -c bind8/src/bin/Makefile:1.1.1.1 bind8/src/bin/Makefile:1.5
*** bind8/src/bin/Makefile:1.1.1.1	Fri Sep 25 14:24:51 1998
--- bind8/src/bin/Makefile	Fri Nov 27 23:16:25 1998
***************
*** 13,19 ****
  ## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  ## SOFTWARE.
  
! # $Id: Makefile,v 8.17 1998/03/20 00:40:13 halley Exp $
  
  DESTDIR=
  CC= cc
--- 13,19 ----
  ## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  ## SOFTWARE.
  
! # $Id: Makefile,v 1.4 1998/11/27 14:14:53 itojun Exp $
  
  DESTDIR=
  CC= cc
***************
*** 58,64 ****
  
  CFLAGS=	${CDEBUG} -I${PORTINCL} -I${INCL}
  
! SUBDIRS = addr nslookup dig dnsquery host named named-xfer ndc nsupdate
  
  all: ${SUBDIRS}
  
--- 58,65 ----
  
  CFLAGS=	${CDEBUG} -I${PORTINCL} -I${INCL}
  
! #SUBDIRS = addr nslookup dig dnsquery host named named-xfer ndc nsupdate
! SUBDIRS = addr nslookup dig named named-xfer
  
  all: ${SUBDIRS}
  
Index: bind8/src/bin/addr/Makefile
diff -c bind8/src/bin/addr/Makefile:1.1.1.1 bind8/src/bin/addr/Makefile:1.2
*** bind8/src/bin/addr/Makefile:1.1.1.1	Fri Sep 25 14:24:52 1998
--- bind8/src/bin/addr/Makefile	Fri Nov 27 23:16:27 1998
***************
*** 13,25 ****
  ## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  ## SOFTWARE.
  
! # $Id: Makefile,v 8.19 1997/06/19 03:22:06 halley Exp $
  
  DESTDIR=
  CC= cc
  SHELL= /bin/sh
  
! CDEBUG= -g
  
  #(net2 and its descendents)
  SYSTYPE = bsdos
--- 13,25 ----
  ## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  ## SOFTWARE.
  
! # $Id: Makefile,v 1.1.1.1 1998/09/25 05:24:52 k-sugyou Exp $
  
  DESTDIR=
  CC= cc
  SHELL= /bin/sh
  
! CDEBUG= -g -DINET6
  
  #(net2 and its descendents)
  SYSTYPE = bsdos
Index: bind8/src/bin/dig/Makefile
diff -c bind8/src/bin/dig/Makefile:1.1.1.1 bind8/src/bin/dig/Makefile:1.2
*** bind8/src/bin/dig/Makefile:1.1.1.1	Fri Sep 25 14:24:52 1998
--- bind8/src/bin/dig/Makefile	Fri Nov 27 22:03:23 1998
***************
*** 13,25 ****
  ## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  ## SOFTWARE.
  
! # $Id: Makefile,v 8.19 1997/06/19 03:22:07 halley Exp $
  
  DESTDIR=
  CC= cc
  SHELL= /bin/sh
  
! CDEBUG= -g
  
  #(net2 and its descendents)
  SYSTYPE = bsdos
--- 13,25 ----
  ## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  ## SOFTWARE.
  
! # $Id: Makefile,v 1.1.1.1 1998/09/25 05:24:52 k-sugyou Exp $
  
  DESTDIR=
  CC= cc
  SHELL= /bin/sh
  
! CDEBUG= -g -DINET6
  
  #(net2 and its descendents)
  SYSTYPE = bsdos
Index: bind8/src/bin/dig/dig.c
diff -c bind8/src/bin/dig/dig.c:1.1.1.1 bind8/src/bin/dig/dig.c:1.4
*** bind8/src/bin/dig/dig.c:1.1.1.1	Fri Sep 25 14:24:52 1998
--- bind8/src/bin/dig/dig.c	Fri Dec 25 14:20:53 1998
***************
*** 1,5 ****
  #ifndef lint
! static char rcsid[] = "$Id: dig.c,v 8.19 1998/03/19 19:30:18 halley Exp $";
  #endif
  
  /*
--- 1,5 ----
  #ifndef lint
! static char rcsid[] = "$Id: dig.c,v 1.3 1998/11/29 13:49:57 itojun Exp $";
  #endif
  
  /*
***************
*** 203,209 ****
  #define DIG_MAXARGS 30
  
  static char		*defsrv, *srvmsg;
! static char		defbuf[40] = "default -- ";
  static char		srvbuf[60];
  static char		myhostname[MAXHOSTNAMELEN];
  
--- 203,209 ----
  #define DIG_MAXARGS 30
  
  static char		*defsrv, *srvmsg;
! static char		defbuf[60] = "default -- ";
  static char		srvbuf[60];
  static char		myhostname[MAXHOSTNAMELEN];
  
***************
*** 228,234 ****
  static int		SetOption(const char *);
  static void		res_re_init(void);
  static int		xstrtonum(char *);
! static int		printZone(const char *, const struct sockaddr_in *);
  static int		print_axfr(FILE *output, const u_char *msg,
  				   size_t msglen);
  static struct timeval	difftv(struct timeval, struct timeval);
--- 228,234 ----
  static int		SetOption(const char *);
  static void		res_re_init(void);
  static int		xstrtonum(char *);
! static int		printZone(const char *, const struct sockaddr *);
  static int		print_axfr(FILE *output, const u_char *msg,
  				   size_t msglen);
  static struct timeval	difftv(struct timeval, struct timeval);
***************
*** 284,290 ****
  	qtypeSet = 0;
  	memset(domain, 0, sizeof domain);
  	gethostname(myhostname, (sizeof myhostname));
! 	defsrv = strcat(defbuf, inet_ntoa(_res.nsaddr.sin_addr));
  	res_x = _res;
  
  /*
--- 284,306 ----
  	qtypeSet = 0;
  	memset(domain, 0, sizeof domain);
  	gethostname(myhostname, (sizeof myhostname));
! #ifdef INET6
! 	switch (_res_ext.nsaddr_list[0].ss_family) {
! 	case AF_INET:
! 		defsrv = strcat(defbuf, inet_ntoa(((struct sockaddr_in *)&_res_ext.nsaddr_list[0])->sin_addr));
! 		break;
! 	case AF_INET6:
! 		inet_ntop(AF_INET6, &((struct sockaddr_in *)&_res_ext.nsaddr_list[0])->sin_addr, defbuf, sizeof(defbuf));
! 		defsrv = defbuf;
! 		break;
! 	default:
! 		defbuf[0] = '\0';
! 		defsrv = defbuf;
! 		break;
! 	}
! #else
! 	defsrv = strcat(defbuf, inet_ntoa(_res.nsaddr_list[0].sin_addr));
! #endif
  	res_x = _res;
  
  /*
***************
*** 547,558 ****
  		srvmsg = defsrv;
  		if (srv != NULL) {
  			struct in_addr addr;
  
! 			if (inet_aton(srv, &addr)) {
! 				_res.nscount = 1;
  				_res.nsaddr.sin_addr = addr;
  				srvmsg = strcat(srvbuf, srv);
! 			} else {
  				res_t = _res;
  				_res.pfcode = 0;
  				_res.options = RES_DEFAULT;
--- 563,601 ----
  		srvmsg = defsrv;
  		if (srv != NULL) {
  			struct in_addr addr;
+ #ifdef INET6
+ 			struct in6_addr addr6;
+ #endif
  
! 			if (inet_pton(AF_INET, srv, &addr) == 1) {
! #ifdef INET6
! 				struct sockaddr_in *sin;
! 				sin = (struct sockaddr_in *)&_res_ext.nsaddr_list[0];
! 				sin->sin_addr = addr;
! 				sin->sin_family = AF_INET;
! 				sin->sin_port = port;
! 				_res.nsaddr_list[0] = *sin;
! #else
  				_res.nsaddr.sin_addr = addr;
+ 				_res.nsaddr.sin_family = AF_INET;
+ 				_res.nsaddr.sin_port = port;
+ #endif
+ 				_res.nscount = 1;
  				srvmsg = strcat(srvbuf, srv);
! 			}
! #ifdef INET6
! 			else if (inet_pton(AF_INET6, srv, &addr6) == 1) {
! 				struct sockaddr_in6 *sin6;
! 				sin6 = (struct sockaddr_in6 *)&_res_ext.nsaddr_list[0];
! 				memset(sin6, 0, sizeof(*sin6));
! 				sin6->sin6_addr = addr6;
! 				sin6->sin6_family = AF_INET6;
! 				sin6->sin6_port = port;
! 				_res.nscount = 1;
! 				srvmsg = strcat(srvbuf, srv);
! 			}
! #endif
! 			else {
  				res_t = _res;
  				_res.pfcode = 0;
  				_res.options = RES_DEFAULT;
***************
*** 571,591 ****
  					srv = NULL;
  				} else {
  					u_int32_t **addr;
  
  					_res.nscount = 0;
  					for (addr = (u_int32_t**)hp->h_addr_list;
  					     *addr && (_res.nscount < MAXNS);
  					     addr++) {
  						_res.nsaddr_list[
  							_res.nscount++
  						].sin_addr.s_addr = **addr;
  					}
  
! 					srvmsg = strcat(srvbuf,srv);
  					strcat(srvbuf, "  ");
  					strcat(srvmsg,
  					       inet_ntoa(_res.nsaddr.sin_addr)
  					       );
  				}
  			}
  			printf("; (%d server%s found)\n",
--- 614,664 ----
  					srv = NULL;
  				} else {
  					u_int32_t **addr;
+ #ifdef INET6
+ 					struct sockaddr_in *sin;
+ #endif
  
  					_res.nscount = 0;
  					for (addr = (u_int32_t**)hp->h_addr_list;
  					     *addr && (_res.nscount < MAXNS);
  					     addr++) {
+ #ifdef INET6
+ 						sin = (struct sockaddr_in *)&_res_ext.nsaddr_list[_res.nscount];
+ 						memset(sin, 0, sizeof(*sin));
+ 						sin->sin_addr.s_addr = **addr;
+ 						sin->sin_family = AF_INET;
+ 						_res.nsaddr_list[_res.nscount] = *sin;
+ 						_res.nscount++;
+ #else
  						_res.nsaddr_list[
  							_res.nscount++
  						].sin_addr.s_addr = **addr;
+ #endif
  					}
  
! 					srvmsg = strcat(srvbuf, srv);
  					strcat(srvbuf, "  ");
+ #ifdef INET6
+ 					switch (_res_ext.nsaddr_list[0].ss_family) {
+ 					case AF_INET:
+ 						strcat(srvmsg,
+ 							inet_ntoa(((struct sockaddr_in *)&_res_ext.nsaddr_list[0])->sin_addr));
+ 						break;
+ 					case AF_INET6:
+ 					    {
+ 						char *p;
+ 						p = srvbuf + strlen(srvbuf);
+ 						inet_ntop(AF_INET6,
+ 							&((struct sockaddr_in6 *)&_res_ext.nsaddr_list[0])->sin6_addr,
+ 							p, sizeof(srvbuf) - (p - srvbuf));
+ 						break;
+ 					    }
+ 					}
+ #else
  					strcat(srvmsg,
  					       inet_ntoa(_res.nsaddr.sin_addr)
  					       );
+ #endif
  				}
  			}
  			printf("; (%d server%s found)\n",
***************
*** 593,622 ****
  			_res.id += _res.retry;
  		}
  
  		{
  			int i;
  
  			for (i = 0;  i < _res.nscount;  i++) {
- 				_res.nsaddr_list[i].sin_family = AF_INET;
- 				_res.nsaddr_list[i].sin_port = port;
  			}
  			_res.id += _res.retry;
  		}
  
  		if (zone) {
  			int i;
  
  			for (i = 0;  i < _res.nscount;  i++) {
  				int x = printZone(domain,
! 						  &_res.nsaddr_list[i]);
  				if (_res.pfcode & RES_PRF_STATS) {
  					struct timeval exectime;
  					time_t t;
  
  					printf(";; FROM: %s to SERVER: %s\n",
! 					       myhostname,
! 					       inet_ntoa(_res.nsaddr_list[i]
! 							 .sin_addr));
  					gettimeofday(&exectime, NULL);
  					t = (time_t)exectime.tv_sec;
  					printf(";; WHEN: %s", ctime(&t));
--- 666,721 ----
  			_res.id += _res.retry;
  		}
  
+ #if 0
  		{
  			int i;
  
  			for (i = 0;  i < _res.nscount;  i++) {
  			}
  			_res.id += _res.retry;
  		}
+ #endif
  
  		if (zone) {
  			int i;
  
  			for (i = 0;  i < _res.nscount;  i++) {
+ #ifdef INET6
  				int x = printZone(domain,
! 						  (struct sockaddr *)&_res_ext.nsaddr_list[i]);
! #else
! 				int x = printZone(domain,
! 						  (struct sockaddr *)&_res.nsaddr_list[i]);
! #endif
  				if (_res.pfcode & RES_PRF_STATS) {
  					struct timeval exectime;
  					time_t t;
+ 					char hostbuf[MAXHOSTNAMELEN];
+ 
+ #ifdef INET6
+ 					switch (_res_ext.nsaddr_list[i].ss_family) {
+ 					case AF_INET:
+ 						inet_ntop(AF_INET,
+ 							&((struct sockaddr_in *)&_res_ext.nsaddr_list[i])->sin_addr,
+ 							hostbuf, sizeof(hostbuf));
+ 						break;
+ 					case AF_INET6:
+ 						inet_ntop(AF_INET6,
+ 							&((struct sockaddr_in6 *)&_res_ext.nsaddr_list[i])->sin6_addr,
+ 							hostbuf, sizeof(hostbuf));
+ 						break;
+ 					default:
+ 						strcpy(hostbuf, "invalid");
+ 						break;
+ 					}
+ #else
+ 					inet_ntop(AF_INET,
+ 						&_res.nsaddr_list[i].sin_addr,
+ 						hostbuf, sizeof(hostbuf));
+ #endif
  
  					printf(";; FROM: %s to SERVER: %s\n",
! 					       myhostname, hostbuf);
  					gettimeofday(&exectime, NULL);
  					t = (time_t)exectime.tv_sec;
  					printf(";; WHEN: %s", ctime(&t));
***************
*** 652,658 ****
  			n = 0 - n;
  			msg[0]=0;
  			strcat(msg,";; res_send to server ");
! 			strcat(msg,srvmsg);
  			perror(msg);
  			fflush(stderr);
  
--- 751,757 ----
  			n = 0 - n;
  			msg[0]=0;
  			strcat(msg,";; res_send to server ");
! 			strcat(msg, srvmsg);
  			perror(msg);
  			fflush(stderr);
  
***************
*** 947,953 ****
  } querybuf;
  
  static int
! printZone(const char *zone, const struct sockaddr_in *sin) {
  	static u_char *answer = NULL;
  	static int answerLen = 0;
  
--- 1046,1052 ----
  } querybuf;
  
  static int
! printZone(const char *zone, const struct sockaddr *sa) {
  	static u_char *answer = NULL;
  	static int answerLen = 0;
  
***************
*** 960,965 ****
--- 1059,1065 ----
  	char dname[2][NS_MAXDNAME], file[NAME_LEN];
  	enum { NO_ERRORS, ERR_READING_LEN, ERR_READING_MSG, ERR_PRINTING }
  		error = NO_ERRORS;
+ 	int salen;
  
  	/*
  	 *  Create a query packet for the requested zone name.
***************
*** 975,987 ****
  	/*
  	 *  Set up a virtual circuit to the server.
  	 */
! 	if ((sockFD = socket(sin->sin_family, SOCK_STREAM, 0)) < 0) {
  		int e = errno;
  
  		perror(";; socket");
  		return (e);
  	}
! 	if (connect(sockFD, (struct sockaddr *)sin, sizeof *sin) < 0) {
  		int e = errno;
  
  		perror(";; connect");
--- 1075,1100 ----
  	/*
  	 *  Set up a virtual circuit to the server.
  	 */
! 	/* sa_len isn't properly set. */
! 	switch (sa->sa_family) {
! 	case AF_INET:
! 		salen = sizeof(struct sockaddr_in);
! 		break;
! #ifdef INET6
! 	case AF_INET6:
! 		salen = sizeof(struct sockaddr_in6);
! 		break;
! #endif
! 	default:
! 		return ERROR;
! 	}
! 	if ((sockFD = socket(sa->sa_family, SOCK_STREAM, 0)) < 0) {
  		int e = errno;
  
  		perror(";; socket");
  		return (e);
  	}
! 	if (connect(sockFD, (struct sockaddr *)sa, salen) < 0) {
  		int e = errno;
  
  		perror(";; connect");
Index: bind8/src/bin/named/Makefile
diff -c bind8/src/bin/named/Makefile:1.1.1.1 bind8/src/bin/named/Makefile:1.2
*** bind8/src/bin/named/Makefile:1.1.1.1	Fri Sep 25 14:24:52 1998
--- bind8/src/bin/named/Makefile	Fri Sep 25 17:16:30 1998
***************
*** 13,25 ****
  ## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  ## SOFTWARE.
  
! # $Id: Makefile,v 8.31 1998/03/20 00:49:46 halley Exp $
  
  DESTDIR=
  CC= cc
  SHELL= /bin/sh
  
! CDEBUG= -g
  
  #(net2 and its descendents)
  SYSTYPE = bsdos
--- 13,25 ----
  ## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  ## SOFTWARE.
  
! # $Id: Makefile,v 1.1.1.1 1998/09/25 05:24:52 k-sugyou Exp $
  
  DESTDIR=
  CC= cc
  SHELL= /bin/sh
  
! CDEBUG= -g -DINET6
  
  #(net2 and its descendents)
  SYSTYPE = bsdos
***************
*** 31,41 ****
  O=o
  LEX = lex -I
  YACC = yacc -d
  SYSLIBS = -ll -lutil
  PIDDIR = /var/run
  DESTBIN = /usr/local/bin
  DESTSBIN = /usr/local/sbin
! DESTEXEC = /usr/local/libexec
  DESTMAN = /usr/share/man
  DESTHELP= /usr/share/misc
  AR= ar cruv
--- 31,42 ----
  O=o
  LEX = lex -I
  YACC = yacc -d
+ INET6_INCLUDE =
  SYSLIBS = -ll -lutil
  PIDDIR = /var/run
  DESTBIN = /usr/local/bin
  DESTSBIN = /usr/local/sbin
! DESTEXEC = /usr/libexec
  DESTMAN = /usr/share/man
  DESTHELP= /usr/share/misc
  AR= ar cruv
***************
*** 44,50 ****
  
  PS=ps
  LDFLAGS=
! CFLAGS=	${CDEBUG} -I${PORTINCL} -I${INCL} ${DEFS}
  
  VER= LOCAL-`date +%y%m%d.%H%M%S`
  HOSTNAMECMD= hostname || uname -n
--- 45,51 ----
  
  PS=ps
  LDFLAGS=
! CFLAGS=	${CDEBUG} ${INET6_INCLUDE} -I${PORTINCL} -I${INCL} ${DEFS}
  
  VER= LOCAL-`date +%y%m%d.%H%M%S`
  HOSTNAMECMD= hostname || uname -n
Index: bind8/src/bin/named/db_dump.c
diff -c bind8/src/bin/named/db_dump.c:1.1.1.1 bind8/src/bin/named/db_dump.c:1.2.2.3
*** bind8/src/bin/named/db_dump.c:1.1.1.1	Fri Sep 25 14:24:52 1998
--- bind8/src/bin/named/db_dump.c	Fri Jun  4 07:56:09 1999
***************
*** 1,6 ****
  #if !defined(lint) && !defined(SABER)
  static char sccsid[] = "@(#)db_dump.c	4.33 (Berkeley) 3/3/91";
! static char rcsid[] = "$Id: db_dump.c,v 8.24 1998/02/13 19:49:09 halley Exp $";
  #endif /* not lint */
  
  /*
--- 1,6 ----
  #if !defined(lint) && !defined(SABER)
  static char sccsid[] = "@(#)db_dump.c	4.33 (Berkeley) 3/3/91";
! static char rcsid[] = "$Id: db_dump.c,v 1.1.1.1 1998/09/25 05:24:52 k-sugyou Exp $";
  #endif /* not lint */
  
  /*
***************
*** 162,167 ****
--- 162,170 ----
  int
  zt_dump(FILE *fp) {
  	struct zoneinfo *zp;
+ #ifdef INET6
+ 	char vname[INET6_ADDRSTRLEN];
+ #endif
  
  	fprintf(fp, ";; ++zone table++\n");
  	for (zp = &zones[1]; zp < &zones[nzones]; zp++) {
***************
*** 183,202 ****
--- 186,274 ----
  		fprintf(fp, ";\trefresh=%u, retry=%u, expire=%u, minimum=%u\n",
  			zp->z_refresh, zp->z_retry,
  			zp->z_expire, zp->z_minimum);
+ #ifdef INET6
+ 		if (zp->z_xaddr.sin6.sin6_family == AF_INET6) {
+ 		    inet_ntop(AF_INET6,&zp->z_xaddr.sin6.sin6_addr,
+ 			      vname, sizeof(vname)); 
+ 		    fprintf(fp,
+ 			    ";\tftime=%lu, xaddr=[%s], state=%04x, pid=%d\n",
+ 			    (u_long)zp->z_ftime, vname, zp->z_flags,
+ 			    (int)zp->z_xferpid);
+ 		} else {
+ 		    fprintf(fp,
+ 			    ";\tftime=%lu, xaddr=[%s], state=%04x, pid=%d\n",
+ 			    (u_long)zp->z_ftime,
+ 			    inet_ntoa(zp->z_xaddr.sin.sin_addr),
+ 			    zp->z_flags, (int)zp->z_xferpid);
+ 		}
+ #else
  		fprintf(fp, ";\tftime=%lu, xaddr=[%s], state=%04x, pid=%d\n",
  			(u_long)zp->z_ftime, inet_ntoa(zp->z_xaddr),
  			zp->z_flags, (int)zp->z_xferpid);
+ #endif
  		sprintf(buf, ";\tz_addr[%d]: ", zp->z_addrcnt);
  		pre = buf;
  		for (cnt = 0;  cnt < zp->z_addrcnt;  cnt++) {
+ #ifdef INET6
+ 		    if (zp->z_addr[cnt].sin6.sin6_family == AF_INET6) {
+ 			inet_ntop(AF_INET6,&zp->z_addr[cnt].sin6.sin6_addr,
+ 				  vname, sizeof(vname)); 
+ 			fprintf(fp, "%s[%s]", pre, vname);
+ 		    } else {
+ 			fprintf(fp, "%s[%s]", pre,
+ 				inet_ntoa(zp->z_addr[cnt].sin.sin_addr));
+ 		    }
+ #else
  			fprintf(fp, "%s[%s]", pre, inet_ntoa(zp->z_addr[cnt]));
+ #endif
  			pre = ", ";
  		}
  		if (zp->z_addrcnt)
  			fputc('\n', fp);
+ #ifdef INET6
+ 	    {
+ 		int showit = 0;
+ 		int aflen;
+ 
+ 		showit = 0;
+ 		switch (zp->z_axfr_src.sin.sin_family) {
+ 		case AF_INET:
+ 			showit = (zp->z_axfr_src.sin.sin_addr.s_addr != 0);
+ 			aflen = sizeof(zp->z_axfr_src.sin);
+ 			break;
+ 		case AF_INET6:
+ 			showit = !IN6_IS_ADDR_UNSPECIFIED(&zp->z_axfr_src.sin6.sin6_addr);
+ 			aflen = sizeof(zp->z_axfr_src.sin6);
+ 			break;
+ 		}
+ 		if (showit) {
+ 			getnameinfo((struct sockaddr *)&zp->z_axfr_src, aflen,
+ 				vname, sizeof(vname), 0, NULL, NI_NUMERICHOST);
+ 			fprintf(fp, "; update source IPv4 [%s]\n", vname);
+ 		}
+ 
+ 		showit = 0;
+ 		switch (zp->z_axfr_src6.sin6.sin6_family) {
+ 		case AF_INET:
+ 			showit = (zp->z_axfr_src.sin.sin_addr.s_addr != 0);
+ 			aflen = sizeof(zp->z_axfr_src.sin);
+ 			break;
+ 		case AF_INET6:
+ 			showit = !IN6_IS_ADDR_UNSPECIFIED(&zp->z_axfr_src.sin6.sin6_addr);
+ 			aflen = sizeof(zp->z_axfr_src.sin6);
+ 			break;
+ 		}
+ 		if (showit) {
+ 			getnameinfo((struct sockaddr *)&zp->z_axfr_src, aflen,
+ 				vname, sizeof(vname), 0, NULL, NI_NUMERICHOST);
+ 			fprintf(fp, "; update source IPv6 [%s]\n", vname);
+ 		}
+ 	    }
+ #else
  		if (zp->z_axfr_src.s_addr != 0)
  			fprintf(fp, "; update source [%s]\n",
  				inet_ntoa(zp->z_axfr_src));
+ #endif
  	}
  	fprintf(fp, ";; --zone table--\n");
  	return (0);
***************
*** 218,223 ****
--- 290,298 ----
  	u_char *sigdata;
  	u_char *savecp;
  	char temp_base64[NS_MD5RSA_MAX_BASE64];
+ #ifdef INET6
+ 	char vname[INET6_ADDRSTRLEN];
+ #endif
  
  	found_data = 0;
  	printed_origin = 0;
***************
*** 492,498 ****
  				cp += sizeof(char); 
  				fprintf(fp, " %s ", proto);
  				i = 0;
! 				while(cp < (u_char *)dp->d_data + dp->d_size) {
  					j = *cp++;
  					do {
  					    if (j & 0200)
--- 567,573 ----
  				cp += sizeof(char); 
  				fprintf(fp, " %s ", proto);
  				i = 0;
! 				while (cp < (u_char *)dp->d_data + dp->d_size) {
  					j = *cp++;
  					do {
  					    if (j & 0200)
***************
*** 593,600 ****
--- 668,687 ----
  			}
   eoln:
  			if (dp->d_ns != NULL){
+ #ifdef INET6
+ 			    if (dp->d_ns->msaddr.sin6.sin6_family == AF_INET6) {
+ 				inet_ntop(AF_INET6,
+ 					  &dp->d_ns->msaddr.sin6.sin6_addr,
+ 					  vname, sizeof(vname)); 
+ 				fprintf(fp, "%s[%s]", sep, vname);
+ 			    } else {
+ 				fprintf(fp, "%s[%s]", sep,
+ 					inet_ntoa(dp->d_ns->msaddr.sin.sin_addr));
+ 			    }
+ #else
  				fprintf(fp, "%s[%s]",
  					sep, inet_ntoa(dp->d_ns->addr));
+ #endif
  				sep = " ";
  			}
  			putc('\n', fp);
Index: bind8/src/bin/named/db_func.h
diff -c bind8/src/bin/named/db_func.h:1.1.1.1 bind8/src/bin/named/db_func.h:1.2
*** bind8/src/bin/named/db_func.h:1.1.1.1	Fri Sep 25 14:24:52 1998
--- bind8/src/bin/named/db_func.h	Fri Sep 25 17:16:32 1998
***************
*** 67,83 ****
  
  /* db_proc.h - prototypes for functions in db_*.c
   *
!  * $Id: db_func.h,v 8.22 1997/12/04 06:47:00 halley Exp $
   */
  
  /* ++from db_update.c++ */
  extern int		db_update(const char *name,
  				  struct databuf *odp,
  				  struct databuf *newdp,
  				  struct databuf **savedpp,
  				  int flags,
  				  struct hashbuf *htp,
  				  struct sockaddr_in from),
                          db_cmp(const struct databuf *, const struct databuf *),
  			findMyZone(struct namebuf *np, int class);
  void			fixttl(struct databuf *dp);
--- 67,93 ----
  
  /* db_proc.h - prototypes for functions in db_*.c
   *
!  * $Id: db_func.h,v 1.1.1.1 1998/09/25 05:24:52 k-sugyou Exp $
   */
  
  /* ++from db_update.c++ */
+ #ifdef INET6
  extern int		db_update(const char *name,
  				  struct databuf *odp,
  				  struct databuf *newdp,
  				  struct databuf **savedpp,
  				  int flags,
  				  struct hashbuf *htp,
+ 				  msockaddr_in mfrom),
+ #else
+ extern int		db_update(const char *name,
+ 				  struct databuf *odp,
+ 				  struct databuf *newdp,
+ 				  struct databuf **savedpp,
+ 				  int flags,
+ 				  struct hashbuf *htp,
  				  struct sockaddr_in from),
+ #endif
                          db_cmp(const struct databuf *, const struct databuf *),
  			findMyZone(struct namebuf *np, int class);
  void			fixttl(struct databuf *dp);
Index: bind8/src/bin/named/db_glue.c
diff -c bind8/src/bin/named/db_glue.c:1.1.1.1 bind8/src/bin/named/db_glue.c:1.1.1.1.2.1
*** bind8/src/bin/named/db_glue.c:1.1.1.1	Fri Sep 25 14:24:52 1998
--- bind8/src/bin/named/db_glue.c	Tue Jun  1 13:13:15 1999
***************
*** 395,403 ****
  	const char *msg;
  
  	/* verify */
! 	if ( (np->n_data && (msg = "data"))
! 	  || (np->n_hash && (msg = "hash"))
! 	    ) {
  		ns_panic(ns_log_db, 1, "rm_name(%#x(%s)): non-nil %s pointer",
  			 np, NAME(*np), msg);
  	}
--- 395,402 ----
  	const char *msg;
  
  	/* verify */
! 	if ((np->n_data && (msg = "data"))
! 	 || (np->n_hash && (msg = "hash"))) {
  		ns_panic(ns_log_db, 1, "rm_name(%#x(%s)): non-nil %s pointer",
  			 np, NAME(*np), msg);
  	}
***************
*** 579,585 ****
  
  	/* We're not sure about that '.', however.  It could be escaped
             and thus not a really a label separator. */
! 	escaped=0;
  	for (i = diff-2; i >= 0; i--)
  		if (a[i] == '\\') {
  			if (escaped)
--- 578,584 ----
  
  	/* We're not sure about that '.', however.  It could be escaped
             and thus not a really a label separator. */
! 	escaped = 0;
  	for (i = diff-2; i >= 0; i--)
  		if (a[i] == '\\') {
  			if (escaped)
Index: bind8/src/bin/named/db_load.c
diff -c bind8/src/bin/named/db_load.c:1.1.1.1 bind8/src/bin/named/db_load.c:1.3.2.2
*** bind8/src/bin/named/db_load.c:1.1.1.1	Fri Sep 25 14:24:52 1998
--- bind8/src/bin/named/db_load.c	Fri Jun  4 07:08:41 1999
***************
*** 1,6 ****
  #if !defined(lint) && !defined(SABER)
  static char sccsid[] = "@(#)db_load.c	4.38 (Berkeley) 3/2/91";
! static char rcsid[] = "$Id: db_load.c,v 8.41 1998/02/13 20:02:28 halley Exp $";
  #endif /* not lint */
  
  /*
--- 1,6 ----
  #if !defined(lint) && !defined(SABER)
  static char sccsid[] = "@(#)db_load.c	4.38 (Berkeley) 3/2/91";
! static char rcsid[] = "$Id: db_load.c,v 1.2 1998/11/27 13:03:26 itojun Exp $";
  #endif /* not lint */
  
  /*
***************
*** 229,239 ****
--- 229,246 ----
  	enum context context;
  	u_int32_t sig_type;
  	u_int32_t keyflags;
+ #ifndef INET6
  	struct sockaddr_in empty_from;
  
  	empty_from.sin_family = AF_INET;
  	empty_from.sin_addr.s_addr = htonl(INADDR_ANY);
  	empty_from.sin_port = htons(0);
+ #else
+ 	msockaddr_in empty_from;
+ 	empty_from.sin.sin_family = AF_INET;
+ 	empty_from.sin.sin_addr.s_addr = htonl(INADDR_ANY);
+ 	empty_from.sin.sin_port = htons(0);
+ #endif
  
  /*
   * We use an 'if' inside of the 'do' below because otherwise the Solaris
***************
*** 392,398 ****
  
  			context = ns_ownercontext(type, transport);
  			if (!ns_nameok(domain, class, zp, transport, context,
! 				       domain, inaddr_any)) {
  				errs++;
  				ns_notice(ns_log_load,
  					  "%s:%d: owner name error",
--- 399,411 ----
  
  			context = ns_ownercontext(type, transport);
  			if (!ns_nameok(domain, class, zp, transport, context,
! 				       domain,
! #ifdef INET6
! 				       empty_from
! #else
! 				       inaddr_any
! #endif
! 				       )) {
  				errs++;
  				ns_notice(ns_log_load,
  					  "%s:%d: owner name error",
***************
*** 437,443 ****
  			switch (type) {
  			case ns_t_a:
  				if (!inet_aton(buf, &ina))
! 					ERRTO("IP Address");
  				(void) ina_put(ina, data);
  				n = NS_INT32SZ;
  				break;
--- 450,456 ----
  			switch (type) {
  			case ns_t_a:
  				if (!inet_aton(buf, &ina))
! 					ERRTO("IPv4 Address");
  				(void) ina_put(ina, data);
  				n = NS_INT32SZ;
  				break;
***************
*** 766,772 ****
  
  			case ns_t_aaaa:
  				if (inet_pton(AF_INET6, buf, data) <= 0)
! 					ERRTO("IPv4 Address");
  				n = NS_IN6ADDRSZ;
  				endline(fp);
  				break;
--- 779,785 ----
  
  			case ns_t_aaaa:
  				if (inet_pton(AF_INET6, buf, data) <= 0)
! 					ERRTO("IPv6 Address");
  				n = NS_IN6ADDRSZ;
  				endline(fp);
  				break;
***************
*** 883,890 ****
  					if (expbytes < 1)
  						ERRTO("Exponent too short");
  					if (expbytes >
! 					    (NS_MD5RSA_MAX_BITS + 7) / 8
! 					    )
  						ERRTO("Exponent too long");
  					if (*expstart == 0)
  						ERRTO("Exponent w/ 0");
--- 896,902 ----
  					if (expbytes < 1)
  						ERRTO("Exponent too short");
  					if (expbytes >
! 					    (NS_MD5RSA_MAX_BITS + 7) / 8)
  						ERRTO("Exponent too long");
  					if (*expstart == 0)
  						ERRTO("Exponent w/ 0");
***************
*** 892,903 ****
  					modbytes = klen -
  						(expbytes + (expstart - cp));
  					if (modbytes < 
! 					    (NS_MD5RSA_MIN_BITS + 7) / 8
! 					    )
  						ERRTO("Modulus too short");
  					if (modbytes > 
! 					    (NS_MD5RSA_MAX_BITS + 7) / 8
! 					    )
  						ERRTO("Modulus too long");
  					if (*(expstart+expbytes) == 0)
  						ERRTO("Modulus starts w/ 0");
--- 904,913 ----
  					modbytes = klen -
  						(expbytes + (expstart - cp));
  					if (modbytes < 
! 					    (NS_MD5RSA_MIN_BITS + 7) / 8)
  						ERRTO("Modulus too short");
  					if (modbytes > 
! 					    (NS_MD5RSA_MAX_BITS + 7) / 8)
  						ERRTO("Modulus too long");
  					if (*(expstart+expbytes) == 0)
  						ERRTO("Modulus starts w/ 0");
***************
*** 1792,1797 ****
--- 1802,1813 ----
  	    const char *owner, const char *filename, int lineno, int size)
  {
  	int ret = 1;
+ #ifdef INET6
+ 	msockaddr_in many;
+ 
+ 	many.sin.sin_family = AF_INET;
+ 	many.sin.sin_addr = inaddr_any;
+ #endif
  
  	if (makename(name, origin, size) == -1) {
  		ns_info(ns_log_db, "%s:%d: makename failed",
***************
*** 1799,1805 ****
  		return (0);
  	}
  	if (!ns_nameok(name, class, zp, transport, context, owner,
! 		       inaddr_any)) {
  		ns_info(ns_log_db, "%s:%d: database naming error",
  			filename, lineno);
  		ret = 0;
--- 1815,1826 ----
  		return (0);
  	}
  	if (!ns_nameok(name, class, zp, transport, context, owner,
! #ifdef INET6
! 		       many
! #else
! 		       inaddr_any
! #endif
! 		       )) {
  		ns_info(ns_log_db, "%s:%d: database naming error",
  			filename, lineno);
  		ret = 0;
***************
*** 2083,2089 ****
  static int
  get_nxt_types(u_char *data, FILE *fp, const char *filename) {
  	char b[MAXLABEL];	/* Not quite the right size, but good enough */
! 	int maxtype=0; 
  	int success;
  	int type;
  	int errs = 0;
--- 2104,2110 ----
  static int
  get_nxt_types(u_char *data, FILE *fp, const char *filename) {
  	char b[MAXLABEL];	/* Not quite the right size, but good enough */
! 	int maxtype = 0; 
  	int success;
  	int type;
  	int errs = 0;
***************
*** 2145,2151 ****
  	 * Sanity: maximum down time if we havn't talked for six months 
  	 * war must have broken out.
  	 */
! 	if (zp->z_expire > ( 183 * 24 * 3600))
  		ns_warning(ns_log_db,
  	         "%s: WARNING SOA expire value is greater than 6 months (%u)",
  			   fn, zp->z_expire);
--- 2166,2172 ----
  	 * Sanity: maximum down time if we havn't talked for six months 
  	 * war must have broken out.
  	 */
! 	if (zp->z_expire > (183 * 24 * 3600))
  		ns_warning(ns_log_db,
  	         "%s: WARNING SOA expire value is greater than 6 months (%u)",
  			   fn, zp->z_expire);
Index: bind8/src/bin/named/db_update.c
diff -c bind8/src/bin/named/db_update.c:1.1.1.1 bind8/src/bin/named/db_update.c:1.2.2.1
*** bind8/src/bin/named/db_update.c:1.1.1.1	Fri Sep 25 14:24:52 1998
--- bind8/src/bin/named/db_update.c	Tue Jun  1 13:13:15 1999
***************
*** 1,6 ****
  #if !defined(lint) && !defined(SABER)
  static char sccsid[] = "@(#)db_update.c	4.28 (Berkeley) 3/21/91";
! static char rcsid[] = "$Id: db_update.c,v 8.23 1998/02/13 20:01:38 halley Exp $";
  #endif /* not lint */
  
  /*
--- 1,6 ----
  #if !defined(lint) && !defined(SABER)
  static char sccsid[] = "@(#)db_update.c	4.28 (Berkeley) 3/21/91";
! static char rcsid[] = "$Id: db_update.c,v 1.1.1.1 1998/09/25 05:24:52 k-sugyou Exp $";
  #endif /* not lint */
  
  /*
***************
*** 216,226 ****
--- 216,233 ----
   *	general enough for this use, and for clean_cache()'s continued use.
   *							vix, 21jul94
   */
+ #ifdef INET6
  int
  db_update(const char *name,
  	  struct databuf *odp, struct databuf *newdp, 
  	  struct databuf **savedpp,
+ 	  int flags, struct hashbuf *htp, msockaddr_in mfrom)
+ #else
+ db_update(const char *name,
+ 	  struct databuf *odp, struct databuf *newdp, 
+ 	  struct databuf **savedpp,
  	  int flags, struct hashbuf *htp, struct sockaddr_in from)
+ #endif
  {
  	struct databuf *dp, *pdp;
  	struct namebuf *np;
***************
*** 233,238 ****
--- 240,249 ----
          u_char *cp1, *cp2;
          u_int32_t dp_serial, newdp_serial;
  #endif
+ #ifdef INET6
+ 	char vname[INET6_ADDRSTRLEN];
+ 	struct sockaddr_in6 from6;
+ #endif
  
  	ns_debug(ns_log_db, 3, "db_update(%s, %#x, %#x, %#x, 0%o, %#x)%s",
  		 name, odp, newdp, savedpp, flags, htp,
***************
*** 262,267 ****
--- 273,292 ----
  				break;
  			}
  		}
+ #ifdef INET6
+ 		if (!foundRR) {
+ 		    if (mfrom.sin6.sin6_family == AF_INET6) {
+ 			;
+ 		    } else {
+ 			ns_debug(ns_log_db, 5,
+ 				 "[%s].%d update? to auth zone \"%s\" (%s)",
+ 				 inet_ntoa(mfrom.sin.sin_addr),
+ 				 ntohs(mfrom.sin.sin_port),
+ 				 zones[zn].z_origin,
+ 				 name);
+ 		    }
+ 		}
+ #else
  		if (!foundRR)
  			ns_debug(ns_log_db, 5,
  				 "[%s].%d update? to auth zone \"%s\" (%s)",
***************
*** 269,274 ****
--- 294,300 ----
  				 ntohs(from.sin_port),
  				 zones[zn].z_origin,
  				 name);
+ #endif
  		return (AUTH);
  	}
  
***************
*** 321,330 ****
--- 347,363 ----
  		dp->d_flags = DB_F_HINT;
  		dp->d_cred = DB_C_CACHE;
  		dp->d_clev = 0;
+ #ifdef INET6
+ 		if (db_update(name,
+ 			      dp, dp, NULL,
+ 			      (flags|DB_NOHINTS),
+ 			      fcachetab, mfrom)
+ #else
  		if (db_update(name,
  			      dp, dp, NULL,
  			      (flags|DB_NOHINTS),
  			      fcachetab, from)
+ #endif
  		    != OK) {
  			ns_debug(ns_log_db, 3,
  				 "db_update: hint %#x freed", dp);
***************
*** 454,468 ****
--- 487,527 ----
  				 flags, odp->d_size, dp->d_size,
  				 db_cmp(dp, odp));
  			if (newdp) {
+ #ifdef INET6
+ 			    if (mfrom.sin6.sin6_family == AF_INET6) {
+ 				inet_ntop(AF_INET6, &mfrom.sin6.sin6_addr,
+ 					  vname, sizeof(vname)); 
  				ns_debug(ns_log_db, 4,
  	     "credibility for %s is %d(%d) from [%s].%d, is %d(%d) in cache",
  					 *name ? name : ".",
  					 newdp->d_cred,
  					 newdp->d_clev,
+ 					 vname,
+ 					 ntohs(mfrom.sin6.sin6_port),
+ 					 dp->d_cred,
+ 					 dp->d_clev);
+ 			    } else {
+ 				ns_debug(ns_log_db, 4,
+ 	     "credibility for %s is %d(%d) from [%s].%d, is %d(%d) in cache",
+ 					 *name ? name : ".",
+ 					 newdp->d_cred,
+ 					 newdp->d_clev,
+ 					 inet_ntoa(mfrom.sin.sin_addr),
+ 					 ntohs(mfrom.sin.sin_port),
+ 					 dp->d_cred,
+ 					 dp->d_clev);
+ 			    }
+ #else
+ 				ns_debug(ns_log_db, 4,
+ 	     "credibility for %s is %d(%d) from [%s].%d, is %d(%d) in cache",
+ 					 *name ? name : ".",
+ 					 newdp->d_cred,
+ 					 newdp->d_clev,
  					 inet_ntoa(from.sin_addr),
  					 ntohs(from.sin_port),
  					 dp->d_cred,
  					 dp->d_clev);
+ #endif
  				if (newdp->d_cred > dp->d_cred) {
  					/* better credibility.
  					 * remove the old datum.
***************
*** 474,480 ****
  					return (AUTH);
  				}
  				if (newdp->d_cred == DB_C_ZONE &&
! 				    dp->d_cred == DB_C_ZONE ) {
  					/* Both records are from a zone file.
  					 * If their credibility levels differ,
  					 * we're dealing with a zone cut.  The
--- 533,539 ----
  					return (AUTH);
  				}
  				if (newdp->d_cred == DB_C_ZONE &&
! 				    dp->d_cred == DB_C_ZONE) {
  					/* Both records are from a zone file.
  					 * If their credibility levels differ,
  					 * we're dealing with a zone cut.  The
***************
*** 700,710 ****
  	fixttl(newdp);
  	ns_debug(ns_log_db, 3, "db_update: adding%s %#x",
  		 (newdp->d_flags&DB_F_HINT) ? " hint":"", newdp);
! 
  	if (NS_OPTION_P(OPTION_HOSTSTATS) &&
  	    newdp->d_zone == DB_Z_CACHE &&
  	    (newdp->d_flags & DB_F_HINT) == 0)
  		newdp->d_ns = nameserFind(from.sin_addr, NS_F_INSERT);
  
  	/* Add to end of list, generally preserving order */
  	newdp->d_next = NULL;
--- 759,775 ----
  	fixttl(newdp);
  	ns_debug(ns_log_db, 3, "db_update: adding%s %#x",
  		 (newdp->d_flags&DB_F_HINT) ? " hint":"", newdp);
! #ifdef INET6
  	if (NS_OPTION_P(OPTION_HOSTSTATS) &&
  	    newdp->d_zone == DB_Z_CACHE &&
  	    (newdp->d_flags & DB_F_HINT) == 0)
+ 		newdp->d_ns = nameserFind(mfrom, NS_F_INSERT);
+ #else
+ 	if (NS_OPTION_P(OPTION_HOSTSTATS) &&
+ 	    newdp->d_zone == DB_Z_CACHE &&
+ 	    (newdp->d_flags & DB_F_HINT) == 0)
  		newdp->d_ns = nameserFind(from.sin_addr, NS_F_INSERT);
+ #endif
  
  	/* Add to end of list, generally preserving order */
  	newdp->d_next = NULL;
Index: bind8/src/bin/named/ns_config.c
diff -c bind8/src/bin/named/ns_config.c:1.1.1.1 bind8/src/bin/named/ns_config.c:1.5.2.4
*** bind8/src/bin/named/ns_config.c:1.1.1.1	Fri Sep 25 14:24:52 1998
--- bind8/src/bin/named/ns_config.c	Fri Jun  4 07:56:10 1999
***************
*** 1,5 ****
  #if !defined(lint) && !defined(SABER)
! static char rcsid[] = "$Id: ns_config.c,v 8.35 1998/05/05 19:44:48 halley Exp $";
  #endif /* not lint */
  
  /*
--- 1,5 ----
  #if !defined(lint) && !defined(SABER)
! static char rcsid[] = "$Id: ns_config.c,v 1.4 1998/11/28 03:41:07 itojun Exp $";
  #endif /* not lint */
  
  /*
***************
*** 609,617 ****
  		int i;
  
  		ns_debug(ns_log_config, 5, "  masters:");
! 		for (i=0; i<new_zp->z_addrcnt; i++)
  			ns_debug(ns_log_config, 5, "    %s",
  				 inet_ntoa(new_zp->z_addr[i]));
  	}
  
  	update_zone_info(zp, new_zp);
--- 609,621 ----
  		int i;
  
  		ns_debug(ns_log_config, 5, "  masters:");
! #ifdef INET6
! 		/* ??? */
! #else
! 		for (i = 0; i<new_zp->z_addrcnt; i++)
  			ns_debug(ns_log_config, 5, "    %s",
  				 inet_ntoa(new_zp->z_addr[i]));
+ #endif
  	}
  
  	update_zone_info(zp, new_zp);
***************
*** 711,716 ****
--- 715,732 ----
  	return (1);
  }
  
+ #ifdef INET6
+ int
+ set_zone_transfer_source(zone_config zh, msockaddr_in ina, int is6) {
+ 	struct zoneinfo *zp = zh.opaque;
+ 
+ 	if (is6)
+ 		zp->z_axfr_src6 = ina;
+ 	else
+ 		zp->z_axfr_src = ina;
+ 	return (1);
+ }
+ #else
  int
  set_zone_transfer_source(zone_config zh, struct in_addr ina) {
  	struct zoneinfo *zp = zh.opaque;
***************
*** 718,723 ****
--- 734,740 ----
  	zp->z_axfr_src = ina;
  	return (1);
  }
+ #endif
  
  int
  set_zone_transfer_acl(zone_config zh, ip_match_list iml) {
***************
*** 747,753 ****
--- 764,788 ----
  	return (1);
  }
  
+ #ifdef INET6
  int
+ add_zone_master(zone_config zh, msockaddr_in address) {
+ 	struct zoneinfo *zp;
+ 
+ 	zp = zh.opaque;
+ 	INSIST(zp != NULL);
+ 
+ 	zp->z_addr[zp->z_addrcnt] = address;
+ 	zp->z_addrcnt++;
+ 	if (zp->z_addrcnt >= NSMAX) {
+ 		ns_warning(ns_log_config, "NSMAX reached for zone '%s'",
+ 			   zp->z_origin);
+ 		zp->z_addrcnt = NSMAX - 1;
+ 	}
+ 	return (1);
+ }
+ #else
+ int
  add_zone_master(zone_config zh, struct in_addr address) {
  	struct zoneinfo *zp;
  
***************
*** 763,771 ****
  	}
  	return (1);
  }
  
  int
! add_zone_notify(zone_config zh, struct in_addr address) {
  	struct zoneinfo *zp;
  
  	zp = zh.opaque;
--- 798,808 ----
  	}
  	return (1);
  }
+ #endif
  
+ #ifdef INET6
  int
! add_zone_notify(zone_config zh, msockaddr_in address) {
  	struct zoneinfo *zp;
  
  	zp = zh.opaque;
***************
*** 780,786 ****
--- 817,840 ----
  	}
  	return (1);
  }
+ #else
+ int
+ add_zone_notify(zone_config zh, struct in_addr address) {
+ 	struct zoneinfo *zp;
+ 
+ 	zp = zh.opaque;
+ 	INSIST(zp != NULL);
  
+ 	zp->z_also_notify[zp->z_notify_count] = address;
+ 	zp->z_notify_count++;
+ 	if (zp->z_notify_count >= NSMAX) {
+ 		ns_warning(ns_log_config, "also-notify set full for zone '%s'",
+ 			   zp->z_origin);
+ 		zp->z_notify_count = NSMAX - 1;
+ 	}
+ 	return (1);
+ }
+ #endif
  /* Options */
  
  options
***************
*** 806,814 ****
  	op->transfer_format = axfr_one_answer;
  	op->max_transfer_time_in = MAX_XFER_TIME;
  	memset(&op->query_source, 0, sizeof op->query_source);
  	op->query_source.sin_family = AF_INET;
- 	op->query_source.sin_addr.s_addr = htonl(INADDR_ANY);
  	op->query_source.sin_port = htons(0);		/* INPORT_ANY */
  	op->query_acl = NULL;
  	op->transfer_acl = NULL;
  	/* default topology is { localhost; localnets; } */
--- 860,876 ----
  	op->transfer_format = axfr_one_answer;
  	op->max_transfer_time_in = MAX_XFER_TIME;
  	memset(&op->query_source, 0, sizeof op->query_source);
+ #ifdef INET6
+ 	op->query_source.sin.sin_family = AF_INET;
+ 	op->query_source.sin.sin_port = htons(0);	/* INPORT_ANY */
+ 
+ 	memset(&op->query_source6, 0, sizeof op->query_source6);
+ 	op->query_source6.sin6.sin6_family = AF_INET6;
+ 	op->query_source6.sin6.sin6_port = htons(0);	/* INPORT_ANY */
+ #else
  	op->query_source.sin_family = AF_INET;
  	op->query_source.sin_port = htons(0);		/* INPORT_ANY */
+ #endif
  	op->query_acl = NULL;
  	op->transfer_acl = NULL;
  	/* default topology is { localhost; localnets; } */
***************
*** 1221,1234 ****
--- 1283,1313 ----
  	if (op->listen_list == NULL) {
  		ip_match_list iml;
  		ip_match_element ime;
+ #ifdef INET6
+ 		msockaddr_in address;
+ #else
  		struct in_addr address;
+ #endif
  
  		op->listen_list = new_listen_info_list();
+ #ifdef INET6
+ 		iml = new_ip_match_list();
  
+ 		address.sin.sin_family      = AF_INET;
+ 		address.sin.sin_addr.s_addr = htonl(INADDR_ANY);
+ 		ime = new_ip_match_pattern(address, 0);
+ 		add_to_ip_match_list(iml, ime);
+ 
+ 		address.sin6.sin6_family    = AF_INET6;
+ 		address.sin6.sin6_addr      = in6addr_any; 
+ 		ime = new_ip_match_pattern(address, 0);
+ 		add_to_ip_match_list(iml, ime);
+ #else
  		address.s_addr = htonl(INADDR_ANY);
  		iml = new_ip_match_list();
  		ime = new_ip_match_pattern(address, 0);
  		add_to_ip_match_list(iml, ime);
+ #endif
  		add_listen_on(op, htons(NS_DEFAULTPORT), iml);
  	}
  	if (server_options != NULL)
***************
*** 1297,1302 ****
--- 1376,1404 ----
  /*
   * IP Matching Lists
   */
+ #ifdef INET6
+ static int
+ msockaddr_onnet(msockaddr_in a1, msockaddr_in a2, msockaddr_in mask)
+ {
+ 	if (a1.sin.sin_family != a2.sin.sin_family
+ 	 || a1.sin.sin_family != mask.sin.sin_family)
+ 		return 0;
+ 	switch (a1.sin.sin_family) {
+ 	case AF_INET:
+ 		return ina_onnet(a1.sin.sin_addr, a2.sin.sin_addr, mask.sin.sin_addr);
+ 	case AF_INET6:
+ 		if (((a1.sin6.sin6_addr.s6_addr32[0] & mask.sin6.sin6_addr.s6_addr32[0]) == a2.sin6.sin6_addr.s6_addr32[0])
+ 		 && ((a1.sin6.sin6_addr.s6_addr32[1] & mask.sin6.sin6_addr.s6_addr32[1]) == a2.sin6.sin6_addr.s6_addr32[1])
+ 		 && ((a1.sin6.sin6_addr.s6_addr32[2] & mask.sin6.sin6_addr.s6_addr32[2]) == a2.sin6.sin6_addr.s6_addr32[2])
+ 		 && ((a1.sin6.sin6_addr.s6_addr32[3] & mask.sin6.sin6_addr.s6_addr32[3]) == a2.sin6.sin6_addr.s6_addr32[3]))
+ 			return 1;
+ 		return 0;
+ 	default:
+ 		panic("unknown address family in msockaddr_onnet", NULL);
+ 		/*NOTREACHED*/
+ 	}
+ }
+ #endif
  
  ip_match_list
  new_ip_match_list() {
***************
*** 1322,1330 ****
--- 1424,1440 ----
  }	
  
  ip_match_element
+ #ifdef INET6
+ new_ip_match_pattern(msockaddr_in address, u_int mask_bits) {
+ #else
  new_ip_match_pattern(struct in_addr address, u_int mask_bits) {
+ #endif
  	ip_match_element ime;
+ #ifdef INET6
+ 	char *p;
+ #else
  	u_int32_t mask;
+ #endif
  
  	ime = (ip_match_element)memget(sizeof (struct ip_match_element));
  	if (ime == NULL)
***************
*** 1332,1337 ****
--- 1442,1465 ----
  	ime->type = ip_match_pattern;
  	ime->flags = 0;
  	ime->u.direct.address = address;
+ #ifdef INET6
+ 	memset(&ime->u.direct.mask, 0, sizeof(ime->u.direct.mask));
+ 	ime->u.direct.mask.sin.sin_family = address.sin.sin_family;
+ 	switch (address.sin.sin_family) {
+ 	case AF_INET:
+ 		p = (char *)&ime->u.direct.mask.sin.sin_addr;
+ 		break;
+ 	case AF_INET6:
+ 		p = (char *)&ime->u.direct.mask.sin6.sin6_addr;
+ 		break;
+ 	default:
+ 		panic("unknown address family in new_ip_match_pattern", NULL);
+ 		/*NOTREACHED*/
+ 	}
+ 	memset(p, 0xff, mask_bits / 8);
+ 	if (mask_bits % 8)
+ 		p[mask_bits / 8] = (0xff00 >> (mask_bits % 8)) & 0xff;
+ #else
  	if (mask_bits == 0)
  		/* can't shift >= the size of a type in bits, so 
  		   we deal with an empty mask here */
***************
*** 1344,1355 ****
--- 1472,1493 ----
  	}
  	mask = ntohl(mask);
  	ime->u.direct.mask.s_addr = mask;
+ #endif
  	ime->next = NULL;
+ #ifdef INET6
+ 	if (!msockaddr_onnet(ime->u.direct.address,
+ 		       ime->u.direct.address,
+ 		       ime->u.direct.mask)) {
+ 		memput(ime, sizeof *ime);
+ 		ime = NULL;
+ 	}
+ #else
  	if (!ina_onnet(ime->u.direct.address, ime->u.direct.address,
  		       ime->u.direct.mask)) {
  		memput(ime, sizeof *ime);
  		ime = NULL;
  	}
+ #endif
  	return (ime);
  }
  
***************
*** 1362,1375 ****
--- 1500,1529 ----
  		panic("memget failed in new_ip_match_pattern", NULL);
  	ime->type = ip_match_pattern;
  	ime->flags = 0;
+ #ifdef INET6
+ 	ime->u.direct.address.sin.sin_family = AF_INET;
+ 	ime->u.direct.address.sin.sin_addr = address;
+ 	ime->u.direct.mask.sin.sin_family = AF_INET;
+ 	ime->u.direct.mask.sin.sin_addr = mask;
+ #else
  	ime->u.direct.address = address;
  	ime->u.direct.mask = mask;
+ #endif
  	ime->next = NULL;
+ #ifdef INET6
+ 	if (!msockaddr_onnet(ime->u.direct.address,
+ 		       ime->u.direct.address,
+ 		       ime->u.direct.mask)) {
+ 		memput(ime, sizeof *ime);
+ 		ime = NULL;
+ 	}
+ #else
  	if (!ina_onnet(ime->u.direct.address, ime->u.direct.address,
  		       ime->u.direct.mask)) {
  		memput(ime, sizeof *ime);
  		ime = NULL;
  	}
+ #endif
  	return (ime);
  }
  
***************
*** 1443,1450 ****
--- 1597,1609 ----
  		     char *allow, char *deny) {
  	ip_match_element ime;
  	char spaces[40+1];
+ #ifdef INET6
+ 	char addr_text[INET6_ADDRSTRLEN];
+ 	char mask_text[INET6_ADDRSTRLEN];
+ #else
  	char addr_text[sizeof "255.255.255.255"];
  	char mask_text[sizeof "255.255.255.255"];
+ #endif
  	char *tmp;
  
  	INSIST(iml != NULL);
***************
*** 1458,1463 ****
--- 1617,1646 ----
  	for (ime = iml->first; ime != NULL; ime = ime->next) {
  		switch (ime->type) {
  		case ip_match_pattern:
+ #ifdef INET6
+ 			memset(addr_text, 0, sizeof addr_text);
+ 			if (ime->u.direct.address.sin6.sin6_family == AF_INET6) {
+ 			    inet_ntop(AF_INET6,&ime->u.direct.address.sin6.sin6_addr,
+ 				      addr_text, sizeof(addr_text)); 
+ 			    inet_ntop(AF_INET6,&ime->u.direct.mask.sin6.sin6_addr,
+ 				      mask_text, sizeof(mask_text)); 
+ 			    ns_debug(category, 7, "%s%saddr: %s, mask: %s",
+ 				     spaces,
+ 				     (ime->flags & IP_MATCH_NEGATE) ? deny : allow,
+ 				     addr_text, mask_text);
+ 			} else {
+ 			    strncpy(addr_text,
+ 				    inet_ntoa(ime->u.direct.address.sin.sin_addr),
+ 				    ((sizeof addr_text) - 1));
+ 			    memset(mask_text, 0, sizeof mask_text);
+ 			    strncpy(mask_text, inet_ntoa(ime->u.direct.mask.sin.sin_addr),
+ 				    ((sizeof mask_text) - 1));
+ 			    ns_debug(category, 7, "%s%saddr: %s, mask: %s",
+ 				     spaces,
+ 				     (ime->flags & IP_MATCH_NEGATE) ? deny : allow,
+ 				     addr_text, mask_text);
+ 			}
+ #else
  			memset(addr_text, 0, sizeof addr_text);
  			strncpy(addr_text, inet_ntoa(ime->u.direct.address),
  				((sizeof addr_text) - 1));
***************
*** 1468,1473 ****
--- 1651,1657 ----
  				 spaces,
  				 (ime->flags & IP_MATCH_NEGATE) ? deny : allow,
  				 addr_text, mask_text);
+ #endif
  			break;
  		case ip_match_localhost:
  			ns_debug(category, 7, "%s%slocalhost", spaces,
***************
*** 1496,1502 ****
--- 1680,1690 ----
  }
  
  int
+ #ifdef INET6
+ ip_match_address(ip_match_list iml, msockaddr_in address) {
+ #else
  ip_match_address(ip_match_list iml, struct in_addr address) {
+ #endif
  	ip_match_element ime;
  	int ret;
  	int indirect;
***************
*** 1531,1536 ****
--- 1719,1734 ----
  				return (ret);
  			}
  		} else {
+ #ifdef INET6
+ 			if (msockaddr_onnet(address,
+ 				      ime->u.direct.address,
+ 				      ime->u.direct.mask)) {
+ 				if (ime->flags & IP_MATCH_NEGATE)
+ 					return (0);
+ 				else
+ 					return (1);
+ 			}
+ #else
  			if (ina_onnet(address, ime->u.direct.address,
  				      ime->u.direct.mask)) {
  				if (ime->flags & IP_MATCH_NEGATE)
***************
*** 1538,1555 ****
--- 1736,1763 ----
  				else
  					return (1);
  			}
+ #endif
  		}
  	}
  	return (-1);
  }
  
+ 
  int
+ #ifdef INET6
+ ip_address_allowed(ip_match_list iml, msockaddr_in address) {
+ #else
  ip_address_allowed(ip_match_list iml, struct in_addr address) {
+ #endif
  	int ret;
  
  	if (iml == NULL)
  		return (0);
+ #ifdef INET6
  	ret = ip_match_address(iml, address);
+ #else
+ 	ret = ip_match_address(iml, address);
+ #endif
  	if (ret < 0)
  		ret = 0;
  	return (ret);
***************
*** 1593,1598 ****
--- 1801,1817 ----
  				return (ret);
  			}
  		} else {
+ #ifdef INET6
+ 			if (ime->u.direct.address.sin.sin_family == AF_INET &&
+ 			    address.s_addr ==
+ 			    ime->u.direct.address.sin.sin_addr.s_addr &&
+ 			    mask.s_addr == ime->u.direct.mask.sin.sin_addr.s_addr) {
+ 				if (ime->flags & IP_MATCH_NEGATE)
+ 					return (0);
+ 				else
+ 					return (1);
+ 			}
+ #else
  			if (address.s_addr == ime->u.direct.address.s_addr &&
  			    mask.s_addr == ime->u.direct.mask.s_addr) {
  				if (ime->flags & IP_MATCH_NEGATE)
***************
*** 1600,1605 ****
--- 1819,1825 ----
  				else
  					return (1);
  			}
+ #endif
  		}
  	}
  	return (-1);
***************
*** 1636,1641 ****
--- 1856,1877 ----
  			      NULL);
  		}
  		if (indirect) {
+ #ifdef INET6
+ 			msockaddr_in saddr;
+ 			saddr.sin.sin_family = AF_INET;
+ 			saddr.sin.sin_addr = address;
+ 			ret = ip_match_address(ime->u.indirect.list, saddr);
+ 			if (ret >= 0) {
+ 				if (ime->flags & IP_MATCH_NEGATE)
+ 					ret = (ret) ? 0 : 1;
+ 				if (distance > MAX_TOPOLOGY_DISTANCE)
+ 					distance = MAX_TOPOLOGY_DISTANCE;
+ 				if (ret)
+ 					return (distance);
+ 				else
+ 					return (MAX_TOPOLOGY_DISTANCE);
+ 			}
+ #else
  			ret = ip_match_address(ime->u.indirect.list, address);
  			if (ret >= 0) {
  				if (ime->flags & IP_MATCH_NEGATE)
***************
*** 1647,1653 ****
--- 1883,1905 ----
  				else
  					return (MAX_TOPOLOGY_DISTANCE);
  			}
+ #endif
  		} else {
+ #ifdef INET6
+ 			msockaddr_in saddr;
+ 			saddr.sin.sin_family = AF_INET;
+ 			saddr.sin.sin_addr = address;
+ 			if (msockaddr_onnet(saddr,
+ 				      ime->u.direct.address,
+ 				      ime->u.direct.mask)) {
+ 				if (distance > MAX_TOPOLOGY_DISTANCE)
+ 					distance = MAX_TOPOLOGY_DISTANCE;
+ 				if (ime->flags & IP_MATCH_NEGATE)
+ 					return (MAX_TOPOLOGY_DISTANCE);
+ 				else
+ 					return (distance);
+ 			}
+ #else
  			if (ina_onnet(address, ime->u.direct.address,
  				      ime->u.direct.mask)) {
  				if (distance > MAX_TOPOLOGY_DISTANCE)
***************
*** 1657,1662 ****
--- 1909,1915 ----
  				else
  					return (distance);
  			}
+ #endif
  		}
  	}
  	return (UNKNOWN_TOPOLOGY_DISTANCE);
***************
*** 1677,1688 ****
--- 1930,1956 ----
  			return (0);
  		ime = iml->first;
  	}
+ #ifdef INET6
  	if (ime->type == ip_match_pattern) {
  		if ((ime->flags & IP_MATCH_NEGATE) &&
+ 		    ime->u.direct.address.sin.sin_family == AF_INET &&
+ 		    ime->u.direct.address.sin.sin_addr.s_addr == 0 && 
+ 		    ime->u.direct.mask.sin.sin_addr.s_addr == 0)
+ 			return (1);
+ 		if ((ime->flags & IP_MATCH_NEGATE) &&
+ 		    ime->u.direct.address.sin6.sin6_family == AF_INET6 &&
+ 		    IN6_IS_ADDR_UNSPECIFIED(&ime->u.direct.address.sin6.sin6_addr) && 
+ 		    IN6_IS_ADDR_UNSPECIFIED(&ime->u.direct.mask.sin6.sin6_addr))
+ 			return (1);
+ 	}
+ #else
+ 	if (ime->type == ip_match_pattern) {
+ 		if ((ime->flags & IP_MATCH_NEGATE) &&
  		    ime->u.direct.address.s_addr == 0 && 
  		    ime->u.direct.mask.s_addr == 0)
  			return (1);
  	}
+ #endif
  	return (0);
  }
  
***************
*** 1693,1699 ****
--- 1961,2053 ----
   * XXX  This will go away when the rest of bind understands 
   *      forward zones.
   */
+ #ifdef INET6
+ void
+ add_forwarder(options op, msockaddr_in address) {
+ 	struct fwdinfo *fip = NULL, *ftp = NULL;
+ 	char vname[INET6_ADDRSTRLEN];
+ #ifdef SLAVE_FORWARD
+ 	int forward_count = 0;
+ #endif
+ 
+ 	INSIST(op != NULL);
+ 
+ 	/* On multiple forwarder lines, move to end of the list. */
+ #ifdef SLAVE_FORWARD
+ 	if (op->fwdtab != NULL) {
+ 		forward_count++;
+ 		for (fip = op->fwdtab; fip->next != NULL; fip = fip->next)
+ 			forward_count++;
+ 	}
+ #else
+ 	if (op->fwdtab != NULL) {
+ 		for (fip = op->fwdtab; fip->next != NULL; fip = fip->next) {
+ 			;
+ 		}
+ 	}
+ #endif /* SLAVE_FORWARD */
+ 
+ 	ftp = (struct fwdinfo *)memget(sizeof(struct fwdinfo));
+ 	if (!ftp)
+ 		panic("memget failed in add_forwarder", NULL);
+ 
+ 	if (address.sin6.sin6_family == AF_INET6) {
+ 	    ftp->fwdaddr.sin6.sin6_family = AF_INET6;
+ 	    ftp->fwdaddr.sin6.sin6_addr = address.sin6.sin6_addr;
+ 	    ftp->fwdaddr.sin6.sin6_port = ns_port;
+ 	} else {
+ 	    ftp->fwdaddr.sin.sin_family = AF_INET;
+ 	    ftp->fwdaddr.sin.sin_addr = address.sin.sin_addr;
+ 	    ftp->fwdaddr.sin.sin_port = ns_port;
+ 	}
+ 
+ #ifdef FWD_LOOP
+ 	if (ftp->fwdaddr.sin6.sin6_family == AF_INET6 &&
+ 	     aIsUs6(ftp->fwdaddr)) {
+ 		inet_ntop(AF_INET6,&address.sin6.sin6_addr,
+ 			  vname, sizeof(vname)); 
+ 		ns_error(ns_log_config, "forwarder '%s' ignored, my address",
+ 			 vname);
+ 		memput(ftp, sizeof *ftp);
+ 		return;
+ 	} else if (ftp->fwdaddr.sin.sin_family == AF_INET &&
+ 		   aIsUs(ftp->fwdaddr.sin.sin_addr)) {
+ 		ns_error(ns_log_config, "forwarder '%s' ignored, my address",
+ 			 inet_ntoa(address.sin.sin_addr));
+ 		memput(ftp, sizeof *ftp);
+ 		return;
+ 	}
+ 
+ #endif /* FWD_LOOP */
  
+ 	if (address.sin6.sin6_family == AF_INET6) {
+ 		inet_ntop(AF_INET6,&address.sin6.sin6_addr,
+ 			  vname, sizeof(vname)); 
+ 	    ns_debug(ns_log_config, 2, "added forwarder %s", vname);
+ 	} else {
+ 	    ns_debug(ns_log_config, 2,
+ 		     "added forwarder %s", inet_ntoa(address.sin.sin_addr));
+ 	}
+ 	ftp->next = NULL;
+ 	if (op->fwdtab == NULL) {
+ 		op->fwdtab = ftp;	/* First time only */
+ 	} else
+ 		fip->next = ftp;
+ #ifdef SLAVE_FORWARD
+ 	forward_count++;
+ 
+ 	/*
+ 	** Set the slave retry time to 60 seconds total divided
+ 	** between each forwarder
+ 	*/
+ 	if (forward_count != 0) {
+ 		slave_retry = (int) (60 / forward_count);
+ 		if (slave_retry <= 0)
+ 			slave_retry = 1;
+ 	}
+ #endif
+ }
+ #else
  void
  add_forwarder(options op, struct in_addr address) {
  	struct fwdinfo *fip = NULL, *ftp = NULL;
***************
*** 1704,1709 ****
--- 2058,2064 ----
  
  	INSIST(op != NULL);
  
+ 
  	/* On multiple forwarder lines, move to end of the list. */
  #ifdef SLAVE_FORWARD
  	if (op->fwdtab != NULL) {
***************
*** 1748,1758 ****
  	*/
  	if (forward_count != 0) {
  		slave_retry = (int) (60 / forward_count);
! 		if(slave_retry <= 0)
  			slave_retry = 1;
  	}
  #endif
  }
  
  void
  free_forwarders(struct fwdinfo *fwdtab) {
--- 2103,2114 ----
  	*/
  	if (forward_count != 0) {
  		slave_retry = (int) (60 / forward_count);
! 		if (slave_retry <= 0)
  			slave_retry = 1;
  	}
  #endif
  }
+ #endif
  
  void
  free_forwarders(struct fwdinfo *fwdtab) {
***************
*** 1768,1774 ****
--- 2124,2147 ----
   * Servers 
   */
  
+ #ifdef INET6
+ static server_info
+ new_server(msockaddr_in address) {
+ 	server_info si;
  
+ 	si = (server_info)memget(sizeof (struct server_info));
+ 	if (si == NULL)
+ 		panic("memget failed in new_server()", NULL);
+ 	si->address = address;
+ 	       
+ 	si->flags = 0U;
+ 	si->transfers = 0;
+ 	si->transfer_format = axfr_use_default;
+ 	si->key_list = NULL;
+ 	si->next = NULL;
+ 	return si;
+ }
+ #else
  static server_info
  new_server(struct in_addr address) {
  	server_info si;
***************
*** 1784,1789 ****
--- 2157,2163 ----
  	si->next = NULL;
  	return si;
  }
+ #endif
  
  static void
  free_server(server_info si) {
***************
*** 1792,1797 ****
--- 2166,2191 ----
  }
  
  server_info
+ #ifdef INET6
+ find_server(msockaddr_in address) {
+ 	server_info si;
+ 
+ 	for (si = nameserver_info; si != NULL; si = si->next) {
+ 	    if (si->address.sin6.sin6_family == AF_INET6 &&
+ 		(si->address.sin6.sin6_family == address.sin6.sin6_family)) {
+ 		if (IN6_ARE_ADDR_EQUAL((&si->address.sin6.sin6_addr),
+ 				      (&address.sin6.sin6_addr)))
+ 		    break;
+ 	    } else if (si->address.sin.sin_family == AF_INET &&
+ 		      (si->address.sin.sin_family == address.sin.sin_family)) {
+ 		if (si->address.sin.sin_addr.s_addr == 
+ 		    address.sin.sin_addr.s_addr)
+ 		    break;
+ 	    }
+ 	}
+ 	return (si);
+ }
+ #else
  find_server(struct in_addr address) {
  	server_info si;
  
***************
*** 1800,1805 ****
--- 2194,2200 ----
  			break;
  	return (si);
  }
+ #endif
  
  static void
  add_server(server_info si) {
***************
*** 1818,1825 ****
--- 2213,2234 ----
  		INSIST(ime != NULL);
  		add_to_ip_match_list(bogus_nameservers, ime);
  	}
+ #ifdef INET6
+ 	if (si->address.sin6.sin6_family == AF_INET6) {
+ 	    char vname[INET6_ADDRSTRLEN];
+ 	    inet_ntop(AF_INET6,&si->address.sin6.sin6_addr,
+ 		      vname, sizeof(vname)); 
+ 	    ns_debug(ns_log_config, 3, "server %s: flags %08x transfers %d",
+ 		     vname, si->flags, si->transfers);
+ 	} else {
+ 	    ns_debug(ns_log_config, 3, "server %s: flags %08x transfers %d",
+ 		     inet_ntoa(si->address.sin.sin_addr),
+ 		     si->flags, si->transfers);
+ 	}
+ #else
  	ns_debug(ns_log_config, 3, "server %s: flags %08x transfers %d",
  		 inet_ntoa(si->address), si->flags, si->transfers);
+ #endif
  	if (si->key_list != NULL)
  		dprint_key_info_list(si->key_list);
  }
***************
*** 1840,1851 ****
--- 2249,2269 ----
  }
  
  server_config
+ #ifdef INET6
+ begin_server(msockaddr_in address) {
+ 	server_config sc;
+ 	
+ 	sc.opaque = new_server(address);
+ 	return (sc);
+ }
+ #else
  begin_server(struct in_addr address) {
  	server_config sc;
  	
  	sc.opaque = new_server(address);
  	return (sc);
  }
+ #endif
  
  void
  end_server(server_config sc, int should_install) {
Index: bind8/src/bin/named/ns_defs.h
diff -c bind8/src/bin/named/ns_defs.h:1.1.1.1 bind8/src/bin/named/ns_defs.h:1.3.2.1
*** bind8/src/bin/named/ns_defs.h:1.1.1.1	Fri Sep 25 14:24:52 1998
--- bind8/src/bin/named/ns_defs.h	Fri Jun  4 07:56:10 1999
***************
*** 1,6 ****
  /*
   *	from ns.h	4.33 (Berkeley) 8/23/90
!  *	$Id: ns_defs.h,v 8.39 1998/04/14 00:35:09 halley Exp $
   */
  
  /*
--- 1,6 ----
  /*
   *	from ns.h	4.33 (Berkeley) 8/23/90
!  *	$Id: ns_defs.h,v 1.2 1998/09/25 08:16:36 k-sugyou Exp $
   */
  
  /*
***************
*** 208,216 ****
--- 208,228 ----
  
  enum axfr_format { axfr_use_default=0, axfr_one_answer, axfr_many_answers };
  
+ #ifdef INET6
+ typedef union {
+   struct sockaddr_in   sin;
+   struct sockaddr_in6 sin6;
+ } msockaddr_in;
+ #endif
+ 
  struct ip_match_direct {
+ #ifdef INET6
+ 	msockaddr_in address;
+ 	msockaddr_in mask;
+ #else
  	struct in_addr address;
  	struct in_addr mask;
+ #endif
  };
  
  struct ip_match_indirect {
***************
*** 247,252 ****
--- 259,265 ----
  /* these fields are ordered to maintain word-alignment;
   * be careful about changing them.
   */
+ 
  struct zoneinfo {
  	char		*z_origin;	/* root domain name of zone */
  	time_t		z_time;		/* time for next refresh */
***************
*** 258,266 ****
--- 271,286 ----
  	u_int32_t	z_serial;	/* changes if zone modified */
  	char		*z_source;	/* source location of data */
  	time_t		z_ftime;	/* modification time of source file */
+ #ifdef INET6
+ 	msockaddr_in    z_axfr_src;
+ 	msockaddr_in    z_axfr_src6;
+ 	msockaddr_in    z_xaddr;
+ 	msockaddr_in    z_addr[NSMAX];
+ #else	
  	struct in_addr	z_axfr_src;	/* bind() the axfr socket to this */
  	struct in_addr	z_xaddr;	/* override server for next xfer */
  	struct in_addr	z_addr[NSMAX];	/* list of master servers for zone */
+ #endif
  	u_char		z_addrcnt;	/* number of entries in z_addr[] */
  	u_char		z_type;		/* type of zone; see below */
  	u_int16_t	z_flags;	/* state bits; see below */
***************
*** 287,293 ****
--- 307,317 ----
  					   from us */
  	long		z_max_transfer_time_in;	/* max num seconds for AXFR */
  	enum znotify	z_notify;	/* Notify mode */
+ #ifdef INET6
+ 	msockaddr_in	z_also_notify[NSMAX];  /* More nameservers to notify */
+ #else
  	struct in_addr	z_also_notify[NSMAX];  /* More nameservers to notify */
+ #endif
  	int		z_notify_count;
  	evTimerID	z_timer;	/* maintenance timer */
  	ztimer_info	z_timerinfo;	/* UAP associated with timer */
***************
*** 334,341 ****
--- 358,369 ----
  
  /* XXX - "struct qserv" is deprecated in favor of "struct nameser" */
  struct qserv {
+ #ifdef INET6
+ 	msockaddr_in	ns_addr;	/* address of NS */
+ #else
  	struct sockaddr_in
  			ns_addr;	/* address of NS */
+ #endif
  	struct databuf	*ns;		/* databuf for NS record */
  	struct databuf	*nsdata;	/* databuf for server address */
  	struct timeval	stime;		/* time first query started */
***************
*** 348,355 ****
--- 376,387 ----
  struct qinfo {
  	u_int16_t	q_id;		/* id of query */
  	u_int16_t	q_nsid;		/* id of forwarded query */
+ #ifdef INET6
+ 	msockaddr_in	q_from;		/* requestor's address */
+ #else
  	struct sockaddr_in
  			q_from;		/* requestor's address */
+ #endif
  	u_char		*q_msg,		/* the message */
  			*q_cmsg;	/* the cname message */
  	int16_t		q_msglen,	/* len of message */
***************
*** 419,425 ****
--- 451,463 ----
  	int			dfd,		/* Datagram file descriptor */
  				sfd;		/* Stream file descriptor. */
  	time_t			gen;		/* Generation number. */
+ #ifdef INET6
+ 	msockaddr_in		msaddr;
+ 	int			dfd6;		/* IPv6 Datagram and Stream */
+ 	int			sfd6;		/* file descriptor.         */
+ #else
  	struct in_addr		addr;		/* Interface address. */
+ #endif
  	u_int16_t		port;		/* Interface port. */
  	u_int16_t		flags;		/* Valid bits for evXXXXID. */
  	evFileID		evID_d;		/* Datagram read-event. */
***************
*** 442,449 ****
--- 480,492 ----
  	u_char		*s_wbuf_end;	/* byte after end of send buffer */
  	sq_closure	s_wbuf_closure;	/* callback for writable descriptor */
  	struct qstream	*s_next;	/* next stream */
+ #ifdef INET6
+ 	msockaddr_in
+ 			s_from;		/* address query came from */
+ #else
  	struct sockaddr_in
  			s_from;		/* address query came from */
+ #endif
  	interface	*s_ifp;		/* interface query came from */
  	time_t		s_time;		/* time stamp of last transaction */
  	int		s_refcnt;	/* number of outstanding queries */
***************
*** 507,514 ****
--- 550,561 ----
  
  struct fwdinfo {
  	struct fwdinfo	*next;
+ #ifdef INET6
+ 	msockaddr_in	fwdaddr;
+ #else
  	struct sockaddr_in
  			fwdaddr;
+ #endif
  };
  
  enum nameserStats {	nssRcvdR,	/* sent us an answer */
***************
*** 539,545 ****
--- 586,596 ----
  			nssLast };
  
  struct nameser {
+ #ifdef INET6
+ 	msockaddr_in 	msaddr;		/* key */
+ #else
  	struct in_addr	addr;		/* key */
+ #endif
  	u_long		stats[nssLast];	/* statistics */
  #ifdef notyet
  	u_int32_t	rtt;		/* round trip time */
***************
*** 586,592 ****
--- 637,648 ----
  	int transfers_out;
  	enum axfr_format transfer_format;
  	long max_transfer_time_in;
+ #ifdef INET6
+ 	msockaddr_in query_source;
+ 	msockaddr_in query_source6;
+ #else
  	struct sockaddr_in query_source;
+ #endif
  	ip_match_list query_acl;
  	ip_match_list transfer_acl;
  	ip_match_list topology;
***************
*** 649,655 ****
--- 705,715 ----
  #define SERVER_INFO_BOGUS	0x01
  
  typedef struct server_info {
+ #ifdef INET6
+ 	msockaddr_in address;
+ #else
  	struct in_addr address;
+ #endif
  	u_int flags;
  	int transfers;
  	enum axfr_format transfer_format;
Index: bind8/src/bin/named/ns_forw.c
diff -c bind8/src/bin/named/ns_forw.c:1.1.1.1 bind8/src/bin/named/ns_forw.c:1.4.2.1
*** bind8/src/bin/named/ns_forw.c:1.1.1.1	Fri Sep 25 14:24:52 1998
--- bind8/src/bin/named/ns_forw.c	Tue Jun  1 13:13:16 1999
***************
*** 1,6 ****
  #if !defined(lint) && !defined(SABER)
  static char sccsid[] = "@(#)ns_forw.c	4.32 (Berkeley) 3/3/91";
! static char rcsid[] = "$Id: ns_forw.c,v 8.34 1998/02/24 01:02:40 halley Exp $";
  #endif /* not lint */
  
  /*
--- 1,6 ----
  #if !defined(lint) && !defined(SABER)
  static char sccsid[] = "@(#)ns_forw.c	4.32 (Berkeley) 3/3/91";
! static char rcsid[] = "$Id: ns_forw.c,v 1.3 1998/11/27 14:12:28 itojun Exp $";
  #endif /* not lint */
  
  /*
***************
*** 101,110 ****
--- 101,115 ----
  
  struct complaint {
  	u_long		tag1, tag2;
+ #ifdef INET6
+         int             type;
+         struct in6_addr tag3;     
+ #endif        
  	time_t		expire;
  	struct complaint *next;
  };
  
+ 
  static struct complaint *complaints = NULL;
  static int retry_timer_set = 0;
  
***************
*** 118,132 ****
--- 123,153 ----
   *
   * (no action is taken on errors and qpp is not filled in.)
   */
+ #ifdef INET6
+ int
+ ns_forw(struct databuf *nsp[], u_char *msg, int msglen,
+ 	msockaddr_in from, struct qstream *qsp, int dfd,
+ 	struct qinfo **qpp, const char *dname, int class, int type,
+ 	struct namebuf *np, int use_tcp)
+ #else
  int
  ns_forw(struct databuf *nsp[], u_char *msg, int msglen,
  	struct sockaddr_in from, struct qstream *qsp, int dfd,
  	struct qinfo **qpp, const char *dname, int class, int type,
  	struct namebuf *np, int use_tcp)
+ #endif
  {
  	struct qinfo *qp;
  	char tmpdomain[MAXDNAME];
+ #ifdef INET6
+ 	msockaddr_in mnsa;
+ 	struct sockaddr *nsa;
+ 	struct sockaddr_in  *nsa4;
+ 	struct sockaddr_in6 *nsa6;	
+         char vname[INET6_ADDRSTRLEN];
+ #else
  	struct sockaddr_in *nsa;
+ #endif
  	HEADER *hp;
  	u_int16_t id;
  	int n;
***************
*** 146,156 ****
  		     )) {
  			ns_debug(ns_log_default, 3, "forw: dropped DUP id=%d",
  				 ntohs(id));
  			nameserIncr(from.sin_addr, nssRcvdDupQ);
  			return (FW_DUP);
  		}
  	}
- 
  	qp = qnew(dname, class, type);
  	getname(np, tmpdomain, sizeof tmpdomain);
  	qp->q_domain = savestr(tmpdomain, 1);
--- 167,180 ----
  		     )) {
  			ns_debug(ns_log_default, 3, "forw: dropped DUP id=%d",
  				 ntohs(id));
+ #ifdef INET6
+ 			nameserIncr(from, nssRcvdDupQ);
+ #else
  			nameserIncr(from.sin_addr, nssRcvdDupQ);
+ #endif
  			return (FW_DUP);
  		}
  	}
  	qp = qnew(dname, class, type);
  	getname(np, tmpdomain, sizeof tmpdomain);
  	qp->q_domain = savestr(tmpdomain, 1);
***************
*** 161,171 ****
--- 185,197 ----
  		ns_freeqry(qp);
  		return (FW_SERVFAIL);
  	}
+ 
  	if (n == 0 && !server_options->fwdtab) {
  		ns_debug(ns_log_default, 2, "forw: no nameservers found");
  		ns_freeqry(qp);
  		return (FW_NOSERVER);
  	}
+ 
  	qp->q_stream = qsp;
  	qp->q_curaddr = 0;
  	qp->q_fwd = server_options->fwdtab;
***************
*** 191,196 ****
--- 217,223 ----
  		qp->q_addr[0].stime = tt;
  	}
  
+ 
  #ifdef SLAVE_FORWARD
  	if (NS_OPTION_P(OPTION_FORWARD_ONLY))
  		schedretry(qp, (time_t)slave_retry);
***************
*** 198,204 ****
--- 225,340 ----
  #endif /* SLAVE_FORWARD */
  	schedretry(qp, qp->q_fwd ?(2*RETRYBASE) :retrytime(qp));
  
+ #ifdef INET6
+ 	if (qp->q_fwd == (struct fwdinfo *)0) {
+ 	    nsa = (struct sockaddr *)&qp->q_addr[0].ns_addr;
+ 	} else {
+ 	    nsa = (struct sockaddr *)&qp->q_fwd->fwdaddr;
+ 	}
+ #else
  	nsa = Q_NEXTADDR(qp, 0);
+ #endif
+ #ifdef INET6
+ 	if (nsa->sa_family == AF_INET6) {
+ 	    nsa6 = (struct sockaddr_in6 *)nsa;
+ 	    inet_ntop(AF_INET6, &nsa6->sin6_addr, vname, sizeof(vname));
+ #ifdef V6DEBUG
+     syslog(LOG_NOTICE,
+ 	   "forw: forw -> [%s].%d ds=%d nsid=%d id=%d %dms retry %dsec",
+ 	   vname, ntohs(nsa6->sin6_port), ds, ntohs(qp->q_nsid),
+ 	   ntohs(qp->q_id), (qp->q_addr[0].nsdata != NULL)
+ 	   ? qp->q_addr[0].nsdata->d_nstime : -1,
+ 	   (int)(qp->q_time - tt.tv_sec));
+ #endif
+     ns_debug(ns_log_default, 1,
+ 	     "forw: forw -> [%s].%d ds=%d nsid=%d id=%d %dms retry %dsec",
+ 	     vname, ntohs(nsa6->sin6_port), ds,
+ 	     ntohs(qp->q_nsid), ntohs(qp->q_id),
+ 	     (qp->q_addr[0].nsdata != NULL)
+ 	     ? qp->q_addr[0].nsdata->d_nstime : -1,
+ 	     (int)(qp->q_time - tt.tv_sec));
+ 	} else {
+ 	    nsa4 = (struct sockaddr_in *)nsa;
+ #ifdef V6DEBUG
+     syslog(LOG_NOTICE,
+ 	   "forw: forw -> [%s].%d ds=%d nsid=%d id=%d %dms retry %dsec",
+ 	   inet_ntoa(nsa4->sin_addr), ntohs(nsa4->sin_port), ds,
+ 	   ntohs(qp->q_nsid), ntohs(qp->q_id),
+ 	   (qp->q_addr[0].nsdata != NULL)
+ 	   ? qp->q_addr[0].nsdata->d_nstime : -1,
+ 	   (int)(qp->q_time - tt.tv_sec));
+ #endif
+ 
+     ns_debug(ns_log_default, 1,
+ 	     "forw: forw -> [%s].%d ds=%d nsid=%d id=%d %dms retry %dsec",
+ 	     inet_ntoa(nsa4->sin_addr),
+ 	     ntohs(nsa4->sin_port), ds,
+ 	     ntohs(qp->q_nsid), ntohs(qp->q_id),
+ 	     (qp->q_addr[0].nsdata != NULL)
+ 	     ? qp->q_addr[0].nsdata->d_nstime : -1,
+ 	     (int)(qp->q_time - tt.tv_sec));
+ 	}
+ #ifdef DEBUG
+ 	if (debug >= 10)
+ 		fp_nquery(msg, msglen, log_get_stream(packet_channel));
+ #endif
+ 
+ 	if (qp->q_flags & Q_USEVC) {
+ 		if (tcp_send(qp) != NOERROR) {
+ 			if (nsa->sa_family == AF_INET)
+ 				mnsa.sin = *nsa4;
+ 			else if (nsa->sa_family == AF_INET6)
+ 				mnsa.sin6 = *nsa6;
+ 			if (!haveComplained46(&mnsa, (u_long)tcpsendStr)) {
+ 				ns_info(ns_log_default,
+ 					"ns_forw: tcp_send(%s) failed: %s",
+ 					sin_ntoa(mnsa), strerror(errno));
+ 			}
+ 		}
+ 	} else if (nsa->sa_family == AF_INET6) {
+ 	    if (sendto(ds6, (char *)msg, msglen, 0, (struct sockaddr *)nsa,
+ 		       sizeof(struct sockaddr_in6)) < 0) {
+ 		if (!haveComplained6(nsa6->sin6_addr,
+ 				    (u_long)sendtoStr)) {
+ 			inet_ntop(AF_INET6, &nsa6->sin6_addr,
+ 				   vname, sizeof(vname));
+ 			ns_info(ns_log_default, "ns_forw: sendto(%s): %s",
+ 				vname, strerror(errno));
+ 		}
+ 		mnsa.sin6 = *nsa6;
+ 		nameserIncr(mnsa, nssSendtoErr);
+ 	    }
+ 	} else {
+ 	    if (sendto(ds, (char *)msg, msglen, 0, (struct sockaddr *)nsa,
+ 		       sizeof(struct sockaddr_in)) < 0) {
+ 		mnsa.sin = *nsa4;
+ 		if (!haveComplained(ina_ulong(nsa4->sin_addr),
+ 				    (u_long)sendtoStr))
+ 		    ns_info(ns_log_default, "ns_forw: sendto(%s): %s",
+ 			    sin_ntoa(mnsa), strerror(errno));
+ 		nameserIncr(mnsa, nssSendtoErr);
+ 	    }
+ 	}
+ 	if (NS_OPTION_P(OPTION_HOSTSTATS))
+ 		nameserIncr(from, nssRcvdFwdQ);
+ 	if (nsa->sa_family == AF_INET6) {
+ 	    mnsa.sin6 = *nsa6;
+ 	    nameserIncr(mnsa, nssSentFwdQ);
+ 	} else {
+ 	    mnsa.sin = *nsa4;
+ 	    nameserIncr(mnsa, nssSentFwdQ);
+ 	}
+ #else
+ 	syslog(LOG_NOTICE,
+ 		"forw: forw -> [%s].%d ds=%d nsid=%d id=%d %dms retry %dsec",
+ 		inet_ntoa(nsa->sin_addr),
+ 		ntohs(nsa->sin_port), ds,
+ 		ntohs(qp->q_nsid), ntohs(qp->q_id),
+ 		(qp->q_addr[0].nsdata != NULL)
+ 			? qp->q_addr[0].nsdata->d_nstime
+ 			: -1,
+ 		(int)(qp->q_time - tt.tv_sec));
+ 
  	ns_debug(ns_log_default, 1,
  		"forw: forw -> [%s].%d ds=%d nsid=%d id=%d %dms retry %dsec",
  		inet_ntoa(nsa->sin_addr),
***************
*** 212,217 ****
--- 348,354 ----
  	if (debug >= 10)
  		fp_nquery(msg, msglen, log_get_stream(packet_channel));
  #endif
+ 
  	if (qp->q_flags & Q_USEVC) {
  		if (tcp_send(qp) != NOERROR) {
  			if (!haveComplained(ina_ulong(nsa->sin_addr),
***************
*** 231,236 ****
--- 368,375 ----
  	if (NS_OPTION_P(OPTION_HOSTSTATS))
  		nameserIncr(from.sin_addr, nssRcvdFwdQ);
  	nameserIncr(nsa->sin_addr, nssSentFwdQ);
+ 
+ #endif
  	if (qpp)
  		*qpp = qp;
  	hp->rd = 1;
***************
*** 246,256 ****
--- 385,445 ----
   * author:
   *	Paul Vixie (DECWRL) April 1991
   */
+ #ifdef INET6
+ int
+ haveComplained46(msockaddr_in *tag1, u_long tag2)
+ {
+ 	switch (tag1->sin.sin_family) {
+ 	case AF_INET:
+ 		return haveComplained(ina_ulong(tag1->sin.sin_addr), tag2);
+ 	case AF_INET6:
+ 		return haveComplained6(tag1->sin6.sin6_addr, tag2);
+ 	default:
+ 		return 0;
+ 	}
+ }
+ 
  int
  haveComplained(u_long tag1, u_long tag2) {
  	struct complaint *cur, *next, *prev;
  	int r = 0;
+ 	for (cur = complaints, prev = NULL;
+ 	     cur != NULL;
+ 	     prev = cur, cur = next) {
+ 		next = cur->next;
+ 		if (tt.tv_sec > cur->expire) {
+ 			if (prev)
+ 				prev->next = next;
+ 			else
+ 				complaints = next;
+ 			memput(cur, sizeof *cur);
+ 			cur = prev;
+ 		} else if (cur->type == 1 &&  tag1 == cur->tag1 && 
+ 			    tag2 == cur->tag2)
+ 			r++;
+ 	}
+ 	if (!r) {
+ 		cur = (struct complaint *)memget(sizeof(struct complaint));
+ 		if (cur) {
+ 			cur->tag1 = tag1;
+ 			cur->tag2 = tag2;
+ 			cur->tag3 = in6addr_any;
+ 			cur->type = 1;
+ 			cur->expire = tt.tv_sec + INIT_REFRESH;	/* "10:00" */
+ 			cur->next = NULL;
+ 			if (prev)
+ 				prev->next = cur;
+ 			else
+ 				complaints = cur;
+ 		}
+ 	}
+ 	return (r);
+ }
  
+ int
+ haveComplained6(struct in6_addr tag3, u_long tag2) {
+ 	struct complaint *cur, *next, *prev;
+ 	int r = 0;
  	for (cur = complaints, prev = NULL;
  	     cur != NULL;
  	     prev = cur, cur = next) {
***************
*** 262,267 ****
--- 451,494 ----
  				complaints = next;
  			memput(cur, sizeof *cur);
  			cur = prev;
+ 		} else if (cur->type == 0 && 
+ 			   IN6_ARE_ADDR_EQUAL((&tag3),(&cur->tag3)) &&
+ 			   tag2 == cur->tag2)
+ 			r++;
+ 	}
+ 	if (!r) {
+ 		cur = (struct complaint *)memget(sizeof(struct complaint));
+ 		if (cur) {
+ 			cur->tag1 = 0;
+ 			cur->tag2 = tag2;
+ 			cur->tag3 = tag3;
+ 			cur->type = 0;
+ 			cur->expire = tt.tv_sec + INIT_REFRESH;	/* "10:00" */
+ 			cur->next = NULL;
+ 			if (prev)
+ 				prev->next = cur;
+ 			else
+ 				complaints = cur;
+ 		}
+ 	}
+ 	return (r);
+ }
+ #else
+ int
+ haveComplained(u_long tag1, u_long tag2) {
+ 	struct complaint *cur, *next, *prev;
+ 	int r = 0;
+ 	for (cur = complaints, prev = NULL;
+ 	     cur != NULL;
+ 	     prev = cur, cur = next) {
+ 		next = cur->next;
+ 		if (tt.tv_sec > cur->expire) {
+ 			if (prev)
+ 				prev->next = next;
+ 			else
+ 				complaints = next;
+ 			memput(cur, sizeof *cur);
+ 			cur = prev;
  		} else if (tag1 == cur->tag1 && tag2 == cur->tag2)
  			r++;
  	}
***************
*** 278,290 ****
  				complaints = cur;
  		}
  	}
  	return (r);
  }
  
  void
  freeComplaints(void) {
  	struct complaint *cur, *next;
- 
  	for (cur = complaints; cur != NULL; cur = next) {
  		next = cur->next;
  		memput(cur, sizeof *cur);
--- 505,518 ----
  				complaints = cur;
  		}
  	}
+ 
  	return (r);
  }
+ #endif
  
  void
  freeComplaints(void) {
  	struct complaint *cur, *next;
  	for (cur = complaints; cur != NULL; cur = next) {
  		next = cur->next;
  		memput(cur, sizeof *cur);
***************
*** 309,314 ****
--- 537,545 ----
  	char *a, *ns;
  	const char *a_type;
  	int print_a;
+ #ifdef INET6
+ 	char vname[INET6_ADDRSTRLEN];
+ #endif
  
  	ns_debug(ns_log_default, 2, "NS '%s' %s", dname, complaint);
  	if (sysloginfo && queryname && !haveComplained((u_long)queryname,
***************
*** 334,348 ****
--- 565,605 ----
  
  			if (nsdp != NULL) {
  				if (nsdp->d_ns != NULL) {
+ #ifdef INET6
+ 				    if (nsdp->d_ns->msaddr.sin6.sin6_family == AF_INET6) {
+ 					inet_ntop(AF_INET6,
+ 					  &nsdp->d_ns->msaddr.sin6.sin6_addr,
+ 						  vname, sizeof(vname)); 
+ 					strcpy(nsbuf, vname);
+ 
+ 				    } else {
  					strcpy(nsbuf,
+ 			       inet_ntoa(nsdp->d_ns->msaddr.sin.sin_addr));
+ 				    }
+ #else
+ 					strcpy(nsbuf,
  					       inet_ntoa(nsdp->d_ns->addr));
+ #endif
  					ns = nsbuf;
  				} else {
  					ns = zones[nsdp->d_zone].z_origin;
  				}
  			}
  			if (a_rr->d_ns != NULL) {
+ #ifdef INET6
+ 				    if (a_rr->d_ns->msaddr.sin6.sin6_family == AF_INET6) {
+ 					inet_ntop(AF_INET6,
+ 					  &a_rr->d_ns->msaddr.sin6.sin6_addr,
+ 						  vname, sizeof(vname)); 
+ 					strcpy(abuf, vname);
+ 
+ 				    } else {
+ 					strcpy(abuf,
+ 			       inet_ntoa(a_rr->d_ns->msaddr.sin.sin_addr));
+ 				    }
+ #else
  				strcpy(abuf, inet_ntoa(a_rr->d_ns->addr));
+ #endif
  				a = abuf;
  			} else {
  				a = zones[a_rr->d_zone].z_origin;
***************
*** 357,363 ****
  				    inet_ntoa(ina_get(a_rr->d_data)) : "",
  				a_type,
  				a ? a : "<Not Available>",
! 				ns ? ns : "<Not Available>" );
  		else
  			ns_info(ns_log_default, "%s: query(%s) %s (%s:%s)",
  				sysloginfo, queryname,
--- 614,620 ----
  				    inet_ntoa(ina_get(a_rr->d_data)) : "",
  				a_type,
  				a ? a : "<Not Available>",
! 				ns ? ns : "<Not Available>");
  		else
  			ns_info(ns_log_default, "%s: query(%s) %s (%s:%s)",
  				sysloginfo, queryname,
***************
*** 397,402 ****
--- 654,662 ----
  	const char *fname;
  	int oldn, naddr, class, found_arr, potential_ns;
  	time_t curtime;
+ #ifdef INET6
+         char vname[INET6_ADDRSTRLEN];
+ #endif
  
  	ns_debug(ns_log_default, 3, "nslookup(nsp=%#x, qp=%#x, \"%s\")",
  		nsp, qp, syslogdname);
***************
*** 429,434 ****
--- 689,695 ----
  			found_arr = 0;
  			goto need_sysquery;
  		}
+ 
  		if (fname != dname) {
  			if (findMyZone(np, class) == DB_Z_CACHE) {
  				/*
***************
*** 464,476 ****
--- 725,742 ----
  				continue;
  			}
  		}
+ 
  		found_arr = 0;
  		oldn = n;
  
  		/* look for name server addresses */
  		delete_stale(np);
  		for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
+ #ifdef INET6
+ 			msockaddr_in nsa;
+ #else
  			struct in_addr nsa;
+ #endif
  
  			if (dp->d_type == T_CNAME && dp->d_class == class) {
  				static const char *complaint =
***************
*** 481,488 ****
--- 747,761 ----
  						complaint, dname, dp, nsdp);
  				goto skipserver;
  			}
+ #ifdef INET6
+ 			if ((dp->d_type != T_A && dp->d_type != T_AAAA) ||
+ 			    dp->d_class != class)
+ 				continue;
+ #else
  			if (dp->d_type != T_A || dp->d_class != class)
  				continue;
+ #endif
+ 
  			if (dp->d_rcode) {
  				static const char *complaint =
  					"A RR negative cache entry";
***************
*** 497,502 ****
--- 770,776 ----
  						 complaint, dname, dp, nsdp);
  				continue;
  			}
+ 
  #ifdef INADDR_LOOPBACK
  			if (ina_hlong(ina_get(dp->d_data))==INADDR_LOOPBACK) {
  				static const char *complaint =
***************
*** 515,520 ****
--- 789,795 ----
  				continue;
  			}
  #endif
+ 
  #ifdef IN_MULTICAST
  			if (IN_MULTICAST(ina_hlong(ina_get(dp->d_data)))) {
  				static const char *complaint =
***************
*** 529,537 ****
  			 * reference later when we do the rtt computation.
  			 * Never delete our safety-belt information!
  			 */
  			if ((dp->d_zone == DB_Z_CACHE) &&
  			    (dp->d_ttl < (u_int32_t)curtime) &&
! 			    !(dp->d_flags & DB_F_HINT) )
  		        {
  				ns_debug(ns_log_default, 1,
  					 "nslookup: stale '%s'",
--- 804,813 ----
  			 * reference later when we do the rtt computation.
  			 * Never delete our safety-belt information!
  			 */
+ 
  			if ((dp->d_zone == DB_Z_CACHE) &&
  			    (dp->d_ttl < (u_int32_t)curtime) &&
! 			    !(dp->d_flags & DB_F_HINT))
  		        {
  				ns_debug(ns_log_default, 1,
  					 "nslookup: stale '%s'",
***************
*** 542,559 ****
--- 818,868 ----
  			}
  
  			found_arr++;
+ #ifdef INET6
+ 			if (dp->d_type == T_A) {
+ 			    nsa.sin.sin_family = AF_INET;
+ 			    nsa.sin.sin_addr = ina_get(dp->d_data);
+ 			}
+ #else
  			nsa = ina_get(dp->d_data);
+ #endif
  			/* don't put in duplicates */
  			qs = qp->q_addr;
+ #ifdef INET6
+ 			for (i = 0; i < (u_int)n; i++, qs++) {
+ 			    if (qs->ns_addr.sin.sin_family == AF_INET &&
+ 				ina_equal(qs->ns_addr.sin.sin_addr,
+ 					  nsa.sin.sin_addr)) {
+ 				ns_debug(ns_log_default, 8, "nslookup: go skipaddr %d", n);
+ 				goto skipaddr;
+ 			    }
+ 			}
+ 
+ 			if (dp->d_type == T_AAAA) {
+ 			    inet_ntop(AF_INET6,
+ 				       (struct in6_addr*)dp->d_data,
+ 				       vname, sizeof(vname));
+ 			    qs->ns_addr.sin6.sin6_family = AF_INET6;
+ 			    qs->ns_addr.sin6.sin6_port = ns_port;
+ 			    qs->ns_addr.sin6.sin6_addr = 
+ 				*(struct in6_addr*)dp->d_data;
+                         } else {
+ 			    qs->ns_addr.sin.sin_family = AF_INET;
+ 			    qs->ns_addr.sin.sin_port = ns_port;
+ 			    qs->ns_addr.sin.sin_addr = nsa.sin.sin_addr;
+ 			}
+ #else
  			for (i = 0; i < (u_int)n; i++, qs++)
  				if (ina_equal(qs->ns_addr.sin_addr, nsa))
  					goto skipaddr;
  			qs->ns_addr.sin_family = AF_INET;
  			qs->ns_addr.sin_port = ns_port;
  			qs->ns_addr.sin_addr = nsa;
+ #endif
  			qs->ns = nsdp;
  			qs->nsdata = dp;
  			qs->nretry = 0;
+ 
  			/*
  			 * If this A RR has no RTT, initialize its RTT to a
  			 * small random value.
***************
*** 577,588 ****
--- 886,911 ----
  			 * try to limp along instead of denying service
  			 * gdonl mar96
  			 */
+ #ifdef INET6
+ 			if (nsa.sin6.sin6_family == AF_INET6) {
+ 			    ;
+ 			} else if (nsa.sin.sin_family == AF_INET &&
+ 				   aIsUs(nsa.sin.sin_addr)) {
+ 			    static char *complaint = "contains our address";
+ 			    nslookupComplain(sysloginfo, syslogdname,
+ 					     complaint, dname, dp, nsdp);
+ 			    continue;
+ 			}
+ #else
+ 
  			if (aIsUs(nsa)) {
  			    static char *complaint = "contains our address";
  			    nslookupComplain(sysloginfo, syslogdname,
  					     complaint, dname, dp, nsdp);
  			    continue;
  			}
+ #endif
+ 
  			/*
  			 * If we want to forward to a host that asked us
  			 * this question then either we or they are sick
***************
*** 600,605 ****
--- 923,929 ----
  					     complaint, dname, dp, nsdp);
  			    continue;
  			}
+ 
  #ifdef BOGUSNS
  			/*
  			 * Don't forward queries to bogus servers.  Note
***************
*** 616,622 ****
  			if (ip_match_address(bogus_nameservers, nsa) > 0)
  				goto skipserver;
  #endif
- 
  			n++;
  			if (n >= NSMAX)
  				goto out;
--- 940,945 ----
***************
*** 627,635 ****
--- 950,965 ----
   need_sysquery:
  		if (found_arr == 0) {
  			potential_ns++;
+ #ifdef INET6
+ 			if (!(qp->q_flags & Q_SYSTEM)) {
+ 				(void) sysquery(dname, class, T_A, NULL, 0,
+ 						QUERY);
+ 			}
+ #else
  			if (!(qp->q_flags & Q_SYSTEM))
  				(void) sysquery(dname, class, T_A, NULL, 0,
  						QUERY);
+ #endif
  		}
   skipserver:
  		(void)NULL;
***************
*** 645,650 ****
--- 975,981 ----
  			ns_info(ns_log_default, "%s: query(%s) %s",
  				sysloginfo, syslogdname, complaint);
  		}
+ 
  		return(-1);
  	}
  	/* Update the refcounts before the sort. */
***************
*** 656,661 ****
--- 987,993 ----
  		qsort((char *)qp->q_addr, n, sizeof(struct qserv),
  		      (int (*)(const void *, const void *))qcomp);
  	}
+ 
  	return (n - naddr);
  }
  
***************
*** 730,736 ****
  	if (debug >= 10) {
  		char a1[sizeof "255.255.255.255"],
  		     a2[sizeof "255.255.255.255"];
! 
  		strcpy(a1, inet_ntoa(qs1->ns_addr.sin_addr));
  		strcpy(a2, inet_ntoa(qs2->ns_addr.sin_addr));
  		ns_debug(ns_log_default, 10,
--- 1062,1069 ----
  	if (debug >= 10) {
  		char a1[sizeof "255.255.255.255"],
  		     a2[sizeof "255.255.255.255"];
! #ifdef INET6
! #else
  		strcpy(a1, inet_ntoa(qs1->ns_addr.sin_addr));
  		strcpy(a2, inet_ntoa(qs2->ns_addr.sin_addr));
  		ns_debug(ns_log_default, 10,
***************
*** 739,751 ****
--- 1072,1092 ----
  			 rtt1, RTTROUND(rtt1),
  			 rtt2, RTTROUND(rtt2),
  			 rtt1 - rtt2);
+ #endif
  	}
  #endif
  	if (RTTROUND(rtt1) == RTTROUND(rtt2)) {
+ #ifdef INET6
+ 		pos1 = distance_of_address(server_options->topology,
+ 					   qs1->ns_addr.sin.sin_addr);
+ 		pos2 = distance_of_address(server_options->topology,
+ 					   qs2->ns_addr.sin.sin_addr);
+ #else
  		pos1 = distance_of_address(server_options->topology,
  					   qs1->ns_addr.sin_addr);
  		pos2 = distance_of_address(server_options->topology,
  					   qs2->ns_addr.sin_addr);
+ #endif
  		pdiff = pos1 - pos2;
  		ns_debug(ns_log_default, 10, "\tpos1=%d, pos2=%d", pos1, pos2);
  		if (pdiff)
***************
*** 819,825 ****
  void
  reset_retrytimer() {
  	static evTimerID id;
- 
  	if (retry_timer_set) {
  		(void) evClearTimer(ev, id);
  		retry_timer_set = 0;
--- 1160,1165 ----
***************
*** 848,855 ****
--- 1188,1201 ----
  retry(struct qinfo *qp) {
  	int n;
  	HEADER *hp;
+ #ifdef INET6
+ 	msockaddr_in *nsa;
+ 	char hostbuf[MAXHOSTNAMELEN];
+ #else
  	struct sockaddr_in *nsa;
+ #endif
  
+ 
  	ns_debug(ns_log_default, 3, "retry(%#lx) id=%d", (u_long)qp,
  		 ntohs(qp->q_id));
  
***************
*** 935,942 ****
--- 1281,1293 ----
  			 "gave up retry(%#lx) nsid=%d id=%d",
  			 (u_long)qp, ntohs(qp->q_nsid), ntohs(qp->q_id));
  	}
+ #ifdef INET6
+ 	if (NS_OPTION_P(OPTION_HOSTSTATS))
+ 		nameserIncr(qp->q_from, nssSentFail);
+ #else
  	if (NS_OPTION_P(OPTION_HOSTSTATS))
  		nameserIncr(qp->q_from.sin_addr, nssSentFail);
+ #endif
  	qremove(qp);
  	return;
  
***************
*** 947,967 ****
--- 1298,1349 ----
  	hp = (HEADER *)qp->q_msg;
  	hp->rd = (qp->q_fwd ? 1 : 0);
  	nsa = Q_NEXTADDR(qp, n);
+ #ifdef INET6
+ 	switch (nsa->sin.sin_family) {
+ 	case AF_INET:
+ 	    inet_ntop(AF_INET, &nsa->sin.sin_addr, hostbuf, sizeof(hostbuf));
+ 	    break;
+ 	case AF_INET6:
+ 	    inet_ntop(AF_INET6, &nsa->sin6.sin6_addr, hostbuf, sizeof(hostbuf));
+ 	    break;
+ 	default:
+ 	    strcpy(hostbuf, "invalid");
+ 	}
+ #endif
  	ns_debug(ns_log_default, 1,
  		 "%s(addr=%d n=%d) -> [%s].%d ds=%d nsid=%d id=%d %dms",
  		 (qp->q_fwd ? "reforw" : "resend"),
  		 n, qp->q_addr[n].nretry,
+ #ifdef INET6
+ 		 hostbuf,
+ 		 ntohs(nsa->sin.sin_port),
+ #else
  		 inet_ntoa(nsa->sin_addr),
+ 		 ntohs(nsa->sin_port),
+ #endif
+ 		 ds,
+ 		 ntohs(qp->q_nsid), ntohs(qp->q_id),
+ 		 (qp->q_addr[n].nsdata != 0)
+ 		 ? qp->q_addr[n].nsdata->d_nstime
+ 		 : (-1));
+ #ifdef V6DEBUG
+ 	syslog(LOG_NOTICE,
+ 		 "%s(addr=%d n=%d) -> [%s].%d ds=%d nsid=%d id=%d %dms",
+ 		 (qp->q_fwd ? "reforw" : "resend"),
+ 		 n, qp->q_addr[n].nretry,
+ 		 inet_ntoa(nsa->sin_addr),
  		 ntohs(nsa->sin_port), ds,
  		 ntohs(qp->q_nsid), ntohs(qp->q_id),
  		 (qp->q_addr[n].nsdata != 0)
  		 ? qp->q_addr[n].nsdata->d_nstime
  		 : (-1));
+ #endif
  #ifdef DEBUG
  	if (debug >= 10)
  		fp_nquery(qp->q_msg, qp->q_msglen,
  			  log_get_stream(packet_channel));
  #endif
+ 
  	if (qp->q_flags & Q_USEVC) {
  		if (tcp_send(qp) != NOERROR)
  			ns_debug(ns_log_default, 3,
***************
*** 975,982 ****
--- 1357,1369 ----
  			 strerror(errno));
  	}
  	hp->rd = 1;	/* leave set to 1 for dup detection */
+ #ifdef INET6
+ 	nameserIncr(*nsa, nssSentDupQ);
+ #else
  	nameserIncr(nsa->sin_addr, nssSentDupQ);
+ #endif
  	unsched(qp);
+ 
  #ifdef SLAVE_FORWARD
  	if (NS_OPTION_P(OPTION_FORWARD_ONLY))
  		schedretry(qp, (time_t)slave_retry);
***************
*** 1012,1030 ****
  
  void
  qflush() {
! 	while (nsqhead)
  		qremove(nsqhead);
  	nsqhead = NULL;
  	priming = 0;
  }
  
  void
  qremove(struct qinfo *qp) {
  	struct sockaddr_in empty_from;
  
  	empty_from.sin_family = AF_INET;
  	empty_from.sin_addr.s_addr = htonl(INADDR_ANY);
  	empty_from.sin_port = htons(0);
  
  	ns_debug(ns_log_default, 3, "qremove(%#lx)", (u_long)qp);
  	
--- 1399,1426 ----
  
  void
  qflush() {
!     while (nsqhead) {
  		qremove(nsqhead);
+     }
  	nsqhead = NULL;
  	priming = 0;
  }
  
  void
  qremove(struct qinfo *qp) {
+ #ifdef INET6
+ 	msockaddr_in empty_from;
+ 
+ 	empty_from.sin.sin_family = AF_INET;
+ 	empty_from.sin.sin_addr.s_addr = htonl(INADDR_ANY);
+ 	empty_from.sin.sin_port = htons(0);
+ #else
  	struct sockaddr_in empty_from;
  
  	empty_from.sin_family = AF_INET;
  	empty_from.sin_addr.s_addr = htonl(INADDR_ANY);
  	empty_from.sin_port = htons(0);
+ #endif
  
  	ns_debug(ns_log_default, 3, "qremove(%#lx)", (u_long)qp);
  	
***************
*** 1119,1125 ****
  	if (nsqhead == qp)
  		nsqhead = qp->q_link;
  	else {
! 		for(np = nsqhead;
  		    np->q_link != NULL;
  		    np = np->q_link) {
  			if (np->q_link != qp)
--- 1515,1521 ----
  	if (nsqhead == qp)
  		nsqhead = qp->q_link;
  	else {
! 		for (np = nsqhead;
  		    np->q_link != NULL;
  		    np = np->q_link) {
  			if (np->q_link != qp)
Index: bind8/src/bin/named/ns_func.h
diff -c bind8/src/bin/named/ns_func.h:1.1.1.1 bind8/src/bin/named/ns_func.h:1.4.2.1
*** bind8/src/bin/named/ns_func.h:1.1.1.1	Fri Sep 25 14:24:52 1998
--- bind8/src/bin/named/ns_func.h	Fri Jun  4 07:56:10 1999
***************
*** 67,78 ****
  
  /* ns_func.h - declarations for ns_*.c's externally visible functions
   *
!  * $Id: ns_func.h,v 8.43 1998/03/20 00:53:44 halley Exp $
   */
  
  /* ++from ns_glue.c++ */
  extern struct in_addr	ina_get(const u_char *data);
  extern const char	*sin_ntoa(struct sockaddr_in);
  extern void		ns_debug(int, int, const char *, ...),
  			ns_info(int, const char *, ...),
  			ns_notice(int, const char *, ...),
--- 67,82 ----
  
  /* ns_func.h - declarations for ns_*.c's externally visible functions
   *
!  * $Id: ns_func.h,v 1.3 1998/11/28 03:41:09 itojun Exp $
   */
  
  /* ++from ns_glue.c++ */
  extern struct in_addr	ina_get(const u_char *data);
+ #ifdef INET6
+ extern const char	*sin_ntoa(msockaddr_in);
+ #else
  extern const char	*sin_ntoa(struct sockaddr_in);
+ #endif
  extern void		ns_debug(int, int, const char *, ...),
  			ns_info(int, const char *, ...),
  			ns_notice(int, const char *, ...),
***************
*** 110,125 ****
--- 114,144 ----
  /* --from ns_glue.c-- */
  
  /* ++from ns_resp.c++ */
+ #ifdef INET6
+ extern void		ns_resp(u_char *, int, msockaddr_in,
+ 				struct qstream *),
+ #else
  extern void		ns_resp(u_char *, int, struct sockaddr_in,
  				struct qstream *),
+ #endif
  			prime_cache(void),
  			delete_all(struct namebuf *, int, int),
                          delete_stale(struct namebuf *);
+ #ifdef INET6
+ extern struct qinfo	*sysquery(const char *, int, int,
+ 				  msockaddr_in *, int, int);
+ #else
  extern struct qinfo	*sysquery(const char *, int, int,
  				  struct in_addr *, int, int);
+ #endif
  extern void		sysnotify(const char *, int, int);
+ #ifdef INET6
  extern int		doupdate(u_char *, u_char *, struct databuf **,
+ 				 int, int, int, u_int, msockaddr_in),
+ #else
+ extern int		doupdate(u_char *, u_char *, struct databuf **,
  				 int, int, int, u_int, struct sockaddr_in),
+ #endif
  			send_msg(u_char *, int, struct qinfo *),
  			findns(struct namebuf **, int,
  			       struct databuf **, int *, int),
***************
*** 133,142 ****
--- 152,168 ----
  /* --from ns_resp.c-- */
  
  /* ++from ns_req.c++ */
+ #ifdef INET6
+ extern void		ns_req(u_char *, int, int,
+ 			       struct qstream *,
+ 			       msockaddr_in,
+ 			       int),
+ #else
  extern void		ns_req(u_char *, int, int,
  			       struct qstream *,
  			       struct sockaddr_in,
  			       int),
+ #endif
  			free_addinfo(void),
  			free_nsp(struct databuf **);
  extern int		stale(struct databuf *),
***************
*** 148,156 ****
--- 174,187 ----
  				  struct namebuf *,
  				  struct databuf *);
  #ifdef BIND_NOTIFY
+ #ifdef INET6
+ extern int		findZonePri(const struct zoneinfo *,
+ 				    msockaddr_in);
+ #else
  extern int		findZonePri(const struct zoneinfo *,
  				    const struct sockaddr_in);
  #endif
+ #endif
  /* --from ns_req.c-- */
  
  /* ++from ns_xfr.c++ */
***************
*** 163,168 ****
--- 194,217 ----
  
  /* ++from ns_forw.c++ */
  extern time_t		retrytime(struct qinfo *);
+ #ifdef INET6
+ extern int		ns_forw(struct databuf *nsp[],
+ 				u_char *msg,
+ 				int msglen,
+ 				msockaddr_in from,
+ 				struct qstream *qsp,
+ 				int dfd,
+ 				struct qinfo **qpp,
+ 				const char *dname,
+ 				int class,
+ 				int type,
+ 				struct namebuf *np,
+ 				int use_tcp),
+ 			haveComplained46(msockaddr_in *, u_long),
+ 			haveComplained(u_long, u_long),
+                         haveComplained6(struct in6_addr, u_long tag2),
+ 
+ #else
  extern int		ns_forw(struct databuf *nsp[],
  				u_char *msg,
  				int msglen,
***************
*** 176,181 ****
--- 225,231 ----
  				struct namebuf *np,
  				int use_tcp),
  			haveComplained(u_long, u_long),
+ #endif
  			nslookup(struct databuf *nsp[],
  				 struct qinfo *qp,
  				 const char *syslogdname,
***************
*** 231,238 ****
--- 281,293 ----
  			loadxfer(void),
  			qserial_retrytime(struct zoneinfo *, time_t),
  			qserial_query(struct zoneinfo *),
+ #ifdef INET6
  			qserial_answer(struct qinfo *, u_int32_t,
+ 				       msockaddr_in),
+ #else
+ 			qserial_answer(struct qinfo *, u_int32_t,
  				       struct sockaddr_in),
+ #endif
  #ifdef DEBUG
  			printzoneinfo(int, int, int),
  #endif
***************
*** 253,259 ****
  				  struct zoneinfo *zp,
  				  enum transport, enum context,
  				  const char *owner,
! 				  struct in_addr source);
  extern int		ns_wildcard(const char *name);
  extern void		zoneinit(struct zoneinfo *),
                          do_reload(const char *, int, int),
--- 308,319 ----
  				  struct zoneinfo *zp,
  				  enum transport, enum context,
  				  const char *owner,
! #ifdef INET6
! 				  msockaddr_in source
! #else
! 				  struct in_addr source
! #endif
! 				  );
  extern int		ns_wildcard(const char *name);
  extern void		zoneinit(struct zoneinfo *),
                          do_reload(const char *, int, int),
***************
*** 261,267 ****
--- 321,331 ----
  /* --from ns_init.c-- */
  
  /* ++from ns_ncache.c++ */
+ #ifdef INET6
+ extern void		cache_n_resp(u_char *, int, msockaddr_in);
+ #else
  extern void		cache_n_resp(u_char *, int, struct sockaddr_in);
+ #endif
  /* --from ns_ncache.c-- */
  
  /* ++from ns_udp.c++ */
***************
*** 274,280 ****
--- 338,348 ----
  extern void		ns_logstats(evContext ctx, void *uap,
  				    struct timespec, struct timespec);
  extern void		qtypeIncr(int qtype);
+ #ifdef INET6
+ extern struct nameser	*nameserFind(msockaddr_in addr, int flags);
+ #else
  extern struct nameser	*nameserFind(struct in_addr addr, int flags);
+ #endif
  #define NS_F_INSERT	0x0001
  #define nameserIncr(a,w) NS_INCRSTAT(a,w)	/* XXX should change name. */
  /* --from ns_stats.c-- */
***************
*** 290,298 ****
--- 358,372 ----
  int			merge_logs(struct zoneinfo *zp);
  int			zonedump(struct zoneinfo *zp);
  void			dynamic_about_to_exit(void);
+ #ifdef INET6
+ enum req_action		req_update(HEADER *hp, u_char *cp, u_char *eom,
+ 				   u_char *msg, struct qstream *qsp,
+ 				   int dfd, msockaddr_in from);
+ #else
  enum req_action		req_update(HEADER *hp, u_char *cp, u_char *eom,
  				   u_char *msg, struct qstream *qsp,
  				   int dfd, struct sockaddr_in from);
+ #endif
  void			rdata_dump(struct databuf *dp, FILE *fp);
  /* --from ns_update.c-- */
  
***************
*** 309,318 ****
--- 383,401 ----
  int			set_zone_update_acl(zone_config, ip_match_list);
  int			set_zone_query_acl(zone_config, ip_match_list);
  int			set_zone_transfer_acl(zone_config, ip_match_list);
+ #ifdef INET6
+ int			set_zone_transfer_source(zone_config, msockaddr_in, int);
+ #else
  int			set_zone_transfer_source(zone_config, struct in_addr);
+ #endif
  int 			set_zone_transfer_time_in(zone_config, long);
+ #ifdef INET6
+ int			add_zone_master(zone_config, msockaddr_in);
+ int			add_zone_notify(zone_config, msockaddr_in);
+ #else
  int			add_zone_master(zone_config, struct in_addr);
  int			add_zone_notify(zone_config, struct in_addr);
+ #endif
  options			new_options(void);
  void			free_options(options);
  void			set_boolean_option(options, int, int);
***************
*** 325,331 ****
--- 408,418 ----
  void			use_default_options(void);
  ip_match_list		new_ip_match_list(void);
  void			free_ip_match_list(ip_match_list);
+ #ifdef INET6
+ ip_match_element	new_ip_match_pattern(msockaddr_in, u_int);
+ #else
  ip_match_element	new_ip_match_pattern(struct in_addr, u_int);
+ #endif
  ip_match_element	new_ip_match_mask(struct in_addr, struct in_addr);
  ip_match_element	new_ip_match_indirect(ip_match_list);
  ip_match_element	new_ip_match_localhost(void);
***************
*** 334,349 ****
--- 421,450 ----
  void			add_to_ip_match_list(ip_match_list, ip_match_element);
  void			dprint_ip_match_list(int, ip_match_list, int, char *,
  					     char *);
+ #ifdef INET6
+ int			ip_match_address(ip_match_list, msockaddr_in);
+ int			ip_address_allowed(ip_match_list, msockaddr_in);
+ #else
  int			ip_match_address(ip_match_list, struct in_addr);
  int			ip_address_allowed(ip_match_list, struct in_addr);
+ #endif
  int			ip_match_network(ip_match_list, struct in_addr,
  					 struct in_addr);
  int			distance_of_address(ip_match_list, struct in_addr);
  int			ip_match_is_none(ip_match_list);
+ #ifdef INET6
+ void			add_forwarder(options, msockaddr_in );
+ #else
  void			add_forwarder(options, struct in_addr);
+ #endif
  void			free_forwarders(struct fwdinfo *);
+ #ifdef INET6
+ server_info		find_server(msockaddr_in);
+ server_config		begin_server(msockaddr_in);
+ #else
  server_info		find_server(struct in_addr);
  server_config		begin_server(struct in_addr);
+ #endif
  void			end_server(server_config, int);
  void			set_server_option(server_config, int, int);
  void			set_server_transfers(server_config, int);
***************
*** 368,373 ****
--- 469,475 ----
  void			init_configuration(void);
  void			shutdown_configuration(void);
  void			load_configuration(const char *);
+ 
  /* --from ns_config.c-- */
  /* ++from parser.y++ */
  ip_match_list		lookup_acl(char *);
Index: bind8/src/bin/named/ns_glob.h
diff -c bind8/src/bin/named/ns_glob.h:1.1.1.1 bind8/src/bin/named/ns_glob.h:1.2
*** bind8/src/bin/named/ns_glob.h:1.1.1.1	Fri Sep 25 14:24:52 1998
--- bind8/src/bin/named/ns_glob.h	Fri Sep 25 17:16:39 1998
***************
*** 1,6 ****
  /*
   *	from ns.h	4.33 (Berkeley) 8/23/90
!  *	$Id: ns_glob.h,v 8.35 1998/05/05 19:44:20 halley Exp $
   */
  
  /* Copyright (c) 1986
--- 1,6 ----
  /*
   *	from ns.h	4.33 (Berkeley) 8/23/90
!  *	$Id: ns_glob.h,v 1.1.1.1 1998/09/25 05:24:52 k-sugyou Exp $
   */
  
  /* Copyright (c) 1986
***************
*** 93,101 ****
--- 93,107 ----
  
  	/* datagram socket for sysquery() and ns_forw(). */
  DECL	int			ds		INIT(-1);
+ #ifdef INET6
+ DECL	int			ds6		INIT(-1);
+ #endif
  
  	/* event ID for reads of "ds". */
  DECL	evFileID		ds_evID;
+ #ifdef INET6
+ DECL	evFileID		ds6_evID;
+ #endif
  
  #ifdef QRYLOG
  	/* is query logging turned on? */
Index: bind8/src/bin/named/ns_glue.c
diff -c bind8/src/bin/named/ns_glue.c:1.1.1.1 bind8/src/bin/named/ns_glue.c:1.2.2.1
*** bind8/src/bin/named/ns_glue.c:1.1.1.1	Fri Sep 25 14:24:52 1998
--- bind8/src/bin/named/ns_glue.c	Tue Jun  1 13:13:16 1999
***************
*** 1,5 ****
  #if !defined(lint) && !defined(SABER)
! static char rcsid[] = "$Id: ns_glue.c,v 8.7 1998/02/13 19:51:45 halley Exp $";
  #endif /* not lint */
  
  /*
--- 1,5 ----
  #if !defined(lint) && !defined(SABER)
! static char rcsid[] = "$Id: ns_glue.c,v 1.1.1.1 1998/09/25 05:24:52 k-sugyou Exp $";
  #endif /* not lint */
  
  /*
***************
*** 74,80 ****
--- 74,111 ----
  /*
   * XXX: sin_ntoa() should probably be in libc.
   */
+ #ifdef INET6
  const char *
+ sin_ntoa(msockaddr_in ms) {
+ 	static char ret[MAXHOSTNAMELEN];
+ 	int af;
+ 	char *p;
+ 	u_short port;
+ 
+ 	switch (ms.sin.sin_family) {
+ 	case AF_INET:
+ 		af = ms.sin.sin_family;
+ 		p = (char *)&ms.sin.sin_addr;
+ 		port = ms.sin.sin_port;
+ 		break;
+ 	case AF_INET6:
+ 		af = ms.sin6.sin6_family;
+ 		p = (char *)&ms.sin6.sin6_addr;
+ 		port = ms.sin6.sin6_port;
+ 		break;
+ 	default:
+ 		strcpy(ret, "[?]?");
+ 		return ret;
+ 	}
+ 	ret[0] = '[';
+ 	inet_ntop(af, p, ret + 1, sizeof(ret) - 10);
+ 	p = ret + strlen(ret);
+ 	*p++ = ']';
+ 	sprintf(p, ".%u", ntohs(port));
+ 	return ret;
+ }
+ #else
+ const char *
  sin_ntoa(struct sockaddr_in sin) {
  	static char ret[sizeof "[111.222.333.444].55555"];
  
***************
*** 83,88 ****
--- 114,120 ----
  		ntohs(sin.sin_port));
  	return (ret);
  }
+ #endif
  
  /*
   * Logging Support
***************
*** 216,222 ****
  	
  	end_tmpdname = tmpdname + tmpdnamelen;
  	
! 	while(tmpdname != end_tmpdname) {
  		count++;
  		/*
  		 * Strip off the first label if we're not already at
--- 248,254 ----
  	
  	end_tmpdname = tmpdname + tmpdnamelen;
  	
! 	while (tmpdname != end_tmpdname) {
  		count++;
  		/*
  		 * Strip off the first label if we're not already at
Index: bind8/src/bin/named/ns_init.c
diff -c bind8/src/bin/named/ns_init.c:1.1.1.1 bind8/src/bin/named/ns_init.c:1.2
*** bind8/src/bin/named/ns_init.c:1.1.1.1	Fri Sep 25 14:24:52 1998
--- bind8/src/bin/named/ns_init.c	Sun Nov 29 02:07:41 1998
***************
*** 1,6 ****
  #if !defined(lint) && !defined(SABER)
  static char sccsid[] = "@(#)ns_init.c	4.38 (Berkeley) 3/21/91";
! static char rcsid[] = "$Id: ns_init.c,v 8.40 1998/04/07 18:11:58 halley Exp $";
  #endif /* not lint */
  
  /*
--- 1,6 ----
  #if !defined(lint) && !defined(SABER)
  static char sccsid[] = "@(#)ns_init.c	4.38 (Berkeley) 3/21/91";
! static char rcsid[] = "$Id: ns_init.c,v 1.1.1.1 1998/09/25 05:24:52 k-sugyou Exp $";
  #endif /* not lint */
  
  /*
***************
*** 398,404 ****
  	  enum transport transport,
  	  enum context context,
  	  const char *owner,
! 	  struct in_addr source)
  {
  	enum severity severity = not_set;
  	int ok = 1;
--- 398,409 ----
  	  enum transport transport,
  	  enum context context,
  	  const char *owner,
! #ifdef INET6
! 	  msockaddr_in source
! #else
! 	  struct in_addr source
! #endif
! 	)
  {
  	enum severity severity = not_set;
  	int ok = 1;
***************
*** 430,435 ****
--- 435,467 ----
  	if (!ok) {
  		char *s, *o;
  
+ #ifdef INET6
+ 		if (source.sin.sin_family == AF_INET
+ 		 && source.sin.sin_addr.s_addr == INADDR_ANY)
+ 			s = savestr(transport_strings[transport], 0);
+ 		else if (source.sin.sin_family == AF_INET) {
+ 			s = newstr(strlen(transport_strings[transport]) +
+ 				   sizeof " from [000.000.000.000]", 0);
+ 			if (s)
+ 				sprintf(s, "%s from [%s]",
+ 					transport_strings[transport],
+ 					inet_ntoa(source.sin.sin_addr));
+ 		} else if (source.sin.sin_family == AF_INET6) {
+ 			char *p;
+ 			s = newstr(strlen(transport_strings[transport]) +
+ 				   sizeof " from []" + INET6_ADDRSTRLEN, 0);
+ 			if (s) {
+ 				sprintf(s, "%s from [",
+ 					transport_strings[transport]);
+ 				p = s + strlen(s);
+ 				inet_ntop(AF_INET6, &source.sin6.sin6_addr,
+ 					p, INET6_ADDRSTRLEN);
+ 				p = s + strlen(s);
+ 				*p++ = ']';
+ 				*p++ = '\0';
+ 			}
+ 		}
+ #else
  		if (source.s_addr == INADDR_ANY)
  			s = savestr(transport_strings[transport], 0);
  		else {
***************
*** 440,445 ****
--- 472,478 ----
  					transport_strings[transport],
  					inet_ntoa(source));
  		}
+ #endif
  		if (strcasecmp(owner, name) == 0)
  			o = savestr("", 0);
  		else {
Index: bind8/src/bin/named/ns_lexer.c
diff -c bind8/src/bin/named/ns_lexer.c:1.1.1.1 bind8/src/bin/named/ns_lexer.c:1.4.2.5
*** bind8/src/bin/named/ns_lexer.c:1.1.1.1	Fri Sep 25 14:24:52 1998
--- bind8/src/bin/named/ns_lexer.c	Fri Jun  4 07:56:11 1999
***************
*** 1,5 ****
  #if !defined(lint) && !defined(SABER)
! static char rcsid[] = "$Id: ns_lexer.c,v 8.12 1997/12/04 08:11:52 halley Exp $";
  #endif /* not lint */
  
  /*
--- 1,5 ----
  #if !defined(lint) && !defined(SABER)
! static char rcsid[] = "$Id: ns_lexer.c,v 1.3 1998/09/25 11:48:30 k-sugyou Exp $";
  #endif /* not lint */
  
  /*
***************
*** 22,28 ****
  #include "port_before.h"
  
  #include <sys/types.h>
! 
  #include <netinet/in.h>
  #include <arpa/nameser.h>
  #include <arpa/inet.h>
--- 22,31 ----
  #include "port_before.h"
  
  #include <sys/types.h>
! #ifdef INET6
! /* need inet_pton */
! #include <sys/socket.h>
! #endif
  #include <netinet/in.h>
  #include <arpa/nameser.h>
  #include <arpa/inet.h>
***************
*** 47,55 ****
--- 50,64 ----
  #include "ns_parseutil.h"
  #include "ns_lexer.h"
  
+ #ifdef INET6
+ typedef enum lexer_state {
+ 		scan, number, identifier, ipv4, ipv6, quoted_string
+ } LexerState;
+ #else
  typedef enum lexer_state {
  		scan, number, identifier, ipv4, quoted_string
  } LexerState;
+ #endif
  
  #define LEX_EOF			0x01
  
***************
*** 69,79 ****
--- 78,94 ----
  
  #define LEX_LAST_WAS_DOT	0x01
  #define LEX_CONSECUTIVE_DOTS	0x02
+ #ifdef INET6
+ #define LEX_LAST_WAS_COL	0x04
+ #endif
  
  typedef struct lexer_identifier {
  	char buffer[LEX_MAX_IDENT_SIZE+1];
  	int index;
  	int num_dots;
+ #ifdef INET6
+ 	int num_cols;
+ #endif
  	unsigned int flags;
  } *LexerIdentifier;
  
***************
*** 116,122 ****
--- 131,149 ----
  			sprintf(buffer, "\"%s\"", lval.cp);
  			break;
  		case L_IPADDR:
+ #ifdef INET6
+ 		    if (lval.ip_addr.sin6.sin6_family == AF_INET6) {
+ 			char vname[INET6_ADDRSTRLEN];
+ 			inet_ntop(AF_INET6,&lval.ip_addr.sin6.sin6_addr,
+ 				  vname, sizeof(vname)); 
+ 			sprintf(buffer, "%s", vname);
+ 		    } else {
+ 			sprintf(buffer, "%s",
+ 				inet_ntoa(lval.ip_addr.sin.sin_addr));
+ 		    }
+ #else
  			sprintf(buffer, "%s", inet_ntoa(lval.ip_addr));
+ #endif
  			break;
  		case L_NUMBER:
  			sprintf(buffer, "%ld", lval.num);
***************
*** 272,277 ****
--- 299,305 ----
  	{"print-category", T_PRINT_CATEGORY},
  	{"print-severity", T_PRINT_SEVERITY},
  	{"print-time", T_PRINT_TIME},
+ 	{"query-source6", T_QUERY_SOURCE6},
  	{"query-source", T_QUERY_SOURCE},
  	{"recursion", T_RECURSION},
  	{"response", T_RESPONSE},
***************
*** 287,292 ****
--- 315,321 ----
  	{"syslog", T_SYSLOG}, 
  	{"topology", T_TOPOLOGY},
  	{"transfer-format", T_TRANSFER_FORMAT}, 
+ 	{"transfer-source6", T_TRANSFER_SOURCE6},
  	{"transfer-source", T_TRANSFER_SOURCE},
  	{"transfers", T_TRANSFERS}, 
  	{"transfers-in", T_TRANSFERS_IN}, 
***************
*** 477,482 ****
--- 506,514 ----
  	INSIST(id != NULL);
  	id->index = 0;
  	id->num_dots = 0;
+ #ifdef INET6
+ 	id->num_cols = 0;
+ #endif
  	id->flags = 0;
  }
  
***************
*** 515,520 ****
--- 547,556 ----
  				id->flags |= LEX_CONSECUTIVE_DOTS;
  			id->flags |= LEX_LAST_WAS_DOT;
  			id->num_dots++;
+ #ifdef INET6
+ 		} else if (c == ':') {
+ 			id->num_cols++;
+ #endif
  		} else {
  			id->flags &= ~LEX_LAST_WAS_DOT;
  		}
***************
*** 533,539 ****
  
  	while (token < 0) {
  		c = get_next_char(comment_ok);
! 		switch(current_file->state) {
  		case scan:
  			if (c == EOF) {
  				if (current_file->next == NULL)
--- 569,575 ----
  
  	while (token < 0) {
  		c = get_next_char(comment_ok);
! 		switch (current_file->state) {
  		case scan:
  			if (c == EOF) {
  				if (current_file->next == NULL)
***************
*** 555,560 ****
--- 591,600 ----
  			if (identifier_char(c)) {
  				if (isdigit(c))
  					current_file->state = number;
+ #ifdef INET6
+ 				else if (c == ':')
+ 					current_file->state = ipv6;
+ #endif
  				else
  					current_file->state = identifier;
  				clear_identifier(id);
***************
*** 582,590 ****
--- 622,641 ----
  
  		case number:
  			if (identifier_char(c)) {
+ #ifdef INET6
+ 				if (!isdigit(c)) {
+ 				    if ((isxdigit(c) || c == ':')) {
+ 					current_file->state = ipv6;
+ 				    } else {
+ 					current_file->state =
+ 					    (c == '.') ? ipv4 : identifier;
+ 				    }
+ 				}
+ #else
  				if (!isdigit(c))
  					current_file->state =
  						(c == '.') ? ipv4 : identifier;
+ #endif
  				add_to_identifier(id, c);
  			} else {
  				put_back_char(c);
***************
*** 613,619 ****
  				}
  			}
  			break;
! 
  		case ipv4:
  			if (identifier_char(c)) {
  				if (!isdigit(c)) {
--- 664,700 ----
  				}
  			}
  			break;
! #ifdef INET6
! 		case ipv6:
! 			if (identifier_char(c)) {
! 			    if (!isxdigit(c)) {
! 				if ((c != '.' && c!=':') ||
! 				    (id->flags & LEX_CONSECUTIVE_DOTS)) {
! 				    current_file->state =
! 					identifier;
! 				}
! 			    }
! 			    add_to_identifier(id, c);
! 			} else {
! 			    put_back_char(c);
! 			    if (id->num_cols > 7)
! 				current_file->state = identifier;
! 			    else {
! 				struct sockaddr_in6 sad6;
! 				current_file->state = scan;
! 				finish_identifier(id);
! 				token = L_IPADDR;
! 				memset(&yylval.ip_addr, 0, sizeof(yylval.ip_addr));
! 				if (inet_pton(AF_INET6, id->buffer, 
! 				      &(yylval.ip_addr.sin6.sin6_addr)) == 0) {
! 				    yylval.cp = dup_identifier(id);
! 				    token = L_STRING;
! 				}
! 				yylval.ip_addr.sin6.sin6_family = AF_INET6;
! 			    }
! 			}
! 		    break;
! #endif
  		case ipv4:
  			if (identifier_char(c)) {
  				if (!isdigit(c)) {
***************
*** 641,651 ****
  					current_file->state = scan;
  					finish_identifier(id);
  					token = L_IPADDR;
  					if (inet_aton(id->buffer,
! 						      &(yylval.ip_addr))==0) {
  						yylval.cp = dup_identifier(id);
  						token = L_STRING;
  					}
  				}
  			}
  			break;
--- 722,743 ----
  					current_file->state = scan;
  					finish_identifier(id);
  					token = L_IPADDR;
+ #ifdef INET6
+ 					memset(&yylval.ip_addr, 0, sizeof(yylval.ip_addr));
+ 					yylval.ip_addr.sin.sin_family = AF_INET;
+ 					if (inet_aton(id->buffer,
+ 					      &(yylval.ip_addr.sin.sin_addr)) == 0) {
+ 					    yylval.cp = dup_identifier(id);
+ 					    token = L_STRING;
+ 					}
+ #else
+ 					memset(&yylval.ip_addr, 0, sizeof(yylval.ip_addr));
  					if (inet_aton(id->buffer,
! 						      &(yylval.ip_addr)) == 0) {
  						yylval.cp = dup_identifier(id);
  						token = L_STRING;
  					}
+ #endif
  				}
  			}
  			break;
Index: bind8/src/bin/named/ns_main.c
diff -c bind8/src/bin/named/ns_main.c:1.1.1.1 bind8/src/bin/named/ns_main.c:1.8.2.4
*** bind8/src/bin/named/ns_main.c:1.1.1.1	Fri Sep 25 14:24:52 1998
--- bind8/src/bin/named/ns_main.c	Fri Jun  4 07:08:42 1999
***************
*** 1,6 ****
  #if !defined(lint) && !defined(SABER)
  static char sccsid[] = "@(#)ns_main.c	4.55 (Berkeley) 7/1/91";
! static char rcsid[] = "$Id: ns_main.c,v 8.67 1998/04/28 19:17:46 halley Exp $";
  #endif /* not lint */
  
  /*
--- 1,6 ----
  #if !defined(lint) && !defined(SABER)
  static char sccsid[] = "@(#)ns_main.c	4.55 (Berkeley) 7/1/91";
! static char rcsid[] = "$Id: ns_main.c,v 1.6 1998/11/28 03:41:11 itojun Exp $";
  #endif /* not lint */
  
  /*
***************
*** 158,164 ****
--- 158,168 ----
  static	void			use_desired_debug(void);
  static	void			stream_write(evContext, void *, int, int);
  
+ #ifdef INET6
+ static	interface *		if_find(msockaddr_in msaddr, u_int16_t port);
+ #else
  static	interface *		if_find(struct in_addr, u_int16_t port);
+ #endif
  
  static	int			sq_here(struct qstream *);
  
***************
*** 168,177 ****
--- 172,188 ----
  				stream_getlen(evContext, void *, int, int),
  				stream_getmsg(evContext, void *, int, int),
  				datagram_read(evContext, void *, int, int),
+ #ifdef INET6
+ 				dispatch_message(u_char *, int, int,
+ 						 struct qstream *,
+ 						 msockaddr_in, int,
+ 						 interface *);
+ #else
  				dispatch_message(u_char *, int, int,
  						 struct qstream *,
  						 struct sockaddr_in, int,
  						 interface *);
+ #endif
  static void			stream_send(evContext, void *, int,
  					       const void *, int,
  					       const void *, int);
***************
*** 513,522 ****
--- 524,540 ----
  #ifdef IP_OPTIONS	/* XXX */
  	u_char ip_opts[IP_OPT_BUF_SIZE];
  #endif
+ #ifdef INET6
+ 	const msockaddr_in *la, *ra;
+ 
+ 	la = (const msockaddr_in *)lav;
+ 	ra = (const msockaddr_in *)rav;
+ #else
  	const struct sockaddr_in *la, *ra;
  
  	la = (const struct sockaddr_in *)lav;
  	ra = (const struct sockaddr_in *)rav;
+ #endif
  
  	INSIST(ifp != NULL);
  
***************
*** 632,646 ****
  	 * problem.
  	 */
  #if defined(IP_OPTIONS)		/* XXX */
  	len = sizeof ip_opts;
! 	if (getsockopt(rfd, IPPROTO_IP, IP_OPTIONS,
! 		       (char *)ip_opts, &len) < 0) {
  		ns_info(ns_log_default, "getsockopt(rfd, IP_OPTIONS): %s",
  			strerror(errno));
  		(void) close(rfd);
  		return;
  	}
  	if (len != 0) {
  		nameserIncr(ra->sin_addr, nssRcvdOpts);
  		if (!haveComplained(ina_ulong(ra->sin_addr),
  				    (u_long)"rcvd ip options")) {
--- 650,704 ----
  	 * problem.
  	 */
  #if defined(IP_OPTIONS)		/* XXX */
+     {
+ #ifdef INET6
+ 	msockaddr_in sa0;
+ #else
+ 	struct sockaddr sa0;
+ #endif
+ 	struct sockaddr *sa = (struct sockaddr *)&sa0;
+ 	int level, optname;
+ 
+ 	len = sizeof sa;
+ 	if (getsockname(rfd, sa, &len) < 0) {
+ 		ns_info(ns_log_default, "getsockname(rfd): %s",
+ 			strerror(errno));
+ 		(void) close(rfd);
+ 		return;
+ 	}
+ 	switch (sa->sa_family) {
+ 	case AF_INET:
+ 		level = IPPROTO_IP;
+ 		optname = IP_OPTIONS;
+ 		break;
+ 	case AF_INET6:
+ 		level = optname = 0;
+ 		break;
+ 	default:
+ 		ns_info(ns_log_default, "unsupported af af %d", sa->sa_family);
+ 		(void) close(rfd);
+ 		return;
+ 	}
  	len = sizeof ip_opts;
! 	if (level == 0)
! 		len = 0;
! 	else if (getsockopt(rfd, level, optname, (char *)ip_opts, &len) < 0) {
  		ns_info(ns_log_default, "getsockopt(rfd, IP_OPTIONS): %s",
  			strerror(errno));
  		(void) close(rfd);
  		return;
  	}
+     }
  	if (len != 0) {
+ #ifdef INET6
+ 		nameserIncr(*ra, nssRcvdOpts);
+ 		if (!haveComplained46((msockaddr_in *)ra,
+ 				(u_long)"rcvd ip options")) {
+ 			ns_info(ns_log_default,
+ 				"rcvd IP_OPTIONS from %s (ignored)",
+ 				sin_ntoa(*ra));
+ 		}
+ #else
  		nameserIncr(ra->sin_addr, nssRcvdOpts);
  		if (!haveComplained(ina_ulong(ra->sin_addr),
  				    (u_long)"rcvd ip options")) {
***************
*** 648,653 ****
--- 706,712 ----
  				"rcvd IP_OPTIONS from %s (ignored)",
  				sin_ntoa(*ra));
  		}
+ #endif
  		if (setsockopt(rfd, IPPROTO_IP, IP_OPTIONS, NULL, 0) < 0) {
  			ns_info(ns_log_default, "setsockopt(!IP_OPTIONS): %s",
  				strerror(errno));
***************
*** 682,688 ****
  tcp_send(struct qinfo *qp) {
  	struct qstream *sp;
  	int on = 1;
! 	
  	ns_debug(ns_log_default, 1, "tcp_send");
  	if ((sp = sq_add()) == NULL) {
  		return(SERVFAIL);
--- 741,747 ----
  tcp_send(struct qinfo *qp) {
  	struct qstream *sp;
  	int on = 1;
! 
  	ns_debug(ns_log_default, 1, "tcp_send");
  	if ((sp = sq_add()) == NULL) {
  		return(SERVFAIL);
***************
*** 871,877 ****
--- 930,940 ----
  		return;
  	}
  
+ #ifdef INET6
+ 	nameserIncr(sp->s_from, nssRcvdTCP);
+ #else
  	nameserIncr(sp->s_from.sin_addr, nssRcvdTCP);
+ #endif
  	sq_query(sp);
  	dispatch_message(sp->s_buf, bytes, sp->s_bufsize, sp, sp->s_from, -1,
  			 sp->s_ifp);
***************
*** 880,895 ****
--- 943,968 ----
  static void
  datagram_read(evContext lev, void *uap, int fd, int evmask) {
  	interface *ifp = uap;
+ #ifdef INET6
+ 	msockaddr_in mfrom;
+ 	int from_len = sizeof mfrom;
+ #else
  	struct sockaddr_in from;
  	int from_len = sizeof from;
+ #endif
  	int n;
  	union {
  		HEADER h;			/* Force alignment of 'buf'. */
  		u_char buf[PACKETSZ+1];
  	} u;
  
+ #ifdef INET6
  	n = recvfrom(fd, (char *)u.buf, sizeof u.buf, 0,
+ 		     (struct sockaddr *)&mfrom, &from_len);
+ #else
+ 	n = recvfrom(fd, (char *)u.buf, sizeof u.buf, 0,
  		     (struct sockaddr *)&from, &from_len);
+ #endif
  
  	if (n < 0) {
  		switch (errno) {
***************
*** 937,944 ****
--- 1010,1022 ----
  		return;
  #endif
  
+ #ifdef INET6
  	ns_debug(ns_log_default, 1, "datagram from %s, fd %d, len %d",
+ 		 sin_ntoa(mfrom), fd, n);
+ #else
+ 	ns_debug(ns_log_default, 1, "datagram from %s, fd %d, len %d",
  		 sin_ntoa(from), fd, n);
+ #endif
  
  	if (n > PACKETSZ) {
  		/*
***************
*** 950,985 ****
  	}
  
  	gettime(&tt);		/* Keep 'tt' current. */
  	dispatch_message(u.buf, n, PACKETSZ, NULL, from, fd, ifp);
  }
  
  static void
  dispatch_message(u_char *msg, int msglen, int buflen, struct qstream *qsp,
  		 struct sockaddr_in from, int dfd, interface *ifp)
  {
  	HEADER *hp = (HEADER *)msg;
  
! 	if (msglen < HFIXEDSZ) {
! 		ns_debug(ns_log_default, 1, "dropping undersize message");
! 		return;
! 	}
! 	if (hp->qr) {
! 		ns_resp(msg, msglen, from, qsp);
! 		if (qsp)
! 			sq_done(qsp);
! 		/* Now is a safe time for housekeeping. */
! 		if (needs_prime_cache)
! 			prime_cache();
! 	} else if (ifp != NULL)
! 		ns_req(msg, msglen, buflen, qsp, from, dfd);
! 	else {
! 		ns_notice(ns_log_security,
! 			  "refused query on non-query socket from %s",
! 			  sin_ntoa(from));
! 		/* XXX Send refusal here. */
  	}
! }
  
  void
  getnetconf(int periodic_scan) {
  	struct ifconf ifc;
--- 1028,1494 ----
  	}
  
  	gettime(&tt);		/* Keep 'tt' current. */
+ #ifdef INET6
+ 	dispatch_message(u.buf, n, PACKETSZ, NULL, mfrom, fd, ifp);
+ #else
  	dispatch_message(u.buf, n, PACKETSZ, NULL, from, fd, ifp);
+ #endif
  }
  
  static void
+ #ifdef INET6
+ dispatch_message(u_char *msg, int msglen, int buflen, struct qstream *qsp,
+ 		 msockaddr_in mfrom, int dfd, interface *ifp)
+ {
+ 	HEADER *hp = (HEADER *)msg;
+ 
+ 	if (msglen < HFIXEDSZ) {
+ 		ns_debug(ns_log_default, 1, "dropping undersize message");
+ 		return;
+ 	}
+ 	if (hp->qr) {
+ 		ns_resp(msg, msglen, mfrom, qsp);
+ 		if (qsp)
+ 			sq_done(qsp);
+ 		/* Now is a safe time for housekeeping. */
+ 		if (needs_prime_cache)
+ 			prime_cache();
+ 	} else if (ifp != NULL)
+ 		ns_req(msg, msglen, buflen, qsp, mfrom, dfd);
+ 	else {
+ 		ns_notice(ns_log_security,
+ 			  "refused query on non-query socket from %s",
+ 			  sin_ntoa(mfrom));
+ 		/* XXX Send refusal here. */
+ 	}
+ }
+ #else
  dispatch_message(u_char *msg, int msglen, int buflen, struct qstream *qsp,
  		 struct sockaddr_in from, int dfd, interface *ifp)
  {
  	HEADER *hp = (HEADER *)msg;
+ 
+ 	if (msglen < HFIXEDSZ) {
+ 		ns_debug(ns_log_default, 1, "dropping undersize message");
+ 		return;
+ 	}
+ 	if (hp->qr) {
+ 		ns_resp(msg, msglen, from, qsp);
+ 		if (qsp)
+ 			sq_done(qsp);
+ 		/* Now is a safe time for housekeeping. */
+ 		if (needs_prime_cache)
+ 			prime_cache();
+ 	} else if (ifp != NULL)
+ 		ns_req(msg, msglen, buflen, qsp, from, dfd);
+ 	else {
+ 		ns_notice(ns_log_security,
+ 			  "refused query on non-query socket from %s",
+ 			  sin_ntoa(from));
+ 		/* XXX Send refusal here. */
+ 	}
+ }
+ #endif
+ 
+ 
+ #ifdef INET6
+ void
+ getnetconf(int periodic_scan) {
+ 	struct ifconf ifc;
+ 	struct ifreq ifreq;
+ 	msockaddr_in ina;
+ 	interface *ifp;
+ 	char buf[32768], *cp, *cplim;
+ 	u_int32_t nm;
+ 	time_t my_generation = time(NULL);
+ 	int s, cpsize;
+ 	int found;
+ 	listen_info li;
+ 	u_int16_t port;
+ 	ip_match_element ime;
+ 	u_char *mask_ptr;
+ 	struct in_addr mask;
+ 	char vname[INET6_ADDRSTRLEN];
+ 	int s6; /* IPv6 socket id */
+ 	struct ifreq* ifreqp;
+ 	struct sockaddr_in6* addr6; /* debug */ 
+ #ifdef INET6
+ 	msockaddr_in msa;
+ #endif
+ 
+ 	ns_debug(ns_log_default, 1, "getnetconf(generation %lu)",
+ 		 (u_long)my_generation);
+ 
+ 	s = s6 = -1;
+ 
+ 	/* Get interface list from system. */
+ 
+ 	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ 		if (!periodic_scan)
+ 			ns_panic(ns_log_default, 1,
+ 				 "socket(AF_INET,SOCK_RAW): %s",
+ 				 strerror(errno));
+ 		ns_error(ns_log_default, "socket(AF_INET,SOCK_RAW): %s",
+ 			 strerror(errno));
+ 		s = -1;
+ 	}
+ 
+ 	if ((s6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+ 		if (!periodic_scan)
+ 			ns_panic(ns_log_default, 1,
+ 				 "socket(AF_INET6,SOCK_RAW): %s",
+ 				 strerror(errno));
+ 		ns_error(ns_log_default, "socket(AF_INET6,SOCK_RAW): %s",
+ 			 strerror(errno));
+ 		if (s == -1) 
+ 		    return;
+ 		s6 = -1; 
+ 	}
+ 
+ 	if (!iflist_initialized) {
+ 		INIT_LIST(iflist);
+ 		iflist_initialized = 1;
+ 	}
+ 
+ 	if (local_addresses != NULL)
+ 		free_ip_match_list(local_addresses);
+ 	local_addresses = new_ip_match_list();
+ 	if (local_networks != NULL)
+ 		free_ip_match_list(local_networks);
+ 	local_networks = new_ip_match_list();
+ 
+ 	ifc.ifc_len = sizeof buf;
+ 	ifc.ifc_buf = buf;
+ 
+ 	if (s6 != -1) {
+ 	    if (ioctl(s6, SIOCGIFCONF, (char *)&ifc) < 0)
+ 		ns_panic(ns_log_default, 1, "get interface configuration: %s",
+ 			 strerror(errno));
+ 	} else {
+ 	    if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0)
+ 		ns_panic(ns_log_default, 1, "get interface configuration: %s",
+ 			 strerror(errno));
+ 	}
+ 
+ 	ns_debug(ns_log_default, 2, "getnetconf: SIOCGIFCONF: ifc_len = %d",
+ 		 ifc.ifc_len);
+ 
+ 	/* Parse system's interface list and open some sockets. */
+ 	cplim = buf + ifc.ifc_len;    /* skip over if's with big ifr_addr's */
+ 	for (cp = buf; cp < cplim; cp += cpsize) {
+ 		ifreqp =(struct ifreq *)cp;
+ 		addr6 = (struct sockaddr_in6 *)&ifreqp->ifr_addr;
+ 
+ 		memcpy(&ifreq, cp, sizeof ifreq); /* sockaddr_in6 size!? */
+ #if defined HAVE_SA_LEN
+ #ifdef FIX_ZERO_SA_LEN
+ 		if (ifreqp->ifr_addr.sa_len == 0)
+ 			ifreqp->ifr_addr.sa_len = 16;
+ #endif
+ #ifdef HAVE_MINIMUM_IFREQ
+ 		ns_debug(ns_log_default, 2, "%s sa_len = %d",
+ 			 ifreqp->ifr_name, (int)ifreq.ifr_addr.sa_len);
+ 		cpsize = sizeof ifreq;
+ 		if (ifreqp->ifr_addr.sa_len > sizeof (struct sockaddr))
+ 			cpsize += (int)ifreqp->ifr_addr.sa_len -
+ 				(int)(sizeof (struct sockaddr));
+ #else
+ 		cpsize = sizeof ifreqp->ifr_name + ifreqp->ifr_addr.sa_len;
+ #endif /* HAVE_MINIMUM_IFREQ */
+ #elif defined SIOCGIFCONF_ADDR
+ 		cpsize = sizeof ifreq;
+ #else
+ 		cpsize = sizeof ifreqp->ifr_name;
+ 
+ 		if (s6!= -1 && ioctl(s6, SIOCGIFADDR, (char *)ifreq) < 0) {
+ 			ns_notice(ns_log_default,
+ 				  "get interface addr (%s): %s",
+ 				  ifreq.ifr_name, strerror(errno));
+ 			continue;
+ 		} else if (ioctl(s, SIOCGIFADDR, (char *)&ifreq) < 0) {
+ 			ns_notice(ns_log_default,
+ 				  "get interface addr (%s): %s",
+ 				  ifreq.ifr_name, strerror(errno));
+ 			continue;
+ 		}
+ #endif
+ 
+ 		if (ifreqp->ifr_addr.sa_family != AF_INET && ifreqp->ifr_addr.sa_family != AF_INET6) {
+ 			ns_debug(ns_log_default, 2, 
+ 				 "getnetconf: %s AF %d != INET && != INET6",
+ 				 ifreqp->ifr_name, ifreqp->ifr_addr.sa_family);
+ 			continue;
+ 		}
+ 		if (((struct sockaddr *)&ifreqp->ifr_addr)->sa_family == 
+ 		    AF_INET6) {
+ 		    ina.sin6 = *(struct sockaddr_in6 *)&ifreqp->ifr_addr;
+ 		    inet_ntop(AF_INET6, &ina.sin6.sin6_addr, vname,
+ 			       sizeof vname);
+ 		    ns_debug(ns_log_default, 1,
+ 			     "getnetconf: considering %s [%s]",
+ 			     ifreqp->ifr_name, vname);
+ 		} else {
+ 		    ina.sin = *(struct sockaddr_in *)&ifreqp->ifr_addr;
+ 		    ns_debug(ns_log_default, 1,
+ 			     "getnetconf: considering %s [%s]",
+ 			     ifreqp->ifr_name, inet_ntoa(ina.sin.sin_addr));
+ 		}
+ 
+ 		/*
+ 		 * Don't test IFF_UP, packets may still be received at this
+ 		 * address if any other interface is up.
+ 		 */
+ 
+ 		if (ifreqp->ifr_addr.sa_family == AF_INET6 && 
+  IN6_IS_ADDR_UNSPECIFIED((&ina.sin6.sin6_addr))) {
+ 		    ns_debug(ns_log_default, 2,
+ 			     "getnetconf: IN6ADDR_ANY, ignoring.");
+ 		    continue;
+ 		} else if (ifreqp->ifr_addr.sa_family == AF_INET &&
+ 			   ina_hlong(ina.sin.sin_addr) == INADDR_ANY) {
+ 		    ns_debug(ns_log_default, 2,
+ 			     "getnetconf: INADDR_ANY, ignoring.");
+ 		    continue;
+ 		}
+ 
+ 		INSIST(server_options != NULL);
+ 		INSIST(server_options->listen_list != NULL);
+ 
+ 		found = 0;
+ 		for (li = server_options->listen_list->first;
+ 		     li != NULL;
+ 		     li = li->next) {
+ 			if (ip_match_address(li->list, ina) > 0) {
+ 				found++;
+ 				/* 
+ 				 * Look for an already existing source
+ 				 * interface address/port pair.
+ 				 * This happens mostly when reinitializing.
+ 				 * Also, if the machine has multiple point to
+ 				 * point interfaces, then the local address
+ 				 * may appear more than once.
+ 				 */
+ 				if (ifreqp->ifr_addr.sa_family == AF_INET6)
+ 				    msa.sin6 = *(struct sockaddr_in6 *)&ifreqp->ifr_addr;
+ 				else
+ 				    msa.sin = *(struct sockaddr_in *)&ifreqp->ifr_addr;
+ 				ifp = if_find(msa, li->port);
+ 				    
+ 				if (ifp != NULL) {
+ 					inet_ntop(ina.sin.sin_family,
+ 						ina.sin.sin_family == AF_INET ? (char *)&ina.sin.sin_addr : (char *)&ina.sin6.sin6_addr,
+ 						vname, sizeof(vname));
+ 					ns_debug(ns_log_default, 1,
+ 					  "dup interface addr [%s].%u (%s)",
+ 						 vname, ntohs(li->port),
+ 						 ifreqp->ifr_name);
+ 					ifp->gen = my_generation;
+ 					continue;
+ 				}
+ 
+ 				ifp = (interface *)memget(sizeof *ifp);
+ 				if (!ifp)
+ 					ns_panic(ns_log_default, 1,
+ 						 "memget(interface)", NULL);
+ 				memset(ifp, 0, sizeof *ifp);
+ 				APPEND(iflist, ifp, link);
+ 
+ 				if (ifreqp->ifr_addr.sa_family == AF_INET6) {
+ 				    ifp->msaddr.sin6.sin6_family = AF_INET6;
+ 				    ifp->msaddr.sin6.sin6_addr =
+ 					ina.sin6.sin6_addr;
+ 				    ifp->msaddr.sin6.sin6_port   = li->port;
+ 				} else {
+ 				    ifp->msaddr.sin.sin_family = AF_INET;
+ 				    ifp->msaddr.sin.sin_addr   = 
+ 					ina.sin.sin_addr;
+ 				    ifp->msaddr.sin.sin_port   = li->port;
+ 				}
+ 				ifp->port = li->port;
+ 				ifp->gen = my_generation;
+ 				ifp->flags = 0;
+ 				ifp->dfd = -1;
+ 				ifp->sfd = -1;
+ 				ifp->dfd6 = -1;
+ 				ifp->sfd6 = -1;
+ 
+ 				if (opensocket_d(ifp) < 0 ||
+ 				    opensocket_s(ifp) < 0) {
+ 					dq_remove(ifp);
+ 					found = 0;
+ 					break;
+ 				}
+ 
+ 				if (ina.sin6.sin6_family == AF_INET6) {
+ 				    inet_ntop(AF_INET6,
+ 					       &ina.sin6.sin6_addr, vname,
+ 					       sizeof vname);
+ 				    ns_info(ns_log_default,
+ 					    "listening on [%s].%u (%s)",
+ 					    vname, ntohs(li->port),
+ 					    ifreqp->ifr_name);
+ 				} else {
+ 				    ns_info(ns_log_default,
+ 					    "listening on [%s].%u (%s)",
+ 					    inet_ntoa(ina.sin.sin_addr),
+ 					    ntohs(li->port),
+ 					    ifreqp->ifr_name);
+ 				}
+ 			}
+ 		}
+ 
+ 		if (!found) {
+ 		    if (ina.sin6.sin6_family == AF_INET6) {
+ 			inet_ntop(AF_INET6,
+ 				  &ina.sin6.sin6_addr, vname,
+ 				  sizeof vname);
+ 			ns_debug(ns_log_default, 1,
+ 				 "not listening on addr [%s] (%s)",
+ 				 vname, ifreqp->ifr_name);
+ 		    } else {
+ 			ns_debug(ns_log_default, 1,
+ 				 "not listening on addr [%s] (%s)",
+ 				 inet_ntoa(ina.sin.sin_addr),
+ 				 ifreqp->ifr_name);
+ 		    }
+ 		}
+ 
+ 		/*
+ 		 * Add this interface's address to the list of local
+ 		 * addresses if we haven't added it already.
+ 		 */
+ 		if (ip_match_address(local_addresses, ina) < 0) {
+ #ifdef INET6
+ 			ime = new_ip_match_pattern(ina,
+ 				(ina.sin.sin_family == AF_INET6) ? 128 : 32);
+ #else
+ 			ime = new_ip_match_pattern(ina, 32);
+ #endif
+ 			add_to_ip_match_list(local_addresses, ime);
+ 		}
+ 
+ 		/*
+ 		 * Get interface flags.
+ 		 */
+ #ifdef INET6
+ 		if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
+ 			ns_notice(ns_log_default, "get interface flags: %s",
+ 				  strerror(errno));
+ 			continue;
+ 		}
+ 
+ 		if ((ifreq.ifr_flags & IFF_POINTOPOINT)) {
+ 			/*
+ 			 * The local network for a PPP link is just the
+ 			 * two ends of the link, so for each endpoint we
+ 			 * add a pattern that will only match the endpoint.
+ 			 */
+ 			if (ioctl(s, SIOCGIFDSTADDR, (char *)&ifreq) < 0) {
+ 				ns_notice(ns_log_default, "get dst addr (%s): %s",
+ 					ifreq.ifr_name, strerror(errno));
+ 				continue;
+ 			}
+ 
+ 			mask.s_addr = htonl(INADDR_BROADCAST);
+ 
+ 			/*
+ 			 * Our end.
+ 			 *
+ 			 * Only add it if we haven't seen it before.
+ 			 */
+ 			if (ina.sin.sin_family == AF_INET &&
+ 			    (ip_match_network(local_networks,
+ 					      ina.sin.sin_addr, mask) < 0)) {
+ 				ime = new_ip_match_pattern(ina, 32);
+ 				add_to_ip_match_list(local_networks, ime);
+ 			}
+ 
+ 			/*
+ 			 * The other end.
+ 			 */
+ 			if (((struct sockaddr *)&ifreqp->ifr_addr)->sa_family
+ 			    ==  AF_INET6) {
+ 				ina.sin6 =
+ 				    *(struct sockaddr_in6 *)&ifreqp->ifr_addr;
+ 			} else {
+ 				ina.sin =
+ 				    *(struct sockaddr_in *)&ifreqp->ifr_addr;
+ 			}
+ 
+ 			/*
+ 			 * Only add it if we haven't seen it before.
+ 			 */
+ 			if (ina.sin.sin_family == AF_INET &&
+ 			    ip_match_network(local_networks,
+ 					     ina.sin.sin_addr, mask) < 0) {
+ 				ime = new_ip_match_pattern(ina, 32);
+ 				add_to_ip_match_list(local_networks, ime);
+ 			}
+ 		} else {
+ 			/*
+ 			 * Add this interface's network and netmask to the
+ 			 * list of local networks.
+ 			 */
+ 
+ #ifdef SIOCGIFNETMASK	/* XXX */
+ 			if (((struct sockaddr *)&ifreqp->ifr_addr)->sa_family
+ 			     == AF_INET) { 
+ 			    if (s != -1 && ioctl(s, SIOCGIFNETMASK, 
+ 						(char *)&ifreq) < 0) {
+ 				ns_notice(ns_log_default, "get netmask: %s",
+ 					  strerror(errno));
+ 				continue;
+ 			    }
+ 			/*
+ 			 * Use ina_get because the ifreq structure might not
+ 			 * be aligned.
+ 			 */
+ 			    mask_ptr =
+ 				(u_char *)&((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr;
+ 			    mask = ina_get(mask_ptr);
+ 			}
+ #else
+ 			mask = net_mask(ina);
+ #endif
  
! 			if (ina.sin.sin_family == AF_INET) {
! 			    ina.sin.sin_addr.s_addr &= mask.s_addr;
! 			    /*
! 			     * Only add it if we haven't seen it before.
! 			     */
! 			    if (ip_match_network(local_networks,
! 						 ina.sin.sin_addr, mask) < 0) {
! 				ime = new_ip_match_mask(ina.sin.sin_addr,
! 							mask);
! 				add_to_ip_match_list(local_networks, ime);
! 			    }
! 			}
! 		}
! #endif /* end ifdef V6 */
  	}
! 	if (s != -1)
! 	    close(s);
! 	if (s6 != -1)
! 	    close(s6);
! 
! 	ns_debug(ns_log_default, 7, "local addresses:");
! 	dprint_ip_match_list(ns_log_default, local_addresses, 2, "", "");
! 	ns_debug(ns_log_default, 7, "local networks:");
! 	dprint_ip_match_list(ns_log_default, local_networks, 2, "", "");
! 
! 	/*
! 	 * now go through the iflist and delete anything that
! 	 * does not have the current generation number.  this is
! 	 * how we catch interfaces that go away or change their
! 	 * addresses.  note that 0.0.0.0 is the wildcard element
! 	 * and should never be deleted by this code.
! 	 */
! 	dq_remove_gen(my_generation);
  
+ 	if (EMPTY(iflist))
+ 		ns_warning(ns_log_default, "not listening on any interfaces");
+ }
+ #else
  void
  getnetconf(int periodic_scan) {
  	struct ifconf ifc;
***************
*** 1001,1006 ****
--- 1510,1516 ----
  		 (u_long)my_generation);
  
  	/* Get interface list from system. */
+ 
  	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  		if (!periodic_scan)
  			ns_panic(ns_log_default, 1, "socket(SOCK_RAW): %s",
***************
*** 1024,1029 ****
--- 1534,1540 ----
  
  	ifc.ifc_len = sizeof buf;
  	ifc.ifc_buf = buf;
+ 
  	if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0)
  		ns_panic(ns_log_default, 1, "get interface configuration: %s",
  			 strerror(errno));
***************
*** 1034,1040 ****
  	/* Parse system's interface list and open some sockets. */
  	cplim = buf + ifc.ifc_len;    /* skip over if's with big ifr_addr's */
  	for (cp = buf; cp < cplim; cp += cpsize) {
! 		memcpy(&ifreq, cp, sizeof ifreq);
  #if defined HAVE_SA_LEN
  #ifdef FIX_ZERO_SA_LEN
  		if (ifreq.ifr_addr.sa_len == 0)
--- 1545,1551 ----
  	/* Parse system's interface list and open some sockets. */
  	cplim = buf + ifc.ifc_len;    /* skip over if's with big ifr_addr's */
  	for (cp = buf; cp < cplim; cp += cpsize) {
! 		memcpy(&ifreq, cp, sizeof ifreq); /* sockaddr_in6 size!? */
  #if defined HAVE_SA_LEN
  #ifdef FIX_ZERO_SA_LEN
  		if (ifreq.ifr_addr.sa_len == 0)
***************
*** 1072,1077 ****
--- 1583,1589 ----
  		ns_debug(ns_log_default, 1,
  			 "getnetconf: considering %s [%s]",
  			 ifreq.ifr_name, inet_ntoa(ina));
+ 
  		/*
  		 * Don't test IFF_UP, packets may still be received at this
  		 * address if any other interface is up.
***************
*** 1085,1091 ****
  		INSIST(server_options != NULL);
  		INSIST(server_options->listen_list != NULL);
  
! 		found=0;
  		for (li = server_options->listen_list->first;
  		     li != NULL;
  		     li = li->next) {
--- 1597,1603 ----
  		INSIST(server_options != NULL);
  		INSIST(server_options->listen_list != NULL);
  
! 		found = 0;
  		for (li = server_options->listen_list->first;
  		     li != NULL;
  		     li = li->next) {
***************
*** 1100,1105 ****
--- 1612,1618 ----
  				 * may appear more than once.
  				 */
  				ifp = if_find(ina, li->port);
+ 
  				if (ifp != NULL) {
  					ns_debug(ns_log_default, 1,
  					  "dup interface addr [%s].%u (%s)",
***************
*** 1122,1127 ****
--- 1635,1641 ----
  				ifp->flags = 0;
  				ifp->dfd = -1;
  				ifp->sfd = -1;
+ 
  				if (opensocket_d(ifp) < 0 ||
  				    opensocket_s(ifp) < 0) {
  					dq_remove(ifp);
***************
*** 1164,1171 ****
  			 * add a pattern that will only match the endpoint.
  			 */
  			if (ioctl(s, SIOCGIFDSTADDR, (char *)&ifreq) < 0) {
! 				ns_notice(ns_log_default, "get dst addr: %s",
! 					  strerror(errno));
  				continue;
  			}
  
--- 1678,1685 ----
  			 * add a pattern that will only match the endpoint.
  			 */
  			if (ioctl(s, SIOCGIFDSTADDR, (char *)&ifreq) < 0) {
! 				ns_notice(ns_log_default, "get dst addr (%s): %s",
! 					ifreq.ifr_name, strerror(errno));
  				continue;
  			}
  
***************
*** 1246,1251 ****
--- 1760,1766 ----
  	if (EMPTY(iflist))
  		ns_warning(ns_log_default, "not listening on any interfaces");
  }
+ #endif
  
  /* opensocket_d(ifp)
   *	Open datagram socket bound to interface address.
***************
*** 1255,1265 ****
--- 1770,1827 ----
   */
  static int
  opensocket_d(interface *ifp) {
+ #ifdef INET6
+ 	msockaddr_in msa;
+ 	char vname[INET6_ADDRSTRLEN];
+ #else
  	struct sockaddr_in nsa;
+ #endif
  	const int on = 1;
  	int m, n;
  	int fd;
  
+ #ifdef INET6
+ 	memset(&msa, 0, sizeof msa);
+ 	msa = ifp->msaddr;
+ 	if (msa.sin6.sin6_family == AF_INET6) {
+ 	    inet_ntop(AF_INET6,&msa.sin6.sin6_addr,
+ 		      vname, sizeof(vname)); 
+ 
+ 	    if ((ifp->dfd6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+ 		ns_error(ns_log_default, "socket(SOCK_DGRAM): %s",
+ 			 strerror(errno));
+ 		return (-1);
+ 	    }
+ #ifdef F_DUPFD		/* XXX */
+ 	    /*
+ 	     * Leave a space for stdio to work in.
+ 	     */
+ 	    if ((fd = fcntl(ifp->dfd6, F_DUPFD, 20)) != -1) {
+ 		close(ifp->dfd6);
+ 		ifp->dfd6 = fd;
+ 	    } else 
+ 		ns_notice(ns_log_default, "fcntl(dfd6, F_DUPFD, 20): %s",
+ 			  strerror(errno));
+ #endif
+ 	} else {
+ 	    if ((ifp->dfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ 		ns_error(ns_log_default, "socket(SOCK_DGRAM): %s",
+ 			 strerror(errno));
+ 		return (-1);
+ 	    }
+ #ifdef F_DUPFD		/* XXX */
+ 	    /*
+ 	     * Leave a space for stdio to work in.
+ 	     */
+ 	    if ((fd = fcntl(ifp->dfd, F_DUPFD, 20)) != -1) {
+ 		close(ifp->dfd);
+ 		ifp->dfd = fd;
+ 	    } else 
+ 		ns_notice(ns_log_default, "fcntl(dfd, F_DUPFD, 20): %s",
+ 			  strerror(errno));
+ #endif
+ 	}
+ #else
  	memset(&nsa, 0, sizeof nsa);
  	nsa.sin_family = AF_INET;
  	nsa.sin_addr = ifp->addr;
***************
*** 1281,1286 ****
--- 1843,1865 ----
  		ns_notice(ns_log_default, "fcntl(dfd, F_DUPFD, 20): %s",
  			  strerror(errno));
  #endif
+ #endif
+ #ifdef INET6
+ 	ns_debug(ns_log_default, 1, "ifp->addr %s d_dfd %d d_dfd6 %d",
+ 		 sin_ntoa(msa), ifp->dfd, ifp->dfd6);
+ 	if (0 <= ifp->dfd6 && setsockopt(ifp->dfd6, SOL_SOCKET, SO_REUSEADDR,
+ 		       (char *)&on, sizeof(on)) != 0) {
+ 		ns_notice(ns_log_default, "setsockopt(REUSEADDR): %s",
+ 			  strerror(errno));
+ 		/* XXX press on regardless, this is not too serious. */
+ 	}
+ 	if (0 <= ifp->dfd && setsockopt(ifp->dfd, SOL_SOCKET, SO_REUSEADDR,
+ 			   (char *)&on, sizeof(on)) != 0) {
+ 		ns_notice(ns_log_default, "setsockopt(REUSEADDR): %s",
+ 			  strerror(errno));
+ 		/* XXX press on regardless, this is not too serious. */
+ 	}
+ #else
  	ns_debug(ns_log_default, 1, "ifp->addr %s d_dfd %d",
  		 sin_ntoa(nsa), ifp->dfd);
  	if (setsockopt(ifp->dfd, SOL_SOCKET, SO_REUSEADDR,
***************
*** 1289,1297 ****
  			  strerror(errno));
  		/* XXX press on regardless, this is not too serious. */
  	}
  #ifdef SO_RCVBUF	/* XXX */
  	m = sizeof n;
! 	if ((getsockopt(ifp->dfd, SOL_SOCKET, SO_RCVBUF, (char*)&n, &m) >= 0)
  	    && (m == sizeof n)
  	    && (n < drbufsize)) {
  		(void) setsockopt(ifp->dfd, SOL_SOCKET, SO_RCVBUF,
--- 1868,1887 ----
  			  strerror(errno));
  		/* XXX press on regardless, this is not too serious. */
  	}
+ #endif
  #ifdef SO_RCVBUF	/* XXX */
  	m = sizeof n;
! #ifdef INET6
! 	if (0 <= ifp->dfd6
! 	    && getsockopt(ifp->dfd6, SOL_SOCKET, SO_RCVBUF, (char*)&n, &m) >= 0
! 	    && (m == sizeof n)
! 	    && (n < drbufsize)) {
! 		(void) setsockopt(ifp->dfd6, SOL_SOCKET, SO_RCVBUF,
! 				  (char *)&drbufsize, sizeof drbufsize);
! 	}
! #endif
! 	if (0 <= ifp->dfd
! 	    && getsockopt(ifp->dfd, SOL_SOCKET, SO_RCVBUF, (char*)&n, &m) >= 0
  	    && (m == sizeof n)
  	    && (n < drbufsize)) {
  		(void) setsockopt(ifp->dfd, SOL_SOCKET, SO_RCVBUF,
***************
*** 1299,1305 ****
  	}
  #endif /* SO_RCVBUF */
  #ifndef CANNOT_SET_SNDBUF
! 	if (setsockopt(ifp->dfd, SOL_SOCKET, SO_SNDBUF,
  		      (char*)&dsbufsize, sizeof dsbufsize) < 0) {
  		ns_info(ns_log_default,
  			"setsockopt(dfd=%d, SO_SNDBUF, %d): %s",
--- 1889,1906 ----
  	}
  #endif /* SO_RCVBUF */
  #ifndef CANNOT_SET_SNDBUF
! #ifdef INET6
! 	if (0 <= ifp->dfd6
! 	 && setsockopt(ifp->dfd6, SOL_SOCKET, SO_SNDBUF,
! 		      (char*)&dsbufsize, sizeof dsbufsize) < 0) {
! 		ns_info(ns_log_default,
! 			"setsockopt(dfd6=%d, SO_SNDBUF, %d): %s",
! 			ifp->dfd6, dsbufsize, strerror(errno));
! 		/* XXX press on regardless, this is not too serious. */
! 	}
! #endif
! 	if (0 <= ifp->dfd
! 	 && setsockopt(ifp->dfd, SOL_SOCKET, SO_SNDBUF,
  		      (char*)&dsbufsize, sizeof dsbufsize) < 0) {
  		ns_info(ns_log_default,
  			"setsockopt(dfd=%d, SO_SNDBUF, %d): %s",
***************
*** 1307,1323 ****
--- 1908,1955 ----
  		/* XXX press on regardless, this is not too serious. */
  	}
  #endif
+ #ifdef INET6
+ 	if (msa.sin6.sin6_family == AF_INET6) {
+ 	    if (bind(ifp->dfd6, (struct sockaddr *)&msa.sin6,
+ 		     sizeof(struct sockaddr_in6))) {
+ 		ns_error(ns_log_default, "bind(dfd6=%d, %s): %s",
+ 			 ifp->dfd6, sin_ntoa(msa), strerror(errno));
+ 		return (-1);
+ 	    }
+ 	    if (evSelectFD(ev, ifp->dfd6, EV_READ, datagram_read, ifp,
+ 			   &ifp->evID_d) == -1) {
+ 		ns_error(ns_log_default, "evSelectFD(dfd6=%d): %s",
+ 			 ifp->dfd6, strerror(errno));
+ 		return (-1);
+ 	    }
+ 	} else {
+ 	    if (bind(ifp->dfd, (struct sockaddr *)&msa.sin,
+ 		     sizeof(struct sockaddr_in))) {
+ 		ns_error(ns_log_default, "bind(dfd=%d, %s): %s",
+ 			 ifp->dfd, sin_ntoa(msa), strerror(errno));
+ 		return (-1);
+ 	    }
+ 	    if (evSelectFD(ev, ifp->dfd, EV_READ, datagram_read, ifp,
+ 			   &ifp->evID_d) == -1) {
+ 		ns_error(ns_log_default, "evSelectFD(dfd=%d): %s",
+ 			 ifp->dfd, strerror(errno));
+ 		return (-1);
+ 	    }
+ 	}
+ #else	
  	if (bind(ifp->dfd, (struct sockaddr *)&nsa, sizeof nsa)) {
  		ns_error(ns_log_default, "bind(dfd=%d, %s): %s",
  			 ifp->dfd, sin_ntoa(nsa), strerror(errno));
  		return (-1);
  	}
+ 
  	if (evSelectFD(ev, ifp->dfd, EV_READ, datagram_read, ifp,
  		       &ifp->evID_d) == -1) {
  		ns_error(ns_log_default, "evSelectFD(dfd=%d): %s",
  			 ifp->dfd, strerror(errno));
  		return (-1);
  	}
+ #endif
  	ifp->flags |= INTERFACE_FILE_VALID;
  	return (0);
  }
***************
*** 1330,1355 ****
--- 1962,2094 ----
   */
  static int
  opensocket_s(interface *ifp) {
+ #ifdef INET6
+ 	msockaddr_in msa;
+ 	char vname[INET6_ADDRSTRLEN];
+ #else
  	struct sockaddr_in nsa;
+ #endif
  	const int on = 1;
  	int n;
  	int fd;
  
+ #ifdef INET6
+ 	memset(&msa, 0, sizeof msa);
+ 	msa = ifp->msaddr;
+ #else
  	memset(&nsa, 0, sizeof nsa);
  	nsa.sin_family = AF_INET;
  	nsa.sin_addr = ifp->addr;
  	nsa.sin_port = ifp->port;
+ #endif
  
  	/*
  	 * Open stream (listener) port.
  	 */
  	n = 0;
   again:
+ #ifdef INET6
+ 	if (msa.sin6.sin6_family == AF_INET6) {
+ 	    if ((ifp->sfd6 = socket(AF_INET6, SOCK_STREAM, 0)) < 0) {
+ 		ns_error(ns_log_default, "socket(SOCK_STREAM): %s",
+ 			 strerror(errno));
+ 		return (-1);
+ 	    }
+ 	} else {
+ 	    if ((ifp->sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ 		ns_error(ns_log_default, "socket(SOCK_STREAM): %s",
+ 			 strerror(errno));
+ 		return (-1);
+ 	    }
+ 	}
+ #else
  	if ((ifp->sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
  		ns_error(ns_log_default, "socket(SOCK_STREAM): %s",
  			 strerror(errno));
  		return (-1);
  	}
+ #endif
+ #ifdef INET6
+ 	if (msa.sin6.sin6_family == AF_INET6) {
+ #ifdef F_DUPFD		/* XXX */
+ 	    /*
+ 	     * Leave a space for stdio to work in.
+ 	     */
+ 	    if ((fd = fcntl(ifp->sfd6, F_DUPFD, 20)) != -1) {
+ 		close(ifp->sfd6);
+ 		ifp->sfd6 = fd;
+ 	    } else 
+ 		ns_notice(ns_log_default, "fcntl(sfd6, F_DUPFD, 20): %s",
+ 			  strerror(errno));
+ #endif
+ 	    if (setsockopt(ifp->sfd6, SOL_SOCKET, SO_REUSEADDR,
+ 			   (char *)&on, sizeof on) != 0) {
+ 		ns_notice(ns_log_default, "setsockopt(sfd6,REUSEADDR): %s",
+ 			  strerror(errno));
+ 		/* Consider that your first warning of trouble to come. */
+ 	    }
+ 
+ 	    if (bind(ifp->sfd6, (struct sockaddr *)&msa.sin6,
+ 		     sizeof(struct sockaddr_in6)) < 0) {
+ 		if (errno != EADDRINUSE || ++n > 4) {
+ 		    if (errno == EADDRINUSE)
+ 			/*ns_error(ns_log_default,
+ 			 "There may be a name server already running on %s",
+ 				 sin_ntoa(nsa))*/;
+ 		    else
+ 			/*ns_error(ns_log_default,
+ 				 "bind(sfd=%d, %s): %s", ifp->sfd,
+ 				 sin_ntoa(nsa), strerror(errno))*/;
+ 		    return (-1);
+ 		}
+ 
+ 		/* Retry opening the socket a few times */
+ 		close(ifp->sfd6);
+ 		ifp->sfd = -1;
+ 		sleep(30);
+ 		goto again;
+ 	    }
+ 	} else {
+ #ifdef F_DUPFD		/* XXX */
+ 	    /*
+ 	     * Leave a space for stdio to work in.
+ 	     */
+ 	    if ((fd = fcntl(ifp->sfd, F_DUPFD, 20)) != -1) {
+ 		close(ifp->sfd);
+ 		ifp->sfd = fd;
+ 	    } else 
+ 		ns_notice(ns_log_default, "fcntl(sfd, F_DUPFD, 20): %s",
+ 			  strerror(errno));
+ #endif
+ 	    if (setsockopt(ifp->sfd, SOL_SOCKET, SO_REUSEADDR,
+ 			   (char *)&on, sizeof on) != 0) {
+ 		ns_notice(ns_log_default, "setsockopt(sfd,REUSEADDR): %s",
+ 			  strerror(errno));
+ 		/* Consider that your first warning of trouble to come. */
+ 	    }
+ 
+ 	    if (bind(ifp->sfd, (struct sockaddr *)&msa.sin,
+ 		     sizeof(struct sockaddr_in)) < 0) {
+ 		if (errno != EADDRINUSE || ++n > 4) {
+ 		    if (errno == EADDRINUSE)
+ 			ns_error(ns_log_default,
+ 			 "There may be a name server already running on %s",
+ 				 sin_ntoa(msa));
+ 		    else
+ 			ns_error(ns_log_default,
+ 				 "bind(sfd=%d, %s): %s", ifp->sfd,
+ 				 sin_ntoa(msa), strerror(errno));
+ 		    return (-1);
+ 		}
+ 
+ 		/* Retry opening the socket a few times */
+ 		close(ifp->sfd);
+ 		ifp->sfd = -1;
+ 		sleep(30);
+ 		goto again;
+ 	    }
+ 	}
+ #else
  #ifdef F_DUPFD		/* XXX */
  	/*
  	 * Leave a space for stdio to work in.
***************
*** 1367,1372 ****
--- 2106,2112 ----
  			  strerror(errno));
  		/* Consider that your first warning of trouble to come. */
  	}
+ 
  	if (bind(ifp->sfd, (struct sockaddr *)&nsa, sizeof nsa) < 0) {
  		if (errno != EADDRINUSE || ++n > 4) {
  			if (errno == EADDRINUSE)
***************
*** 1386,1397 ****
--- 2126,2156 ----
  		sleep(30);
  		goto again;
  	}
+ #endif
+ #ifdef INET6
+ 	if (msa.sin6.sin6_family == AF_INET6) {
+ 	    if (evListen(ev, ifp->sfd6, 5/*XXX*/, stream_accept, ifp,
+ 			 &ifp->evID_s) == -1) {
+ 		ns_error(ns_log_default, "evListen(sfd6=%d): %s",
+ 			 ifp->sfd6, strerror(errno));
+ 		return (-1);
+ 	    }
+ 	} else {
+ 	    if (evListen(ev, ifp->sfd, 5/*XXX*/, stream_accept, ifp,
+ 			 &ifp->evID_s) == -1) {
+ 		ns_error(ns_log_default, "evListen(sfd=%d): %s",
+ 			 ifp->sfd, strerror(errno));
+ 		return (-1);
+ 	    }
+ 	}
+ #else
  	if (evListen(ev, ifp->sfd, 5/*XXX*/, stream_accept, ifp, &ifp->evID_s)
  	    == -1) {
  		ns_error(ns_log_default, "evListen(sfd=%d): %s",
  			 ifp->sfd, strerror(errno));
  		return (-1);
  	}
+ #endif
  	ifp->flags |= INTERFACE_CONN_VALID;
  	return (0);
  }
***************
*** 1405,1416 ****
--- 2164,2204 ----
  	static struct sockaddr_in prev_qsrc;
  	static int been_here;
  	static interface *prev_ifp;
+ #ifdef INET6
+ 	static struct sockaddr_in6 prev_qsrc6;
+ 	struct sockaddr_in nsa6;
+ 	msockaddr_in msa;
+ 	char vname[MAXHOSTNAMELEN];
+ #endif
  	struct sockaddr_in nsa;
  	const int on = 1;
  	int n, need_close;
  	interface *ifp;
  
  	need_close = 0;
+ #ifdef INET6
+ 	if (been_here) {
+ 	    if (prev_ifp != NULL)
+ 		prev_ifp->flags &= ~INTERFACE_FORWARDING;
+ 	    else if (server_options->query_source.sin.sin_family == AF_INET &&
+ 		     (server_options->query_source.sin.sin_port == htons(0) ||
+ 		      prev_qsrc.sin_addr.s_addr !=
+ 		      server_options->query_source.sin.sin_addr.s_addr ||
+ 		      prev_qsrc.sin_port !=
+ 		      server_options->query_source.sin.sin_port))
+ 		need_close = 1;
+ 	    else if (server_options->query_source.sin6.sin6_family == AF_INET6 &&
+ 		     (server_options->query_source.sin6.sin6_port == htons(0) ||
+ 		      !IN6_ARE_ADDR_EQUAL((&prev_qsrc6.sin6_addr),
+ 					  (&server_options->query_source.sin6.sin6_addr)) ||
+ 		      prev_qsrc6.sin6_port !=
+ 		      server_options->query_source.sin6.sin6_port))
+ 		need_close = 1;
+ 	} else {
+ 		ds = -1;
+ 		ds6 = -1;
+ 	}
+ #else
  	if (been_here) {
  		if (prev_ifp != NULL)
  			prev_ifp->flags &= ~INTERFACE_FORWARDING;
***************
*** 1422,1444 ****
--- 2210,2250 ----
  			need_close = 1;
  	} else
  		ds = -1;
+ #endif
  
  	been_here = 1;
  	INSIST(server_options != NULL);
  
  	if (need_close) {
  		evDeselectFD(ev, ds_evID);
+ #ifdef INET6
+ 		if (server_options->query_source.sin6.sin6_family == AF_INET6) {
+ 		    close(ds6);
+ 		    ds6 = -1;
+ 		} else if (server_options->query_source.sin.sin_family == AF_INET) {
+ 		    close(ds);
+ 		    ds = -1;
+ 		}
+ #else
  		close(ds);
  		ds = -1;
+ #endif
  	}
  
+ 
  	/*
  	 * If we're already listening on the query_source address and port,
  	 * we don't need to open another socket.  We mark the interface, so
  	 * we'll notice we're in trouble if it goes away.
  	 */
+ #ifdef INET6
+ 	ifp = if_find(server_options->query_source,
+ 		      server_options->query_source.sin.sin_port);
+ #else
  	ifp = if_find(server_options->query_source.sin_addr,
  		      server_options->query_source.sin_port);
+ #endif
+ 
  	if (ifp != NULL) {
  		ifp->flags |= INTERFACE_FORWARDING;
  		prev_ifp = ifp;
***************
*** 1454,1462 ****
  	if (ds >= 0)
  		return;
  
! 	prev_qsrc = server_options->query_source;
  	prev_ifp = NULL;
  
  	if ((ds = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
  		ns_panic(ns_log_default, 1, "socket(SOCK_DGRAM): %s",
  			 strerror(errno));
--- 2260,2346 ----
  	if (ds >= 0)
  		return;
  
! #ifdef INET6
! 	prev_qsrc = server_options->query_source.sin;
  	prev_ifp = NULL;
+ 	if (server_options->query_source6.sin6.sin6_family != AF_INET6) {
+ 	    ns_panic(ns_log_default, 1, "query_source6 with non-IPv6 address");
+ 	} else {
+ 	    int salen;
+ 	    int family;
+ 
+ 	    salen = (server_options->query_source6.sin6.sin6_family == AF_INET6)
+ 		? sizeof server_options->query_source6.sin6
+ 		: sizeof server_options->query_source.sin;
+ 	    family = server_options->query_source6.sin6.sin6_family;
+ 	    vname[0] = '\0';
+ 	    if ((ds6 = socket(family, SOCK_DGRAM, 0)) < 0)
+ 		ns_panic(ns_log_default, 1, "socket(AF_INET6,SOCK_DGRAM): %s",
+ 			 strerror(errno));
+ 	    if (setsockopt(ds6, SOL_SOCKET, SO_REUSEADDR,
+ 			   (char *)&on, sizeof on) != 0) {
+ 		ns_notice(ns_log_default, "setsockopt(ds6,REUSEADDR): %s",
+ 			  strerror(errno));
+ 		/* XXX press on regardless, this is not too serious. */
+ 	    }
+ 	    if (bind(ds6, (struct sockaddr *)&server_options->query_source6,
+ 		     salen) < 0) {
+ 		getnameinfo((struct addrinfo *)&server_options->query_source6, 
+ 			salen, vname, sizeof(vname), 0, NULL, NI_NUMERICHOST);
+ 		ns_panic(ns_log_default, 1, "opensocket_f: bind(%s): %s",
+ 			 vname, strerror(errno));
+ 	    }
+ 
+ 	    n = sizeof msa;
+ 	    if (getsockname(ds6, (struct sockaddr *)&msa, &n) < 0)
+ 		ns_panic(ns_log_default, 1,
+ 			 "opensocket_f: getsockadd(ds6)r: %s",
+ 			 strerror(errno));
+ 
+ 	    ns_debug(ns_log_default, 1, "fwd ds6 %d addr %s",
+ 		ds6, sin_ntoa(msa));
+ 	    ns_info(ns_log_default, "Forwarding source address is %s",
+ 		    sin_ntoa(msa));
+ 
+ 	    if (evSelectFD(ev, ds6, EV_READ, datagram_read, NULL, &ds6_evID) == -1)
+ 		ns_panic(ns_log_default, 1, "evSelectFD(fd %d): %s",
+ 			 (void *)ds, strerror(errno));
+ 	}
+ 
+ 	if (server_options->query_source.sin.sin_family != AF_INET) {
+ 	    ns_panic(ns_log_default, 1, "query_source with non-IPv4 address");
+ 	} else {
+ 	    if ((ds = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ 		ns_panic(ns_log_default, 1, "socket(SOCK_DGRAM): %s",
+ 			 strerror(errno));
+ 	    if (setsockopt(ds, SOL_SOCKET, SO_REUSEADDR,
+ 			   (char *)&on, sizeof on) != 0) {
+ 		ns_notice(ns_log_default, "setsockopt(REUSEADDR): %s",
+ 			  strerror(errno));
+ 		/* XXX press on regardless, this is not too serious. */
+ 	    }
+ 	    if (bind(ds, (struct sockaddr *)&server_options->query_source,
+ 		     sizeof server_options->query_source.sin) < 0)
+ 		ns_panic(ns_log_default, 1, "opensocket_f: bind(%s): %s",
+ 			 sin_ntoa(server_options->query_source),
+ 			 strerror(errno));
+ 
+ 	    n = sizeof msa;
+ 	    if (getsockname(ds, (struct sockaddr *)&msa, &n) < 0)
+ 		ns_panic(ns_log_default, 1, "opensocket_f: getsockaddr: %s",
+ 			 strerror(errno));
  
+ 	    ns_debug(ns_log_default, 1, "fwd ds %d addr %s", ds, sin_ntoa(msa));
+ 	    ns_info(ns_log_default, "Forwarding source address is %s",
+ 		    sin_ntoa(msa));
+ 
+ 	    if (evSelectFD(ev, ds, EV_READ, datagram_read, NULL, &ds_evID) == -1)
+ 		ns_panic(ns_log_default, 1, "evSelectFD(fd %d): %s",
+ 			 (void *)ds, strerror(errno));
+ 	}
+ #else
+ 	prev_qsrc = server_options->query_source;
+ 	prev_ifp = NULL;
  	if ((ds = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
  		ns_panic(ns_log_default, 1, "socket(SOCK_DGRAM): %s",
  			 strerror(errno));
***************
*** 1484,1489 ****
--- 2368,2374 ----
  	if (evSelectFD(ev, ds, EV_READ, datagram_read, NULL, &ds_evID) == -1)
  		ns_panic(ns_log_default, 1, "evSelectFD(fd %d): %s",
  			 (void *)ds, strerror(errno));
+ #endif
  	/* XXX: should probably use a different FileFunc that only accepts
  	 *	responses, since requests on this socket make no sense.
  	 */
***************
*** 1864,1871 ****
--- 2749,2761 ----
  
  	for (this = HEAD(iflist); this != NULL; this = next) {
  		next = NEXT(this, link);
+ #ifdef INET6
+ 		if (this->gen != gen && ina_hlong(this->msaddr.sin.sin_addr) != INADDR_ANY)
+ 			dq_remove(this);
+ #else
  		if (this->gen != gen && ina_hlong(this->addr) != INADDR_ANY)
  			dq_remove(this);
+ #endif
  	}
  }
  
***************
*** 1898,1921 ****
   */
  static void
  dq_remove(interface *this) {
  	ns_notice(ns_log_default, "deleting interface [%s].%u",
  		  inet_ntoa(this->addr), ntohs(this->port));
- 
  	if ((this->flags & INTERFACE_FORWARDING) != 0)
  		ns_panic(ns_log_default, 0,
  			 "forwarding interface [%s].%u gone",
  			 inet_ntoa(this->addr),
  			 ntohs(this->port));
  
  	/* Deallocate fields. */
  	if ((this->flags & INTERFACE_FILE_VALID) != 0)
  		(void) evDeselectFD(ev, this->evID_d);
  	if (this->dfd >= 0)
  		(void) close(this->dfd);
  	if ((this->flags & INTERFACE_CONN_VALID) != 0)
  		(void) evCancelConn(ev, this->evID_s);
  	if (this->sfd >= 0)
  		(void) close(this->sfd);
  
  	UNLINK(iflist, this, link);
  	memput(this, sizeof *this);
--- 2788,2828 ----
   */
  static void
  dq_remove(interface *this) {
+ #ifdef INET6
+ 	ns_notice(ns_log_default, "deleting interface [%s].%u",
+ 		  inet_ntoa(this->msaddr.sin.sin_addr), ntohs(this->port));
+ 	if ((this->flags & INTERFACE_FORWARDING) != 0)
+ 		ns_panic(ns_log_default, 0,
+ 			 "forwarding interface [%s].%u gone",
+ 			 inet_ntoa(this->msaddr.sin.sin_addr),
+ 			 ntohs(this->port));
+ #else
  	ns_notice(ns_log_default, "deleting interface [%s].%u",
  		  inet_ntoa(this->addr), ntohs(this->port));
  	if ((this->flags & INTERFACE_FORWARDING) != 0)
  		ns_panic(ns_log_default, 0,
  			 "forwarding interface [%s].%u gone",
  			 inet_ntoa(this->addr),
  			 ntohs(this->port));
+ #endif
  
  	/* Deallocate fields. */
  	if ((this->flags & INTERFACE_FILE_VALID) != 0)
  		(void) evDeselectFD(ev, this->evID_d);
  	if (this->dfd >= 0)
  		(void) close(this->dfd);
+ #ifdef INET6
+ 	if (this->dfd6 >= 0)
+ 		(void) close(this->dfd6);
+ #endif
  	if ((this->flags & INTERFACE_CONN_VALID) != 0)
  		(void) evCancelConn(ev, this->evID_s);
  	if (this->sfd >= 0)
  		(void) close(this->sfd);
+ #ifdef INET6
+ 	if (this->sfd6 >= 0)
+ 		(void) close(this->sfd6);
+ #endif
  
  	UNLINK(iflist, this, link);
  	memput(this, sizeof *this);
***************
*** 1948,1961 ****
   *	0: address isn't one of our interfaces
   *	>0: address is one of our interfaces, or INADDR_ANY
   */
  int
  aIsUs(struct in_addr addr) {
  	interface *ifp;
! 
  	if (ina_hlong(addr) == INADDR_ANY || if_find(addr, 0) != NULL)
  		return (1);
  	return (0);
  }
  
  /* interface *
   * if_find(addr, port)
--- 2855,2892 ----
   *	0: address isn't one of our interfaces
   *	>0: address is one of our interfaces, or INADDR_ANY
   */
+ #ifdef INET6
  int
  aIsUs(struct in_addr addr) {
  	interface *ifp;
! 	msockaddr_in saddr;
! 	saddr.sin.sin_family = AF_INET;
! 	saddr.sin.sin_addr = addr;
! 	if (ina_hlong(addr) == INADDR_ANY || if_find(saddr, 0) != NULL)
! 		return (1);
! 	return (0);
! }
! #else
! int
! aIsUs(struct in_addr addr) {
! 	interface *ifp;
  	if (ina_hlong(addr) == INADDR_ANY || if_find(addr, 0) != NULL)
  		return (1);
  	return (0);
  }
+ #endif
+ 
+ 
+ #ifdef INET6
+ int aIsUs6(msockaddr_in maddr) {
+ 	if (maddr.sin6.sin6_family != AF_INET6)
+ 		return (0);
+ 	if (IN6_IS_ADDR_UNSPECIFIED((&maddr.sin6.sin6_addr))
+ 	    || if_find(maddr, 0) != NULL)
+ 		return (1);
+ 	return (0);
+ }
+ #endif
  
  /* interface *
   * if_find(addr, port)
***************
*** 1966,1971 ****
--- 2897,2926 ----
   *      one.
   */
  static interface *
+ #ifdef INET6
+ if_find(msockaddr_in msaddr, u_int16_t port) {
+ 	interface *ifp;
+ 	char vname1[INET6_ADDRSTRLEN], vname2[INET6_ADDRSTRLEN];
+ 	struct in_addr ina;
+ 
+ 	for (ifp = HEAD(iflist); ifp != NULL; ifp = NEXT(ifp, link)) {
+ 	    if (ifp->msaddr.sin.sin_family == msaddr.sin.sin_family && 
+ 		(port == 0 || ifp->port == port)) {
+ 		if (ifp->msaddr.sin.sin_family == AF_INET6) {
+ 		    if (memcmp(&msaddr.sin6.sin6_addr,&ifp->msaddr.sin6.sin6_addr,
+ 			       sizeof(struct in6_addr)) == 0)
+ 			break;
+ 		} else {
+ 		    if (memcmp(&msaddr.sin.sin_addr,&ifp->msaddr.sin.sin_addr,
+ 			       sizeof(struct in_addr)) == 0)
+ 			break;
+ 		}
+ 	    }
+ 	}
+ 
+ 	return (ifp);
+ }
+ #else
  if_find(struct in_addr addr, u_int16_t port) {
  	interface *ifp;
  
***************
*** 1975,1980 ****
--- 2930,2936 ----
  				break;
  	return (ifp);
  }
+ #endif
  
  /*
   * These are here in case we ever want to get more clever, like perhaps
***************
*** 2216,2218 ****
--- 3172,3191 ----
  	}
  	return (1);
  }
+ 
+ #ifdef INET6
+ int ima_equal(struct sockaddr* saddp1, struct sockaddr* saddp2) {
+     if (saddp1->sa_family != saddp2->sa_family)
+ 	return (0);
+     if (saddp1->sa_family == AF_INET6) {
+ 	if (IN6_ARE_ADDR_EQUAL((&((struct sockaddr_in6 *)saddp1)->sin6_addr),
+ 			       (&((struct sockaddr_in6 *)saddp2)->sin6_addr)))
+ 	    return (1);
+     } else {
+ 	if (ina_equal(((struct sockaddr_in *)saddp1)->sin_addr,
+ 		      ((struct sockaddr_in *)saddp2)->sin_addr))
+ 	    return (1);
+     }
+     return (0);
+ }
+ #endif
Index: bind8/src/bin/named/ns_maint.c
diff -c bind8/src/bin/named/ns_maint.c:1.1.1.1 bind8/src/bin/named/ns_maint.c:1.3.2.1
*** bind8/src/bin/named/ns_maint.c:1.1.1.1	Fri Sep 25 14:24:52 1998
--- bind8/src/bin/named/ns_maint.c	Fri Jun  4 07:56:11 1999
***************
*** 1,6 ****
  #if !defined(lint) && !defined(SABER)
  static char sccsid[] = "@(#)ns_maint.c	4.39 (Berkeley) 3/2/91";
! static char rcsid[] = "$Id: ns_maint.c,v 8.39 1998/04/14 00:34:39 halley Exp $";
  #endif /* not lint */
  
  /*
--- 1,6 ----
  #if !defined(lint) && !defined(SABER)
  static char sccsid[] = "@(#)ns_maint.c	4.39 (Berkeley) 3/2/91";
! static char rcsid[] = "$Id: ns_maint.c,v 1.2 1998/09/25 08:16:43 k-sugyou Exp $";
  #endif /* not lint */
  
  /*
***************
*** 94,99 ****
--- 94,100 ----
  #include <syslog.h>
  #include <time.h>
  #include <unistd.h>
+ #include <netdb.h>
  
  #include <isc/eventlib.h>
  #include <isc/logging.h>
***************
*** 423,430 ****
--- 424,436 ----
  		return;
  	}
  
+ #ifdef INET6
  	qp = sysquery(zp->z_origin, zp->z_class, T_SOA,
  		      zp->z_addr, zp->z_addrcnt, QUERY);
+ #else
+ 	qp = sysquery(zp->z_origin, zp->z_class, T_SOA,
+ 		      zp->z_addr, zp->z_addrcnt, QUERY);
+ #endif
  	if (!qp) {
  		ns_info(ns_log_default, "qserial_query(%s): sysquery FAILED",
  			zp->z_origin);
***************
*** 435,448 ****
--- 441,465 ----
  	qp->q_flags |= Q_ZSERIAL;
  	qp->q_zquery = zp;
  	zp->z_flags |= Z_QSERIAL;
+ #ifdef INET6
+ 	zp->z_xaddr.sin.sin_addr   = inaddr_any;
+ 	zp->z_xaddr.sin.sin_family = AF_INET;
+ #else
  	zp->z_xaddr = inaddr_any;
+ #endif
  	ns_refreshtime(zp, tt.tv_sec);
  	qserials_running++;
  	ns_debug(ns_log_default, 1, "qserial_query(%s) QUEUED", zp->z_origin);
  }
  
+ #ifdef INET6
  void
+ qserial_answer(struct qinfo *qp, u_int32_t serial, msockaddr_in from) {
+ 	char vname[INET6_ADDRSTRLEN];
+ #else
+ void
  qserial_answer(struct qinfo *qp, u_int32_t serial, struct sockaddr_in from) {
+ #endif
  	struct zoneinfo *zp = qp->q_zquery;
  
  	ns_debug(ns_log_default, 1, "qserial_answer(%s, %u)", zp->z_origin,
***************
*** 458,471 ****
  	} else if (SEQ_GT(serial, zp->z_serial) || !zp->z_serial) {
  		ns_debug(ns_log_default, 1,
  			 "qserial_answer: zone is out of date");
  		zp->z_xaddr = from.sin_addr; /* don't use qp->q_from */
  		addxfer(zp);
  	} else if (SEQ_GT(zp->z_serial, serial)) {
! 		if (!haveComplained((u_long)zp, (u_long)"went backward")) {
  			ns_notice(ns_log_default,
     "Zone \"%s\" (class %d) SOA serial# (%u) rcvd from [%s] is < ours (%u)",
  				  zp->z_origin, zp->z_class, serial,
  				  inet_ntoa(from.sin_addr), zp->z_serial);
  		}
  	} else {
  		ns_debug(ns_log_default, 1,
--- 475,508 ----
  	} else if (SEQ_GT(serial, zp->z_serial) || !zp->z_serial) {
  		ns_debug(ns_log_default, 1,
  			 "qserial_answer: zone is out of date");
+ #ifdef INET6
+ 		zp->z_xaddr = from; /* don't use qp->q_from */
+ #else
  		zp->z_xaddr = from.sin_addr; /* don't use qp->q_from */
+ #endif
  		addxfer(zp);
  	} else if (SEQ_GT(zp->z_serial, serial)) {
! 		if (!haveComplained((u_long)zp, (u_long)"went backward"), 1) {
! #ifdef INET6
! 		    if (from.sin6.sin6_family == AF_INET6) {
! 			inet_ntop(AF_INET6,&from.sin6.sin6_addr,
! 				  vname, sizeof(vname)); 
  			ns_notice(ns_log_default,
     "Zone \"%s\" (class %d) SOA serial# (%u) rcvd from [%s] is < ours (%u)",
  				  zp->z_origin, zp->z_class, serial,
+ 				  vname, zp->z_serial);
+ 		    } else {
+ 			ns_notice(ns_log_default,
+    "Zone \"%s\" (class %d) SOA serial# (%u) rcvd from [%s] is < ours (%u)",
+ 				  zp->z_origin, zp->z_class, serial,
+ 				  inet_ntoa(from.sin.sin_addr), zp->z_serial);
+ 		    }
+ #else
+ 			ns_notice(ns_log_default,
+    "Zone \"%s\" (class %d) SOA serial# (%u) rcvd from [%s] is < ours (%u)",
+ 				  zp->z_origin, zp->z_class, serial,
  				  inet_ntoa(from.sin_addr), zp->z_serial);
+ #endif
  		}
  	} else {
  		ns_debug(ns_log_default, 1,
***************
*** 489,496 ****
  	char serial_str[10];
  	char port_str[10];
  	char class_str[10];
  	char src_str[20];
! 
  	ns_debug(ns_log_default, 1, "startxfer() %s", zp->z_origin);
  
  	argv[argc++] = server_options->named_xfer;
--- 526,538 ----
  	char serial_str[10];
  	char port_str[10];
  	char class_str[10];
+ #ifdef INET6
+ 	char src_str[INET6_ADDRSTRLEN];
+ 	char src_str6[INET6_ADDRSTRLEN];
+ 	char vname[INET6_ADDRSTRLEN];
+ #else
  	char src_str[20];
! #endif
  	ns_debug(ns_log_default, 1, "startxfer() %s", zp->z_origin);
  
  	argv[argc++] = server_options->named_xfer;
***************
*** 501,510 ****
--- 543,595 ----
  	argv[argc++] = "-s";
  	sprintf(serial_str, "%u", zp->z_serial);
  	argv[argc++] = serial_str;
+ #ifdef INET6
+     {
+ 	int addit;
+ 	int aflen;
+ 
+ 	addit = 0;
+ 	switch (zp->z_axfr_src.sin.sin_family) {
+ 	case AF_INET:
+ 		addit = (zp->z_axfr_src.sin.sin_addr.s_addr != 0);
+ 		aflen = sizeof(zp->z_axfr_src.sin);
+ 		break;
+ 	case AF_INET6:
+ 		addit = !IN6_IS_ADDR_UNSPECIFIED(&zp->z_axfr_src.sin6.sin6_addr);
+ 		aflen = sizeof(zp->z_axfr_src.sin6);
+ 		break;
+ 	}
+ 	if (addit) {
+ 		getnameinfo((struct sockaddr *)&zp->z_axfr_src, aflen,
+ 			vname, sizeof(vname), NULL, 0, NI_NUMERICHOST);
+ 		argv[argc++] = "-x";
+ 		argv[argc++] = strcpy(src_str,  vname);
+ 	}
+ 
+ 	addit = 0;
+ 	switch (zp->z_axfr_src6.sin6.sin6_family) {
+ 	case AF_INET:
+ 		addit = (zp->z_axfr_src6.sin.sin_addr.s_addr != 0);
+ 		aflen = sizeof(zp->z_axfr_src6.sin);
+ 		break;
+ 	case AF_INET6:
+ 		addit = !IN6_IS_ADDR_UNSPECIFIED(&zp->z_axfr_src6.sin6.sin6_addr);
+ 		aflen = sizeof(zp->z_axfr_src6.sin6);
+ 		break;
+ 	}
+ 	if (addit) {
+ 		getnameinfo((struct sockaddr *)&zp->z_axfr_src6, aflen,
+ 			vname, sizeof(vname), NULL, 0, NI_NUMERICHOST);
+ 		argv[argc++] = "-x";
+ 		argv[argc++] = strcpy(src_str6,  vname);
+ 	}
+     }
+ #else
  	if (zp->z_axfr_src.s_addr != 0) {
  		argv[argc++] = "-x";
  		argv[argc++] = strcpy(src_str, inet_ntoa(zp->z_axfr_src));
  	}
+ #endif
  	argv[argc++] = "-C";
  	sprintf(class_str, "%d", zp->z_class);
  	argv[argc++] = class_str;
***************
*** 530,536 ****
  		}
  	}
  #endif
! 	
  	if (ina_hlong(zp->z_xaddr) != INADDR_ANY) {
  		/*
  		 * Address was specified by the qserial logic, use it
--- 615,653 ----
  		}
  	}
  #endif
! 
! #ifdef INET6	
! 	if (zp->z_xaddr.sin.sin_family == AF_INET &&
! 	    ina_hlong(zp->z_xaddr.sin.sin_addr) != INADDR_ANY) {
! 	    /*
! 	     * Address was specified by the qserial logic, use it
! 	     * first.
! 	     */
! 	    if (aIsUs(zp->z_xaddr.sin.sin_addr) &&
! 		!haveComplained((u_long)zp, (u_long)startxfer)) {
! 		ns_notice(ns_log_default,
! 			  "attempted to fetch zone %s from self (%s)",
! 			  zp->z_origin, inet_ntoa(zp->z_xaddr.sin.sin_addr));
! 	    } else
! 		argv[argc++] = strcpy(argv_ns[argc_ns++],
! 				      inet_ntoa(zp->z_xaddr.sin.sin_addr));
! 	} else if (zp->z_xaddr.sin.sin_family == AF_INET6 &&
! 		!IN6_IS_ADDR_UNSPECIFIED(&zp->z_xaddr.sin6.sin6_addr)) {
! 	    /*
! 	     * Address was specified by the qserial logic, use it
! 	     * first.
! 	     */
! 	    char hostbuf[MAXHOSTNAMELEN];
! 	    inet_ntop(AF_INET6, &zp->z_xaddr.sin6.sin6_addr, hostbuf, sizeof(hostbuf));
! 	    if (aIsUs6(zp->z_xaddr) &&
! 		!haveComplained((u_long)zp, (u_long)startxfer)) {
! 		ns_notice(ns_log_default,
! 			  "attempted to fetch zone %s from self (%s)",
! 			  zp->z_origin, hostbuf);
! 	    } else
! 		argv[argc++] = strcpy(argv_ns[argc_ns++], hostbuf);
! 	}
! #else
  	if (ina_hlong(zp->z_xaddr) != INADDR_ANY) {
  		/*
  		 * Address was specified by the qserial logic, use it
***************
*** 545,558 ****
  			argv[argc++] = strcpy(argv_ns[argc_ns++],
  					      inet_ntoa(zp->z_xaddr));
  	}
  	/*
  	 * Copy the server ip addresses into argv, after converting
  	 * to ascii and saving the static inet_ntoa result.  Skip zp->z_xaddr
  	 * if seen.
  	 */
  	for (cnt = 0;  cnt < zp->z_addrcnt;  cnt++) {
  		struct in_addr a;
- 
  		a = zp->z_addr[cnt];
  		if (ina_equal(a, zp->z_xaddr))
  			continue;
--- 662,707 ----
  			argv[argc++] = strcpy(argv_ns[argc_ns++],
  					      inet_ntoa(zp->z_xaddr));
  	}
+ #endif
  	/*
  	 * Copy the server ip addresses into argv, after converting
  	 * to ascii and saving the static inet_ntoa result.  Skip zp->z_xaddr
  	 * if seen.
  	 */
  	for (cnt = 0;  cnt < zp->z_addrcnt;  cnt++) {
+ #ifdef INET6
+ 	    struct in_addr a;
+ 	    if (zp->z_addr[cnt].sin6.sin6_family == AF_INET6) {
+ 		if (zp->z_xaddr.sin6.sin6_family == AF_INET6 &&
+ 		    IN6_ARE_ADDR_EQUAL((&zp->z_addr[cnt].sin6.sin6_addr),
+ 				       (&zp->z_xaddr.sin6.sin6_addr)))
+ 		    continue;
+ 		if (aIsUs6(zp->z_addr[cnt]) && /* V6 code add */
+ 		    !haveComplained((u_long)zp, (u_long)startxfer)) {
+ 		    ns_notice(ns_log_default,
+ 			      "attempted to fetch zone %s from self (%s)",
+ 			      zp->z_origin, inet_ntoa(a));
+ 		    continue;
+ 		}
+ 		inet_ntop(AF_INET6,&zp->z_addr[cnt].sin6.sin6_addr,
+ 			  vname, sizeof(vname)); 
+ 		argv[argc++] = strcpy(argv_ns[argc_ns++], vname);
+ 	    } else {
+ 		a = zp->z_addr[cnt].sin.sin_addr;
+ 		if (zp->z_xaddr.sin.sin_family == AF_INET &&
+ 		    ina_equal(a, zp->z_xaddr.sin.sin_addr))
+ 		    continue;
+ 		if (aIsUs(a) &&
+ 		    !haveComplained((u_long)zp, (u_long)startxfer)) {
+ 		    ns_notice(ns_log_default,
+ 			      "attempted to fetch zone %s from self (%s)",
+ 			      zp->z_origin, inet_ntoa(a));
+ 		    continue;
+ 		}
+ 		argv[argc++] = strcpy(argv_ns[argc_ns++], inet_ntoa(a));
+ 	    }
+ #else
  		struct in_addr a;
  		a = zp->z_addr[cnt];
  		if (ina_equal(a, zp->z_xaddr))
  			continue;
***************
*** 564,569 ****
--- 713,719 ----
  			continue;
  		}
  		argv[argc++] = strcpy(argv_ns[argc_ns++], inet_ntoa(a));
+ #endif
  	}
  
  	argv[argc] = NULL;
***************
*** 899,904 ****
--- 1049,1085 ----
   */
  static int
  nxfers(struct zoneinfo *zp, int delta) {
+ #ifdef INET6
+ 	msockaddr_in   msaddr;
+ 	struct nameser *nsp;
+ 	int ret;
+ 
+ 	if (zp->z_xaddr.sin.sin_family == AF_INET &&
+ 	    ina_hlong(zp->z_xaddr.sin.sin_addr) != INADDR_ANY)
+ 	    msaddr = zp->z_xaddr;	/* qserial overrode address */
+ 	else if (zp->z_xaddr.sin6.sin6_family == AF_INET6 &&
+ 		 !IN6_IS_ADDR_UNSPECIFIED((&zp->z_xaddr.sin6.sin6_addr)))
+ 	    msaddr = zp->z_xaddr;	/* qserial overrode address */
+ 	else if (!zp->z_addrcnt)
+ 		return (-1);
+ 	else
+ 		msaddr = zp->z_addr[0];	/* first ns holds zone's xfer limit */
+ 
+ #ifdef INET6
+ 	if (!(nsp = nameserFind(msaddr, NS_F_INSERT)))
+ 		return (-1);		/* probably ENOMEM */
+ #else
+ 	if (!(nsp = nameserFind(nsa, NS_F_INSERT)))
+ 		return (-1);		/* probably ENOMEM */
+ #endif
+ 
+ 	ret = nsp->xfers;
+ 	if (delta < 0 && -delta > ret)
+ 		return (-1);		/* taking more than we have */
+ 
+ 	nsp->xfers += delta;
+ 	return (ret);
+ #else
  	struct in_addr nsa;
  	struct nameser *nsp;
  	int ret;
***************
*** 919,924 ****
--- 1100,1106 ----
  
  	nsp->xfers += delta;
  	return (ret);
+ #endif
  }
  
  /*
Index: bind8/src/bin/named/ns_ncache.c
diff -c bind8/src/bin/named/ns_ncache.c:1.1.1.1 bind8/src/bin/named/ns_ncache.c:1.2.2.1
*** bind8/src/bin/named/ns_ncache.c:1.1.1.1	Fri Sep 25 14:24:52 1998
--- bind8/src/bin/named/ns_ncache.c	Tue Jun  1 13:13:17 1999
***************
*** 1,5 ****
  #if !defined(lint) && !defined(SABER)
! static char rcsid[] = "$Id: ns_ncache.c,v 8.17 1998/03/20 01:12:01 halley Exp $";
  #endif /* not lint */
  
  /*
--- 1,5 ----
  #if !defined(lint) && !defined(SABER)
! static char rcsid[] = "$Id: ns_ncache.c,v 1.1.1.1 1998/09/25 05:24:52 k-sugyou Exp $";
  #endif /* not lint */
  
  /*
***************
*** 51,57 ****
--- 51,61 ----
  	} while (0)
  
  void
+ #ifdef INET6
+ cache_n_resp(u_char *msg, int msglen, msockaddr_in mfrom) {
+ #else
  cache_n_resp(u_char *msg, int msglen, struct sockaddr_in from) {
+ #endif
  	struct databuf *dp;
  	HEADER *hp;
  	u_char *cp, *eom, *rdatap;
***************
*** 63,70 ****
  	u_int16_t ancount;
  	u_int dlen;
  
  	nameserIncr(from.sin_addr, nssRcvdNXD);
! 
  	hp = (HEADER *)msg;
  	cp = msg+HFIXEDSZ;
  	eom = msg + msglen;
--- 67,77 ----
  	u_int16_t ancount;
  	u_int dlen;
  
+ #ifdef INET6
+ 	nameserIncr(mfrom, nssRcvdNXD);
+ #else
  	nameserIncr(from.sin_addr, nssRcvdNXD);
! #endif
  	hp = (HEADER *)msg;
  	cp = msg+HFIXEDSZ;
  	eom = msg + msglen;
***************
*** 205,211 ****
  	dp->d_zone = DB_Z_CACHE;
  	dp->d_cred = hp->aa ? DB_C_AUTH : DB_C_ANSWER;
  	dp->d_clev = 0;
! 	if(hp->rcode == NXDOMAIN) {
  		dp->d_rcode = NXDOMAIN;
  		flags = DB_NODATA|DB_NOTAUTH|DB_NOHINTS;
  	} else {
--- 212,218 ----
  	dp->d_zone = DB_Z_CACHE;
  	dp->d_cred = hp->aa ? DB_C_AUTH : DB_C_ANSWER;
  	dp->d_clev = 0;
! 	if (hp->rcode == NXDOMAIN) {
  		dp->d_rcode = NXDOMAIN;
  		flags = DB_NODATA|DB_NOTAUTH|DB_NOHINTS;
  	} else {
***************
*** 213,224 ****
--- 220,240 ----
  		flags = DB_NOTAUTH|DB_NOHINTS;
  	}
  
+ #ifdef INET6
+ 	if ((n = db_update(dname, dp, dp, NULL, flags, hashtab, mfrom)) != OK) {
+ 		ns_debug(ns_log_ncache, 1,
+ 			 "db_update failed (%d), cache_n_resp()", n);
+ 		db_freedata(dp);
+ 		return;
+ 	}
+ #else
  	if ((n = db_update(dname, dp, dp, NULL, flags, hashtab, from)) != OK) {
  		ns_debug(ns_log_ncache, 1,
  			 "db_update failed (%d), cache_n_resp()", n);
  		db_freedata(dp);
  		return;
  	}
+ #endif
  	ns_debug(ns_log_ncache, 4,
  		 "ncache succeeded: [%s %s %s] rcode:%d ttl:%ld",
  		    dname, p_type(type), p_class(class),
Index: bind8/src/bin/named/ns_parser.y
diff -c bind8/src/bin/named/ns_parser.y:1.1.1.1 bind8/src/bin/named/ns_parser.y:1.2.2.4
*** bind8/src/bin/named/ns_parser.y:1.1.1.1	Fri Sep 25 14:24:52 1998
--- bind8/src/bin/named/ns_parser.y	Fri Jun  4 07:56:11 1999
***************
*** 1,6 ****
  %{
  #if !defined(lint) && !defined(SABER)
! static char rcsid[] = "$Id: ns_parser.y,v 8.11 1997/12/04 07:03:05 halley Exp $";
  #endif /* not lint */
  
  /*
--- 1,6 ----
  %{
  #if !defined(lint) && !defined(SABER)
! static char rcsid[] = "$Id: ns_parser.y,v 1.1.1.1 1998/09/25 05:24:52 k-sugyou Exp $";
  #endif /* not lint */
  
  /*
***************
*** 25,30 ****
--- 25,31 ----
  #include "port_before.h"
  
  #include <sys/types.h>
+ #include <sys/socket.h>
  
  #include <netinet/in.h>
  #include <arpa/nameser.h>
***************
*** 99,105 ****
  	long			num;
  	u_long			ul_int;
  	u_int16_t		us_int;
! 	struct in_addr		ip_addr;
  	ip_match_element	ime;
  	ip_match_list		iml;
  	key_info		keyi;
--- 100,106 ----
  	long			num;
  	u_long			ul_int;
  	u_int16_t		us_int;
! 	msockaddr_in		ip_addr;
  	ip_match_element	ime;
  	ip_match_list		iml;
  	key_info		keyi;
***************
*** 123,128 ****
--- 124,130 ----
  %token			T_DUMP_FILE T_STATS_FILE T_MEMSTATS_FILE
  %token			T_FAKE_IQUERY T_RECURSION T_FETCH_GLUE
  %token			T_QUERY_SOURCE T_LISTEN_ON T_PORT T_ADDRESS
+ %token			T_QUERY_SOURCE6
  %type	<us_int>	in_port
  %type	<us_int>	maybe_port
  %type	<us_int>	maybe_wild_port
***************
*** 170,175 ****
--- 172,178 ----
  %token			T_MASTER T_SLAVE T_STUB T_RESPONSE
  %token			T_HINT
  %token			T_MASTERS T_TRANSFER_SOURCE
+ %token			T_TRANSFER_SOURCE6
  %token			T_ALSO_NOTIFY
  
  /* Items used for access control lists and "allow" clauses: */
***************
*** 356,361 ****
--- 359,365 ----
  	}
  	'{' opt_forwarders_list '}'
  	| T_QUERY_SOURCE query_source
+ 	| T_QUERY_SOURCE6 query_source6
  	| T_ALLOW_QUERY '{' address_match_list '}'
  	{
  		if (current_options->query_acl)
***************
*** 411,419 ****
  		$$ = axfr_many_answers;
  	}
  	;
! 	
  maybe_wild_addr: L_IPADDR { $$ = $1; }
! 	| '*' { $$.s_addr = htonl(INADDR_ANY); }
  	;
  
  maybe_wild_port: in_port { $$ = $1; }
--- 415,429 ----
  		$$ = axfr_many_answers;
  	}
  	;
! 
  maybe_wild_addr: L_IPADDR { $$ = $1; }
! 	| '*' {
! 	    if ($$.sin6.sin6_family == AF_INET6) {
! 		$$.sin6.sin6_addr = in6addr_any;
! 	    } else {
! 		$$.sin.sin_addr.s_addr = htonl(INADDR_ANY);
! 	    }
! 	}
  	;
  
  maybe_wild_port: in_port { $$ = $1; }
***************
*** 422,434 ****
  
  query_source_address: T_ADDRESS maybe_wild_addr
  	{
! 		current_options->query_source.sin_addr = $2;
  	}
  	;
  
  query_source_port: T_PORT maybe_wild_port
  	{
! 		current_options->query_source.sin_port = $2;
  	}
  	;
  
--- 432,447 ----
  
  query_source_address: T_ADDRESS maybe_wild_addr
  	{
! 		current_options->query_source = $2;
  	}
  	;
  
  query_source_port: T_PORT maybe_wild_port
  	{
! 		if (current_options->query_source.sin6.sin6_family == AF_INET6)
! 			current_options->query_source.sin6.sin6_port = $2;
! 		else
! 			current_options->query_source.sin.sin_port = $2;
  	}
  	;
  
***************
*** 438,443 ****
--- 451,476 ----
  	| query_source_port query_source_address
  	;
  
+ query_source6_address: T_ADDRESS maybe_wild_addr
+ 	{
+ 		current_options->query_source6 = $2;
+ 	}
+ 	;
+ 
+ query_source6_port: T_PORT maybe_wild_port
+ 	{
+ 		if (current_options->query_source6.sin6.sin6_family == AF_INET6)
+ 			current_options->query_source6.sin6.sin6_port = $2;
+ 		else
+ 			current_options->query_source6.sin.sin_port = $2;
+ 	}
+ 	;
+ 
+ query_source6: query_source6_address
+ 	| query_source6_port
+ 	| query_source6_address query_source6_port
+ 	;
+ 
  maybe_port: /* nothing */ { $$ = htons(NS_DEFAULTPORT); }
  	| T_PORT in_port { $$ = $2; }
  	;
***************
*** 851,860 ****
  
  server_stmt: T_SERVER L_IPADDR
  	{
! 		char *ip_printable;
  		symbol_value value;
  		
! 		ip_printable = inet_ntoa($2);
  		value.pointer = NULL;
  		if (lookup_symbol(symtab, ip_printable, SYM_SERVER, NULL))
  			seen_server = 1;
--- 884,898 ----
  
  server_stmt: T_SERVER L_IPADDR
  	{
! 		char ip_printable[INET6_ADDRSTRLEN];
  		symbol_value value;
  		
! 		if ($2.sin6.sin6_family == AF_INET6) {
! 		    inet_ntop(AF_INET6,&$2.sin6.sin6_addr,
! 			      ip_printable, sizeof(ip_printable)); 
! 		} else {
! 			strcpy(ip_printable, inet_ntoa($2.sin.sin_addr));
! 		}
  		value.pointer = NULL;
  		if (lookup_symbol(symtab, ip_printable, SYM_SERVER, NULL))
  			seen_server = 1;
***************
*** 927,937 ****
  
  address_match_simple: L_IPADDR
  	{
! 		$$ = new_ip_match_pattern($1, 32);
  	}
  	| L_IPADDR '/' L_NUMBER
  	{
! 		if ($3 < 0 || $3 > 32) {
  			parser_error(0, "mask bits out of range; skipping");
  			$$ = NULL;
  		} else {
--- 965,982 ----
  
  address_match_simple: L_IPADDR
  	{
! 		if ($1.sin6.sin6_family == AF_INET6)
! 			$$ = new_ip_match_pattern($1, sizeof($1.sin6.sin6_addr) * 8);
! 		else
! 			$$ = new_ip_match_pattern($1, sizeof($1.sin.sin_addr) * 8);
  	}
  	| L_IPADDR '/' L_NUMBER
  	{
! 		int len;
! 		len = ($1.sin.sin_family == AF_INET)
! 			? (sizeof($1.sin.sin_addr) * 8)
! 			: (sizeof($1.sin6.sin6_addr) * 8);
! 		if ($3 < 0 || $3 > len) {
  			parser_error(0, "mask bits out of range; skipping");
  			$$ = NULL;
  		} else {
***************
*** 943,949 ****
  	}
  	| L_NUMBER '/' L_NUMBER
  	{
! 		struct in_addr ia;
  
  		if ($1 > 255) {
  			parser_error(0, "address out of range; skipping");
--- 988,994 ----
  	}
  	| L_NUMBER '/' L_NUMBER
  	{
! 		msockaddr_in ia;
  
  		if ($1 > 255) {
  			parser_error(0, "address out of range; skipping");
***************
*** 954,960 ****
  					"mask bits out of range; skipping");
  					$$ = NULL;
  			} else {
! 				ia.s_addr = htonl(($1 & 0xff) << 24);
  				$$ = new_ip_match_pattern(ia, $3);
  				if ($$ == NULL)
  					parser_error(0, 
--- 999,1006 ----
  					"mask bits out of range; skipping");
  					$$ = NULL;
  			} else {
! 			        /* ? 98.8.20 S.Shin */ 
! 				ia.sin.sin_addr.s_addr = htonl(($1 & 0xff) << 24);
  				$$ = new_ip_match_pattern(ia, $3);
  				if ($$ == NULL)
  					parser_error(0, 
***************
*** 1182,1188 ****
--- 1228,1246 ----
  	| T_MASTERS '{' master_in_addr_list '}'
  	| T_TRANSFER_SOURCE maybe_wild_addr
  	{
+ #ifdef INET6
+ 		set_zone_transfer_source(current_zone, $2, 0);
+ #else
+ 		set_zone_transfer_source(current_zone, $2);
+ #endif
+ 	}
+ 	| T_TRANSFER_SOURCE6 maybe_wild_addr
+ 	{
+ #ifdef INET6
+ 		set_zone_transfer_source(current_zone, $2, 1);
+ #else
  		set_zone_transfer_source(current_zone, $2);
+ #endif
  	}
  	| T_CHECK_NAMES check_names_opt
  	{
***************
*** 1296,1306 ****
--- 1354,1373 ----
  init_acls() {
  	ip_match_element ime;
  	ip_match_list iml;
+ #ifdef INET6
+ 	msockaddr_in address;
+ #else
  	struct in_addr address;
+ #endif
  
  	/* Create the predefined ACLs */
  
+ #ifdef INET6
+ 	address.sin.sin_family      = AF_INET;
+ 	address.sin.sin_addr.s_addr = 0U;
+ #else
  	address.s_addr = 0U;
+ #endif
  
  	/* ACL "any" */
  	ime = new_ip_match_pattern(address, 0);
Index: bind8/src/bin/named/ns_parseutil.c
diff -c bind8/src/bin/named/ns_parseutil.c:1.1.1.1 bind8/src/bin/named/ns_parseutil.c:1.1.1.1.2.1
*** bind8/src/bin/named/ns_parseutil.c:1.1.1.1	Fri Sep 25 14:24:52 1998
--- bind8/src/bin/named/ns_parseutil.c	Tue Jun  1 13:13:18 1999
***************
*** 116,123 ****
  		c = *s;
  		if (isascii(c) && isupper(c))
  			c = tolower(c);
! 		h = ( h << 4 ) + c;
! 		if ((g = ( h & 0xf0000000 )) != 0) {
  			h = h ^ (g >> 24);
  			h = h ^ g;
  		}
--- 116,123 ----
  		c = *s;
  		if (isascii(c) && isupper(c))
  			c = tolower(c);
! 		h = (h << 4) + c;
! 		if ((g = (h & 0xf0000000)) != 0) {
  			h = h ^ (g >> 24);
  			h = h ^ g;
  		}
Index: bind8/src/bin/named/ns_req.c
diff -c bind8/src/bin/named/ns_req.c:1.1.1.1 bind8/src/bin/named/ns_req.c:1.3
*** bind8/src/bin/named/ns_req.c:1.1.1.1	Fri Sep 25 14:24:52 1998
--- bind8/src/bin/named/ns_req.c	Sat Nov 28 12:41:14 1998
***************
*** 1,6 ****
  #if !defined(lint) && !defined(SABER)
  static char sccsid[] = "@(#)ns_req.c	4.47 (Berkeley) 7/1/91";
! static char rcsid[] = "$Id: ns_req.c,v 8.46 1998/03/27 00:21:03 halley Exp $";
  #endif /* not lint */
  
  /*
--- 1,6 ----
  #if !defined(lint) && !defined(SABER)
  static char sccsid[] = "@(#)ns_req.c	4.47 (Berkeley) 7/1/91";
! static char rcsid[] = "$Id: ns_req.c,v 1.2 1998/09/25 08:16:46 k-sugyou Exp $";
  #endif /* not lint */
  
  /*
***************
*** 143,178 ****
  				u_int16_t, u_int16_t);
  static void		copyCharString(u_char **, const char *);
  
  static enum req_action	req_query(HEADER *hp, u_char **cpp, u_char *eom,
  				  struct qstream *qsp,
  				  int *buflenp, int *msglenp,
  				  u_char *msg, int dfd,
! 				  struct sockaddr_in from);
  
  static enum req_action	req_iquery(HEADER *hp, u_char **cpp, u_char *eom,
  				   int *buflenp, u_char *msg,
  				   struct sockaddr_in from);
  
  #ifdef BIND_NOTIFY
  static enum req_action	req_notify(HEADER *hp, u_char **cpp, u_char *eom,
  				   u_char *msg,struct sockaddr_in from);
  #endif
  
  /*
   * Process request using database; assemble and send response.
   */
  void
  ns_req(u_char *msg, int msglen, int buflen, struct qstream *qsp,
         struct sockaddr_in from, int dfd)
  {
  	HEADER *hp = (HEADER *) msg;
  	u_char *cp, *eom;
  	enum req_action action;
  	int n;
  
  #ifdef DEBUG
  	if (debug > 3) {
  		ns_debug(ns_log_packet, 3, "ns_req(from %s)", sin_ntoa(from));
  		fp_nquery(msg, msglen, log_get_stream(packet_channel));
  	}
  #endif
--- 143,207 ----
  				u_int16_t, u_int16_t);
  static void		copyCharString(u_char **, const char *);
  
+ #ifdef INET6
  static enum req_action	req_query(HEADER *hp, u_char **cpp, u_char *eom,
  				  struct qstream *qsp,
  				  int *buflenp, int *msglenp,
  				  u_char *msg, int dfd,
! 				  msockaddr_in mfrom);
  
  static enum req_action	req_iquery(HEADER *hp, u_char **cpp, u_char *eom,
  				   int *buflenp, u_char *msg,
+ 				   msockaddr_in mfrom);
+ 
+ #ifdef BIND_NOTIFY
+ static enum req_action	req_notify(HEADER *hp, u_char **cpp, u_char *eom,
+ 				   u_char *msg, msockaddr_in from);
+ #endif
+ #else
+ static enum req_action	req_query(HEADER *hp, u_char **cpp, u_char *eom,
+ 				  struct qstream *qsp,
+ 				  int *buflenp, int *msglenp,
+ 				  u_char *msg, int dfd,
+ 				  struct sockaddr_in mfrom);
+ 
+ static enum req_action	req_iquery(HEADER *hp, u_char **cpp, u_char *eom,
+ 				   int *buflenp, u_char *msg,
  				   struct sockaddr_in from);
  
  #ifdef BIND_NOTIFY
  static enum req_action	req_notify(HEADER *hp, u_char **cpp, u_char *eom,
  				   u_char *msg,struct sockaddr_in from);
  #endif
+ #endif
  
  /*
   * Process request using database; assemble and send response.
   */
  void
+ #ifdef INET6
+ ns_req(u_char *msg, int msglen, int buflen, struct qstream *qsp,
+        msockaddr_in mfrom, int dfd)
+ #else
  ns_req(u_char *msg, int msglen, int buflen, struct qstream *qsp,
         struct sockaddr_in from, int dfd)
+ #endif
  {
  	HEADER *hp = (HEADER *) msg;
  	u_char *cp, *eom;
  	enum req_action action;
  	int n;
+ #ifdef INET6
+ 	char vname[INET6_ADDRSTRLEN];
+ #endif
  
  #ifdef DEBUG
  	if (debug > 3) {
+ #ifdef INET6
+ 		ns_debug(ns_log_packet, 3, "ns_req(from %s)", sin_ntoa(mfrom));
+ #else
  		ns_debug(ns_log_packet, 3, "ns_req(from %s)", sin_ntoa(from));
+ #endif
  		fp_nquery(msg, msglen, log_get_stream(packet_channel));
  	}
  #endif
***************
*** 195,218 ****
--- 224,266 ----
  
  	switch (hp->opcode) {
  	case ns_o_query:
+ #ifdef INET6
+ 		action = req_query(hp, &cp, eom, qsp,
+ 				   &buflen, &msglen,
+ 				   msg, dfd, mfrom);
+ #else
  		action = req_query(hp, &cp, eom, qsp,
  				   &buflen, &msglen,
  				   msg, dfd, from);
+ #endif
  		break;
  
  	case ns_o_iquery:
+ #ifdef INET6
+ 		action = req_iquery(hp, &cp, eom, &buflen, msg, mfrom);
+ #else
  		action = req_iquery(hp, &cp, eom, &buflen, msg, from);
+ #endif
  		break;
  
  #ifdef BIND_NOTIFY
  	case ns_o_notify:
+ #ifdef INET6
+ 		action = req_notify(hp, &cp, eom, msg, mfrom);
+ #else
  		action = req_notify(hp, &cp, eom, msg, from);
+ #endif
  		break;
  #endif
  
  #ifdef BIND_UPDATE
  	case ns_o_update:
+ #ifdef INET6
+ 		action = req_update(hp, cp, eom, msg, qsp, dfd, mfrom);
+ #else
  		action = req_update(hp, cp, eom, msg, qsp, dfd, from);
+ #endif
+ 
  		break;
  #endif /* BIND_UPDATE */
  
***************
*** 257,270 ****
--- 305,344 ----
  	buflen -= n;
  
  #ifdef DEBUG
+ #ifdef INET6
+ 	ns_debug(ns_log_default, 1,
+ 		 "ns_req: answer -> %s fd=%d id=%d size=%d",
+ 		 sin_ntoa(mfrom), (qsp == NULL) ? dfd : qsp->s_rfd,
+ 		 ntohs(hp->id), cp - msg);
+ #else
  	ns_debug(ns_log_default, 1,
  		 "ns_req: answer -> %s fd=%d id=%d size=%d",
  		 sin_ntoa(from), (qsp == NULL) ? dfd : qsp->s_rfd,
  		 ntohs(hp->id), cp - msg);
+ #endif
  	if (debug >= 10)
  		fp_nquery(msg, cp - msg, log_get_stream(packet_channel));
  #endif /*DEBUG*/
  	if (qsp == NULL) {
+ #ifdef INET6
+ 	    int ssize = mfrom.sin6.sin6_family == AF_INET6 ?
+ 		sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
+ 
+ 	    if (sendto(dfd, (char*)msg, cp - msg, 0,
+ 		       (struct sockaddr *)&mfrom,
+ 			   ssize) < 0) {
+ 		if (!haveComplained46(&mfrom, (u_long)sendtoStr)) {
+ 			ns_info(ns_log_default,	"ns_req: sendto(%s): %s",
+ 				sin_ntoa(mfrom), strerror(errno));
+ 		}
+ 		nameserIncr(mfrom, nssSendtoErr);
+ 	    }
+ 	    nameserIncr(mfrom, nssSentAns);
+ 	    if (hp->rcode == NXDOMAIN) 
+ 		nameserIncr(mfrom, nssSentNXD);
+ 	    if (!hp->aa) 
+ 		nameserIncr(mfrom, nssSentNaAns);
+ #else
  		if (sendto(dfd, (char*)msg, cp - msg, 0,
  			   (struct sockaddr *)&from,
  			   sizeof(from)) < 0) {
***************
*** 280,285 ****
--- 354,360 ----
  			nameserIncr(from.sin_addr, nssSentNXD);
  		if (!hp->aa) 
  			nameserIncr(from.sin_addr, nssSentNaAns);
+ #endif
  	} else
  		writestream(qsp, msg, cp - msg);
  
***************
*** 289,295 ****
--- 364,389 ----
  }
  
  #ifdef BIND_NOTIFY
+ #ifdef INET6
  int
+ findZonePri(const struct zoneinfo *zp, const msockaddr_in from) {
+ 	int i;
+ 
+ 	for (i = 0; (u_int)i < zp->z_addrcnt; i++) {
+ 	    if (from.sin.sin_family == zp->z_addr[i].sin.sin_family) {
+ 		if (from.sin.sin_family == AF_INET &&
+ 		    ina_equal(zp->z_addr[i].sin.sin_addr, from.sin.sin_addr))
+ 		    return (i);
+ 		else if (from.sin6.sin6_family == AF_INET6 &&
+ 			 IN6_ARE_ADDR_EQUAL((&from.sin6.sin6_addr),
+ 					    (&zp->z_addr[i].sin6.sin6_addr)))
+ 		    return (i);			 
+ 	    }
+ 	}
+ 	return (-1);
+ }
+ #else
+ int
  findZonePri(const struct zoneinfo *zp, const struct sockaddr_in from) {
  	struct in_addr ina;
  	int i;
***************
*** 300,309 ****
--- 394,410 ----
  			return (i);
  	return (-1);
  }
+ #endif
  
+ #ifdef INET6
+ static enum req_action
+ req_notify(HEADER *hp, u_char **cpp, u_char *eom, u_char *msg,
+ 	   msockaddr_in from)
+ #else
  static enum req_action
  req_notify(HEADER *hp, u_char **cpp, u_char *eom, u_char *msg,
  	   struct sockaddr_in from)
+ #endif
  {
  	int n, type, class, zn;
  	char dnbuf[MAXDNAME];
***************
*** 342,349 ****
--- 443,455 ----
  	}
  	GETSHORT(type, *cpp);
  	GETSHORT(class, *cpp);
+ #ifdef INET6
+ 	/*ns_info(ns_log_notify, "rcvd NOTIFY(%s, %s, %s) from %s",
+ 		dnbuf, p_class(class), p_type(type), sin_ntoa(from));*/
+ #else
  	ns_info(ns_log_notify, "rcvd NOTIFY(%s, %s, %s) from %s",
  		dnbuf, p_class(class), p_type(type), sin_ntoa(from));
+ #endif
  	/* XXX - when answers are allowed, we'll need to do compression
  	 * correctly here, and we will need to check for packet underflow.
  	 */
***************
*** 364,386 ****
--- 470,501 ----
  		 * "dig".  this condition can be avoided by using secure zones
  		 * since that way only real secondaries can AXFR from you.
  		 */
+ #ifdef INET6
+ #else
  		ns_info(ns_log_notify,
  			"NOTIFY for non-secondary name (%s), from %s",
  			dnbuf, sin_ntoa(from));
+ #endif
  		goto refuse;
  	}
  	if (findZonePri(&zones[zn], from) == -1) {
+ #ifdef INET6
+ #else
  		ns_info(ns_log_notify,
  			"NOTIFY from non-master server (zone %s), from %s",
  			zones[zn].z_origin, sin_ntoa(from));
+ #endif
  		goto refuse;
  	}
  	switch (type) {
  	case T_SOA:
  		if (strcasecmp(dnbuf, zones[zn].z_origin) != 0) {
+ #ifdef INET6
+ #else
  			ns_info(ns_log_notify,
  				"NOTIFY(SOA) for non-origin (%s), from %s",
  				dnbuf, sin_ntoa(from));
+ #endif
  			goto refuse;
  		}
  		if (zones[zn].z_flags &
***************
*** 409,418 ****
--- 524,540 ----
  }
  #endif /*BIND_NOTIFY*/
  
+ #ifdef INET6
+ static enum req_action
+ req_query(HEADER *hp, u_char **cpp, u_char *eom, struct qstream *qsp,
+ 	  int *buflenp, int *msglenp, u_char *msg, int dfd,
+ 	  msockaddr_in from)
+ #else
  static enum req_action
  req_query(HEADER *hp, u_char **cpp, u_char *eom, struct qstream *qsp,
  	  int *buflenp, int *msglenp, u_char *msg, int dfd,
  	  struct sockaddr_in from)
+ #endif
  {
  	int n, class, type, count, zone, foundname, founddata, omsglen, cname;
  	u_int16_t id;
***************
*** 426,433 ****
  	struct zoneinfo *zp;
  	struct databuf *dp;
  
  	nameserIncr(from.sin_addr, nssRcvdQ);
! 
  	nsp[0] = NULL;
  	dpp = dnptrs;
  	*dpp++ = msg;
--- 548,558 ----
  	struct zoneinfo *zp;
  	struct databuf *dp;
  
+ #ifdef INET6
+ 	nameserIncr(from, nssRcvdQ);
+ #else
  	nameserIncr(from.sin_addr, nssRcvdQ);
! #endif
  	nsp[0] = NULL;
  	dpp = dnptrs;
  	*dpp++ = msg;
***************
*** 490,502 ****
--- 615,634 ----
  	if (type == T_AXFR) {
  		/* Refuse request if not a TCP connection. */
  		if (qsp == NULL) {
+ #ifdef INET6
+ #else
  			ns_info(ns_log_default,
  				"rejected UDP AXFR from %s for \"%s\"",
  				sin_ntoa(from), *dnbuf ? dnbuf : ".");
+ #endif
  			return (Refuse);
  		}
  		/* The position of this is subtle. */
+ #ifdef INET6
+ 		nameserIncr(from, nssRcvdAXFR);
+ #else
  		nameserIncr(from.sin_addr, nssRcvdAXFR);
+ #endif
  		hp->rd = 0;		/* Recursion not possible. */
  	}
  	*buflenp -= *msglenp;
***************
*** 507,516 ****
--- 639,651 ----
  
  #ifdef QRYLOG
  	if (qrylog) {
+ #ifdef INET6
+ #else
  		ns_info(ns_log_queries, "XX /%s/%s/%s",
  			inet_ntoa(from.sin_addr), 
  			(dname[0] == '\0') ? "." : dname, 
  			p_type(type));
+ #endif
  	}
  #endif /*QRYLOG*/
  
***************
*** 593,598 ****
--- 728,742 ----
  		else
  			query_acl = server_options->query_acl;
  
+ #ifdef INET6
+ 		if (query_acl != NULL
+ 		    && !ip_address_allowed(query_acl, from)) {
+ 			ns_notice(ns_log_security,
+ 				  "unapproved query from %s for \"%s\"",
+ 				  sin_ntoa(from), *dname ? dname : ".");
+ 			return (Refuse);
+ 		}
+ #else
  		if (query_acl != NULL
  		    && !ip_address_allowed(query_acl, from.sin_addr)) {
  			ns_notice(ns_log_security,
***************
*** 600,605 ****
--- 744,750 ----
  				  sin_ntoa(from), *dname ? dname : ".");
  			return (Refuse);
  		}
+ #endif
  	} else {
  		ip_match_list transfer_acl;
  
***************
*** 610,615 ****
--- 755,769 ----
  		else
  			transfer_acl = server_options->transfer_acl;
  
+ #ifdef INET6
+ 		if (transfer_acl != NULL
+ 		    && !ip_address_allowed(transfer_acl, from)) {
+ 			ns_notice(ns_log_security,
+ 				  "unapproved AXFR from %s for \"%s\" (acl)",
+ 				  sin_ntoa(from), *dname ? dname : ".");
+ 			return (Refuse);
+ 		}
+ #else
  		if (transfer_acl != NULL
  		    && !ip_address_allowed(transfer_acl, from.sin_addr)) {
  			ns_notice(ns_log_security,
***************
*** 617,643 ****
--- 771,807 ----
  				  sin_ntoa(from), *dname ? dname : ".");
  			return (Refuse);
  		}
+ #endif
  
  		/* Are we authoritative? */
  
  		if ((zp->z_flags & Z_AUTH) == 0) {
+ #ifdef INET6
+ #else
  			ns_notice(ns_log_security,
  			  "unapproved AXFR from %s for \"%s\" (not auth)",
  				  sin_ntoa(from), *dname ? dname : ".");
+ #endif
  			return (Refuse);
  		}
  
  		/* Is the name at a zone cut? */
  
  		if (strcasecmp(zp->z_origin, dname) != 0) {
+ #ifdef INET6
+ #else
  			ns_notice(ns_log_security,
  			  "unapproved AXFR from %s for \"%s\" (not zone top)",
  				  sin_ntoa(from), *dname ? dname : ".");
+ #endif
  			return (Refuse);
  		}
  
+ #ifdef INET6
+ #else
  		ns_info(ns_log_security, "approved AXFR from %s for \"%s\"",
  			sin_ntoa(from), *dname ? dname : ".");
+ #endif
  	}
  
  	/*
***************
*** 905,910 ****
--- 1069,1075 ----
  		}
  		*msglenp = n;
  	}
+ 
  	n = ns_forw(nsp, msg, *msglenp, from, qsp, dfd, &qp,
  		    dname, class, type, np, 0);
  	if (n != FW_OK && cname)
***************
*** 969,983 ****
  	return (Return);
  }
  
  static enum req_action
  req_iquery(HEADER *hp, u_char **cpp, u_char *eom, int *buflenp,
  	   u_char *msg, struct sockaddr_in from)
  {
  	int dlen, alen, n, type, class, count;
  	char dnbuf[MAXDNAME], anbuf[PACKETSZ], *data, *fname;
  
  	nameserIncr(from.sin_addr, nssRcvdIQ);
! 
  	if (ntohs(hp->ancount) != 1
  	    || ntohs(hp->qdcount) != 0
  	    || ntohs(hp->nscount) != 0
--- 1134,1157 ----
  	return (Return);
  }
  
+ #ifdef INET6
  static enum req_action
  req_iquery(HEADER *hp, u_char **cpp, u_char *eom, int *buflenp,
+ 	   u_char *msg, msockaddr_in from)
+ #else
+ static enum req_action
+ req_iquery(HEADER *hp, u_char **cpp, u_char *eom, int *buflenp,
  	   u_char *msg, struct sockaddr_in from)
+ #endif
  {
  	int dlen, alen, n, type, class, count;
  	char dnbuf[MAXDNAME], anbuf[PACKETSZ], *data, *fname;
  
+ #ifdef INET6
+ 	nameserIncr(from, nssRcvdIQ);
+ #else
  	nameserIncr(from.sin_addr, nssRcvdIQ);
! #endif
  	if (ntohs(hp->ancount) != 1
  	    || ntohs(hp->qdcount) != 0
  	    || ntohs(hp->nscount) != 0
***************
*** 1047,1057 ****
  #ifdef QRYLOG
  	if (qrylog) {
  		char tmp[sizeof "255.255.255.255"];
! 
  		strcpy(tmp, inet_ntoa(from.sin_addr));
  		ns_info(ns_log_queries, "XX /%s/%s/-%s",
  			tmp, inet_ntoa(ina_get((u_char *)data)),
  			p_type(type));
  	}
  #endif /*QRYLOG*/
  
--- 1221,1233 ----
  #ifdef QRYLOG
  	if (qrylog) {
  		char tmp[sizeof "255.255.255.255"];
! #ifdef INET6
! #else
  		strcpy(tmp, inet_ntoa(from.sin_addr));
  		ns_info(ns_log_queries, "XX /%s/%s/-%s",
  			tmp, inet_ntoa(ina_get((u_char *)data)),
  			p_type(type));
+ #endif
  	}
  #endif /*QRYLOG*/
  
Index: bind8/src/bin/named/ns_resp.c
diff -c bind8/src/bin/named/ns_resp.c:1.1.1.1 bind8/src/bin/named/ns_resp.c:1.6.2.1
*** bind8/src/bin/named/ns_resp.c:1.1.1.1	Fri Sep 25 14:24:53 1998
--- bind8/src/bin/named/ns_resp.c	Tue Jun  1 13:13:18 1999
***************
*** 1,6 ****
  #if !defined(lint) && !defined(SABER)
  static char sccsid[] = "@(#)ns_resp.c	4.65 (Berkeley) 3/3/91";
! static char rcsid[] = "$Id: ns_resp.c,v 8.56 1998/03/16 19:40:07 halley Exp $";
  #endif /* not lint */
  
  /*
--- 1,6 ----
  #if !defined(lint) && !defined(SABER)
  static char sccsid[] = "@(#)ns_resp.c	4.65 (Berkeley) 3/3/91";
! static char rcsid[] = "$Id: ns_resp.c,v 1.5 1998/11/28 03:41:15 itojun Exp $";
  #endif /* not lint */
  
  /*
***************
*** 126,131 ****
--- 126,137 ----
  
  #include "named.h"
  
+ 
+ #ifdef INET6
+ /* in ns_main.c */
+ extern int ima_equal(struct sockaddr*, struct sockaddr*);
+ #endif
+ 
  static u_int8_t		norootlogged[MAXCLASS];	/* XXX- should be a bitmap */
  
  static const char	skipnameFailedAnswer[] = "skipname failed in answer",
***************
*** 163,178 ****
  
  static void		rrsetadd(struct flush_set *, const char *, 
  				 struct databuf *),
  			rrsetupdate(struct flush_set *, int flags,
  				    struct sockaddr_in),
  			flushrrset(struct flush_set *, struct sockaddr_in),
  			free_flushset(struct flush_set *, int);
  static int		rrsetcmp(char *, struct db_list *),
  			check_root(void),
  			check_ns(void),
  			rrextract(u_char *, int, u_char *,
  				  struct databuf **, char *, int,
! 				  struct sockaddr_in, char **);
  static void		sysnotify_slaves(const char *, const char *,
  					 int, int, int *, int *);
  static void		sysnotify_ns(const char *, const char *,
--- 169,196 ----
  
  static void		rrsetadd(struct flush_set *, const char *, 
  				 struct databuf *),
+ #ifdef INET6
  			rrsetupdate(struct flush_set *, int flags,
+ 				    msockaddr_in),
+ 			flushrrset(struct flush_set *, msockaddr_in),
+ 			free_flushset(struct flush_set *, int);
+ #else
+ 			rrsetupdate(struct flush_set *, int flags,
  				    struct sockaddr_in),
  			flushrrset(struct flush_set *, struct sockaddr_in),
  			free_flushset(struct flush_set *, int);
+ #endif
  static int		rrsetcmp(char *, struct db_list *),
  			check_root(void),
  			check_ns(void),
  			rrextract(u_char *, int, u_char *,
  				  struct databuf **, char *, int,
! #ifdef INET6
! 				  msockaddr_in,
! #else
! 				  struct sockaddr_in,
! #endif
! 				  char **);
  static void		sysnotify_slaves(const char *, const char *,
  					 int, int, int *, int *);
  static void		sysnotify_ns(const char *, const char *,
***************
*** 193,202 ****
--- 211,277 ----
  	char *a, *ns, *na;
  	struct databuf *db;
  	int i;
+ #ifdef INET6
+ 	char vname[INET6_ADDRSTRLEN];
+ #endif
  	
  	a = ns = na = "<Not Available>";
  
  	for (i = 0; (u_int)i < qp->q_naddr; i++) {
+ #ifdef INET6
+ 	    if (qp->q_addr[i].ns_addr.sin.sin_family == server->sin_family &&
+ 		((qp->q_addr[i].ns_addr.sin.sin_family == AF_INET &&
+ 		  ina_equal(qp->q_addr[i].ns_addr.sin.sin_addr,
+ 			    server->sin_addr))||
+ 		 (qp->q_addr[i].ns_addr.sin6.sin6_family == AF_INET6 &&
+ 		  IN6_ARE_ADDR_EQUAL((&qp->q_addr[i].ns_addr.sin6.sin6_addr),
+ 				     (&((struct sockaddr_in6 *)server)->sin6_addr))))) {
+ 		db = qp->q_addr[i].ns;
+ 		if (db != NULL) {
+ 		    if (NS_OPTION_P(OPTION_HOSTSTATS)) {
+ 			char nsbuf[20];
+ 			if (db->d_ns != NULL) {
+ 			    if (db->d_ns->msaddr.sin6.sin6_family == AF_INET6) {
+ 				inet_ntop(AF_INET6,
+ 					  &db->d_ns->msaddr.sin6.sin6_addr,
+ 					  vname, sizeof(vname)); 
+ 				strcpy(nsbuf, vname);
+ 			    } else {
+ 				strcpy(nsbuf,
+ 				       inet_ntoa(db->d_ns->msaddr.sin.sin_addr));
+ 			    }
+ 			    ns = nsbuf;
+ 			} else {
+ 			    ns = zones[db->d_zone].z_origin;
+ 			}
+ 		    }
+ 		    if (db->d_rcode == 0)
+ 			na = (char*)qp->q_addr[i].ns->d_data;
+ 		}
+ 
+ 		if (NS_OPTION_P(OPTION_HOSTSTATS)) {
+ 		    char abuf[20];
+ 		    db = qp->q_addr[i].nsdata;
+ 		    if (db != NULL) {
+ 			if (db->d_ns != NULL) {
+ 			    if (db->d_ns->msaddr.sin6.sin6_family == AF_INET6) {
+ 				inet_ntop(AF_INET6,
+ 					  &db->d_ns->msaddr.sin6.sin6_addr,
+ 					  vname, sizeof(vname)); 
+ 				strcpy(abuf, vname);
+ 			    } else {
+ 				strcpy(abuf,
+ 				       inet_ntoa(db->d_ns->msaddr.sin.sin_addr));
+ 			    }
+ 			    a = abuf;
+ 			} else {
+ 			    a = zones[db->d_zone].z_origin;
+ 			}
+ 		    }
+ 		}
+ 		break;
+ 	    }
+ #else
  		if (ina_equal(qp->q_addr[i].ns_addr.sin_addr,
  			      server->sin_addr)) {
  			db = qp->q_addr[i].ns;
***************
*** 233,238 ****
--- 308,314 ----
  			}
  			break;
  		}
+ #endif
  	}
  
  	if (a == ns && ns == na)	/* all "UNKNOWN" */
***************
*** 266,272 ****
  }
  
  void
! ns_resp(u_char *msg, int msglen, struct sockaddr_in from, struct qstream *qsp) {
  	struct qinfo *qp;
  	HEADER *hp;
  	struct qserv *qs;
--- 342,353 ----
  }
  
  void
! #ifdef INET6
! ns_resp(u_char *msg, int msglen, msockaddr_in from, struct qstream *qsp)
! #else
! ns_resp(u_char *msg, int msglen, struct sockaddr_in from, struct qstream *qsp)
! #endif
! {
  	struct qinfo *qp;
  	HEADER *hp;
  	struct qserv *qs;
***************
*** 275,281 ****
--- 356,366 ----
  	u_char *eom = msg + msglen;
  	struct flush_set *flushset = NULL;
  	int flushset_size = 0;
+ #ifdef INET6
+ 	msockaddr_in *nsa;
+ #else
  	struct sockaddr_in *nsa;
+ #endif
  	struct databuf *nsp[NSMAX];
  	int i, c, n, qdcount, ancount, aucount, nscount, arcount, arfirst;
  	u_int qtype, qclass;
***************
*** 299,312 ****
  	struct databuf *dp;
  	int forcecmsg = 0;
  	char *tname = NULL;
  
  	nameserIncr(from.sin_addr, nssRcvdR);
  	nsp[0] = NULL;
  	hp = (HEADER *) msg;
! 	if ((qp = qfindid(hp->id)) == NULL ) {
  		ns_debug(ns_log_default, 1, "DUP? dropped (id %d)",
  			 ntohs(hp->id));
  		nameserIncr(from.sin_addr, nssRcvdDupR);
  		return;
  	}
  
--- 384,407 ----
  	struct databuf *dp;
  	int forcecmsg = 0;
  	char *tname = NULL;
+ 	char hostbuf[MAXHOSTNAMELEN];
+ 	int salen;
  
+ #ifdef INET6
+ 	nameserIncr(from, nssRcvdR);
+ #else
  	nameserIncr(from.sin_addr, nssRcvdR);
+ #endif
  	nsp[0] = NULL;
  	hp = (HEADER *) msg;
! 	if ((qp = qfindid(hp->id)) == NULL) {
  		ns_debug(ns_log_default, 1, "DUP? dropped (id %d)",
  			 ntohs(hp->id));
+ #ifdef INET6
+ 		nameserIncr(from, nssRcvdDupR);
+ #else
  		nameserIncr(from.sin_addr, nssRcvdDupR);
+ #endif
  		return;
  	}
  
***************
*** 343,354 ****
--- 438,458 ----
  		}
  		GETSHORT(qtype, cp);
  		GETSHORT(qclass, cp);
+ #ifdef INET6
  		if (!ns_nameok(qname, qclass, NULL, response_trans,
  			       ns_ownercontext(qtype, response_trans),
+ 			       qname, from)) {
+ 			formerrmsg = badNameFound;
+ 			goto refused;
+ 		}
+ #else
+ 		if (!ns_nameok(qname, qclass, NULL, response_trans,
+ 			       ns_ownercontext(qtype, response_trans),
  			       qname, from.sin_addr)) {
  			formerrmsg = badNameFound;
  			goto refused;
  		}
+ #endif
  		if (cp > eom) {
  			formerrmsg = outofDataQuery;
  			goto formerr;
***************
*** 395,400 ****
--- 499,515 ----
  			 "resp: error (ret %d, op %d), dropped",
  			 hp->rcode, hp->opcode);
  		switch (hp->rcode) {
+ #ifdef INET6
+ 		case SERVFAIL:
+ 			nameserIncr(from, nssRcvdFail);
+ 			break;
+ 		case FORMERR:
+ 			nameserIncr(from, nssRcvdFErr);
+ 			break;
+ 		default:
+ 			nameserIncr(from, nssRcvdErr);
+ 			break;
+ #else
  		case SERVFAIL:
  			nameserIncr(from.sin_addr, nssRcvdFail);
  			break;
***************
*** 404,425 ****
--- 519,562 ----
  		default:
  			nameserIncr(from.sin_addr, nssRcvdErr);
  			break;
+ #endif
  		}
  		/* mark server as bad */
  		if (!qp->q_fwd)
  			for (i = 0; i < (int)qp->q_naddr; i++)
+ #ifdef INET6
+ 	    if (qp->q_addr[i].ns_addr.sin.sin_family == from.sin.sin_family) {
+ 		if (qp->q_addr[i].ns_addr.sin6.sin6_family == AF_INET6 &&
+ 		    IN6_ARE_ADDR_EQUAL((&qp->q_addr[i].ns_addr.sin6.sin6_addr),
+ 				       (&from.sin6.sin6_addr)))
+ 		    qp->q_addr[i].nretry = MAXRETRY;
+ 		else if (qp->q_addr[i].ns_addr.sin.sin_family == AF_INET &&
+ 			 ina_equal(qp->q_addr[i].ns_addr.sin.sin_addr,
+ 				   from.sin.sin_addr))
+ 		    qp->q_addr[i].nretry = MAXRETRY;
+ 	    } 
+ #else
  				if (ina_equal(qp->q_addr[i].ns_addr.sin_addr,
  					      from.sin_addr))
  					qp->q_addr[i].nretry = MAXRETRY;
+ #endif
  		/*
  		 * XXX:	doesn't handle responses sent from the wrong
  		 *	interface on a multihomed server.
  		 */
+ #ifdef INET6
+ 		if (qp->q_fwd ||
+ 	    ima_equal((struct sockaddr *)&qp->q_addr[qp->q_curaddr].ns_addr,
+ 		      (struct sockaddr *)&from))
+ 			retry(qp);
+ 		return;
+ #else
  		if (qp->q_fwd ||
  		    ina_equal(qp->q_addr[qp->q_curaddr].ns_addr.sin_addr,
  			   from.sin_addr))
  			retry(qp);
  		return;
+ #endif
  	}
  
  	if (qdcount != 1) {
***************
*** 434,442 ****
--- 571,593 ----
  	 * might have forwarded the query will be dropped.
  	 * XXX - should put this in STATS somewhere.
  	 */
+ #ifdef INET6
+ 	for (fwd = server_options->fwdtab; fwd; fwd = fwd->next) {
+ 	    if (fwd->fwdaddr.sin.sin_family == from.sin.sin_family) {
+ 		if (IN6_ARE_ADDR_EQUAL((&fwd->fwdaddr.sin6.sin6_addr),
+ 				       (&from.sin6.sin6_addr)))
+ 		    break;
+ 		else if (from.sin.sin_family == AF_INET && 
+ 			 ina_equal(fwd->fwdaddr.sin.sin_addr,
+ 				   from.sin.sin_addr))
+ 		    break;
+ 	    }
+ 	}
+ #else
  	for (fwd = server_options->fwdtab; fwd; fwd = fwd->next)
  		if (ina_equal(fwd->fwdaddr.sin_addr, from.sin_addr))
  			break;
+ #endif
  	/*
  	 * XXX:	note bad ambiguity here.  if one of our forwarders is also
  	 *	a delegated server for some domain, then we will not update
***************
*** 451,468 ****
--- 602,635 ----
  	if (fwd == NULL) {
  		struct timeval *stp;
  
+ #ifdef INET6
+ 		for (n = 0,qs = qp->q_addr;(u_int)n < qp->q_naddr;n++,qs++) {
+ 		    if (ima_equal((struct sockaddr *)&qs->ns_addr,
+ 				  (struct sockaddr *)&from))
+ 			break;
+ 		}
+ #else
  		for (n = 0, qs = qp->q_addr;
  		     (u_int)n < qp->q_naddr;
  		     n++, qs++)
  			if (ina_equal(qs->ns_addr.sin_addr, from.sin_addr))
  				break;
+ #endif
  		if ((u_int)n >= qp->q_naddr) {
+ #ifdef INET6
+ 			if (!haveComplained46(&from, (u_long)"unexpected source")) {
+ 				ns_info(ns_log_default,
+ 					"Response from unexpected source (%s)",
+ 					sin_ntoa(from));
+ 			}
+ #else
  			if (!haveComplained(ina_ulong(from.sin_addr),
  					    (u_long)"unexpected source")) {
  				ns_info(ns_log_default,
  					"Response from unexpected source (%s)",
  					sin_ntoa(from));
  			}
+ #endif
  			/* 
  			 * We don't know who this response came from so it
  			 * gets dropped on the floor.
***************
*** 622,630 ****
  		}
  		GETSHORT(type, tp);
  		GETSHORT(class, tp);
  		if (!ns_nameok(name, class, NULL, response_trans,
  			       ns_ownercontext(type, response_trans),
! 			       name, from.sin_addr)) {
  			formerrmsg = badNameFound;
  			goto refused;
  		}
--- 789,804 ----
  		}
  		GETSHORT(type, tp);
  		GETSHORT(class, tp);
+ #ifdef INET6
+ 		if (!ns_nameok(name, class, NULL, response_trans,
+ 			       ns_ownercontext(type, response_trans),
+ 			       name, from))
+ #else
  		if (!ns_nameok(name, class, NULL, response_trans,
  			       ns_ownercontext(type, response_trans),
! 			       name, from.sin_addr))
! #endif
! 		{
  			formerrmsg = badNameFound;
  			goto refused;
  		}
***************
*** 639,644 ****
--- 813,840 ----
  		 */
  
  		if (type == T_NS && samedomain(qp->q_domain, name)) {
+ #ifdef INET6
+ 			nameserIncr(from, nssRcvdLDel);
+ 			/* mark server as bad */
+ 			if (!qp->q_fwd)
+ 			    for (i = 0; i < (int)qp->q_naddr; i++)
+ 		if (ima_equal((struct sockaddr *)&qp->q_addr[i].ns_addr,
+ 			      (struct sockaddr *)&from))
+ 					qp->q_addr[i].nretry = MAXRETRY;
+ 			if (class == C_IN &&
+ 			    !haveComplained46(&from, nhash(qp->q_domain))) {
+ 				char *learnt_from = learntFrom(qp, &from.sin);
+ 
+ 				ns_info(ns_log_lame_servers,
+ 					"Lame server on '%s' (in '%s'?): %s%s",
+ 					qname, qp->q_domain, 
+ 					sin_ntoa(from),
+ 					(learnt_from == NULL) ? "" :
+ 					learnt_from);
+ 				if (learnt_from != NULL)
+ 					freestr(learnt_from);
+ 			}
+ #else
  			nameserIncr(from.sin_addr, nssRcvdLDel);
  			/* mark server as bad */
  			if (!qp->q_fwd)
***************
*** 660,673 ****
--- 856,877 ----
  				if (learnt_from != NULL)
  					freestr(learnt_from);
  			}
+ #endif
  
  			/* XXX - doesn't handle responses sent from the wrong
  			 * interface on a multihomed server
  			 */
+ #ifdef INET6
  			if (qp->q_fwd ||
+ 	  ima_equal((struct sockaddr *)&qp->q_addr[qp->q_curaddr].ns_addr,
+ 		    (struct sockaddr *)&from))
+ 				retry(qp);
+ #else
+ 			if (qp->q_fwd ||
  			  ina_equal(qp->q_addr[qp->q_curaddr].ns_addr.sin_addr,
  				    from.sin_addr))
  				retry(qp);
+ #endif
  			return;
  		}
  	}
***************
*** 697,708 ****
--- 901,921 ----
  			tp += INT32SZ;		/* ttl */
  			GETSHORT(dlen, tp); 	/* dlen */
  			rdatap = tp;		/* start of rdata */
+ #ifdef INET6
  			if (!ns_nameok(name, class, NULL, response_trans,
  				       ns_ownercontext(type, response_trans),
+ 				       name, from)) {
+ 				formerrmsg = badNameFound;
+ 				goto refused;
+ 			}
+ #else
+ 			if (!ns_nameok(name, class, NULL, response_trans,
+ 				       ns_ownercontext(type, response_trans),
  				       name, from.sin_addr)) {
  				formerrmsg = badNameFound;
  				goto refused;
  			}
+ #endif
  			if (strcasecmp(qname, name) ||
  			    qtype != type ||
  			    qclass != class) {
***************
*** 794,802 ****
--- 1007,1021 ----
  		/* mark this server as bad */
  		if (!qp->q_fwd)
  			for (i = 0; i < (int)qp->q_naddr; i++)
+ #ifdef INET6
+ 		if (ima_equal((struct sockaddr *)&qp->q_addr[i].ns_addr,
+ 			      (struct sockaddr *)&from))
+ 					qp->q_addr[i].nretry = MAXRETRY;
+ #else
  				if (ina_equal(qp->q_addr[i].ns_addr.sin_addr,
  					      from.sin_addr))
  					qp->q_addr[i].nretry = MAXRETRY;
+ #endif
  
  		/* try another server, it may have a bigger write buffer */
  		retry(qp);
***************
*** 932,941 ****
--- 1151,1163 ----
  					   NS or SOA or NXT */
  					break;
  				default:
+ #ifdef INET6
+ #else
  					ns_info(ns_log_resp_checks,
  	"invalid RR type '%s' in authority section (name = '%s') from %s",
  						p_type(type), name,
  						sin_ntoa(from));
+ #endif
  					db_freedata(dp);
  					continue;
  				}
***************
*** 953,962 ****
--- 1175,1187 ----
  						continue;
  					}
  					if (!related_additional(name)) {
+ #ifdef INET6
+ #else
  						ns_info(ns_log_resp_checks,
  			     "unrelated additional info '%s' type %s from %s",
  							 name, p_type(type),
  							 sin_ntoa(from));
+ #endif
  						db_freedata(dp);
  						continue;
  					}
***************
*** 973,982 ****
--- 1198,1210 ----
  					 */
  					break;
  				default:
+ #ifdef INET6
+ #else
  					ns_info(ns_log_resp_checks,
  	"invalid RR type '%s' in additional section (name = '%s') from %s",
  						p_type(type), name,
  						sin_ntoa(from));
+ #endif
  					db_freedata(dp);
  					continue;
  				}
***************
*** 1004,1021 ****
--- 1232,1264 ----
  	if ((qp->q_flags & Q_SYSTEM) && ancount) {
  		if ((qp->q_flags & Q_PRIMING) && !check_root()) {
  			/* mark server as bad */
+ #ifdef INET6
  			if (!qp->q_fwd)
  			    for (i = 0; i < (int)qp->q_naddr; i++)
+ 		    if (ima_equal((struct sockaddr *)&qp->q_addr[i].ns_addr,
+ 				  (struct sockaddr *)&from))
+ 					    qp->q_addr[i].nretry = MAXRETRY;
+ #else
+ 			if (!qp->q_fwd)
+ 			    for (i = 0; i < (int)qp->q_naddr; i++)
  				    if (ina_equal(qp->q_addr[i].ns_addr.sin_addr,
  						  from.sin_addr))
  					    qp->q_addr[i].nretry = MAXRETRY;
+ #endif
  			/* XXX - doesn't handle responses sent from
  			* the wronginterface on a multihomed server
  		 	*/
+ #ifdef INET6
+ 			if (qp->q_fwd ||
+ 		    qp->q_addr[qp->q_curaddr].ns_addr.sin.sin_addr.s_addr
+ 			    == from.sin.sin_addr.s_addr)
+ 				retry(qp);
+ #else
  			if (qp->q_fwd ||
  			    qp->q_addr[qp->q_curaddr].ns_addr.sin_addr.s_addr
  			    == from.sin_addr.s_addr)
  				retry(qp);
+ #endif
  			return;
  		}
  		ns_debug(ns_log_default, 3,
***************
*** 1163,1169 ****
  #ifdef RETURNSOA
  			n = finddata(np, qclass, T_SOA, hp, &dname,
  				     &buflen, &count);
! 			if ( n != 0) {
  				if (count) {
  					cp += n;
  					buflen -= n;
--- 1406,1412 ----
  #ifdef RETURNSOA
  			n = finddata(np, qclass, T_SOA, hp, &dname,
  				     &buflen, &count);
! 			if (n != 0) {
  				if (count) {
  					cp += n;
  					buflen -= n;
***************
*** 1360,1368 ****
  	unsched(qp);
  	schedretry(qp, retrytime(qp));
  	nsa = Q_NEXTADDR(qp, 0);
  	ns_debug(ns_log_default, 1,
  		 "resp: forw -> %s ds=%d nsid=%d id=%d %dms",
! 		 sin_ntoa(*nsa), ds,
  		 ntohs(qp->q_nsid), ntohs(qp->q_id),
  		 (qp->q_addr[0].nsdata != NULL)
  			? qp->q_addr[0].nsdata->d_nstime
--- 1603,1628 ----
  	unsched(qp);
  	schedretry(qp, retrytime(qp));
  	nsa = Q_NEXTADDR(qp, 0);
+ #ifdef INET6
+ 	switch (nsa->sin.sin_family) {
+ 	case AF_INET:
+ 		inet_ntop(AF_INET, &nsa->sin.sin_addr, hostbuf, sizeof(hostbuf));
+ 		salen = sizeof(nsa->sin);
+ 		break;
+ 	case AF_INET6:
+ 		inet_ntop(AF_INET6, &nsa->sin6.sin6_addr, hostbuf, sizeof(hostbuf));
+ 		salen = sizeof(nsa->sin6);
+ 		break;
+ 	default:
+ 		strcpy(hostbuf, "invalid");
+ 	}
+ #else
+ 	strncpy(hostbuf, sin_ntoa(*nsa), sizeof(hostbuf));
+ 	salen = sizeof(*nsa);
+ #endif
  	ns_debug(ns_log_default, 1,
  		 "resp: forw -> %s ds=%d nsid=%d id=%d %dms",
! 		 hostbuf, ds,
  		 ntohs(qp->q_nsid), ntohs(qp->q_id),
  		 (qp->q_addr[0].nsdata != NULL)
  			? qp->q_addr[0].nsdata->d_nstime
***************
*** 1372,1429 ****
  		fp_nquery(qp->q_msg, qp->q_msglen,
  			  log_get_stream(packet_channel));
  #endif
  	if (qp->q_flags & Q_USEVC) {
  		if (tcp_send(qp) != NOERROR) {
  			if (!haveComplained(ina_ulong(nsa->sin_addr),
  					    (u_long)tcpsendStr))
  				ns_info(ns_log_default,
  					"ns_forw: tcp_send(%s) failed: %s",
! 					sin_ntoa(*nsa), strerror(errno));
  		}
  	} else if (sendto(ds, (char*)qp->q_msg, qp->q_msglen, 0,
! 		   (struct sockaddr *)nsa,
! 		   sizeof(struct sockaddr_in)) < 0)
  	{
  		if (!haveComplained(ina_ulong(nsa->sin_addr),
  				    (u_long)sendtoStr))
  			ns_info(ns_log_default, "ns_resp: sendto(%s): %s",
! 				sin_ntoa(*nsa), strerror(errno));
  		nameserIncr(nsa->sin_addr, nssSendtoErr);
  	}
  	hp->rd = 0;	/* leave set to 0 for dup detection */
  	nameserIncr(nsa->sin_addr, nssSentFwdR);
  	nameserIncr(qp->q_from.sin_addr, nssRcvdFwdR);
  	ns_debug(ns_log_default, 3, "resp: Query sent.");
  	free_nsp(nsp);
  	return;
  
   formerr:
  	if (!haveComplained(ina_ulong(from.sin_addr), (u_long)formerrmsg))
  		ns_info(ns_log_resp_checks, "Malformed response from %s (%s)",
  			sin_ntoa(from), formerrmsg);
  	free_nsp(nsp);
  	return;
  
   return_msg:
  	nameserIncr(from.sin_addr, nssRcvdFwdR);
  	nameserIncr(qp->q_from.sin_addr, nssSentFwdR);
  	/* The "standard" return code */
  	hp->qr = 1;
  	hp->id = qp->q_id;
  	hp->rd = 1;
  	hp->ra = (NS_OPTION_P(OPTION_NORECURSE) == 0);
  	(void) send_msg(msg, msglen, qp);
  	qremove(qp);
  	free_nsp(nsp);
  	return;
  
   return_newmsg:
  	nameserIncr(qp->q_from.sin_addr, nssSentAns);
- 
  	if (!hp->aa)
  		nameserIncr(qp->q_from.sin_addr, nssSentNaAns);
  	if (hp->rcode == NXDOMAIN) 
  		nameserIncr(qp->q_from.sin_addr, nssSentNXD);
  	n = doaddinfo(hp, cp, buflen);
  	cp += n;
  	buflen -= n;
--- 1632,1730 ----
  		fp_nquery(qp->q_msg, qp->q_msglen,
  			  log_get_stream(packet_channel));
  #endif
+ 
  	if (qp->q_flags & Q_USEVC) {
  		if (tcp_send(qp) != NOERROR) {
+ #ifdef INET6
+ 			if (!haveComplained46(nsa, (u_long)tcpsendStr))
+ #else
  			if (!haveComplained(ina_ulong(nsa->sin_addr),
  					    (u_long)tcpsendStr))
+ #endif
+ 			{
  				ns_info(ns_log_default,
  					"ns_forw: tcp_send(%s) failed: %s",
! 					hostbuf, strerror(errno));
! 			}
  		}
  	} else if (sendto(ds, (char*)qp->q_msg, qp->q_msglen, 0,
! 		   (struct sockaddr *)nsa, salen) < 0)
  	{
+ #ifdef INET6
+ 		if (!haveComplained46(nsa, (u_long)sendtoStr))
+ #else
  		if (!haveComplained(ina_ulong(nsa->sin_addr),
  				    (u_long)sendtoStr))
+ #endif
+ 		{
  			ns_info(ns_log_default, "ns_resp: sendto(%s): %s",
! 				hostbuf, strerror(errno));
! 		}
! #ifdef INET6
! 		nameserIncr(*nsa, nssSendtoErr);
! #else
  		nameserIncr(nsa->sin_addr, nssSendtoErr);
+ #endif
  	}
  	hp->rd = 0;	/* leave set to 0 for dup detection */
+ #ifdef INET6
+ 	nameserIncr(*nsa, nssSentFwdR);
+ 	nameserIncr(qp->q_from, nssRcvdFwdR);
+ #else
  	nameserIncr(nsa->sin_addr, nssSentFwdR);
  	nameserIncr(qp->q_from.sin_addr, nssRcvdFwdR);
+ #endif
  	ns_debug(ns_log_default, 3, "resp: Query sent.");
  	free_nsp(nsp);
  	return;
  
   formerr:
+ #ifdef INET6
+ 	if (!haveComplained46(&from, (u_long)formerrmsg))
+ 		ns_info(ns_log_resp_checks, "Malformed response from %s (%s)",
+ 			sin_ntoa(from), formerrmsg);
+ 		free_nsp(nsp);
+ #else
  	if (!haveComplained(ina_ulong(from.sin_addr), (u_long)formerrmsg))
  		ns_info(ns_log_resp_checks, "Malformed response from %s (%s)",
  			sin_ntoa(from), formerrmsg);
  	free_nsp(nsp);
+ #endif
  	return;
  
   return_msg:
+ #ifdef INET6
+ 	nameserIncr(from, nssRcvdFwdR);
+ 	nameserIncr(qp->q_from, nssSentFwdR);
+ #else
  	nameserIncr(from.sin_addr, nssRcvdFwdR);
  	nameserIncr(qp->q_from.sin_addr, nssSentFwdR);
+ #endif
  	/* The "standard" return code */
  	hp->qr = 1;
  	hp->id = qp->q_id;
  	hp->rd = 1;
  	hp->ra = (NS_OPTION_P(OPTION_NORECURSE) == 0);
  	(void) send_msg(msg, msglen, qp);
+ 
  	qremove(qp);
  	free_nsp(nsp);
  	return;
  
   return_newmsg:
+ #ifdef INET6
+ 	nameserIncr(qp->q_from, nssSentAns);
+ 	if (!hp->aa)
+ 		nameserIncr(qp->q_from, nssSentNaAns);
+ 	if (hp->rcode == NXDOMAIN) 
+ 		nameserIncr(qp->q_from, nssSentNXD);
+ #else
  	nameserIncr(qp->q_from.sin_addr, nssSentAns);
  	if (!hp->aa)
  		nameserIncr(qp->q_from.sin_addr, nssSentNaAns);
  	if (hp->rcode == NXDOMAIN) 
  		nameserIncr(qp->q_from.sin_addr, nssSentNXD);
+ #endif
  	n = doaddinfo(hp, cp, buflen);
  	cp += n;
  	buflen -= n;
***************
*** 1432,1437 ****
--- 1733,1739 ----
  	hp->rd = 1;
  	hp->ra = (NS_OPTION_P(OPTION_NORECURSE) == 0);
  	(void) send_msg(newmsg, cp - newmsg, qp);
+ 
  	qremove(qp);
  	free_nsp(nsp);
  	return;
***************
*** 1451,1457 ****
--- 1753,1763 ----
  	return;
  	
   servfail:
+ #ifdef INET6
+ 	nameserIncr(qp->q_from, nssSentFail);
+ #else
  	nameserIncr(qp->q_from.sin_addr, nssSentFail);
+ #endif
  	hp = (HEADER *)(qp->q_cmsglen ? qp->q_cmsg : qp->q_msg);
  	hp->rcode = SERVFAIL;
  	hp->qr = 1;
***************
*** 1483,1489 ****
  
  static int
  rrextract(u_char *msg, int msglen, u_char *rrp, struct databuf **dpp,
! 	  char *dname, int namelen, struct sockaddr_in from, char **tnamep)
  {
  	u_char *cp, *eom, *rdatap;
  	u_int class, type, dlen;
--- 1789,1801 ----
  
  static int
  rrextract(u_char *msg, int msglen, u_char *rrp, struct databuf **dpp,
! 	  char *dname, int namelen,
! #ifdef INET6
! 	  msockaddr_in from,
! #else
! 	  struct sockaddr_in from,
! #endif
! 	  char **tnamep)
  {
  	u_char *cp, *eom, *rdatap;
  	u_int class, type, dlen;
***************
*** 1516,1524 ****
  	GETSHORT(dlen, cp);
  	BOUNDS_CHECK(cp, dlen);
  	rdatap = cp;
  	if (!ns_nameok(dname, class, NULL, response_trans,
  		       ns_ownercontext(type, response_trans),
! 		       dname, from.sin_addr)) {
  		hp->rcode = REFUSED;
  		return (-1);
  	}
--- 1828,1843 ----
  	GETSHORT(dlen, cp);
  	BOUNDS_CHECK(cp, dlen);
  	rdatap = cp;
+ #ifdef INET6
  	if (!ns_nameok(dname, class, NULL, response_trans,
  		       ns_ownercontext(type, response_trans),
! 		       dname, from))
! #else
! 	if (!ns_nameok(dname, class, NULL, response_trans,
! 		       ns_ownercontext(type, response_trans),
! 		       dname, from.sin_addr))
! #endif
! 	{
  		hp->rcode = REFUSED;
  		return (-1);
  	}
***************
*** 1574,1582 ****
  			hp->rcode = FORMERR;
  			return (-1);
  		}
  		if (!ns_nameok((char *)data, class, NULL, response_trans,
  			       type == T_PTR ?ns_ptrcontext(dname) :domain_ctx,
! 			       dname, from.sin_addr)) {
  			hp->rcode = FORMERR;
  			return (-1);
  		}
--- 1893,1908 ----
  			hp->rcode = FORMERR;
  			return (-1);
  		}
+ #ifdef INET6
+ 		if (!ns_nameok((char *)data, class, NULL, response_trans,
+ 			       type == T_PTR ?ns_ptrcontext(dname) :domain_ctx,
+ 			       dname, from))
+ #else
  		if (!ns_nameok((char *)data, class, NULL, response_trans,
  			       type == T_PTR ?ns_ptrcontext(dname) :domain_ctx,
! 			       dname, from.sin_addr))
! #endif
! 		{
  			hp->rcode = FORMERR;
  			return (-1);
  		}
***************
*** 1600,1607 ****
  			hp->rcode = FORMERR;
  			return (-1);
  		}
  		if (!ns_nameok((char *)data, class, NULL, response_trans,
! 			       context, dname, from.sin_addr)) {
  			hp->rcode = FORMERR;
  			return (-1);
  		}
--- 1926,1939 ----
  			hp->rcode = FORMERR;
  			return (-1);
  		}
+ #ifdef INET6
+ 		if (!ns_nameok((char *)data, class, NULL, response_trans,
+ 			       context, dname, from))
+ #else
  		if (!ns_nameok((char *)data, class, NULL, response_trans,
! 			       context, dname, from.sin_addr))
! #endif
! 		{
  			hp->rcode = FORMERR;
  			return (-1);
  		}
***************
*** 1623,1630 ****
  			context = domain_ctx;
  		else
  			context = mailname_ctx;
  		if (!ns_nameok((char *)cp1, class, NULL, response_trans,
! 			       context, dname, from.sin_addr)) {
  			hp->rcode = FORMERR;
  			return (-1);
  		}
--- 1955,1968 ----
  			context = domain_ctx;
  		else
  			context = mailname_ctx;
+ #ifdef INET6
+ 		if (!ns_nameok((char *)cp1, class, NULL, response_trans,
+ 			       context, dname, from))
+ #else
  		if (!ns_nameok((char *)cp1, class, NULL, response_trans,
! 			       context, dname, from.sin_addr))
! #endif
! 		{
  			hp->rcode = FORMERR;
  			return (-1);
  		}
***************
*** 1679,1686 ****
  			hp->rcode = FORMERR;
  			return (-1);
  		}
  		if (!ns_nameok((char *)cp1, class, NULL, response_trans,
! 			       hostname_ctx, dname, from.sin_addr)) {
  			hp->rcode = FORMERR;
  			return (-1);
  		}
--- 2017,2030 ----
  			hp->rcode = FORMERR;
  			return (-1);
  		}
+ #ifdef INET6
+ 		if (!ns_nameok((char *)cp1, class, NULL, response_trans,
+ 			       hostname_ctx, dname, from))
+ #else
  		if (!ns_nameok((char *)cp1, class, NULL, response_trans,
! 			       hostname_ctx, dname, from.sin_addr))
! #endif
! 		{
  			hp->rcode = FORMERR;
  			return (-1);
  		}
***************
*** 1718,1725 ****
  			hp->rcode = FORMERR;
  			return (-1);
  		}
  		if (!ns_nameok((char *)cp1, class, NULL, response_trans,
! 			       hostname_ctx, dname, from.sin_addr)) {
  			hp->rcode = FORMERR;
  			return (-1);
  		}
--- 2062,2075 ----
  			hp->rcode = FORMERR;
  			return (-1);
  		}
+ #ifdef INET6
+ 		if (!ns_nameok((char *)cp1, class, NULL, response_trans,
+ 			       hostname_ctx, dname, from))
+ #else
  		if (!ns_nameok((char *)cp1, class, NULL, response_trans,
! 			       hostname_ctx, dname, from.sin_addr))
! #endif
! 		{
  			hp->rcode = FORMERR;
  			return (-1);
  		}
***************
*** 1749,1756 ****
  			hp->rcode = FORMERR;
  			return (-1);
  		}
  		if (!ns_nameok((char *)cp1, class, NULL, response_trans,
! 			       domain_ctx, dname, from.sin_addr)) {
  			hp->rcode = FORMERR;
  			return (-1);
  		}
--- 2099,2112 ----
  			hp->rcode = FORMERR;
  			return (-1);
  		}
+ #ifdef INET6
+ 		if (!ns_nameok((char *)cp1, class, NULL, response_trans,
+ 			       domain_ctx, dname, from))
+ #else
  		if (!ns_nameok((char *)cp1, class, NULL, response_trans,
! 			       domain_ctx, dname, from.sin_addr))
! #endif
! 		{
  			hp->rcode = FORMERR;
  			return (-1);
  		}
***************
*** 1766,1773 ****
  			hp->rcode = FORMERR;
  			return (-1);
  		}
  		if (!ns_nameok((char *)cp1, class, NULL, response_trans,
! 			       domain_ctx, dname, from.sin_addr)) {
  			hp->rcode = FORMERR;
  			return (-1);
  		}
--- 2122,2135 ----
  			hp->rcode = FORMERR;
  			return (-1);
  		}
+ #ifdef INET6
+ 		if (!ns_nameok((char *)cp1, class, NULL, response_trans,
+ 			       domain_ctx, dname, from))
+ #else
  		if (!ns_nameok((char *)cp1, class, NULL, response_trans,
! 			       domain_ctx, dname, from.sin_addr))
! #endif
! 		{
  			hp->rcode = FORMERR;
  			return (-1);
  		}
***************
*** 1899,1909 ****
--- 2261,2274 ----
  		return (1);
  	if (!qp->q_stream && (msglen > PACKETSZ))
  		msglen = trunc_adjust(msg, msglen, PACKETSZ);
+ #ifdef INET6
+ #else
  	ns_debug(ns_log_default, 1, "send_msg -> %s (%s %d) id=%d",
  		 sin_ntoa(qp->q_from), 
  		 qp->q_stream == NULL ? "UDP" : "TCP",
  		 qp->q_stream == NULL ? qp->q_dfd : qp->q_stream->s_rfd,
  		 ntohs(qp->q_id));
+ #endif
  #ifdef DEBUG
  	if (debug > 4) {
  		struct qinfo *tqp;
***************
*** 1925,1930 ****
--- 2290,2324 ----
  		fp_nquery(msg, msglen, log_get_stream(packet_channel));
  #endif /* DEBUG */
  	if (qp->q_stream == NULL) {
+ #ifdef INET6
+ 		int salen;
+ 		switch (qp->q_from.sin.sin_family) {
+ 		case AF_INET:
+ 			salen = sizeof(qp->q_from.sin);
+ 			break;
+ 		case AF_INET6:
+ 			salen = sizeof(qp->q_from.sin6);
+ 			break;
+ 		default:
+ 			ns_info(ns_log_default,
+ 				"send_msg: sendto(?): unknown address family");
+ 			return 1;
+ 		}
+ 		if (sendto(qp->q_dfd, (char*)msg, msglen, 0,
+ 			   (struct sockaddr *)&qp->q_from, salen) < 0) {
+ 			if (!haveComplained46(&qp->q_from, (u_long)sendtoStr))
+ #if defined(SPURIOUS_ECONNREFUSED)
+                            if (errno != ECONNREFUSED)
+ #endif
+ 				ns_info(ns_log_default,
+ 					"send_msg: sendto(%s): %s",
+ 					sin_ntoa(qp->q_from),
+ 					strerror(errno));
+ 			nameserIncr(qp->q_from, nssSendtoErr);
+ 			return (1);
+ 		}
+ #else
+ 
  		if (sendto(qp->q_dfd, (char*)msg, msglen, 0,
  			   (struct sockaddr *)&qp->q_from,
  			   sizeof(qp->q_from)) < 0) {
***************
*** 1940,1945 ****
--- 2334,2340 ----
  			nameserIncr(qp->q_from.sin_addr, nssSendtoErr);
  			return (1);
  		}
+ #endif
  	} else
  		writestream(qp->q_stream, (u_char*)msg, msglen);
  	return (0);
***************
*** 1961,1966 ****
--- 2356,2362 ----
  	    sizeof(dname)) < 0)
  		return;
  	ns_debug(ns_log_default, 2, "prime: %s", dname);
+ 
  	(void) sysquery(dname, class, type, NULL, 0, QUERY);
  }
  #endif
***************
*** 1974,1979 ****
--- 2370,2376 ----
  	 *       or should it be another option?  What about when we are
  	 *	 doing selective forwarding?
  	 */
+ 
  	if (!NS_OPTION_P(OPTION_FORWARD_ONLY)) {
  		ns_debug(ns_log_default, 1, "prime_cache: priming = %d",
  			 priming);
***************
*** 2034,2041 ****
  	if (zp->z_type == z_master)
  		sysnotify_slaves(dname, zname, class, zn, &nns, &na);
  	if (zp->z_notify_count != 0) {
- 		struct in_addr *also_addr = zp->z_also_notify;
  		int i;
  		
  		for (i = 0; i < zp->z_notify_count; i++) {
  			sysquery(dname, class, T_SOA, also_addr, 1,
--- 2431,2442 ----
  	if (zp->z_type == z_master)
  		sysnotify_slaves(dname, zname, class, zn, &nns, &na);
  	if (zp->z_notify_count != 0) {
  		int i;
+ #ifdef INET6
+ 		msockaddr_in *also_addr = zp->z_also_notify;
+ #else
+ 		struct in_addr *also_addr = zp->z_also_notify;
+ #endif
  		
  		for (i = 0; i < zp->z_notify_count; i++) {
  			sysquery(dname, class, T_SOA, also_addr, 1,
***************
*** 2104,2110 ****
--- 2505,2515 ----
  	struct databuf *adp;
  	struct namebuf *anp;
  	const char *fname;
+ #ifdef INET6
+ 	msockaddr_in nss[NSMAX];
+ #else
  	struct in_addr nss[NSMAX];
+ #endif
  	struct hashbuf *htp;
  	int is_us, nsc;
  
***************
*** 2123,2130 ****
  				is_us = 1;
  				continue;
  			}
! 			if (nsc < NSMAX)
  				nss[nsc++] = ina;
  		} /*next A*/
  	if (nsc == 0) {
  		if (!is_us) {
--- 2528,2542 ----
  				is_us = 1;
  				continue;
  			}
! 			if (nsc < NSMAX) {
! #ifdef INET6
! 				nss[nsc].sin.sin_family = AF_INET;
! 				nss[nsc].sin.sin_addr = ina;
! 				nsc++;
! #else
  				nss[nsc++] = ina;
+ #endif
+ 			}
  		} /*next A*/
  	if (nsc == 0) {
  		if (!is_us) {
***************
*** 2136,2150 ****
--- 2548,2569 ----
  		}
  		return;
  	}
+ 
  	(void) sysquery(dname, class, T_SOA, nss, nsc, NS_NOTIFY_OP);
  	(*nns)++;
  	*na += nsc;
  }
  #endif /*BIND_NOTIFY*/
  
+ #ifdef INET6
+ struct qinfo *
+ sysquery(const char *dname, int class, int type,
+ 	 msockaddr_in *nss, int nsc, int opcode)
+ #else
  struct qinfo *
  sysquery(const char *dname, int class, int type,
  	 struct in_addr *nss, int nsc, int opcode)
+ #endif
  {
  	struct qinfo *qp, *oqp;
  	HEADER *hp;
***************
*** 2152,2160 ****
  	struct namebuf *np;
  	struct databuf *nsp[NSMAX];
  	struct hashbuf *htp;
! 	struct sockaddr_in *nsa;
  	const char *fname;
  	int n, count;
  
  	nsp[0] = NULL;
  	ns_debug(ns_log_default, 3, "sysquery(%s, %d, %d, %#x, %d)",
--- 2571,2583 ----
  	struct namebuf *np;
  	struct databuf *nsp[NSMAX];
  	struct hashbuf *htp;
! 	struct sockaddr *nsa;
  	const char *fname;
  	int n, count;
+ #ifdef INET6
+ 	msockaddr_in msa;
+ #endif
+ 	int salen;
  
  	nsp[0] = NULL;
  	ns_debug(ns_log_default, 3, "sysquery(%s, %d, %d, %#x, %d)",
***************
*** 2192,2198 ****
  
  	/* build new qinfo struct */
  	qp->q_cmsg = qp->q_msg = NULL;
- 	qp->q_dfd = ds;
  	if (nss && nsc)
  		qp->q_fwd = NULL;
  	else
--- 2615,2620 ----
***************
*** 2245,2254 ****
  	if (nss && nsc) {
  		int i;
  		struct qserv *qs;
! 
  		for (i = 0, qs = qp->q_addr;
  		     i < nsc;
  		     i++, qs++) {
  			qs->ns_addr.sin_family = AF_INET;
  			qs->ns_addr.sin_addr = nss[i];
  			qs->ns_addr.sin_port = ns_port;
--- 2667,2694 ----
  	if (nss && nsc) {
  		int i;
  		struct qserv *qs;
! #ifdef INET6
  		for (i = 0, qs = qp->q_addr;
  		     i < nsc;
  		     i++, qs++) {
+ 		    if (nss[i].sin6.sin6_family == AF_INET6) {
+ 			qs->ns_addr.sin6.sin6_family = AF_INET6;
+ 			qs->ns_addr.sin6.sin6_addr = nss[i].sin6.sin6_addr;
+ 			qs->ns_addr.sin6.sin6_port = ns_port;
+ 		    } else {
+ 			qs->ns_addr.sin.sin_family = AF_INET;
+ 			qs->ns_addr.sin.sin_addr = nss[i].sin.sin_addr;
+ 			qs->ns_addr.sin.sin_port = ns_port;
+ 		    }
+ 		    qs->ns = NULL;
+ 		    qs->nsdata = NULL;
+ 		    qs->stime = tt;
+ 		    qs->nretry = 0;
+ 		}
+ #else
+ 		for (i = 0, qs = qp->q_addr;
+ 		     i < nsc;
+ 		     i++, qs++) {
  			qs->ns_addr.sin_family = AF_INET;
  			qs->ns_addr.sin_addr = nss[i];
  			qs->ns_addr.sin_port = ns_port;
***************
*** 2257,2266 ****
--- 2697,2708 ----
  			qs->stime = tt;
  			qs->nretry = 0;
  		}
+ #endif
  		qp->q_naddr = nsc;
  	} else {
   fetch_a:
  		count = nslookup(nsp, qp, dname, "sysquery");
+ 
  		if (count <= 0) {
  			if (count < 0) {
  				ns_info(ns_log_default,
***************
*** 2312,2339 ****
  	schedretry(qp, retrytime(qp));
  	if (qp->q_fwd == NULL)
  		qp->q_addr[0].stime = tt;	/* XXX - why not every? */
  	nsa = Q_NEXTADDR(qp, 0);
  
  	ns_debug(ns_log_default, 1,
  		 "sysquery: send -> %s dfd=%d nsid=%d id=%d retry=%ld",
! 		 sin_ntoa(*nsa), qp->q_dfd, 
  		 ntohs(qp->q_nsid), ntohs(qp->q_id),
  		 (long)qp->q_time);
  #ifdef DEBUG
  	if (debug >= 10)
  		fp_nquery(qp->q_msg, qp->q_msglen,
  			  log_get_stream(packet_channel));
  #endif
  	if (sendto(qp->q_dfd, (char*)qp->q_msg, qp->q_msglen, 0,
! 		   (struct sockaddr *)nsa,
! 		   sizeof(struct sockaddr_in)) < 0) {
  		if (!haveComplained(ina_ulong(nsa->sin_addr),
  				    (u_long)sendtoStr))
  			ns_info(ns_log_default, "sysquery: sendto(%s): %s",
! 				sin_ntoa(*nsa), strerror(errno));
  		nameserIncr(nsa->sin_addr, nssSendtoErr);
  	}
  	nameserIncr(nsa->sin_addr, nssSentSysQ);
  	free_nsp(nsp);
  	return (qp);
  }
--- 2754,2817 ----
  	schedretry(qp, retrytime(qp));
  	if (qp->q_fwd == NULL)
  		qp->q_addr[0].stime = tt;	/* XXX - why not every? */
+ #ifdef INET6
+ 	msa = *Q_NEXTADDR(qp, 0);
+ 	nsa = (struct sockaddr *)&msa.sin;
+ 	qp->q_dfd = (nsa->sa_family == AF_INET) ? ds : ds6;
+ 	salen = (nsa->sa_family == AF_INET) ? sizeof(msa.sin) : sizeof(msa.sin6);
+ #else
  	nsa = Q_NEXTADDR(qp, 0);
+ 	qp->q_dfd = ds;
+ 	salen = sizeof(struct sockaddr_in);
+ #endif
  
  	ns_debug(ns_log_default, 1,
  		 "sysquery: send -> %s dfd=%d nsid=%d id=%d retry=%ld",
! #ifdef INET6
! 		 sin_ntoa(msa),
! #else
! 		 sin_ntoa(nsa),
! #endif
! 		 qp->q_dfd, 
  		 ntohs(qp->q_nsid), ntohs(qp->q_id),
  		 (long)qp->q_time);
+ #ifdef INET6
+ 	if (nsa->sa_family == AF_INET)
+ 		msa.sin.sin_port = htons(53);
+ 	else
+ 		msa.sin6.sin6_port = htons(53);
+ #else
+ 	nsa->sin_port = htons(53);
+ #endif
  #ifdef DEBUG
  	if (debug >= 10)
  		fp_nquery(qp->q_msg, qp->q_msglen,
  			  log_get_stream(packet_channel));
  #endif
+ 
  	if (sendto(qp->q_dfd, (char*)qp->q_msg, qp->q_msglen, 0,
! 		   (struct sockaddr *)nsa, salen) < 0) {
! #ifdef INET6
! 		if (!haveComplained46(&msa, (u_long)sendtoStr))
! #else
  		if (!haveComplained(ina_ulong(nsa->sin_addr),
  				    (u_long)sendtoStr))
+ #endif
+ 		{
  			ns_info(ns_log_default, "sysquery: sendto(%s): %s",
! 				sin_ntoa(msa), strerror(errno));
! 		}
! #ifdef INET6
! 		nameserIncr(msa, nssSendtoErr);
! #else
  		nameserIncr(nsa->sin_addr, nssSendtoErr);
+ #endif
  	}
+ #ifdef INET6
+ 	nameserIncr(msa, nssSentSysQ);
+ #else
  	nameserIncr(nsa->sin_addr, nssSentSysQ);
+ #endif
  	free_nsp(nsp);
  	return (qp);
  }
***************
*** 2461,2469 ****
  				ns_info(ns_log_default,
  					"Root NS %s -> CNAME %s",
  					NAME(*np), NAME(*tnp));
! 			else
  				sysquery(dname, dp->d_class, T_A, NULL,
  					 0, QUERY);
  	        }
  	}
  
--- 2939,2948 ----
  				ns_info(ns_log_default,
  					"Root NS %s -> CNAME %s",
  					NAME(*np), NAME(*tnp));
! 			else {
  				sysquery(dname, dp->d_class, T_A, NULL,
  					 0, QUERY);
+ 			}
  	        }
  	}
  
***************
*** 2643,2649 ****
  		     dpp = &dp->d_next) {
  			if (dp->d_next && wanted(dp, class, type)) {
  				struct databuf *lp;
- 
  				*dpp = lp = dp->d_next;
  				dp->d_next = NULL;
  
--- 3122,3127 ----
***************
*** 2730,2736 ****
  		/* Don't put anything but key or sig RR's in response to
  			     requests for key or sig */
  		if (((type == T_SIG) || (type == T_KEY)) &&
! 		    (!((dp->d_type == T_SIG) || (dp->d_type == T_KEY))) )
  			continue;
  
  		if ((n = make_rr(*dnamep, dp, (u_char *)cp, buflen, 1,
--- 3208,3214 ----
  		/* Don't put anything but key or sig RR's in response to
  			     requests for key or sig */
  		if (((type == T_SIG) || (type == T_KEY)) &&
! 		    (!((dp->d_type == T_SIG) || (dp->d_type == T_KEY))))
  			continue;
  
  		if ((n = make_rr(*dnamep, dp, (u_char *)cp, buflen, 1,
***************
*** 2832,2837 ****
--- 3310,3316 ----
  		else
  			break;
  	}
+ 
  	/* OK, now look at the type of query.  */
  	switch (type) {
  	case T_ANY:
***************
*** 2854,2859 ****
--- 3333,3339 ----
  			return (1);
  		break;
  	}
+ 
  	return (0);
  }
  
***************
*** 3057,3063 ****
  }
  
  static void
! rrsetupdate(struct flush_set * flushset, int flags, struct sockaddr_in from) {
  	struct flush_set *fs = flushset;
  	struct db_list *dbp, *odbp;
  	int n;
--- 3537,3548 ----
  }
  
  static void
! #ifdef INET6
! rrsetupdate(struct flush_set * flushset, int flags, msockaddr_in from)
! #else
! rrsetupdate(struct flush_set * flushset, int flags, struct sockaddr_in from)
! #endif
! {
  	struct flush_set *fs = flushset;
  	struct db_list *dbp, *odbp;
  	int n;
***************
*** 3102,3108 ****
  }
  
  static void
! flushrrset(struct flush_set * fs, struct sockaddr_in from) {
  	struct databuf *dp;
  	int n;
  
--- 3587,3598 ----
  }
  
  static void
! #ifdef INET6
! flushrrset(struct flush_set * fs, msockaddr_in from)
! #else
! flushrrset(struct flush_set * fs, struct sockaddr_in from)
! #endif
! {
  	struct databuf *dp;
  	int n;
  
Index: bind8/src/bin/named/ns_stats.c
diff -c bind8/src/bin/named/ns_stats.c:1.1.1.1 bind8/src/bin/named/ns_stats.c:1.2.2.1
*** bind8/src/bin/named/ns_stats.c:1.1.1.1	Fri Sep 25 14:24:53 1998
--- bind8/src/bin/named/ns_stats.c	Tue Jun  1 13:13:18 1999
***************
*** 1,6 ****
  #if !defined(lint) && !defined(SABER)
  static char sccsid[] = "@(#)ns_stats.c	4.10 (Berkeley) 6/27/90";
! static char rcsid[] = "$Id: ns_stats.c,v 8.18 1998/02/13 19:50:24 halley Exp $";
  #endif /* not lint */
  
  /*
--- 1,6 ----
  #if !defined(lint) && !defined(SABER)
  static char sccsid[] = "@(#)ns_stats.c	4.10 (Berkeley) 6/27/90";
! static char rcsid[] = "$Id: ns_stats.c,v 1.1.1.1 1998/09/25 05:24:53 k-sugyou Exp $";
  #endif /* not lint */
  
  /*
***************
*** 161,167 ****
  
  	/* query type statistics */
  	fprintf(f, "%lu\tUnknown query types\n", (u_long)typestats[0]);
! 	for(i=1; i < T_ANY+1; i++)
  		if (typestats[i]) {
  			if (typenames[i] != NULL)
  				fprintf(f, "%lu\t%s queries\n",
--- 161,167 ----
  
  	/* query type statistics */
  	fprintf(f, "%lu\tUnknown query types\n", (u_long)typestats[0]);
! 	for (i = 1; i < T_ANY+1; i++)
  		if (typestats[i]) {
  			if (typenames[i] != NULL)
  				fprintf(f, "%lu\t%s queries\n",
***************
*** 244,253 ****
--- 244,260 ----
  	return (0);
  }
  
+ #ifdef INET6
  struct nameser *
+ nameserFind(msaddr, flags)
+ 	msockaddr_in msaddr;
+ 	int flags;
+ #else
+ struct nameser *
  nameserFind(addr, flags)
  	struct in_addr addr;
  	int flags;
+ #endif
  {
  	struct nameser dummy;
  	struct nameser *ns;
***************
*** 257,263 ****
  		nameserInit++;
  	}
  
! 	dummy.addr = addr;
  	ns = (struct nameser *)tree_srch(&nameserTree, nameserCompar,
  					 (tree_t)&dummy);
  	if (ns == NULL && (flags & NS_F_INSERT) != 0) {
--- 264,273 ----
  		nameserInit++;
  	}
  
! #ifdef INET6
! 	dummy.msaddr = msaddr;
! #else
! #endif
  	ns = (struct nameser *)tree_srch(&nameserTree, nameserCompar,
  					 (tree_t)&dummy);
  	if (ns == NULL && (flags & NS_F_INSERT) != 0) {
***************
*** 270,276 ****
--- 280,290 ----
  			return (NULL);
  		}
  		memset(ns, 0, sizeof *ns);
+ #ifdef INET6
+ 		ns->msaddr = msaddr;
+ #else
  		ns->addr = addr;
+ #endif
  		if (!tree_add(&nameserTree, nameserCompar, (tree_t)ns, NULL)) {
  			int save = errno;
  			memput(ns, sizeof *ns);
***************
*** 318,325 ****
  {
  	struct nameser *ns = (struct nameser *)t;
  
  	fprintf(nameserStatsFile, "[%s]\n",	/* : rtt %u */
! 		inet_ntoa(ns->addr)  /*, ns->rtt*/ );
  	nameserStatsOut(nameserStatsFile, ns->stats);
  	return (1);
  }
--- 332,343 ----
  {
  	struct nameser *ns = (struct nameser *)t;
  
+ #ifdef INET6
+ 	/* ???? */
+ #else
  	fprintf(nameserStatsFile, "[%s]\n",	/* : rtt %u */
! 		inet_ntoa(ns->addr)  /*, ns->rtt*/);
! #endif
  	nameserStatsOut(nameserStatsFile, ns->stats);
  	return (1);
  }
Index: bind8/src/bin/named/ns_update.c
diff -c bind8/src/bin/named/ns_update.c:1.1.1.1 bind8/src/bin/named/ns_update.c:1.3.2.2
*** bind8/src/bin/named/ns_update.c:1.1.1.1	Fri Sep 25 14:24:53 1998
--- bind8/src/bin/named/ns_update.c	Wed Jun  2 21:12:57 1999
***************
*** 1,5 ****
  #if !defined(lint) && !defined(SABER)
! static char rcsid[] = "$Id: ns_update.c,v 8.26 1998/05/05 19:45:10 halley Exp $";
  #endif /* not lint */
  
  /*
--- 1,5 ----
  #if !defined(lint) && !defined(SABER)
! static char rcsid[] = "$Id: ns_update.c,v 1.2 1998/09/25 08:16:51 k-sugyou Exp $";
  #endif /* not lint */
  
  /*
***************
*** 160,166 ****
   *	append an ascii form to the zone's transaction log file.
   */
  static void
! printupdatelog(struct sockaddr_in srcaddr,
  	       ns_updrec *firstp,
  	       HEADER *hp,
  	       struct zoneinfo *zp,
--- 160,171 ----
   *	append an ascii form to the zone's transaction log file.
   */
  static void
! printupdatelog(
! #ifdef INET6
! 	       msockaddr_in srcaddr,
! #else
! 	       struct sockaddr_in srcaddr,
! #endif
  	       ns_updrec *firstp,
  	       HEADER *hp,
  	       struct zoneinfo *zp,
***************
*** 172,177 ****
--- 177,183 ----
  	int opcode;
  	char time[25];
  	FILE *fp;
+ 	char hostbuf[MAXHOSTNAMELEN];
  
  	if (!firstp)
  		return;
***************
*** 181,188 ****
  		return;
  
  	sprintf(time, "at %lu", (u_long)tt.tv_sec);
  	fprintf(fp, "[DYNAMIC_UPDATE] id %u from %s %s (named pid %ld):\n",
! 	        hp->id, sin_ntoa(srcaddr), time, (long)getpid());
  	for (rrecp = firstp; rrecp; rrecp = rrecp->r_next) {
  		INSIST(zp == &zones[rrecp->r_zone]);
  		switch (rrecp->r_section) {
--- 187,208 ----
  		return;
  
  	sprintf(time, "at %lu", (u_long)tt.tv_sec);
+ #ifdef INET6
+ 	switch (srcaddr.sin.sin_family) {
+ 	case AF_INET:
+ 		inet_ntop(AF_INET, &srcaddr.sin.sin_addr, hostbuf, sizeof(hostbuf));
+ 		break;
+ 	case AF_INET6:
+ 		inet_ntop(AF_INET6, &srcaddr.sin6.sin6_addr, hostbuf, sizeof(hostbuf));
+ 		break;
+ 	default:
+ 		strcpy(hostbuf, "invalid");
+ 	}
+ #else
+ 	strncpy(hostbuf, sin_ntoa(srcaddr), sizeof(hostbuf));
+ #endif
  	fprintf(fp, "[DYNAMIC_UPDATE] id %u from %s %s (named pid %ld):\n",
! 	        hp->id, hostbuf, time, (long)getpid());
  	for (rrecp = firstp; rrecp; rrecp = rrecp->r_next) {
  		INSIST(zp == &zones[rrecp->r_zone]);
  		switch (rrecp->r_section) {
***************
*** 598,604 ****
   *	can schedule maintainance for zone dumps and soa.serial# increments.
   */
  static int
! process_updates(ns_updrec *firstp, int *rcodep, struct sockaddr_in from) {
  	int i, j, n, dbflags, matches, zonenum;
  	int numupdated = 0, soaupdated = 0, schedmaint = 0;
  	u_int16_t zclass;
--- 618,629 ----
   *	can schedule maintainance for zone dumps and soa.serial# increments.
   */
  static int
! #ifdef INET6
! process_updates(ns_updrec *firstp, int *rcodep, msockaddr_in from)
! #else
! process_updates(ns_updrec *firstp, int *rcodep, struct sockaddr_in from)
! #endif
! {
  	int i, j, n, dbflags, matches, zonenum;
  	int numupdated = 0, soaupdated = 0, schedmaint = 0;
  	u_int16_t zclass;
***************
*** 783,790 ****
--- 808,820 ----
  }
  
  static enum req_action
+ #ifdef INET6
+ req_update_private(HEADER *hp, u_char *cp, u_char *eom, u_char *msg, 
+ 		   struct qstream *qsp, int dfd, msockaddr_in from)
+ #else
  req_update_private(HEADER *hp, u_char *cp, u_char *eom, u_char *msg, 
  		   struct qstream *qsp, int dfd, struct sockaddr_in from)
+ #endif
  {
  	char dnbuf[MAXDNAME], *dname;
  	u_int zocount, prcount, upcount, adcount, class, type, dlen;
***************
*** 801,806 ****
--- 831,837 ----
  	int zonelist[MAXDNAME];
  	int should_use_tcp;
  	u_int32_t old_serial;
+ 	char hostbuf[MAXHOSTNAMELEN];
  
  	nsp[0] = NULL;
  
***************
*** 854,862 ****
  	 * Begin Access Control Point
  	 */
  
  	if (!ip_address_allowed(zp->z_update_acl, from.sin_addr)) {
  		ns_notice(ns_log_security, "unapproved update from %s for %s",
! 			  sin_ntoa(from), *dname ? dname : ".");
  		return (Refuse);
  	}
  
--- 885,913 ----
  	 * Begin Access Control Point
  	 */
  
+ #ifdef INET6
+ 	switch (from.sin.sin_family) {
+ 	case AF_INET:
+ 		inet_ntop(AF_INET, &from.sin.sin_addr, hostbuf, sizeof(hostbuf));
+ 		break;
+ 	case AF_INET6:
+ 		inet_ntop(AF_INET6, &from.sin6.sin6_addr, hostbuf, sizeof(hostbuf));
+ 		break;
+ 	default:
+ 		strcpy(hostbuf, "invalid");
+ 	}
+ #else
+ 	strncpy(hostbuf, sin_ntoa(from), sizeof(hostbuf));
+ #endif
+ 
+ #ifdef INET6
+ 	if (!ip_address_allowed(zp->z_update_acl, from))
+ #else
  	if (!ip_address_allowed(zp->z_update_acl, from.sin_addr)) {
+ #endif
+ 	{
  		ns_notice(ns_log_security, "unapproved update from %s for %s",
! 			  hostbuf, *dname ? dname : ".");
  		return (Refuse);
  	}
  
***************
*** 884,892 ****
--- 935,949 ----
  		
  		/* We are a slave for this zone, forward it to the master. */
  		for (cnt = 0; cnt < zp->z_addrcnt; cnt++)
+ #ifdef INET6
+ 			*nspp++ = savedata(zp->z_class, T_A, USE_MINIMUM,
+ 					   (u_char *)&zp->z_addr[cnt].sin.sin_addr.s_addr,
+ 					   INT32SZ);
+ #else
  			*nspp++ = savedata(zp->z_class, T_A, USE_MINIMUM,
  					   (u_char *)&zp->z_addr[cnt].s_addr,
  					   INT32SZ);
+ #endif
  		*nspp = NULL;
  		/*
  		 * If the request came in over TCP, forward it over TCP
***************
*** 983,989 ****
             	if (cp > eom) {
  			ns_info(ns_log_update,
  				"Malformed response from %s (overrun)",
! 				inet_ntoa(from.sin_addr));
  			hp->rcode = FORMERR;
  			return (Finish);
  		}
--- 1040,1046 ----
             	if (cp > eom) {
  			ns_info(ns_log_update,
  				"Malformed response from %s (overrun)",
! 				hostbuf);
  			hp->rcode = FORMERR;
  			return (Finish);
  		}
***************
*** 992,1001 ****
  	/* Now process all parsed records in the prereq and update sections. */
  	numupdated = process_updates(rrecp_start, &rcode, from);
  	hp->rcode = rcode;
  	if (numupdated <= 0) {
  		ns_error(ns_log_update,
  			 "error processing update packet id %d from %s",
! 			 hp->id, sin_ntoa(from));
  		return (Finish);
  	}
  
--- 1049,1072 ----
  	/* Now process all parsed records in the prereq and update sections. */
  	numupdated = process_updates(rrecp_start, &rcode, from);
  	hp->rcode = rcode;
+ #ifdef INET6
+ 	switch (from.sin.sin_family) {
+ 	case AF_INET:
+ 		inet_ntop(AF_INET, &from.sin.sin_addr, hostbuf, sizeof(hostbuf));
+ 		break;
+ 	case AF_INET6:
+ 		inet_ntop(AF_INET6, &from.sin6.sin6_addr, hostbuf, sizeof(hostbuf));
+ 		break;
+ 	default:
+ 		strcpy(hostbuf, "invalid");
+ 	}
+ #else
+ 	strncpy(hostbuf, sin_ntoa(from), sizeof(hostbuf));
+ #endif
  	if (numupdated <= 0) {
  		ns_error(ns_log_update,
  			 "error processing update packet id %d from %s",
! 			 hp->id, hostbuf);
  		return (Finish);
  	}
  
***************
*** 1007,1013 ****
  
  static void
  free_rrecp(ns_updrec **startpp, ns_updrec **lastpp, int rcode,
! 	   struct sockaddr_in from)
  {
  	ns_updrec *rrecp, *first_rrecp, *next_rrecp;
  	struct databuf *dp, *tmpdp;
--- 1078,1089 ----
  
  static void
  free_rrecp(ns_updrec **startpp, ns_updrec **lastpp, int rcode,
! #ifdef INET6
! 	   msockaddr_in from
! #else
! 	   struct sockaddr_in from
! #endif
! 	)
  {
  	ns_updrec *rrecp, *first_rrecp, *next_rrecp;
  	struct databuf *dp, *tmpdp;
***************
*** 1114,1119 ****
--- 1190,1210 ----
  }
  
  enum req_action
+ #ifdef INET6
+ req_update(HEADER *hp, u_char *cp, u_char *eom, u_char *msg, 
+ 	   struct qstream *qsp, int dfd, msockaddr_in mfrom)
+ {
+ 	enum req_action ret;
+ 
+ 	ret = req_update_private(hp, cp, eom, msg, qsp, dfd, mfrom);
+ 	free_rrecp(&rrecp_start, &rrecp_last, hp->rcode, mfrom);
+ 	if (ret == Finish) {
+ 		hp->qdcount = hp->ancount = hp->nscount = hp->arcount = 0;
+ 		memset(msg + HFIXEDSZ, 0, (eom - msg) - HFIXEDSZ);
+ 	}
+ 	return (ret);
+ }
+ #else
  req_update(HEADER *hp, u_char *cp, u_char *eom, u_char *msg, 
  	   struct qstream *qsp, int dfd, struct sockaddr_in from)
  {
***************
*** 1127,1132 ****
--- 1218,1224 ----
  	}
  	return (ret);
  }
+ #endif
  
  /*
   * expand rdata portion of a compressed resource record at cp into cp1
***************
*** 1377,1383 ****
  		cp += sizeof(char); 
  		fprintf(fp, "%s ", proto);
  		i = 0;
! 		while(cp < (u_char *)dp->d_data + dp->d_size) {
  			j = *cp++;
  			do {
  				if (j & 0200)
--- 1469,1475 ----
  		cp += sizeof(char); 
  		fprintf(fp, "%s ", proto);
  		i = 0;
! 		while (cp < (u_char *)dp->d_data + dp->d_size) {
  			j = *cp++;
  			do {
  				if (j & 0200)
***************
*** 1556,1567 ****
  	int zonelist[MAXDNAME];
  	struct stat st;
  	u_char *serialp;
- 	struct sockaddr_in empty_from;
  	int datasize;
  
  	empty_from.sin_family = AF_INET;
  	empty_from.sin_addr.s_addr = htonl(INADDR_ANY);
  	empty_from.sin_port = htons(0);
  
  	/* XXX - much of this stuff is similar to that in nsupdate.c
  	 * getword_str() was used in nsupdate.c for reasons described there
--- 1648,1667 ----
  	int zonelist[MAXDNAME];
  	struct stat st;
  	u_char *serialp;
  	int datasize;
+ #ifdef INET6
+ 	msockaddr_in empty_from;
  
+ 	empty_from.sin.sin_family = AF_INET;
+ 	empty_from.sin.sin_addr.s_addr = htonl(INADDR_ANY);
+ 	empty_from.sin.sin_port = htons(0);
+ #else
+ 	struct sockaddr_in empty_from;
+ 
  	empty_from.sin_family = AF_INET;
  	empty_from.sin_addr.s_addr = htonl(INADDR_ANY);
  	empty_from.sin_port = htons(0);
+ #endif
  
  	/* XXX - much of this stuff is similar to that in nsupdate.c
  	 * getword_str() was used in nsupdate.c for reasons described there
***************
*** 1589,1595 ****
  	 * be garbage!
  	 */
  
! 	if (fgets(buf, sizeof(buf), fp)==NULL) {
  		ns_error(ns_log_update, "fgets() from %s failed: %s",
  			 zp->z_updatelog, strerror(errno));
  		fclose(fp);
--- 1689,1695 ----
  	 * be garbage!
  	 */
  
! 	if (fgets(buf, sizeof(buf), fp) == NULL) {
  		ns_error(ns_log_update, "fgets() from %s failed: %s",
  			 zp->z_updatelog, strerror(errno));
  		fclose(fp);
Index: bind8/src/bin/named/ns_xfr.c
diff -c bind8/src/bin/named/ns_xfr.c:1.1.1.1 bind8/src/bin/named/ns_xfr.c:1.3
*** bind8/src/bin/named/ns_xfr.c:1.1.1.1	Fri Sep 25 14:24:53 1998
--- bind8/src/bin/named/ns_xfr.c	Sat Nov 28 12:41:16 1998
***************
*** 1,5 ****
  #if !defined(lint) && !defined(SABER)
! static char rcsid[] = "$Id: ns_xfr.c,v 8.25 1998/03/25 18:47:34 halley Exp $";
  #endif /* not lint */
  
  /*
--- 1,5 ----
  #if !defined(lint) && !defined(SABER)
! static char rcsid[] = "$Id: ns_xfr.c,v 1.2 1998/09/25 08:16:52 k-sugyou Exp $";
  #endif /* not lint */
  
  /*
***************
*** 118,124 ****
--- 118,128 ----
  	zones[zone].z_numxfrs++;
  	qsp->flags |= STREAM_AXFR;
  
+ #ifdef INET6
+ 	si = find_server(qsp->s_from);
+ #else
  	si = find_server(qsp->s_from.sin_addr);
+ #endif
  	if (si != NULL && si->transfer_format != axfr_use_default)
  		qsp->xfr.transfer_format = si->transfer_format;
  	else	
Index: bind8/src/bin/named-xfer/Makefile
diff -c bind8/src/bin/named-xfer/Makefile:1.1.1.1 bind8/src/bin/named-xfer/Makefile:1.2
*** bind8/src/bin/named-xfer/Makefile:1.1.1.1	Fri Sep 25 14:24:53 1998
--- bind8/src/bin/named-xfer/Makefile	Fri Sep 25 17:16:55 1998
***************
*** 13,25 ****
  ## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  ## SOFTWARE.
  
! # $Id: Makefile,v 8.21 1998/04/14 00:39:03 halley Exp $
  
  DESTDIR=
  CC= cc
  SHELL= /bin/sh
  
! CDEBUG= -g
  
  #(net2 and its descendents)
  SYSTYPE = bsdos
--- 13,25 ----
  ## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  ## SOFTWARE.
  
! # $Id: Makefile,v 1.1.1.1 1998/09/25 05:24:53 k-sugyou Exp $
  
  DESTDIR=
  CC= cc
  SHELL= /bin/sh
  
! CDEBUG= -g -DINET6 
  
  #(net2 and its descendents)
  SYSTYPE = bsdos
***************
*** 30,40 ****
  A=a
  O=o
  LEX = lex -I
  SYSLIBS = -ll -lutil
  PIDDIR = /var/run
  DESTBIN = /usr/local/bin
  DESTSBIN = /usr/local/sbin
! DESTEXEC = /usr/local/libexec
  DESTMAN = /usr/share/man
  DESTHELP= /usr/share/misc
  AR= ar cruv
--- 30,41 ----
  A=a
  O=o
  LEX = lex -I
+ INET6_INCLUDE =
  SYSLIBS = -ll -lutil
  PIDDIR = /var/run
  DESTBIN = /usr/local/bin
  DESTSBIN = /usr/local/sbin
! DESTEXEC = /usr/libexec
  DESTMAN = /usr/share/man
  DESTHELP= /usr/share/misc
  AR= ar cruv
***************
*** 43,49 ****
  
  PS=ps
  LDFLAGS=
! CFLAGS=	${CDEBUG} -I${PORTINCL} -I${INCL}
  
  NAMED_OBJS= \
  	../named/db_glue.${O} ../named/ns_glue.${O} ../named/tmp_version.${O}
--- 44,50 ----
  
  PS=ps
  LDFLAGS=
! CFLAGS=	${CDEBUG} ${INET6_INCLUDE} -I${PORTINCL} -I${INCL}
  
  NAMED_OBJS= \
  	../named/db_glue.${O} ../named/ns_glue.${O} ../named/tmp_version.${O}
Index: bind8/src/bin/named-xfer/named-xfer.c
diff -c bind8/src/bin/named-xfer/named-xfer.c:1.1.1.1 bind8/src/bin/named-xfer/named-xfer.c:1.2.2.4
*** bind8/src/bin/named-xfer/named-xfer.c:1.1.1.1	Fri Sep 25 14:24:53 1998
--- bind8/src/bin/named-xfer/named-xfer.c	Fri Jun  4 07:53:38 1999
***************
*** 110,116 ****
  
  #if !defined(lint) && !defined(SABER)
  static char sccsid[] = "@(#)named-xfer.c	4.18 (Berkeley) 3/7/91";
! static char rcsid[] = "$Id: named-xfer.c,v 8.38 1998/03/27 00:19:28 halley Exp $";
  #endif /* not lint */
  
  #include "port_before.h"
--- 110,116 ----
  
  #if !defined(lint) && !defined(SABER)
  static char sccsid[] = "@(#)named-xfer.c	4.18 (Berkeley) 3/7/91";
! static char rcsid[] = "$Id: named-xfer.c,v 1.1.1.1 1998/09/25 05:24:53 k-sugyou Exp $";
  #endif /* not lint */
  
  #include "port_before.h"
***************
*** 250,257 ****
--- 250,264 ----
  int
  main(int argc, char *argv[]) {
  	struct zoneinfo *zp;
+ 	struct addrinfo hints, *res;
+ 	int error;
  	struct hostent *hp;
+ #ifdef INET6
+ 	struct sockaddr_storage axfr_src[10];	/*?*/
+ 	int naxfr_src = 0;
+ #else
  	struct in_addr axfr_src;
+ #endif
   	char *dbfile = NULL, *tracefile = NULL, *tm = NULL;
  	int dbfd, ddtd, result, c, fd, closed = 0;
  	u_int32_t serial_no = 0;
***************
*** 293,299 ****
  #else
  	openlog(ProgName, LOG_PID|LOG_CONS|n, LOG_DAEMON);
  #endif
! 	axfr_src.s_addr = 0;
  #ifdef STUBS
  	while ((c = getopt(argc, argv, "C:d:l:s:t:z:f:p:P:qx:S")) != EOF)
  #else
--- 300,306 ----
  #else
  	openlog(ProgName, LOG_PID|LOG_CONS|n, LOG_DAEMON);
  #endif
! 	memset(&axfr_src, 0, sizeof(axfr_src));
  #ifdef STUBS
  	while ((c = getopt(argc, argv, "C:d:l:s:t:z:f:p:P:qx:S")) != EOF)
  #else
***************
*** 360,368 ****
--- 367,392 ----
  			quiet++;
  			break;
  		case 'x':
+ #ifdef INET6
+ 			if (naxfr_src >= sizeof(axfr_src)/sizeof(axfr_src[0]))
+ 				panic("too many -x option: %s", optarg);
+ 			memset(&hints, 0, sizeof(hints));
+ 			hints.ai_socktype = SOCK_STREAM;
+ 			error = getaddrinfo(optarg, NULL, &hints, &res);
+ 			if (error || res->ai_next
+ 			 || sizeof(axfr_src) < res->ai_addrlen) {
+ 				panic("bad -x addr: %s", optarg);
+ 			}
+ 			memcpy(&axfr_src[naxfr_src++],
+ 				res->ai_addr, res->ai_addrlen);
+ 			naxfr_src++;
+ 			freeaddrinfo(res);
+ 			break;
+ #else
  			if (!inet_aton(optarg, &axfr_src))
  				panic("bad -x addr: %s", optarg);
  			break;
+ #endif
  		case '?':
  		default:
  			usage("unrecognized argument");
***************
*** 482,488 ****
--- 506,532 ----
  	zp->z_class = class;
  	zp->z_origin = domain;
  	zp->z_source = dbfile;
+ #ifdef INET6
+ 	memset(&zp->z_axfr_src, 0, sizeof(zp->z_axfr_src));
+ 	zp->z_axfr_src.sin.sin_family = AF_INET;
+ 	memset(&zp->z_axfr_src6, 0, sizeof(zp->z_axfr_src6));
+ 	zp->z_axfr_src.sin6.sin6_family = AF_INET6;
+     {
+ 	int i;
+ 	for (i = 0; i < naxfr_src; i++) {
+ 		switch (axfr_src[i].ss_family) {
+ 		case AF_INET:
+ 			memcpy(&zp->z_axfr_src, &axfr_src[i], sizeof(struct sockaddr_in));
+ 			break;
+ 		case AF_INET6:
+ 			memcpy(&zp->z_axfr_src6, &axfr_src[i], sizeof(struct sockaddr_in6));
+ 			break;
+ 		}
+ 	}
+     }
+ #else
  	zp->z_axfr_src = axfr_src;
+ #endif
  	zp->z_addrcnt = 0;
  	dprintf(1, "zone found (%d): \"%s\", source = %s\n",
  		zp->z_type,
***************
*** 491,496 ****
--- 535,581 ----
  
  	for (; optind != argc; optind++) {
  		tm = argv[optind];
+ #ifdef INET6
+ 		fprintf(stderr,"tm=%s\n", tm);
+ 		if (inet_aton(tm, &zp->z_addr[zp->z_addrcnt].sin.sin_addr)) {
+ 			zp->z_addr[zp->z_addrcnt].sin.sin_family = AF_INET;
+ 			fprintf(stderr, "v4addr\n");
+ 		} else if (inet_pton(AF_INET6, tm, &zp->z_addr[zp->z_addrcnt].sin6.sin6_addr)) {
+ 			zp->z_addr[zp->z_addrcnt].sin6.sin6_family = AF_INET6;
+ 			fprintf(stderr, "v6addr\n");
+ 		} else {
+ 			hp = gethostbyname(tm);
+ 			if (hp == NULL) {
+ 				hp = gethostbyname2(tm, AF_INET6);
+ 				if (hp == NULL) {
+ 				  fprintf(stderr,"foz\n");
+ 					syslog(LOG_NOTICE,
+ 				       		"uninterpretable server (%s) for %s\n",
+ 				       		tm, zp->z_origin);
+ 					continue;
+ 				} else {
+ 					fprintf(stderr, "v6host\n");
+ 					memcpy(&zp->z_addr[zp->z_addrcnt].sin6.sin6_addr,
+ 					       hp->h_addr,
+ 					       IN6ADDRSZ);
+ 					zp->z_addr[zp->z_addrcnt].sin6.sin6_family = AF_INET6;
+ 					dprintf(1, "Arg: \"%s\"\n", tm);
+ 				}
+ 			} else {
+ 			fprintf(stderr, "v4host\n");
+ 				memcpy(&zp->z_addr[zp->z_addrcnt].sin.sin_addr,
+ 				       hp->h_addr,
+ 				       INADDRSZ);
+ 				zp->z_addr[zp->z_addrcnt].sin.sin_family = AF_INET;
+ 				dprintf(1, "Arg: \"%s\"\n", tm);
+ 			}
+ 		}
+ 		if (++zp->z_addrcnt >= NSMAX) {
+ 			zp->z_addrcnt = NSMAX;
+ 			dprintf(1, "NSMAX reached\n");
+ 			break;
+ 		}
+ #else
  		if (!inet_aton(tm, &zp->z_addr[zp->z_addrcnt])) {
  			hp = gethostbyname(tm);
  			if (hp == NULL) {
***************
*** 509,514 ****
--- 594,600 ----
  			dprintf(1, "NSMAX reached\n");
  			break;
  		}
+ #endif
  	}
  	dprintf(1, "addrcnt = %d\n", zp->z_addrcnt);
  
***************
*** 597,603 ****
--- 683,694 ----
  	u_char *buf = NULL;
  	u_int bufsize = 0;
  	char name[MAXDNAME], name2[MAXDNAME];
+ #ifdef INET6
+ 	msockaddr_in sin;
+ 	char vname[INET6_ADDRSTRLEN];
+ #else
  	struct sockaddr_in sin;
+ #endif
  #ifdef POSIX_SIGNALS
  	struct sigaction sv, osv;
  #else
***************
*** 661,671 ****
  			}
  			bufsize = 2 * PACKETSZ;
  		}
! 		if ((s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0) {
! 			syslog(LOG_INFO, "socket: %m");
! 			error++;
! 			break;
! 		}	
  		if (zp->z_axfr_src.s_addr != 0) {
  			memset(&sin, 0, sizeof sin);
  			sin.sin_family = AF_INET;
--- 752,847 ----
  			}
  			bufsize = 2 * PACKETSZ;
  		}
! #ifdef INET6
! 		if (zp->z_addr[cnt].sin6.sin6_family == AF_INET6) {
! 		        fprintf(stderr,"v6 socket\n");
! 			if ((s = socket(AF_INET6, SOCK_STREAM,
! 					PF_UNSPEC)) < 0) {
! 				syslog(LOG_INFO, "socket: %m");
! 				error++;
! 				break;
! 			}
! 		} else {
! 		        fprintf(stderr,"v4 socket\n");
! 			if ((s = socket(AF_INET, SOCK_STREAM,
! 					PF_UNSPEC)) < 0) {
! 				syslog(LOG_INFO, "socket: %m");
! 				error++;
! 				break;
! 			}
! 		}
! 		if ((zp->z_axfr_src.sin.sin_family == AF_INET &&
! 		     zp->z_axfr_src.sin.sin_addr.s_addr != 0) ||
! 		    (zp->z_axfr_src.sin6.sin6_family == AF_INET6 &&
! 		     !IN6_IS_ADDR_UNSPECIFIED((&zp->z_axfr_src.sin6.sin6_addr)))){
! 			if (zp->z_axfr_src.sin6.sin6_family == AF_INET6) {
! 				memset(&sin.sin6, 0, sizeof(struct sockaddr_in6));
! 				sin.sin6.sin6_family = AF_INET6;
! 				sin.sin6.sin6_port = 0;		/* "ANY" */
! 				sin.sin6.sin6_addr = zp->z_axfr_src.sin6.sin6_addr;
! 				inet_ntop(AF_INET6, &sin.sin6.sin6_addr,
! 					  vname, sizeof(vname));
! 				dprintf(2, "binding to address [%s]\n",
! 					vname);
! 				if (bind(s, (struct sockaddr *)&sin.sin6,
! 					 sizeof(struct sockaddr_in6)) < 0)
! 					syslog(LOG_INFO,
! 					       "warning: bind(%s) failed",
! 					       vname);
! 			} else {
! 				memset(&sin.sin, 0, sizeof(struct sockaddr_in));
! 				sin.sin.sin_family = AF_INET;
! 				sin.sin.sin_port = 0;		/* "ANY" */
! 				sin.sin.sin_addr = zp->z_axfr_src.sin.sin_addr;
! 				dprintf(2, "binding to address [%s]\n",
! 					inet_ntoa(sin.sin.sin_addr));
! 				if (bind(s, (struct sockaddr *)&sin.sin,
! 					 sizeof(struct sockaddr_in)) < 0)
! 					syslog(LOG_INFO, "warning: bind(%s) failed",
! 					       inet_ntoa(zp->z_axfr_src.sin.sin_addr));
! 			}
! 
! 		}
! 		if (zp->z_addr[cnt].sin6.sin6_family == AF_INET6) {
! 			memset(&sin.sin6, 0, sizeof(struct sockaddr_in6));
! 			sin.sin6.sin6_family = AF_INET6;
! 			sin.sin6.sin6_port = port;
! 			sin.sin6.sin6_addr = zp->z_addr[cnt].sin6.sin6_addr;
! 			inet_ntop(AF_INET6, &sin.sin6.sin6_addr,
! 				  vname, sizeof(vname));
! 			dprintf(2, "connecting to server #%d [%s].%d\n",
! 				cnt+1, vname, ntohs(sin.sin6.sin6_port));
! 			if (connect(s, (struct sockaddr *)&sin.sin6,
! 				    sizeof(struct sockaddr_in6)) < 0) {
! 				if (!quiet)
! 					syslog(LOG_INFO,
! 					       "connect(%s) for zone %s failed: %m",
! 					       vname, zp->z_origin);
! 				error++;
! 				(void) my_close(s);
! 				continue;
! 			}	
! 		} else {
! 			memset(&sin.sin, 0, sizeof(struct sockaddr_in));
! 			sin.sin.sin_family = AF_INET;
! 			sin.sin.sin_port = port;
! 			sin.sin.sin_addr = zp->z_addr[cnt].sin.sin_addr;
! 			dprintf(2, "connecting to server #%d [%s].%d\n", cnt+1,
! 				inet_ntoa(sin.sin.sin_addr),
! 				ntohs(sin.sin.sin_port));
! 			if (connect(s, (struct sockaddr *)&sin.sin,
! 				    sizeof(struct sockaddr_in)) < 0) {
! 				if (!quiet)
! 					syslog(LOG_INFO,
! 					       "connect(%s) for zone %s failed: %m",
! 					       inet_ntoa(sin.sin.sin_addr),
! 					       zp->z_origin);
! 				error++;
! 				(void) my_close(s);
! 				continue;
! 			}	
! 		}
! #else
  		if (zp->z_axfr_src.s_addr != 0) {
  			memset(&sin, 0, sizeof sin);
  			sin.sin_family = AF_INET;
***************
*** 692,697 ****
--- 868,874 ----
  			(void) my_close(s);
  			continue;
  		}	
+ #endif
  		n = res_mkquery(QUERY, zp->z_origin, curclass,
  				T_SOA, NULL, 0, NULL, buf, bufsize);
  		if (n < 0) {
***************
*** 730,740 ****
--- 907,926 ----
  		}
  		if (len > bufsize) {
  			if ((buf = (u_char *)realloc(buf, len)) == NULL) {
+ #ifdef INET6
+ 				getnameinfo((struct sockaddr *)&sin, sin.sin6.sin6_len, 
+ 					vname, sizeof(vname), 0, NULL,
+ 					NI_NUMERICHOST);
+ 				syslog(LOG_INFO,
+ 		       "malloc(%u) failed for SOA from server [%s], zone %s\n",
+ 					       len, vname, zp->z_origin);
+ #else
  				syslog(LOG_INFO,
  		       "malloc(%u) failed for SOA from server [%s], zone %s\n",
  				       len,
  				       inet_ntoa(sin.sin_addr),
  				       zp->z_origin);
+ #endif
  				(void) my_close(s);
  				continue;
  			}
***************
*** 766,771 ****
--- 952,980 ----
  		if (hp->rcode != NOERROR || !hp->aa || qdcount != 1 ||
  		    (ancount < 1 && aucount < 1)) {
  #ifndef ultrix  /*XXX*/
+ #ifdef INET6
+ 			if (sin.sin6.sin6_family == AF_INET6) {
+ 				inet_ntop(AF_INET6, &sin.sin6.sin6_addr,
+ 					  vname, sizeof(vname));
+ 				syslog(LOG_NOTICE,
+        "[%s] %s for %s, SOA query got rcode %d, aa %d, ancount %d, aucount %d",
+ 			       vname,
+ 			       (hp->aa
+ 				? (qdcount==1 ?"no SOA found" :"bad response")
+ 				: "not authoritative"),
+ 			       zp->z_origin[0] != '\0' ? zp->z_origin : ".",
+ 			       hp->rcode, hp->aa, ancount, aucount);
+ 			} else {
+ 				syslog(LOG_NOTICE,
+        "[%s] %s for %s, SOA query got rcode %d, aa %d, ancount %d, aucount %d",
+ 			       inet_ntoa(sin.sin.sin_addr),
+ 			       (hp->aa
+ 				? (qdcount==1 ?"no SOA found" :"bad response")
+ 				: "not authoritative"),
+ 			       zp->z_origin[0] != '\0' ? zp->z_origin : ".",
+ 			       hp->rcode, hp->aa, ancount, aucount);
+ 			}
+ #else
  			syslog(LOG_NOTICE,
         "[%s] %s for %s, SOA query got rcode %d, aa %d, ancount %d, aucount %d",
  			       inet_ntoa(sin.sin_addr),
***************
*** 775,780 ****
--- 984,990 ----
  			       zp->z_origin[0] != '\0' ? zp->z_origin : ".",
  			       hp->rcode, hp->aa, ancount, aucount);
  #endif
+ #endif
  			error++;
  			(void) my_close(s);
  			continue;
***************
*** 783,792 ****
--- 993,1018 ----
  		if ((int)len < HFIXEDSZ + QFIXEDSZ) {
  			badsoa_msg = "too short";
   badsoa:
+ #ifdef INET6
+ 			if (sin.sin6.sin6_family == AF_INET6) {
+ 				inet_ntop(AF_INET6,
+ 					  &sin.sin6.sin6_addr,
+ 					  vname, sizeof(vname));
+ 				syslog(LOG_INFO,
+ 				       "malformed SOA from [%s], zone %s: %s",
+ 				       vname, zp->z_origin, badsoa_msg);
+ 			} else {
+ 				syslog(LOG_INFO,
+ 				       "malformed SOA from [%s], zone %s: %s",
+ 				       inet_ntoa(sin.sin.sin_addr),
+ 				       zp->z_origin, badsoa_msg);
+ 			}
+ #else
  			syslog(LOG_INFO,
  			       "malformed SOA from [%s], zone %s: %s",
  			       inet_ntoa(sin.sin_addr), zp->z_origin,
  			       badsoa_msg);
+ #endif
  			error++;
  			(void) my_close(s);
  			continue;
***************
*** 811,820 ****
--- 1037,1063 ----
  		NS_GET16(class, tmp);
  		if (class != curclass || type != T_SOA ||
  		    strcasecmp(zp->z_origin, name2) != 0) {
+ #ifdef INET6
+ 			if (sin.sin6.sin6_family == AF_INET6) {
+ 				inet_ntop(AF_INET6, &sin.sin6.sin6_addr,
+ 					  vname, sizeof(vname));
+ 				syslog(LOG_INFO,
+ 			"wrong query in resp from [%s], zone %s: [%s %s %s]\n",
+ 				       vname, zp->z_origin,
+ 				       name2, p_class(class), p_type(type));
+ 			} else {
+ 				syslog(LOG_INFO,
+ 			"wrong query in resp from [%s], zone %s: [%s %s %s]\n",
+ 				       inet_ntoa(sin.sin.sin_addr),
+ 				       zp->z_origin,
+ 				       name2, p_class(class), p_type(type));
+ 			}
+ #else
  			syslog(LOG_INFO,
  			"wrong query in resp from [%s], zone %s: [%s %s %s]\n",
  			       inet_ntoa(sin.sin_addr), zp->z_origin,
  			       name2, p_class(class), p_type(type));
+ #endif
  			error++;
  			(void) my_close(s);
  			continue;
***************
*** 858,867 ****
--- 1101,1126 ----
  		} while (1);
  
  		if (strcasecmp(zp->z_origin, name2) != 0) {
+ #ifdef INET6
+ 			if (sin.sin6.sin6_family == AF_INET6) {
+ 				inet_ntop(AF_INET6, &sin.sin6.sin6_addr,
+ 					  vname, sizeof(vname));
+ 				syslog(LOG_INFO,
+ 		       "wrong answer in resp from [%s], zone %s: [%s %s %s]\n",
+ 				       vname, zp->z_origin,
+ 				       name2, p_class(class), p_type(type));
+ 			} else {
+ 				syslog(LOG_INFO,
+ 		       "wrong answer in resp from [%s], zone %s: [%s %s %s]\n",
+ 				       inet_ntoa(sin.sin.sin_addr), zp->z_origin,
+ 				       name2, p_class(class), p_type(type));
+ 			}
+ #else
  			syslog(LOG_INFO,
  		       "wrong answer in resp from [%s], zone %s: [%s %s %s]\n",
  			       inet_ntoa(sin.sin_addr), zp->z_origin,
  			       name2, p_class(class), p_type(type));
+ #endif
  			error++;
  			(void) my_close(s);
  			continue;
***************
*** 896,904 ****
--- 1155,1176 ----
  			}
  			fprintf(dbfp, "; zone '%s'   last serial %u\n",
  				domain, serial_no);
+ #ifdef INET6
+ 			if (sin.sin6.sin6_family == AF_INET6) {
+ 				inet_ntop(AF_INET6, &sin.sin6.sin6_addr,
+ 					  vname, sizeof(vname));
+ 				fprintf(dbfp, "; from %s   at %s",
+ 					vname, ctimel(tt.tv_sec));
+ 			} else {
+ 				fprintf(dbfp, "; from %s   at %s",
+ 					inet_ntoa(sin.sin.sin_addr),
+ 					ctimel(tt.tv_sec));
+ 			}
+ #else
  			fprintf(dbfp, "; from %s   at %s",
  				inet_ntoa(sin.sin_addr),
  				ctimel(tt.tv_sec));
+ #endif
  			for (;;) {
  				if ((soa_cnt == 0) || (zp->z_type == Z_STUB)) {
  #ifdef STUBS
***************
*** 965,975 ****
--- 1237,1263 ----
  				if (len > bufsize) {
  					buf = (u_char *)realloc(buf, len);
  					if (buf == NULL) {
+ #ifdef INET6
+ 					if (sin.sin6.sin6_family == AF_INET6) {
+ 						inet_ntop(AF_INET6,
+ 							  &sin.sin6.sin6_addr,
+ 							  vname,
+ 							  sizeof(vname));
  						syslog(LOG_INFO,
  		    "malloc(%u) failed for packet from server [%s], zone %s\n",
+ 		    len, vname, zp->z_origin);
+ 					 } else {
+ 						syslog(LOG_INFO,
+ 		    "malloc(%u) failed for packet from server [%s], zone %s\n",
+ 		    len, inet_ntoa(sin.sin.sin_addr), zp->z_origin);
+ 					 }
+ #else
+ 						syslog(LOG_INFO,
+ 		    "malloc(%u) failed for packet from server [%s], zone %s\n",
  						       len,
  						       inet_ntoa(sin.sin_addr),
  						       zp->z_origin);
+ #endif
  						error++;
  						break;
  					}
***************
*** 1009,1019 ****
--- 1297,1325 ----
  								  sin_addr),
  							ntohs(my_addr.sin_port)
  							);
+ #ifdef INET6
+ 					if (sin.sin6.sin6_family == AF_INET6) {
+ 						inet_ntop(AF_INET6,
+ 							  &sin.sin6.sin6_addr,
+ 							  vname,
+ 							  sizeof(vname));
+ 						syslog(LOG_INFO,
+ 				  "[%s] record too short from [%s], zone %s\n",
+ 						       my_addr_text, vname,
+ 						       zp->z_origin);
+ 					} else {
+ 						syslog(LOG_INFO,
+ 				  "[%s] record too short from [%s], zone %s\n",
+ 				  my_addr_text, inet_ntoa(sin.sin.sin_addr),
+ 						       zp->z_origin);
+ 					}
+ #else
  					syslog(LOG_INFO,
  				  "[%s] record too short from [%s], zone %s\n",
  					       my_addr_text,
  					       inet_ntoa(sin.sin_addr),
  					       zp->z_origin);
+ #endif
  					break;
  				}
  				cp = buf + HFIXEDSZ;
***************
*** 1142,1152 ****
--- 1448,1476 ----
  		return (XFER_UPTODATE);
  	    } else {
  		(void) my_close(s);
+ #ifdef INET6
+ 		if (!quiet) {
+ 			if (sin.sin6.sin6_family == AF_INET6) {
+ 				inet_ntop(AF_INET6, &sin.sin6.sin6_addr,
+ 					  vname, sizeof(vname));
+ 				syslog(LOG_NOTICE,
+ 		      "serial from [%s], zone %s: %u lower than current: %u\n",
+ 				vname, zp->z_origin,
+ 				zp_start.z_serial, serial_no);
+ 			} else {
+ 				syslog(LOG_NOTICE,
+ 		      "serial from [%s], zone %s: %u lower than current: %u\n",
+ 				inet_ntoa(sin.sin.sin_addr), zp->z_origin,
+ 				zp_start.z_serial, serial_no);
+ 			}
+ 		}
+ #else
  		if (!quiet)
  		    syslog(LOG_NOTICE,
  		      "serial from [%s], zone %s: %u lower than current: %u\n",
  			   inet_ntoa(sin.sin_addr), zp->z_origin,
  			   zp_start.z_serial, serial_no);
+ #endif
  		return (XFER_FAIL);
  	    }
  	}
***************
*** 1912,1918 ****
  	case T_SOA:
  		(void) fprintf(dbfp, "%s.", cp);
  		cp += strlen((char *) cp) + 1;
! 		(void) fprintf(dbfp, " %s. (\n", cp);
  		cp += strlen((char *) cp) + 1;
  		NS_GET32(tmpnum, cp);
  		(void) fprintf(dbfp, "%s\t\t%u", ignore, tmpnum);
--- 2236,2242 ----
  	case T_SOA:
  		(void) fprintf(dbfp, "%s.", cp);
  		cp += strlen((char *) cp) + 1;
! 		(void) fprintf(dbfp, " %s. ( \n", cp);
  		cp += strlen((char *) cp) + 1;
  		NS_GET32(tmpnum, cp);
  		(void) fprintf(dbfp, "%s\t\t%u", ignore, tmpnum);
***************
*** 2153,2173 ****
  	char *dirname, *filename;
  
  	/* determine the length of filename allowed */
! 	if((dirname = strrchr(optarg, '/')) == NULL){
  		filename = optarg;
  	} else {
  		*dirname++ = '\0';
  		filename = dirname;
  	}
  	namelen = pathconf(dirname == NULL? "." : optarg, _PC_NAME_MAX);
! 	if(namelen <= 0)
  		namelen = 255;  /* length could not be determined */
! 	if(dirname != NULL)
  		*--dirname = '/';
  
  	/* copy a shorter name if it will be longer than allowed */
  	extra = (strlen(filename)+strlen(".XXXXXX")) - namelen;
! 	if(extra > 0){
  		len = strlen(optarg) - extra;
  		(void) strncpy(ddtfile, optarg, len);
  		ddtfile[len] = '\0';
--- 2477,2497 ----
  	char *dirname, *filename;
  
  	/* determine the length of filename allowed */
! 	if ((dirname = strrchr(optarg, '/')) == NULL){
  		filename = optarg;
  	} else {
  		*dirname++ = '\0';
  		filename = dirname;
  	}
  	namelen = pathconf(dirname == NULL? "." : optarg, _PC_NAME_MAX);
! 	if (namelen <= 0)
  		namelen = 255;  /* length could not be determined */
! 	if (dirname != NULL)
  		*--dirname = '/';
  
  	/* copy a shorter name if it will be longer than allowed */
  	extra = (strlen(filename)+strlen(".XXXXXX")) - namelen;
! 	if (extra > 0){
  		len = strlen(optarg) - extra;
  		(void) strncpy(ddtfile, optarg, len);
  		ddtfile[len] = '\0';
Index: bind8/src/bin/nslookup/Makefile
diff -c bind8/src/bin/nslookup/Makefile:1.1.1.1 bind8/src/bin/nslookup/Makefile:1.2
*** bind8/src/bin/nslookup/Makefile:1.1.1.1	Fri Sep 25 14:24:53 1998
--- bind8/src/bin/nslookup/Makefile	Fri Sep 25 17:16:58 1998
***************
*** 13,25 ****
  ## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  ## SOFTWARE.
  
! # $Id: Makefile,v 8.18 1997/12/03 22:55:16 halley Exp $
  
  DESTDIR=
  CC= cc
  SHELL= /bin/sh
  
! CDEBUG= -g
  
  #(net2 and its descendents)
  SYSTYPE = bsdos
--- 13,25 ----
  ## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  ## SOFTWARE.
  
! # $Id: Makefile,v 1.1.1.1 1998/09/25 05:24:53 k-sugyou Exp $
  
  DESTDIR=
  CC= cc
  SHELL= /bin/sh
  
! CDEBUG= -g -DINET6
  
  #(net2 and its descendents)
  SYSTYPE = bsdos
***************
*** 30,35 ****
--- 30,36 ----
  A=a
  O=o
  LEX = lex -I
+ INET6_INCLUDE =
  SYSLIBS = -ll -lutil
  PIDDIR = /var/run
  DESTBIN = /usr/local/bin
***************
*** 41,47 ****
  
  LDFLAGS=
  DEFS=	-D_PATH_HELPFILE=\"${DESTDIR}${DESTHELP}/nslookup.help\"
! CFLAGS=	${CDEBUG} -I${PORTINCL} -I${INCL} ${DEFS}
  
  PROG= nslookup
  CSRCS=	main.c getinfo.c debug.c send.c skip.c list.c subr.c
--- 42,48 ----
  
  LDFLAGS=
  DEFS=	-D_PATH_HELPFILE=\"${DESTDIR}${DESTHELP}/nslookup.help\"
! CFLAGS=	${CDEBUG} ${INET6_INCLUDE} -I${PORTINCL} -I${INCL} ${DEFS}
  
  PROG= nslookup
  CSRCS=	main.c getinfo.c debug.c send.c skip.c list.c subr.c
Index: bind8/src/bin/nslookup/commands.l
diff -c bind8/src/bin/nslookup/commands.l:1.1.1.1 bind8/src/bin/nslookup/commands.l:1.2
*** bind8/src/bin/nslookup/commands.l:1.1.1.1	Fri Sep 25 14:24:53 1998
--- bind8/src/bin/nslookup/commands.l	Fri Sep 25 17:16:59 1998
***************
*** 103,111 ****
  
  %}
  WS	[ \t]
! FLET	[A-Za-z0-9.*\\]
! LET	[A-Za-z0-9.*]
! NAME	[A-Za-z0-9.*=_/-]
  %%
  ^{WS}*server{WS}+{LET}{NAME}*{WS}*$	{
  					    /*
--- 103,111 ----
  
  %}
  WS	[ \t]
! FLET	[A-Za-z0-9.:*\\]
! LET	[A-Za-z0-9.:*]
! NAME	[A-Za-z0-9.:*=_/-]
  %%
  ^{WS}*server{WS}+{LET}{NAME}*{WS}*$	{
  					    /*
Index: bind8/src/bin/nslookup/getinfo.c
diff -c bind8/src/bin/nslookup/getinfo.c:1.1.1.1 bind8/src/bin/nslookup/getinfo.c:1.4
*** bind8/src/bin/nslookup/getinfo.c:1.1.1.1	Fri Sep 25 14:24:53 1998
--- bind8/src/bin/nslookup/getinfo.c	Thu Dec  3 04:55:18 1998
***************
*** 53,59 ****
  
  #ifndef lint
  static char sccsid[] = "@(#)getinfo.c	5.26 (Berkeley) 3/21/91";
! static char rcsid[] = "$Id: getinfo.c,v 8.11 1998/03/19 19:30:55 halley Exp $";
  #endif /* not lint */
  
  /*
--- 53,59 ----
  
  #ifndef lint
  static char sccsid[] = "@(#)getinfo.c	5.26 (Berkeley) 3/21/91";
! static char rcsid[] = "$Id: getinfo.c,v 1.3 1998/09/25 11:48:33 k-sugyou Exp $";
  #endif /* not lint */
  
  /*
***************
*** 137,145 ****
--- 137,150 ----
   ******************************************************************************
   */
  
+ 
  static int
  GetAnswer(nsAddrPtr, queryType, msg, msglen, iquery, hostPtr, isServer)
+ #ifdef INET6
+     struct sockaddr	*nsAddrPtr;
+ #else
      struct in_addr	*nsAddrPtr;
+ #endif
      char		*msg;
      int			queryType;
      int			msglen;
***************
*** 168,174 ****
      Boolean		haveAnswer;
      Boolean		printedAnswers = FALSE;
  
! 
      /*
       *  If the hostPtr was used before, free up the calloc'd areas.
       */
--- 173,181 ----
      Boolean		haveAnswer;
      Boolean		printedAnswers = FALSE;
  
! #ifdef INET6
!     char vname[INET6_ADDRSTRLEN];
! #endif
      /*
       *  If the hostPtr was used before, free up the calloc'd areas.
       */
***************
*** 236,242 ****
  	    printf("Non-authoritative answer:\n");
  	}
  
! 	if (queryType != T_A && !(iquery && queryType == T_PTR)) {
  	    while (--ancount >= 0 && cp < eom) {
  		if ((cp = (u_char *)Print_rr(cp,
  		    (u_char *)&answer, eom, stdout)) == NULL) {
--- 243,255 ----
  	    printf("Non-authoritative answer:\n");
  	}
  
! #ifdef INET6
! 	if (queryType != T_A && queryType != T_AAAA &&
! 	    !(iquery && queryType == T_PTR))
! #else
! 	if (queryType != T_A && !(iquery && queryType == T_PTR))
! #endif
! 	{
  	    while (--ancount >= 0 && cp < eom) {
  		if ((cp = (u_char *)Print_rr(cp,
  		    (u_char *)&answer, eom, stdout)) == NULL) {
***************
*** 288,299 ****
  		    memcpy(hostPtr->name, bp, len);
  		    haveAnswer = TRUE;
  		    break;
! 		} else if (type != T_A) {
  		    cp += dlen;
  		    continue;
  		}
  		if (dlen != INADDRSZ)
  			return (ERROR);
  		if (haveAnswer) {
  		    /*
  		     * If we've already got 1 address, we aren't interested
--- 301,326 ----
  		    memcpy(hostPtr->name, bp, len);
  		    haveAnswer = TRUE;
  		    break;
! 		}
! #ifdef INET6
! 		else if (type != T_A && type != T_AAAA) {
! 		    cp += dlen;
! 		    continue;
! 		}
! #else
! 		else if (type != T_A) {
  		    cp += dlen;
  		    continue;
  		}
+ #endif
+ 
+ #ifdef INET6
+ 		if (dlen != INADDRSZ && dlen != IN6ADDRSZ)
+ 			return (ERROR);
+ #else
  		if (dlen != INADDRSZ)
  			return (ERROR);
+ #endif
  		if (haveAnswer) {
  		    /*
  		     * If we've already got 1 address, we aren't interested
***************
*** 327,337 ****
--- 354,366 ----
  		    }
  		    break;
  		}
+ 
  		if (numAddresses >= MAXADDRS) {
  			printf("MAXADDRS exceeded: skipping address\n");
  			cp += dlen;
  			continue;
  		}
+ 
  		memcpy(*addrPtr++ = (char *)bp, cp, dlen);
  		bp += dlen;
  		cp += dlen;
***************
*** 340,348 ****
  	    }
  	}
      }
- 
-     if ((queryType == T_A || queryType == T_PTR) && haveAnswer) {
  
  	/*
  	 *  Go through the alias and address lists and return them
  	 *  in the hostPtr variable.
--- 369,381 ----
  	    }
  	}
      }
  
+ #ifdef INET6
+     if ((queryType == T_A || queryType == T_AAAA || queryType == T_PTR) && haveAnswer)
+ #else
+     if ((queryType == T_A || queryType == T_PTR) && haveAnswer)
+ #endif
+     {
  	/*
  	 *  Go through the alias and address lists and return them
  	 *  in the hostPtr variable.
***************
*** 362,369 ****
--- 395,419 ----
  	    hostPtr->addrList =
  		(char **)Calloc(1+numAddresses, sizeof(char *));
  	    for (i = 0; i < numAddresses; i++) {
+ #ifdef INET6
+ 		hostPtr->addrList[i] = Calloc(1, sizeof(struct sockaddr_storage));
+ 		if (queryType==T_AAAA) {
+ 		    struct sockaddr_in6 * inaddr6p; 
+ 		    inaddr6p = (struct sockaddr_in6 *)hostPtr->addrList[i];
+ 		    memcpy(&inaddr6p->sin6_addr, addr_list[i], hostPtr->addrLen);
+ 		    inaddr6p->sin6_family = AF_INET6;
+ 		} else {
+ 		    struct sockaddr_in * inaddr4p; 
+ 			
+ 		    inaddr4p = (struct sockaddr_in *)hostPtr->addrList[i];
+ 		    memcpy(&inaddr4p->sin_addr,addr_list[i],hostPtr->addrLen);
+ 		    inaddr4p->sin_family = AF_INET;
+ 		}
+ 		    
+ #else
  		hostPtr->addrList[i] = Calloc(1, hostPtr->addrLen);
  		memcpy(hostPtr->addrList[i], addr_list[i], hostPtr->addrLen);
+ #endif
  	    }
  	    hostPtr->addrList[i] = NULL;
  	}
***************
*** 394,399 ****
--- 444,450 ----
      cp = (u_char *)res_skip((char *) &answer, 2, eom);
  
      numServers = 0;
+ 
      if (queryType != T_A) {
  	/*
  	 * If we don't need to save the record, just print it.
***************
*** 530,535 ****
--- 581,587 ----
      /*
       * If we are returning name server info, transfer it to the hostPtr.
       */
+ 
      if (numServers > 0) {
  	hostPtr->servers = (ServerInfo **)
  				Calloc(numServers+1, sizeof(ServerInfo *));
***************
*** 589,595 ****
--- 641,651 ----
  
  int
  GetHostInfoByName(nsAddrPtr, queryClass, queryType, name, hostPtr, isServer)
+ #ifdef INET6
+     struct sockaddr	*nsAddrPtr;
+ #else
      struct in_addr	*nsAddrPtr;
+ #endif
      int			queryClass;
      int			queryType;
      char		*name;
***************
*** 601,610 ****
--- 657,704 ----
      register char	**domain;
      const char		*cp;
      Boolean		got_nodata = FALSE;
+ #ifdef INET6
+     struct sockaddr_in  inaddr4;
+     struct sockaddr_in6 inaddr6;
+ #else
      struct in_addr	ina;
+ #endif
      Boolean		tried_as_is = FALSE;
  
      /* Catch explicit addresses */
+ 
+ #ifdef INET6
+     if ((queryType == T_A) && IsAddr(name, &inaddr4)) {
+ 
+ 	hostPtr->name = Calloc(strlen(name)+3, 1);
+ 	(void)sprintf(hostPtr->name,"[%s]",name);
+ 	hostPtr->aliases = NULL;
+ 	hostPtr->servers = NULL;
+ 	hostPtr->addrType = AF_INET;
+ 	hostPtr->addrLen = sizeof(struct sockaddr_in);
+ 	hostPtr->addrList = (char **)Calloc(2, sizeof(char *));
+ 	hostPtr->addrList[0] = Calloc(sizeof(struct sockaddr_storage),
+ 				      sizeof(char));
+ 	memcpy(hostPtr->addrList[0], &inaddr4, sizeof(struct sockaddr_in));
+ 	hostPtr->addrList[1] = NULL;
+ 	return(SUCCESS);
+     } 
+     if ((queryType == T_AAAA) && IsAddr6(name, &inaddr6)) {
+ 
+ 	hostPtr->name = Calloc(strlen(name)+3, 1);
+ 	(void)sprintf(hostPtr->name,"[%s]",name);
+ 	hostPtr->aliases = NULL;
+ 	hostPtr->servers = NULL;
+ 	hostPtr->addrType = AF_INET6;
+ 	hostPtr->addrLen = sizeof(struct sockaddr_in6);
+ 	hostPtr->addrList = (char **)Calloc(2, sizeof(char *));
+ 	hostPtr->addrList[0] = Calloc(sizeof(struct sockaddr_storage),
+ 				      sizeof(char));
+ 	memcpy(hostPtr->addrList[0], &inaddr6, sizeof(struct sockaddr_in6));
+ 	hostPtr->addrList[1] = NULL;
+ 	return(SUCCESS);
+     }
+ #else
      if ((queryType == T_A) && IsAddr(name, &ina)) {
  	hostPtr->name = Calloc(strlen(name)+3, 1);
  	(void)sprintf(hostPtr->name,"[%s]",name);
***************
*** 618,623 ****
--- 712,718 ----
  	hostPtr->addrList[1] = NULL;
  	return(SUCCESS);
      }
+ #endif
  
      result = NXDOMAIN;
      for (cp = name, n = 0; *cp; cp++)
***************
*** 678,688 ****
--- 773,785 ----
       * note that we do this regardless of how many dots were in the
       * name or whether it ends with a dot.
       */
+ 
      if (!tried_as_is &&
  	(result = GetHostDomain(nsAddrPtr, queryClass, queryType,
  				name, (char *)NULL, hostPtr, isServer)
  	 ) == SUCCESS)
  	    return (result);
+ 
      if (got_nodata)
  	result = NO_INFO;
      return (result);
***************
*** 693,699 ****
--- 790,800 ----
   * removing a trailing dot from name if domain is NULL.
   */
  GetHostDomain(nsAddrPtr, queryClass, queryType, name, domain, hostPtr, isServer)
+ #ifdef INET6
+     struct sockaddr	*nsAddrPtr;
+ #else
      struct in_addr	*nsAddrPtr;
+ #endif
      int			queryClass;
      int			queryType;
      char		*name, *domain;
***************
*** 763,775 ****
--- 864,916 ----
  
  int
  GetHostInfoByAddr(nsAddrPtr, address, hostPtr)
+ #ifdef INET6
+     struct sockaddr	*nsAddrPtr;
+     struct sockaddr	*address;
+ #else
      struct in_addr	*nsAddrPtr;
      struct in_addr	*address;
+ #endif
      HostInfo		*hostPtr;
  {
      int		n;
      querybuf	buf;
      char	qbuf[MAXDNAME];
+ #ifdef INET6
+     char vname[INET6_ADDRSTRLEN];
+ 
+     if (address->sa_family == AF_INET6) {
+ 	struct in6_addr *in6;
+ 	in6 = &((struct sockaddr_in6 *)address)->sin6_addr;
+ 	(void)sprintf(qbuf, "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.int.",
+ 		in6->s6_addr8[15] & 0x0f, in6->s6_addr8[15] >> 4 & 0x0f,
+ 		in6->s6_addr8[14] & 0x0f, in6->s6_addr8[14] >> 4 & 0x0f,
+ 		in6->s6_addr8[13] & 0x0f, in6->s6_addr8[13] >> 4 & 0x0f,
+ 		in6->s6_addr8[12] & 0x0f, in6->s6_addr8[12] >> 4 & 0x0f,
+ 		in6->s6_addr8[11] & 0x0f, in6->s6_addr8[11] >> 4 & 0x0f,
+ 		in6->s6_addr8[10] & 0x0f, in6->s6_addr8[10] >> 4 & 0x0f,
+ 		in6->s6_addr8[9] & 0x0f, in6->s6_addr8[9] >> 4 & 0x0f,
+ 		in6->s6_addr8[8] & 0x0f, in6->s6_addr8[8] >> 4 & 0x0f,
+ 		in6->s6_addr8[7] & 0x0f, in6->s6_addr8[7] >> 4 & 0x0f,
+ 		in6->s6_addr8[6] & 0x0f, in6->s6_addr8[6] >> 4 & 0x0f,
+ 		in6->s6_addr8[5] & 0x0f, in6->s6_addr8[5] >> 4 & 0x0f,
+ 		in6->s6_addr8[4] & 0x0f, in6->s6_addr8[4] >> 4 & 0x0f,
+ 		in6->s6_addr8[3] & 0x0f, in6->s6_addr8[3] >> 4 & 0x0f,
+ 		in6->s6_addr8[2] & 0x0f, in6->s6_addr8[2] >> 4 & 0x0f,
+ 		in6->s6_addr8[1] & 0x0f, in6->s6_addr8[1] >> 4 & 0x0f,
+ 		in6->s6_addr8[0] & 0x0f, in6->s6_addr8[0] >> 4 & 0x0f
+ 	    );
+     } else {
+ 	char *p;
+ 	p = (char *)&((struct sockaddr_in *)address)->sin_addr.s_addr;
+ 	(void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa.",
+ 		      ((unsigned)p[3] & 0xff),
+ 		      ((unsigned)p[2] & 0xff),
+ 		      ((unsigned)p[1] & 0xff),
+ 		      ((unsigned)p[0] & 0xff));
+     }
+ 
+ #else
      char	*p = (char *) &address->s_addr;
  
      (void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
***************
*** 777,782 ****
--- 918,925 ----
  	    ((unsigned)p[2] & 0xff),
  	    ((unsigned)p[1] & 0xff),
  	    ((unsigned)p[0] & 0xff));
+ #endif
+ 
      n = res_mkquery(QUERY, qbuf, C_IN, T_PTR, NULL, 0, NULL,
  		    buf.qb2, sizeof buf);
      if (n < 0) {
***************
*** 785,797 ****
--- 928,961 ----
  	}
  	return (ERROR);
      }
+ 
      n = GetAnswer(nsAddrPtr, T_PTR, (char *) &buf, n, 1, hostPtr, 1);
      if (n == SUCCESS) {
+ #ifdef INET6
+ 	if (nsAddrPtr->sa_family == AF_INET6) {
+ 	    hostPtr->addrType = AF_INET6;
+ 	    hostPtr->addrLen = sizeof(struct sockaddr_in6);
+ 	    hostPtr->addrList = (char **)Calloc(2, sizeof(char *));
+ 	    hostPtr->addrList[0] = Calloc(sizeof(struct sockaddr_storage),
+ 					  sizeof(char));
+ 	    memcpy(hostPtr->addrList[0], (char *)address,
+ 		   sizeof(struct sockaddr_in6));
+ 	} else {
+ 	    hostPtr->addrType = AF_INET;
+ 	    hostPtr->addrLen = sizeof(struct sockaddr_in);
+ 	    hostPtr->addrList = (char **)Calloc(2, sizeof(char *));
+ 	    hostPtr->addrList[0] = Calloc(sizeof(struct sockaddr_storage),
+ 					  sizeof(char));
+ 	    memcpy(hostPtr->addrList[0], (char *)address,
+ 		   sizeof(struct sockaddr_in));
+ 	}
+ #else
  	hostPtr->addrType = AF_INET;
  	hostPtr->addrLen = 4;
  	hostPtr->addrList = (char **)Calloc(2, sizeof(char *));
  	hostPtr->addrList[0] = Calloc(INT32SZ, sizeof(char));
  	memcpy(hostPtr->addrList[0], p, INADDRSZ);
+ #endif
  	hostPtr->addrList[1] = NULL;
      }
      return n;
Index: bind8/src/bin/nslookup/list.c
diff -c bind8/src/bin/nslookup/list.c:1.1.1.1 bind8/src/bin/nslookup/list.c:1.2
*** bind8/src/bin/nslookup/list.c:1.1.1.1	Fri Sep 25 14:24:53 1998
--- bind8/src/bin/nslookup/list.c	Fri Sep 25 17:17:01 1998
***************
*** 53,59 ****
  
  #ifndef lint
  static char sccsid[] = "@(#)list.c	5.23 (Berkeley) 3/21/91";
! static char rcsid[] = "$Id: list.c,v 8.13 1997/11/18 00:32:33 halley Exp $";
  #endif /* not lint */
  
  /*
--- 53,59 ----
  
  #ifndef lint
  static char sccsid[] = "@(#)list.c	5.23 (Berkeley) 3/21/91";
! static char rcsid[] = "$Id: list.c,v 1.1.1.1 1998/09/25 05:24:53 k-sugyou Exp $";
  #endif /* not lint */
  
  /*
***************
*** 229,235 ****
--- 229,241 ----
  
  	ns_msg handle;
  	querybuf buf;
+ #ifdef INET6
+ 	struct sockaddr_in6 sin;
+ 	struct sockaddr_in* sin4p;
+ 	int slen; 
+ #else
  	struct sockaddr_in sin;
+ #endif
  	HEADER *headerPtr;
  	int msglen, amtToRead, numRead, n, count, soacnt;
  	u_int len;
***************
*** 240,245 ****
--- 246,254 ----
  	enum { NO_ERRORS, ERR_READING_LEN, ERR_READING_MSG, ERR_PRINTING }
  		error = NO_ERRORS;
  
+ #ifdef INET6
+ 	sin4p = (struct sockaddr_in*)&sin;
+ #endif
  	/*
  	 * Create a query packet for the requested domain name.
  	 */
***************
*** 251,260 ****
  		return (ERROR);
  	}
  
  	memset(&sin, 0, sizeof sin);
  	sin.sin_family = AF_INET;
  	sin.sin_port = htons(nsport);
- 
  	/*
  	 * Check to see if we have the address of the server or the
  	 * address of a server who knows about this domain.
--- 260,321 ----
  		return (ERROR);
  	}
  
+ #ifdef INET6
+ 	memset(&sin, 0, sizeof(struct sockaddr_in6));
+ 	if (defaultPtr->addrList != NULL) {
+ 	    if(((struct sockaddr_in6 *)defaultPtr->addrList[0])->sin6_family==
+ 	       AF_INET6) {
+ 		sin = *(struct sockaddr_in6 *)defaultPtr->addrList[0];
+ 		sin.sin6_port = htons(nsport);
+ 		slen = sizeof(struct sockaddr_in6);
+ 	    } else {
+ 		*sin4p = *(struct sockaddr_in *)defaultPtr->addrList[0];
+ 		sin4p->sin_port = htons(nsport);
+ 		slen = sizeof(struct sockaddr_in);
+ 	    }
+ 	} else {
+    if(((struct sockaddr_in6 *)defaultPtr->servers[0]->addrList[0])->sin6_family
+       == AF_INET6) {
+        sin = *(struct sockaddr_in6 *)defaultPtr->servers[0]->addrList[0];
+        sin.sin6_port = htons(nsport);
+        slen = sizeof(struct sockaddr_in6);
+    } else {
+        *sin4p = *(struct sockaddr_in *)defaultPtr->servers[0]->addrList[0];
+        sin4p->sin_port = htons(nsport);
+        slen = sizeof(struct sockaddr_in);
+    }
+ 	}
+ 
+ 
+ 	/*
+ 	 *  Set up a virtual circuit to the server.
+ 	 */
+ 	if (sin.sin6_family == AF_INET6) {
+ 	    sockFD = socket(AF_INET6, SOCK_STREAM, 0);
+ 	} else {
+ 	    sockFD = socket(AF_INET, SOCK_STREAM, 0);
+ 	}
+ 	if (sockFD < 0) {
+ 		perror("ls: socket");
+ 		return (ERROR);
+ 	}
+ 	if (connect(sockFD, (struct sockaddr *)&sin, slen) < 0) {
+ 		int e;
+ 
+ 		if (errno == ECONNREFUSED)
+ 			e = NO_RESPONSE;
+ 		else {
+ 			perror("ls: connect");
+ 			e = ERROR;
+ 		}
+ 		(void) close(sockFD);
+ 		sockFD = -1;
+ 		return (e);
+ 	}
+ #else
  	memset(&sin, 0, sizeof sin);
  	sin.sin_family = AF_INET;
  	sin.sin_port = htons(nsport);
  	/*
  	 * Check to see if we have the address of the server or the
  	 * address of a server who knows about this domain.
***************
*** 289,294 ****
--- 350,356 ----
  		sockFD = -1;
  		return (e);
  	}
+ #endif
  
  	/*
  	 * Send length & message for zone transfer
Index: bind8/src/bin/nslookup/main.c
diff -c bind8/src/bin/nslookup/main.c:1.1.1.1 bind8/src/bin/nslookup/main.c:1.6
*** bind8/src/bin/nslookup/main.c:1.1.1.1	Fri Sep 25 14:24:53 1998
--- bind8/src/bin/nslookup/main.c	Thu Dec  3 04:55:19 1998
***************
*** 59,65 ****
  
  #ifndef lint
  static char sccsid[] = "@(#)main.c	5.42 (Berkeley) 3/3/91";
! static char rcsid[] = "$Id: main.c,v 8.7 1997/04/25 00:27:18 vixie Exp $";
  #endif /* not lint */
  
  /*
--- 59,65 ----
  
  #ifndef lint
  static char sccsid[] = "@(#)main.c	5.42 (Berkeley) 3/3/91";
! static char rcsid[] = "$Id: main.c,v 1.5 1998/12/02 17:56:04 itojun Exp $";
  #endif /* not lint */
  
  /*
***************
*** 133,146 ****
  
  HostInfo	*defaultPtr = NULL;
  char		defaultServer[NAME_LEN];
  struct in_addr	defaultAddr;
  
  
  /*
   *  Initial name server query type is Address.
   */
! 
  int		queryType = T_A;
  int		queryClass = C_IN;
  
  /*
--- 133,154 ----
  
  HostInfo	*defaultPtr = NULL;
  char		defaultServer[NAME_LEN];
+ #ifdef INET6
+ struct sockaddr_storage defaultAddr;
+ #else
  struct in_addr	defaultAddr;
+ #endif
  
  
  /*
   *  Initial name server query type is Address.
   */
! #ifdef INET6
! extern          IpType;
! int		queryType = T_A;
! #else
  int		queryType = T_A;
+ #endif
  int		queryClass = C_IN;
  
  /*
***************
*** 182,187 ****
--- 190,198 ----
      int		result;
      int		i;
      struct hostent	*hp;
+ #ifdef INET6
+     char vname[INET6_ADDRSTRLEN];
+ #endif
  
      /*
       *  Initialize the resolver library routines.
***************
*** 238,254 ****
      useLocalServer = FALSE;
      if (argc == 2) {
  	struct in_addr addr;
! 
  	/*
  	 * Use an explicit name server. If the hostname lookup fails,
  	 * default to the server(s) in resolv.conf.
  	 */ 
! 
  	if (inet_aton(*++argv, &addr)) {
  	    _res.nscount = 1;
! 	    _res.nsaddr.sin_addr = addr;
  	} else {
  	    hp = gethostbyname(*argv);
  	    if (hp == NULL) {
  		fprintf(stderr, "*** Can't find server address for '%s': ", 
  			*argv);
--- 249,314 ----
      useLocalServer = FALSE;
      if (argc == 2) {
  	struct in_addr addr;
! #ifdef INET6
! 	struct in6_addr addr6;
! #endif
  	/*
  	 * Use an explicit name server. If the hostname lookup fails,
  	 * default to the server(s) in resolv.conf.
  	 */ 
! #ifdef INET6
! 	if (inet_aton(*++argv, &addr)) {
! 	    struct sockaddr_in *sin;
! 	    sin = (struct sockaddr_in *)&_res_ext.nsaddr_list[0];
! 	    memset(sin, 0, sizeof(*sin));
! 	    sin->sin_addr = addr;
! 	    sin->sin_family = AF_INET;
! 	    _res.nsaddr_list[0] = *sin;
! 	    _res.nscount = 1;
! 	} else if( inet_pton( AF_INET6, *argv, &addr6) != 0 ){
! 	    struct sockaddr_in6 *sin6;
! 	    inet_ntop(AF_INET6, &addr6, vname, sizeof vname);
! 	    sin6 = (struct sockaddr_in6 *)&_res_ext.nsaddr_list[0];
! 	    memset(sin6, 0, sizeof(*sin6));
! 	    sin6->sin6_addr = addr6;
! 	    sin6->sin6_family = AF_INET6;
! 	    _res.nscount = 1;
! #else
  	if (inet_aton(*++argv, &addr)) {
  	    _res.nscount = 1;
! 	    _res.nsaddr.sin_addr   = addr;
! 	    _res.nsaddr.sin_family = AF_INET;
! #endif
  	} else {
  	    hp = gethostbyname(*argv);
+ #ifdef INET6
+ 	    if (hp == NULL && (hp = gethostbyname2(*argv, AF_INET6)) == NULL) {
+ 		fprintf(stderr,
+ 			"*** Can't find server address for '%s': ", *argv);
+ 		herror((char *)NULL);
+ 		fputc('\n', stderr);
+ 	    } else {
+ 		for (i = 0; i < MAXNS && hp->h_addr_list[i] != NULL; i++) {
+ 		    if (hp->h_addrtype == AF_INET6) {
+ 			struct sockaddr_in6 *sin6;
+ 			sin6 = (struct sockaddr_in6 *)&_res_ext.nsaddr_list[i];
+ 			memset(sin6, 0, sizeof(*sin6));
+ 			memcpy(&sin6->sin6_addr, hp->h_addr_list[i],
+ 			       hp->h_length);
+ 			sin6->sin6_family = AF_INET6;
+ 		    } else {
+ 			struct sockaddr_in *sin;
+ 			sin = (struct sockaddr_in *)&_res_ext.nsaddr_list[i];
+ 			memset(sin, 0, sizeof(*sin));
+ 			memcpy(&sin->sin_addr, hp->h_addr_list[i],
+ 			       hp->h_length);
+ 			sin->sin_family = AF_INET;
+ 			_res.nsaddr_list[i] = *sin;
+ 		    }
+ 		}
+ 		_res.nscount = i;
+ 	    } 
+ #else
  	    if (hp == NULL) {
  		fprintf(stderr, "*** Can't find server address for '%s': ", 
  			*argv);
***************
*** 261,274 ****
  		}
  		_res.nscount = i;
  	    } 
  	}
      }
  
- 
      if (_res.nscount == 0 || useLocalServer) {
  	LocalServer(defaultPtr);
      } else {
  	for (i = 0; i < _res.nscount; i++) {
  	    if (_res.nsaddr_list[i].sin_addr.s_addr == INADDR_ANY) {
  	        LocalServer(defaultPtr);
  		break;
--- 321,393 ----
  		}
  		_res.nscount = i;
  	    } 
+ #endif
  	}
      }
  
      if (_res.nscount == 0 || useLocalServer) {
  	LocalServer(defaultPtr);
      } else {
  	for (i = 0; i < _res.nscount; i++) {
+ #ifdef INET6
+ 	    if (_res_ext.nsaddr_list[i].ss_family == AF_INET &&
+ 		((struct sockaddr_in *)&_res_ext.nsaddr_list[i])->sin_addr.s_addr == INADDR_ANY) {
+ 	        LocalServer(defaultPtr);
+ 		break;
+ 	    } else if (_res_ext.nsaddr_list[i].ss_family == AF_INET6 &&
+ 		IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)&_res_ext.nsaddr_list[i])->sin6_addr)) {
+ 		struct sockaddr_in6 *sin6;
+ 		char hostName[NAME_LEN];
+ 
+ 		gethostname(hostName, sizeof(hostName));
+ 
+ 		sin6 = (struct sockaddr_in6 *)&defaultAddr;
+ 		sin6->sin6_addr = in6addr_any;
+ 		sin6->sin6_family = AF_INET6;
+ 		GetHostInfoByName(&defaultAddr, C_IN, T_AAAA,
+ 				  "::1", defaultPtr, 1);
+ 		free(defaultPtr->name);
+ 		defaultPtr->name = Calloc(1, sizeof(hostName)+1);
+ 		strcpy(defaultPtr->name, hostName);
+ 	    } else {
+ 		if (_res_ext.nsaddr_list[i].ss_family == AF_INET6) {
+ 		    inet_ntop(AF_INET6, 
+ 		    	      &((struct sockaddr_in6 *)&_res_ext.nsaddr_list[i])->sin6_addr,
+ 			      vname, sizeof vname);
+ 		    result = GetHostInfoByAddr(&_res_ext.nsaddr_list[i], 
+ 					       &_res_ext.nsaddr_list[i], 
+ 					       defaultPtr);
+ 		} else {
+ 		    result = GetHostInfoByAddr(&_res_ext.nsaddr_list[i], 
+ 					       &_res_ext.nsaddr_list[i], 
+ 					       defaultPtr);
+ 		}
+ 		if (result != SUCCESS) {
+ 		    if (_res_ext.nsaddr_list[i].ss_family == AF_INET6) {
+ 			fprintf(stderr,
+ 				"*** Can't find server name for address %s: %s\n", 
+ 				vname, DecodeError(result));
+ 		    } else {
+ 		fprintf(stderr,
+ 			"*** Can't find server name for address %s: %s\n", 
+ 			inet_ntoa(((struct sockaddr_in *)&_res_ext.nsaddr_list[i])->sin_addr),
+ 			DecodeError(result));
+ 		    }
+ 		} else {
+ 		    if (_res_ext.nsaddr_list[i].ss_family == AF_INET6) {
+ 			memcpy(&defaultAddr, &_res_ext.nsaddr_list[i],
+ 			    sizeof(struct sockaddr_in6));
+ 			inet_ntop(AF_INET6,
+ 				  &((struct sockaddr_in6 *)&defaultAddr)->sin6_addr,
+ 				  vname, sizeof vname);
+ 		    } else {
+ 			memcpy(&defaultAddr, &_res_ext.nsaddr_list[i],
+ 			    sizeof(struct sockaddr_in));
+ 		    }
+ 		    break;
+ 		}
+ 	    }
+ #else
  	    if (_res.nsaddr_list[i].sin_addr.s_addr == INADDR_ANY) {
  	        LocalServer(defaultPtr);
  		break;
***************
*** 286,291 ****
--- 405,411 ----
  		    break;
  		}
  	    }
+ #endif
  	}
  
  	/*
***************
*** 362,368 ****
--- 482,493 ----
  
      (void) gethostname(hostName, sizeof(hostName));
  
+ #ifdef INET6
+     memset(&defaultAddr, 0, sizeof(defaultAddr));
+     defaultAddr.ss_family = AF_INET;
+ #else
      defaultAddr.s_addr = htonl(INADDR_ANY);
+ #endif
      (void) GetHostInfoByName(&defaultAddr, C_IN, T_A,
  			     "0.0.0.0", defaultPtr, 1);
      free(defaultPtr->name);
***************
*** 410,416 ****
--- 535,545 ----
  Boolean
  IsAddr(host, addrPtr)
      char *host;
+ #ifdef INET6
+     struct sockaddr_in *addrPtr;
+ #else
      struct in_addr *addrPtr;	/* If return TRUE, contains IP address */
+ #endif
  {
      register char *cp;
  
***************
*** 422,434 ****
--- 551,583 ----
  	    }
  	    /* If it has a trailing dot, don't treat it as an address. */
  	    if (*--cp != '.') { 
+ #ifdef INET6
+ 		addrPtr->sin_family = AF_INET;
+ 		return inet_aton(host, &addrPtr->sin_addr);
+ #else
  		return inet_aton(host, addrPtr);
+ #endif
  	    }
      }
      return FALSE;
  }
  
+ #ifdef INET6
+ Boolean
+ IsAddr6(host, addrPtr)
+     char *host;
+     struct sockaddr_in6 *addrPtr;
+ {
+     register char *cp;
  
+     if (inet_pton(AF_INET6, host, &addrPtr->sin6_addr) == 1) {
+ 	    addrPtr->sin6_family = AF_INET6;
+ 	    return TRUE;
+     }
+     return FALSE;
+ }
+ 
+ #endif
  /*
   ******************************************************************************
   *
***************
*** 459,466 ****
--- 608,621 ----
      Boolean	local;
  {
      register HostInfo	*newDefPtr;
+ #ifdef INET6
+     struct sockaddr	*servAddrPtr;
+     struct sockaddr_in	addr;
+     struct sockaddr_in6	addr6;
+ #else
      struct in_addr	*servAddrPtr;
      struct in_addr	addr;
+ #endif
      char		newServer[NAME_LEN];
      int			result;
      int			i;
***************
*** 501,522 ****
       *  XXX For now, just use the first address in the list.
       */
  
      if (local) {
  	servAddrPtr = &defaultAddr;
      } else if (defaultPtr->addrList != NULL) {
  	servAddrPtr = (struct in_addr *) defaultPtr->addrList[0];
      } else {
  	servAddrPtr = (struct in_addr *) defaultPtr->servers[0]->addrList[0];
      }
  
      result = ERROR;
      if (IsAddr(newServer, &addr)) {
  	result = GetHostInfoByAddr(servAddrPtr, &addr, newDefPtr);
  	/* If we can't get the name, fall through... */
!     } 
      if (result != SUCCESS && result != NONAUTH) {
  	result = GetHostInfoByName(servAddrPtr, C_IN, T_A, 
  			newServer, newDefPtr, 1);
      }
  
      /* If we ask for an A record and get none back, but get an NS
--- 656,702 ----
       *  XXX For now, just use the first address in the list.
       */
  
+ #ifdef INET6
      if (local) {
+ 	servAddrPtr = (struct sockaddr *) &defaultAddr;
+     } else if (defaultPtr->addrList != NULL) {
+ 	servAddrPtr = (struct sockaddr *) defaultPtr->addrList[0];
+     } else {
+ 	servAddrPtr = (struct sockaddr *) defaultPtr->servers[0]->addrList[0];
+     }
+ #else
+     if (local) {
  	servAddrPtr = &defaultAddr;
      } else if (defaultPtr->addrList != NULL) {
  	servAddrPtr = (struct in_addr *) defaultPtr->addrList[0];
      } else {
  	servAddrPtr = (struct in_addr *) defaultPtr->servers[0]->addrList[0];
      }
+ #endif
  
      result = ERROR;
      if (IsAddr(newServer, &addr)) {
  	result = GetHostInfoByAddr(servAddrPtr, &addr, newDefPtr);
  	/* If we can't get the name, fall through... */
!     }
! #ifdef INET6
!     else if (IsAddr6(newServer, &addr6)) {
! 	result = GetHostInfoByAddr(servAddrPtr, &addr6, newDefPtr);
! 	/* If we can't get the name, fall through... */
!     }
! #endif
      if (result != SUCCESS && result != NONAUTH) {
+ #ifdef INET6
+ 	result = GetHostInfoByName(servAddrPtr, C_IN, T_A, 
+ 				   newServer, newDefPtr, 1);
+ 	if (result != SUCCESS && result != NONAUTH) {
+ 	    result = GetHostInfoByName(servAddrPtr, C_IN, T_AAAA, 
+ 				       newServer, newDefPtr, 1);
+ 	}
+ #else
  	result = GetHostInfoByName(servAddrPtr, C_IN, T_A, 
  			newServer, newDefPtr, 1);
+ #endif
      }
  
      /* If we ask for an A record and get none back, but get an NS
***************
*** 568,575 ****
--- 748,761 ----
      char	*serverName;
  {
      int result;
+ #ifdef INET6
+     struct sockaddr *servAddrPtr;
+     struct sockaddr_in inaddr; 
+     struct sockaddr_in6 inaddr6; 
+ #else
      struct in_addr *servAddrPtr;
      struct in_addr addr; 
+ #endif
  
      /* Skip escape character */
      if (host[0] == '\\')
***************
*** 585,600 ****
--- 771,807 ----
       *  XXX For now, just use the first address in the list.
       */
  
+ #ifdef INET6
+     if (servPtr->addrList != NULL) {
+ 	servAddrPtr = (struct sockaddr *) servPtr->addrList[0];
+     } else {
+ 	servAddrPtr = (struct sockaddr *) servPtr->servers[0]->addrList[0];
+     }
+ #else
      if (servPtr->addrList != NULL) {
  	servAddrPtr = (struct in_addr *) servPtr->addrList[0];
      } else {
  	servAddrPtr = (struct in_addr *) servPtr->servers[0]->addrList[0];
      }
+ #endif
  
      /* 
       * RFC1123 says we "SHOULD check the string syntactically for a 
       * dotted-decimal number before looking it up [...]" (p. 13).
       */
+ #ifdef INET6
+     if (queryType == T_A && IsAddr(host, &inaddr)) {
+ 	result = GetHostInfoByAddr(servAddrPtr, &inaddr, &curHostInfo);
+     } else if (queryType == T_AAAA && IsAddr6(host, &inaddr6)) {
+ 	result = GetHostInfoByAddr(servAddrPtr, &inaddr6, &curHostInfo);
+     } else {
+ 	if (queryType == T_PTR) {
+ 	    CvtAddrToPtr(host);
+ 	} 
+ 	result = GetHostInfoByName(servAddrPtr, queryClass, queryType, host, 
+ 			&curHostInfo, 0);
+     }
+ #else
      if (queryType == T_A && IsAddr(host, &addr)) {
  	result = GetHostInfoByAddr(servAddrPtr, &addr, &curHostInfo);
      } else {
***************
*** 604,609 ****
--- 811,817 ----
  	result = GetHostInfoByName(servAddrPtr, queryClass, queryType, host, 
  			&curHostInfo, 0);
      }
+ #endif
  
      switch (result) {
  	case SUCCESS:
***************
*** 613,622 ****
--- 821,837 ----
  	     *  There's no need to print anything for other query types
  	     *  because the info has already been printed.
  	     */
+ #ifdef INET6
+ 	    if (queryType == T_A||queryType==T_AAAA) {
+ 		curHostValid = TRUE;
+ 		PrintHostInfo(filePtr, "Name:", &curHostInfo);
+ 	    }
+ #else
  	    if (queryType == T_A) {
  		curHostValid = TRUE;
  		PrintHostInfo(filePtr, "Name:", &curHostInfo);
  	    }
+ #endif
  	    break;
  
  	/*
***************
*** 924,929 ****
--- 1139,1158 ----
  	    _res.options |= RES_USEVC;
  	} else if (strncmp(option, "nov", 3) == 0) {
  	    _res.options &= ~RES_USEVC;
+ #ifdef INET6
+ 	} else if (strncmp(option, "ip", 2) == 0) {
+ 	    ptr = strchr(option, '=');
+ 	    if (ptr != NULL) {
+ 		int ip;
+ 		sscanf(++ptr, "%d", &ip);
+ 		if( ip == 4 )
+ 		    IpType = AF_INET;
+ 		else if( ip == 6 )
+ 		    IpType = AF_INET6;
+ 		else
+ 		    fprintf(stderr, "*** Invalid ip: %d\n", ip);
+ 	    }
+ #endif
  	} else {
  	    fprintf(stderr, "*** Invalid option: %s\n",  option);
  	    return(ERROR);
***************
*** 1025,1030 ****
--- 1254,1265 ----
      printf("  class=%s\t", p_class(queryClass));
      printf("  timeout=%d\t", _res.retrans);
      printf("  retry=%d\n", _res.retry);
+ #ifdef INET6
+     if (IpType==AF_INET6)
+ 	printf("  ip=Ipv6\n");
+     else
+ 	printf("  ip=Ipv4\n");
+ #endif
      printf("  root=%s\n", rootServerName);
      printf("  domain=%s\n", _res.defdname);
  
***************
*** 1079,1092 ****
--- 1314,1361 ----
      char *p;
      int ip[4];
      struct in_addr addr;
+ #ifdef INET6
+     char vname[INET6_ADDRSTRLEN];
+     struct sockaddr_in6 inaddr6;
+ #endif
  
+ #ifdef INET6
      if (IsAddr(name, &addr)) {
  	p = inet_ntoa(addr);
  	if (sscanf(p, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]) == 4) {
  	    sprintf(name, "%d.%d.%d.%d.in-addr.arpa.", 
  		ip[3], ip[2], ip[1], ip[0]);
  	}
+     } else if (IsAddr6(name, &inaddr6)) {
+ 	p = (char *)inaddr6.sin6_addr.s6_addr;
+ 	(void)sprintf(name, "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.int.",
+ 		      (unsigned)p[15] & 0x0f, (unsigned)p[15] >> 4 & 0x0f,
+ 		      (unsigned)p[14] & 0x0f, (unsigned)p[14] >> 4 & 0x0f,
+ 		      (unsigned)p[13] & 0x0f, (unsigned)p[13] >> 4 & 0x0f,
+ 		      (unsigned)p[12] & 0x0f, (unsigned)p[12] >> 4 & 0x0f,
+ 		      (unsigned)p[11] & 0x0f, (unsigned)p[11] >> 4 & 0x0f,
+ 		      (unsigned)p[10] & 0x0f, (unsigned)p[10] >> 4 & 0x0f,
+ 		      (unsigned)p[9] & 0x0f, (unsigned)p[9] >> 4 & 0x0f,
+ 		      (unsigned)p[8] & 0x0f, (unsigned)p[8] >> 4 & 0x0f,
+ 		      (unsigned)p[7] & 0x0f, (unsigned)p[7] >> 4 & 0x0f,
+ 		      (unsigned)p[6] & 0x0f, (unsigned)p[6] >> 4 & 0x0f,
+ 		      (unsigned)p[5] & 0x0f, (unsigned)p[5] >> 4 & 0x0f,
+ 		      (unsigned)p[4] & 0x0f, (unsigned)p[4] >> 4 & 0x0f,
+ 		      (unsigned)p[3] & 0x0f, (unsigned)p[3] >> 4 & 0x0f,
+ 		      (unsigned)p[2] & 0x0f, (unsigned)p[2] >> 4 & 0x0f,
+ 		      (unsigned)p[1] & 0x0f, (unsigned)p[1] >> 4 & 0x0f,
+ 		      (unsigned)p[0] & 0x0f, (unsigned)p[0] >> 4 & 0x0f
+ 	    );
      }
+ #else
+     if (IsAddr(name, &addr)) {
+ 	p = inet_ntoa(addr);
+ 	if (sscanf(p, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]) == 4) {
+ 	    sprintf(name, "%d.%d.%d.%d.in-addr.arpa.", 
+ 		ip[3], ip[2], ip[1], ip[0]);
+ 	}
+     }
+ #endif
  }
  
  /*
Index: bind8/src/bin/nslookup/res.h
diff -c bind8/src/bin/nslookup/res.h:1.1.1.1 bind8/src/bin/nslookup/res.h:1.2
*** bind8/src/bin/nslookup/res.h:1.1.1.1	Fri Sep 25 14:24:53 1998
--- bind8/src/bin/nslookup/res.h	Fri Sep 25 17:17:03 1998
***************
*** 55,61 ****
  
  /*
   *	@(#)res.h	5.10 (Berkeley) 6/1/90
!  *	$Id: res.h,v 8.4 1996/12/04 09:38:59 vixie Exp $
   */
  
  /*
--- 55,61 ----
  
  /*
   *	@(#)res.h	5.10 (Berkeley) 6/1/90
!  *	$Id: res.h,v 1.1.1.1 1998/09/25 05:24:53 k-sugyou Exp $
   */
  
  /*
***************
*** 161,166 ****
--- 161,169 ----
  
  /* XXX need prototypes */
  extern Boolean IsAddr();
+ #ifdef INET6
+ extern Boolean IsAddr6();
+ #endif
  void Print_query(const u_char *msg, const u_char *eom, int printHeader);
  void Fprint_query(const u_char *msg, const u_char *eom, int printHeader,
  		  FILE *file);
***************
*** 181,183 ****
--- 184,187 ----
  extern void FreeHostInfoPtr();
  extern FILE *OpenFile();
  extern char *res_skip();
+ 
Index: bind8/src/bin/nslookup/send.c
diff -c bind8/src/bin/nslookup/send.c:1.1.1.1 bind8/src/bin/nslookup/send.c:1.2
*** bind8/src/bin/nslookup/send.c:1.1.1.1	Fri Sep 25 14:24:53 1998
--- bind8/src/bin/nslookup/send.c	Fri Sep 25 17:17:04 1998
***************
*** 53,59 ****
  
  #ifndef lint
  static char sccsid[] = "@(#)send.c	5.18 (Berkeley) 3/2/91";
! static char rcsid[] = "$Id: send.c,v 8.6 1997/05/21 19:49:58 halley Exp $";
  #endif /* not lint */
  
  /*
--- 53,59 ----
  
  #ifndef lint
  static char sccsid[] = "@(#)send.c	5.18 (Berkeley) 3/2/91";
! static char rcsid[] = "$Id: send.c,v 1.1.1.1 1998/09/25 05:24:53 k-sugyou Exp $";
  #endif /* not lint */
  
  /*
***************
*** 105,110 ****
--- 105,113 ----
  #define FD_ZERO(p)	memset((p), 0, sizeof(*(p)))
  #endif
  
+ #ifdef INET6 
+ int             IpType = AF_INET;
+ #endif
  
  
  unsigned short nsport = NAMESERVER_PORT;
***************
*** 131,138 ****
--- 134,146 ----
   */
  
  int
+ #ifdef INET6
+ SendRequest(struct sockaddr *nsAddrPtr, const u_char *buf, int buflen,
+ 	    u_char *answer, u_int anslen, int *trueLenPtr)
+ #else
  SendRequest(struct in_addr *nsAddrPtr, const u_char *buf, int buflen,
  	    u_char *answer, u_int anslen, int *trueLenPtr)
+ #endif
  {
  	int n, try, v_circuit, resplen, salen;
  	int gotsomewhere = 0, connected = 0;
***************
*** 146,160 ****
--- 154,187 ----
  	struct iovec iov[2];
  	int terrno = ETIMEDOUT;
  	char junk[512];
+ #ifdef INET6
+ 	char vname[INET6_ADDRSTRLEN];
+ 	struct sockaddr_in6 sin_tmp, sa_tmp;
+ 	struct sockaddr_in  *sin4p = (struct sockaddr_in  *)&sin_tmp;
+ 	struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *)&sin_tmp;
+ #else
  	struct sockaddr_in sin, sa;
+ #endif
  
  	if (_res.options & RES_DEBUG2) {
  	    printf("------------\nSendRequest(), len %d\n", buflen);
  	    Print_query(buf, buf + buflen, 1);
  	}
+ #ifdef INET6
+ 	if (nsAddrPtr->sa_family==AF_INET6) {
+ 	    sin6p->sin6_family = AF_INET6;
+ 	    sin6p->sin6_port   = htons(nsport);
+ 	    sin6p->sin6_addr   = ((struct sockaddr_in6 *)nsAddrPtr)->sin6_addr;
+ 	} else {
+ 	    sin4p->sin_family  = AF_INET;
+ 	    sin4p->sin_port    = htons(nsport);
+ 	    sin4p->sin_addr    = ((struct sockaddr_in *)nsAddrPtr)->sin_addr;
+ 	}
+ #else
  	sin.sin_family	= AF_INET;
  	sin.sin_port	= htons(nsport);
  	sin.sin_addr	= *nsAddrPtr;
+ #endif
  	v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
  	id = hp->id;
  	/*
***************
*** 170,175 ****
--- 197,243 ----
  			 * at most one attempt per server.
  			 */
  			try = _res.retry;
+ #ifdef INET6
+ 			if (s < 0 || sin6p->sin6_family!=IpType) {
+ 			    if (sin6p->sin6_family==AF_INET6) {
+ 				IpType = AF_INET6;
+ 				s = socket(AF_INET6, SOCK_STREAM, 0);
+ 				if (s < 0) {
+ 					terrno = errno;
+ 					if (_res.options & RES_DEBUG)
+ 					    perror("socket (vc) failed");
+ 					continue;
+ 				}
+ 				if (connect(s, (struct sockaddr *)sin6p,
+ 				   sizeof(struct sockaddr_in6)) < 0) {
+ 					terrno = errno;
+ 					if (_res.options & RES_DEBUG)
+ 					    perror("connect failed");
+ 					(void) close(s);
+ 					s = -1;
+ 					continue;
+ 				}
+ 			    } else {
+ 				IpType = AF_INET;
+ 				s = socket(AF_INET, SOCK_STREAM, 0);
+ 				if (s < 0) {
+ 					terrno = errno;
+ 					if (_res.options & RES_DEBUG)
+ 					    perror("socket (vc) failed");
+ 					continue;
+ 				}
+ 				if (connect(s, (struct sockaddr *)sin4p,
+ 				   sizeof(struct sockaddr_in)) < 0) {
+ 					terrno = errno;
+ 					if (_res.options & RES_DEBUG)
+ 					    perror("connect failed");
+ 					(void) close(s);
+ 					s = -1;
+ 					continue;
+ 				}
+ 			    }
+ 			}
+ #else
  			if (s < 0) {
  				s = socket(AF_INET, SOCK_STREAM, 0);
  				if (s < 0) {
***************
*** 188,193 ****
--- 256,262 ----
  					continue;
  				}
  			}
+ #endif
  			/*
  			 * Send length & message
  			 */
***************
*** 276,282 ****
--- 345,361 ----
  			 * Use datagrams.
  			 */
  			if (s < 0) {
+ #ifdef INET6
+ 			    if (sin6p->sin6_family==AF_INET6) {
+ 				IpType = AF_INET6;
+ 				s = socket(AF_INET6, SOCK_DGRAM, 0);
+ 			    } else {
+ 				IpType = AF_INET;
+ 				s = socket(AF_INET, SOCK_DGRAM, 0);
+ 			    }
+ #else
  				s = socket(AF_INET, SOCK_DGRAM, 0);
+ #endif
  				if (s < 0) {
  					terrno = errno;
  					if (_res.options & RES_DEBUG)
***************
*** 284,291 ****
--- 363,406 ----
  					continue;
  				}
  			}
+ #ifdef INET6
  #if BSD >= 43
  			if (connected == 0) {
+ 			    if (sin6p->sin6_family==AF_INET6) {
+ 				if (connect(s, (struct sockaddr *)sin6p,
+ 					    sizeof(struct sockaddr_in6)) < 0) {
+ 				    if (_res.options & RES_DEBUG)
+ 					perror("connect");
+ 				    continue;
+ 				}
+ 				connected = 1;
+ 			    } else {
+ 				if (connect(s, (struct sockaddr *)sin4p,
+ 					    sizeof(struct sockaddr_in)) < 0) {
+ 				    if (_res.options & RES_DEBUG)
+ 					perror("connect");
+ 				    continue;
+ 				}
+ 				connected = 1;
+ 			    }
+ 			}
+ 			if (send(s, buf, buflen, 0) != buflen) {
+ 			    if (_res.options & RES_DEBUG)
+ 				perror("send");
+ 			    continue;
+ 			}
+ #else /* BSD */
+ 			if (sendto(s, (const char *)buf, buflen, 0,
+ 				   (struct sockaddr *) &sin,
+ 				   sizeof sin) != buflen) {
+ 				if (_res.options & RES_DEBUG)
+ 					perror("sendto");
+ 				continue;
+ 			}
+ #endif
+ #else
+ #if BSD >= 43
+ 			if (connected == 0) {
  				if (connect(s, (struct sockaddr *)&sin,
  				    sizeof sin) < 0) {
  					if (_res.options & RES_DEBUG)
***************
*** 308,314 ****
  				continue;
  			}
  #endif
! 
  			/*
  			 * Wait for reply
  			 */
--- 423,429 ----
  				continue;
  			}
  #endif
! #endif
  			/*
  			 * Wait for reply
  			 */
***************
*** 338,346 ****
--- 453,473 ----
  				continue;
  			}
  
+ #ifdef INET6
+ 			if (sin6p->sin6_family==AF_INET6) {
+ 			    salen = sizeof(struct sockaddr_in6);
+ 			    resplen = recvfrom(s, (char *)answer, anslen, 0,
+ 					       (struct sockaddr *)&sa_tmp, &salen);
+ 			} else {
+ 			    salen = sizeof(struct sockaddr_in);
+ 			    resplen = recvfrom(s, (char *)answer, anslen, 0,
+ 					       (struct sockaddr *)&sa_tmp, &salen);
+ 			}
+ #else
  			salen = sizeof sa;
  			resplen = recvfrom(s, (char *)answer, anslen, 0,
  					   (struct sockaddr *)&sa, &salen);
+ #endif
  			if (resplen <= 0) {
  				if (_res.options & RES_DEBUG)
  					perror("recvfrom");
Index: bind8/src/bin/nslookup/subr.c
diff -c bind8/src/bin/nslookup/subr.c:1.1.1.1 bind8/src/bin/nslookup/subr.c:1.3
*** bind8/src/bin/nslookup/subr.c:1.1.1.1	Fri Sep 25 14:24:53 1998
--- bind8/src/bin/nslookup/subr.c	Thu Dec  3 04:55:20 1998
***************
*** 53,59 ****
  
  #ifndef lint
  static char sccsid[] = "@(#)subr.c	5.24 (Berkeley) 3/2/91";
! static char rcsid[] = "$Id: subr.c,v 8.9 1997/04/25 00:27:19 vixie Exp $";
  #endif /* not lint */
  
  /*
--- 53,59 ----
  
  #ifndef lint
  static char sccsid[] = "@(#)subr.c	5.24 (Berkeley) 3/2/91";
! static char rcsid[] = "$Id: subr.c,v 1.2 1998/09/25 08:17:06 k-sugyou Exp $";
  #endif /* not lint */
  
  /*
***************
*** 239,244 ****
--- 239,247 ----
  	register ServerInfo	**sp;
  	char			comma;
  	int			i;
+ #ifdef INET6
+ 	char vname[INET6_ADDRSTRLEN];
+ #endif
  
  	fprintf(file, "%-7s  %s", title, hp->name);
  
***************
*** 257,263 ****
--- 260,278 ----
  		    comma = ' ';
  		    i = 0;
  		}
+ #ifdef INET6
+ 		if (((struct sockaddr_in6 *)*cp)->sin6_family == AF_INET6) {
+ 		    inet_ntop(AF_INET6,
+ 			       &((struct sockaddr_in6 *)*cp)->sin6_addr,
+ 			       vname, sizeof vname);
+ 		    fprintf(file,"%c %s", comma, vname);
+ 		} else {
+ 		    fprintf(file,"%c %s", comma,
+ 			    inet_ntoa(((struct sockaddr_in *)*cp)->sin_addr));
+ 		}
+ #else
  		fprintf(file,"%c %s", comma, inet_ntoa(*(struct in_addr *)*cp));
+ #endif
  		comma = ',';
  	    }
  	}
Index: bind8/src/include/netdb.h
diff -c bind8/src/include/netdb.h:1.1.1.1 bind8/src/include/netdb.h:1.2
*** bind8/src/include/netdb.h:1.1.1.1	Fri Sep 25 14:25:03 1998
--- bind8/src/include/netdb.h	Fri Dec 25 14:20:55 1998
***************
*** 55,61 ****
  
  /*
   *      @(#)netdb.h	8.1 (Berkeley) 6/2/93
!  *	$Id: netdb.h,v 8.9 1996/11/19 08:39:29 vixie Exp $
   */
  
  #ifndef _NETDB_H_
--- 55,61 ----
  
  /*
   *      @(#)netdb.h	8.1 (Berkeley) 6/2/93
!  *	$Id: netdb.h,v 1.1.1.1 1998/09/25 05:25:03 k-sugyou Exp $
   */
  
  #ifndef _NETDB_H_
***************
*** 115,120 ****
--- 115,131 ----
  	int	p_proto;	/* protocol # */
  };
  
+ struct addrinfo {
+ 	int	ai_flags;	/* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
+ 	int	ai_family;	/* PF_xxx */
+ 	int	ai_socktype;	/* SOCK_xxx */
+ 	int	ai_protocol;	/* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+ 	size_t	ai_addrlen;	/* length of ai_addr */
+ 	char	*ai_canonname;	/* canonical name for hostname */
+ 	struct sockaddr *ai_addr;	/* binary address */
+ 	struct addrinfo *ai_next;	/* next structure in linked list */
+ };
+ 
  /*
   * Error return codes from gethostbyname() and gethostbyaddr()
   * (left in extern int h_errno).
***************
*** 128,133 ****
--- 139,193 ----
  #define	NO_DATA		4 /* Valid name, no data record of requested type */
  #define	NO_ADDRESS	NO_DATA		/* no address, look for MX record */
  
+ /*
+  * Error return codes from getaddrinfo()
+  */
+ #define	EAI_ADDRFAMILY	 1	/* address family for hostname not supported */
+ #define	EAI_AGAIN	 2	/* temporary failure in name resolution */
+ #define	EAI_BADFLAGS	 3	/* invalid value for ai_flags */
+ #define	EAI_FAIL	 4	/* non-recoverable failure in name resolution */
+ #define	EAI_FAMILY	 5	/* ai_family not supported */
+ #define	EAI_MEMORY	 6	/* memory allocation failure */
+ #define	EAI_NODATA	 7	/* no address associated with hostname */
+ #define	EAI_NONAME	 8	/* hostname nor servname provided, or not known */
+ #define	EAI_SERVICE	 9	/* servname not supported for ai_socktype */
+ #define	EAI_SOCKTYPE	10	/* ai_socktype not supported */
+ #define	EAI_SYSTEM	11	/* system error returned in errno */
+ #define EAI_BADHINTS	12
+ #define EAI_PROTOCOL	13
+ #define EAI_MAX		14
+ 
+ /*
+  * Flag values for getaddrinfo()
+  */
+ #define AI_PASSIVE	0x00000001 /* get address to use bind() */
+ #define AI_CANONNAME	0x00000002 /* fill ai_canonname */
+ #define AI_NUMERICHOST	0x00000004 /* prevent name resolution */
+ /* valid flags for addrinfo */
+ #define AI_MASK		(AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST)
+ 
+ #define AI_ALL		0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */
+ #define AI_V4MAPPED_CFG	0x00000200 /* accept IPv4-mapped if kernel supports */
+ #define AI_ADDRCONFIG	0x00000400 /* only if any address is assigned */
+ #define AI_V4MAPPED	0x00000800 /* accept IPv4-mapped IPv6 address */
+ /* special recommended flags for getipnodebyname */
+ #define AI_DEFAULT	(AI_V4MAPPED_CFG | AI_ADDRCONFIG)
+ 
+ /*
+  * Constants for getnameinfo()
+  */
+ #define	NI_MAXHOST	1025
+ #define	NI_MAXSERV	32
+ 
+ /*
+  * Flag values for getnameinfo()
+  */
+ #define	NI_NOFQDN	0x00000001
+ #define	NI_NUMERICHOST	0x00000002
+ #define	NI_NAMEREQD	0x00000004
+ #define	NI_NUMERICSERV	0x00000008
+ #define	NI_DGRAM	0x00000010
+ 
  __BEGIN_DECLS
  void		endhostent __P((void));
  void		endnetent __P((void));
***************
*** 152,157 ****
--- 212,218 ----
  /* void		sethostfile __P((const char *)); */
  void		setnetent __P((int));
  void		setprotoent __P((int));
+ char		*gai_strerror __P((int));
  void		setservent __P((int));
  __END_DECLS
  
Index: bind8/src/include/resolv.h
diff -c bind8/src/include/resolv.h:1.1.1.1 bind8/src/include/resolv.h:1.4
*** bind8/src/include/resolv.h:1.1.1.1	Fri Sep 25 14:25:03 1998
--- bind8/src/include/resolv.h	Sun Nov 29 22:50:01 1998
***************
*** 50,56 ****
  
  /*
   *	@(#)resolv.h	8.1 (Berkeley) 6/2/93
!  *	$Id: resolv.h,v 8.12 1998/04/28 19:36:46 halley Exp $
   */
  
  #ifndef _RESOLV_H_
--- 50,56 ----
  
  /*
   *	@(#)resolv.h	8.1 (Berkeley) 6/2/93
!  *	$Id: resolv.h,v 1.3 1998/09/25 11:48:35 k-sugyou Exp $
   */
  
  #ifndef _RESOLV_H_
***************
*** 63,68 ****
--- 63,69 ----
  # include <sys/types.h>
  #endif
  #include <sys/cdefs.h>
+ #include <sys/socket.h>
  #include <stdio.h>
  
  /*
***************
*** 111,119 ****
--- 112,124 ----
  	int	retry;			/* number of times to retransmit */
  	u_long	options;		/* option flags - see below. */
  	int	nscount;		/* number of name servers */
+ #ifdef INET6
+ 	struct sockaddr_in nsaddr_list[MAXNS];	/*leave it unused*/
+ #else
  	struct sockaddr_in
  		nsaddr_list[MAXNS];	/* address of name server */
  #define	nsaddr	nsaddr_list[0]		/* for backward compatibility */
+ #endif
  	u_short	id;			/* current message id */
  	char	*dnsrch[MAXDNSRCH+1];	/* components of domain to search */
  	char	defdname[256];		/* default domain (deprecated) */
***************
*** 124,132 ****
  	struct {
  		struct in_addr	addr;
  		u_int32_t	mask;
  	} sort_list[MAXRESOLVSORT];
- 	char	pad[72];		/* On an i386 this means 512b total. */
  };
  
  /*
   * Resolver options (keep these in synch with res_debug.c, please)
--- 129,153 ----
  	struct {
  		struct in_addr	addr;
  		u_int32_t	mask;
+ 	} sort_list[MAXRESOLVSORT];
+         char    pad[72];                /* on an i386 this means 512b total */
+ };
+ 
+ #if 1 /*INET6*/
+ /*
+  * replacement of __res_state, separated to keep binary compatibility.
+  */
+ struct __res_state_ext {
+ 	struct sockaddr_storage nsaddr_list[MAXNS];
+ 	struct {
+ 		int af;		/* address family for addr, mask */
+ 		union {
+ 			struct in_addr ina;
+ 			struct in6_addr in6a;
+ 		} addr, mask;
  	} sort_list[MAXRESOLVSORT];
  };
+ #endif
  
  /*
   * Resolver options (keep these in synch with res_debug.c, please)
***************
*** 192,197 ****
--- 213,221 ----
  };
  
  extern struct __res_state _res;
+ #if 1 /*INET6*/
+ extern struct __res_state_ext _res_ext;
+ #endif
  extern const struct res_sym __p_class_syms[];
  extern const struct res_sym __p_type_syms[];
  
Index: bind8/src/lib/Makefile
diff -c bind8/src/lib/Makefile:1.1.1.1 bind8/src/lib/Makefile:1.2
*** bind8/src/lib/Makefile:1.1.1.1	Fri Sep 25 14:25:03 1998
--- bind8/src/lib/Makefile	Fri Sep 25 17:17:09 1998
***************
*** 13,19 ****
  # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  # SOFTWARE.
  
! # $Id: Makefile,v 8.10 1997/09/26 17:56:00 halley Exp $
  
  SUBDIRS = resolv irs isc bsd inet nameser
  
--- 13,19 ----
  # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  # SOFTWARE.
  
! # $Id: Makefile,v 1.1.1.1 1998/09/25 05:25:03 k-sugyou Exp $
  
  SUBDIRS = resolv irs isc bsd inet nameser
  
***************
*** 35,41 ****
  RANLIB= ranlib
  AR= ar cruv
  INSTALL= install
! CDEBUG= -g
  
  # Warning: this MARGS has RANLIB=: to prevent submakes from running ranlib
  MARGS =	"SYSTYPE=${SYSTYPE}" "SHELL=${SHELL}" "A=${A}" "O=${O}" \
--- 35,41 ----
  RANLIB= ranlib
  AR= ar cruv
  INSTALL= install
! CDEBUG= -g -DINET6
  
  # Warning: this MARGS has RANLIB=: to prevent submakes from running ranlib
  MARGS =	"SYSTYPE=${SYSTYPE}" "SHELL=${SHELL}" "A=${A}" "O=${O}" \
Index: bind8/src/lib/inet/Makefile
diff -c bind8/src/lib/inet/Makefile:1.1.1.1 bind8/src/lib/inet/Makefile:1.2
*** bind8/src/lib/inet/Makefile:1.1.1.1	Fri Sep 25 14:25:03 1998
--- bind8/src/lib/inet/Makefile	Fri Sep 25 17:17:11 1998
***************
*** 13,19 ****
  # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  # SOFTWARE.
  
! # $Id: Makefile,v 8.8 1997/05/21 19:32:07 halley Exp $
  
  # these are only appropriate for BSD 4.4 or derivatives, and are used in
  # development.  normal builds will be done in the top level directory and
--- 13,19 ----
  # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  # SOFTWARE.
  
! # $Id: Makefile,v 1.1.1.1 1998/09/25 05:25:03 k-sugyou Exp $
  
  # these are only appropriate for BSD 4.4 or derivatives, and are used in
  # development.  normal builds will be done in the top level directory and
***************
*** 26,37 ****
  CC= cc
  LD= ld
  SHELL= /bin/sh
! CDEBUG= -g
  TOP= ../..
  INCL = ${TOP}/include
  PORTINCL = ${TOP}/port/${SYSTYPE}/include
  LIBBIND = ${TOP}/lib/libbind.${A}
! CFLAGS=	${CDEBUG} -I${PORTINCL} -I${INCL}
  LD_LIBFLAGS= -x -r
  AR= ar cruv
  RANLIB= ranlib
--- 26,38 ----
  CC= cc
  LD= ld
  SHELL= /bin/sh
! CDEBUG= -g -DINET6
  TOP= ../..
  INCL = ${TOP}/include
+ INET6_INCLUDE =
  PORTINCL = ${TOP}/port/${SYSTYPE}/include
  LIBBIND = ${TOP}/lib/libbind.${A}
! CFLAGS=	${CDEBUG} ${INET6_INCLUDE} -I${PORTINCL} -I${INCL}
  LD_LIBFLAGS= -x -r
  AR= ar cruv
  RANLIB= ranlib
***************
*** 39,49 ****
  
  SRCS=	nsap_addr.c inet_addr.c inet_ntop.c inet_pton.c \
  	inet_ntoa.c inet_neta.c inet_net_ntop.c inet_net_pton.c \
! 	inet_lnaof.c inet_makeaddr.c inet_netof.c inet_network.c
  
  OBJS=	nsap_addr.${O} inet_addr.${O} inet_ntop.${O} inet_pton.${O} \
  	inet_ntoa.${O} inet_neta.${O} inet_net_ntop.${O} inet_net_pton.${O} \
! 	inet_lnaof.${O} inet_makeaddr.${O} inet_netof.${O} inet_network.${O}
  
  
  all: ${LIBBIND}
--- 40,52 ----
  
  SRCS=	nsap_addr.c inet_addr.c inet_ntop.c inet_pton.c \
  	inet_ntoa.c inet_neta.c inet_net_ntop.c inet_net_pton.c \
! 	inet_lnaof.c inet_makeaddr.c inet_netof.c inet_network.c \
! 	inet6_vars.c
  
  OBJS=	nsap_addr.${O} inet_addr.${O} inet_ntop.${O} inet_pton.${O} \
  	inet_ntoa.${O} inet_neta.${O} inet_net_ntop.${O} inet_net_pton.${O} \
! 	inet_lnaof.${O} inet_makeaddr.${O} inet_netof.${O} inet_network.${O} \
! 	inet6_vars.${O}
  
  
  all: ${LIBBIND}
Index: bind8/src/lib/inet/inet6_vars.c
diff -c /dev/null bind8/src/lib/inet/inet6_vars.c:1.1
*** /dev/null	Fri Jun  4 08:02:55 1999
--- bind8/src/lib/inet/inet6_vars.c	Fri Sep 25 17:17:12 1998
***************
*** 0 ****
--- 1,44 ----
+ /*
+  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 3. All advertising materials mentioning features or use of this software
+  *    must display the following acknowledgement:
+  *    This product includes software developed by WIDE Project and
+  *    its contributors.
+  * 4. Neither the name of the project nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #include <sys/types.h>
+ #include <netinet/in.h>
+ 
+ /*
+  * Definitions of some costant IPv6 addresses.
+  */
+ const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
+ const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
+ const struct in6_addr in6addr_nodelocal_allnodes = IN6ADDR_NODELOCAL_ALLNODES_INIT;
+ const struct in6_addr in6addr_linklocal_allnodes = IN6ADDR_LINKLOCAL_ALLNODES_INIT;
+ 
Index: bind8/src/lib/irs/Makefile
diff -c bind8/src/lib/irs/Makefile:1.1.1.1 bind8/src/lib/irs/Makefile:1.3
*** bind8/src/lib/irs/Makefile:1.1.1.1	Fri Sep 25 14:25:04 1998
--- bind8/src/lib/irs/Makefile	Fri Dec 25 14:20:56 1998
***************
*** 13,19 ****
  # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  # SOFTWARE.
  
! # $Id: Makefile,v 8.6 1997/05/21 19:23:18 halley Exp $
  
  # these are only appropriate for BSD 4.4 or derivatives, and are used in
  # development.  normal builds will be done in the top level directory and
--- 13,19 ----
  # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  # SOFTWARE.
  
! # $Id: Makefile,v 1.2 1998/09/25 08:17:13 k-sugyou Exp $
  
  # these are only appropriate for BSD 4.4 or derivatives, and are used in
  # development.  normal builds will be done in the top level directory and
***************
*** 26,37 ****
  CC= cc
  LD= ld
  SHELL= /bin/sh
! CDEBUG= -g
  TOP= ../..
  INCL = ${TOP}/include
  PORTINCL = ${TOP}/port/${SYSTYPE}/include
  LIBBIND = ${TOP}/lib/libbind.${A}
! CFLAGS=	${CDEBUG} -I${PORTINCL} -I${INCL}
  LD_LIBFLAGS= -x -r
  AR= ar cruv
  RANLIB= ranlib
--- 26,38 ----
  CC= cc
  LD= ld
  SHELL= /bin/sh
! CDEBUG= -g -DINET6
  TOP= ../..
  INCL = ${TOP}/include
+ INET6_INCLUDE =
  PORTINCL = ${TOP}/port/${SYSTYPE}/include
  LIBBIND = ${TOP}/lib/libbind.${A}
! CFLAGS=	${CDEBUG} ${INET6_INCLUDE} -I${PORTINCL} -I${INCL}
  LD_LIBFLAGS= -x -r
  AR= ar cruv
  RANLIB= ranlib
***************
*** 42,48 ****
  	getgrent.c gethostent.c getnetent.c getnetgrent.c getprotoent.c \
  	getpwent.c getservent.c hesiod.c irs_data.c lcl.c lcl_gr.c lcl_ho.c \
  	lcl_ng.c lcl_nw.c lcl_pr.c lcl_pw.c lcl_sv.c nis.c nis_gr.c nis_ho.c \
! 	nis_ng.c nis_nw.c nis_pr.c nis_pw.c nis_sv.c nul_ng.c util.c
  
  OBJS=	dns.${O} dns_gr.${O} dns_ho.${O} dns_nw.${O} dns_pr.${O} dns_pw.${O} \
  	dns_sv.${O} gen.${O} gen_gr.${O} gen_ho.${O} gen_ng.${O} gen_nw.${O} \
--- 43,50 ----
  	getgrent.c gethostent.c getnetent.c getnetgrent.c getprotoent.c \
  	getpwent.c getservent.c hesiod.c irs_data.c lcl.c lcl_gr.c lcl_ho.c \
  	lcl_ng.c lcl_nw.c lcl_pr.c lcl_pw.c lcl_sv.c nis.c nis_gr.c nis_ho.c \
! 	nis_ng.c nis_nw.c nis_pr.c nis_pw.c nis_sv.c nul_ng.c util.c \
! 	getaddrinfo.c getnameinfo.c name6.c
  
  OBJS=	dns.${O} dns_gr.${O} dns_ho.${O} dns_nw.${O} dns_pr.${O} dns_pw.${O} \
  	dns_sv.${O} gen.${O} gen_gr.${O} gen_ho.${O} gen_ng.${O} gen_nw.${O} \
***************
*** 51,57 ****
  	getservent.${O} hesiod.${O} irs_data.${O} lcl.${O} lcl_gr.${O} \
  	lcl_ho.${O} lcl_ng.${O} lcl_nw.${O} lcl_pr.${O} lcl_pw.${O} \
  	lcl_sv.${O} nis.${O} nis_gr.${O} nis_ho.${O} nis_ng.${O} nis_nw.${O} \
! 	nis_pr.${O} nis_pw.${O} nis_sv.${O} nul_ng.${O} util.${O}
  
  all: ${LIBBIND}
  
--- 53,60 ----
  	getservent.${O} hesiod.${O} irs_data.${O} lcl.${O} lcl_gr.${O} \
  	lcl_ho.${O} lcl_ng.${O} lcl_nw.${O} lcl_pr.${O} lcl_pw.${O} \
  	lcl_sv.${O} nis.${O} nis_gr.${O} nis_ho.${O} nis_ng.${O} nis_nw.${O} \
! 	nis_pr.${O} nis_pw.${O} nis_sv.${O} nul_ng.${O} util.${O} \
! 	getaddrinfo.${O} getnameinfo.${O} name6.${O}
  
  all: ${LIBBIND}
  
Index: bind8/src/lib/irs/Makefile.BSD
diff -c bind8/src/lib/irs/Makefile.BSD:1.1.1.1 bind8/src/lib/irs/Makefile.BSD:1.2
*** bind8/src/lib/irs/Makefile.BSD:1.1.1.1	Fri Sep 25 14:25:04 1998
--- bind8/src/lib/irs/Makefile.BSD	Fri Dec 25 14:20:57 1998
***************
*** 1,4 ****
! #	BSDI $Id: Makefile.BSD,v 1.4 1996/10/25 07:22:55 vixie Exp $
  #
  #	@(#)Makefile	5.12 (Berkeley) 7/15/92
  
--- 1,4 ----
! #	BSDI $Id: Makefile.BSD,v 1.1.1.1 1998/09/25 05:25:04 k-sugyou Exp $
  #
  #	@(#)Makefile	5.12 (Berkeley) 7/15/92
  
***************
*** 16,22 ****
  	getgrent.c getpwent.c getservent.c getprotoent.c gethostent.c \
  	getnetent.c getnetgrent.c \
  	nul_ng.c irs_data.c \
! 	hesiod.c util.c bitncmp.c
  NOMAN=
  
  all: libirs.a
--- 16,23 ----
  	getgrent.c getpwent.c getservent.c getprotoent.c gethostent.c \
  	getnetent.c getnetgrent.c \
  	nul_ng.c irs_data.c \
! 	hesiod.c util.c bitncmp.c \
! 	getaddrinfo.c getnameinfo.c name6.c
  NOMAN=
  
  all: libirs.a
Index: bind8/src/lib/irs/dns_ho.c
diff -c bind8/src/lib/irs/dns_ho.c:1.1.1.1 bind8/src/lib/irs/dns_ho.c:1.2
*** bind8/src/lib/irs/dns_ho.c:1.1.1.1	Fri Sep 25 14:25:04 1998
--- bind8/src/lib/irs/dns_ho.c	Fri Sep 25 17:17:14 1998
***************
*** 52,58 ****
  /* BIND Id: gethnamaddr.c,v 8.15 1996/05/22 04:56:30 vixie Exp $ */
  
  #if defined(LIBC_SCCS) && !defined(lint)
! static char rcsid[] = "$Id: dns_ho.c,v 1.18 1998/01/26 23:08:22 halley Exp $";
  #endif /* LIBC_SCCS and not lint */
  
  /* Imports. */
--- 52,58 ----
  /* BIND Id: gethnamaddr.c,v 8.15 1996/05/22 04:56:30 vixie Exp $ */
  
  #if defined(LIBC_SCCS) && !defined(lint)
! static char rcsid[] = "$Id: dns_ho.c,v 1.1.1.1 1998/09/25 05:25:04 k-sugyou Exp $";
  #endif /* LIBC_SCCS and not lint */
  
  /* Imports. */
***************
*** 250,259 ****
--- 250,269 ----
  	    (!memcmp(uaddr, mapped, sizeof mapped) ||
  	     !memcmp(uaddr, tunnelled, sizeof tunnelled))) {
  		/* Unmap. */
+ #ifdef INET6
+                 if( bcmp(uaddr, &in6addr_any, sizeof in6addr_any) &&
+                     bcmp(uaddr, &in6addr_loopback, sizeof in6addr_loopback)) {
+                   addr += sizeof mapped;
+                   uaddr += sizeof mapped;
+                   af = AF_INET;
+                   len = INADDRSZ;
+                 }
+ #else
  		addr = (char *)addr + sizeof mapped;
  		uaddr += sizeof mapped;
  		af = AF_INET;
  		len = INADDRSZ;
+ #endif
  	}
  	switch (af) {
  	case AF_INET:
Index: bind8/src/lib/irs/getaddrinfo.3
diff -c /dev/null bind8/src/lib/irs/getaddrinfo.3:1.1
*** /dev/null	Fri Jun  4 08:02:58 1999
--- bind8/src/lib/irs/getaddrinfo.3	Fri Dec 25 14:20:59 1998
***************
*** 0 ****
--- 1,361 ----
+ .\" Copyright (c) 1983, 1987, 1991, 1993
+ .\"	The Regents of the University of California.  All rights reserved.
+ .\"
+ .\" Redistribution and use in source and binary forms, with or without
+ .\" modification, are permitted provided that the following conditions
+ .\" are met:
+ .\" 1. Redistributions of source code must retain the above copyright
+ .\"    notice, this list of conditions and the following disclaimer.
+ .\" 2. Redistributions in binary form must reproduce the above copyright
+ .\"    notice, this list of conditions and the following disclaimer in the
+ .\"    documentation and/or other materials provided with the distribution.
+ .\" 3. All advertising materials mentioning features or use of this software
+ .\"    must display the following acknowledgement:
+ .\"	This product includes software developed by the University of
+ .\"	California, Berkeley and its contributors.
+ .\" 4. Neither the name of the University nor the names of its contributors
+ .\"    may be used to endorse or promote products derived from this software
+ .\"    without specific prior written permission.
+ .\"
+ .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ .\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ .\" SUCH DAMAGE.
+ .\"
+ .\"     From: @(#)gethostbyname.3	8.4 (Berkeley) 5/25/95
+ .\"     $Id: getaddrinfo.3,v 1.1.2.2 1998/06/02 06:42:34 itojun Exp $
+ .\"
+ .Dd May 25, 1995
+ .Dt GETADDRINFO 3
+ .Os KAME
+ .Sh NAME
+ .Nm getaddrinfo
+ .Nm freeaddrinfo ,
+ .Nm gai_strerror
+ .Nd nodename-to-address translation in protocol-independent manner
+ .Sh SYNOPSIS
+ .Fd #include <sys/socket.h>
+ .Fd #include <netdb.h>
+ .Ft int
+ .Fn getaddrinfo "const char *nodename" "const char *servname" \
+ "const struct addrinfo *hints" "struct addrinfo **res"
+ .Ft void
+ .Fn freeaddrinfo "struct addrinfo *ai"
+ .Ft "char *"
+ .Fn gai_strerror "int ecode"
+ .Sh DESCRIPTION
+ The
+ .Fn getaddrinfo
+ function is defined for protocol-independent nodename-to-address translation.
+ It performs functionality of 
+ .Xr gethostbyname 3
+ and
+ .Xr getservbyname 3 ,
+ in more sophisticated manner.
+ .Pp
+ The addrinfo structure is defined as a result of including the
+ .Li <netdb.h>
+ header:
+ .Bd -literal -offset
+ struct addrinfo {                                                  *
+      int     ai_flags;     /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
+      int     ai_family;    /* PF_xxx */
+      int     ai_socktype;  /* SOCK_xxx */
+      int     ai_protocol;  /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+      size_t  ai_addrlen;   /* length of ai_addr */
+      char   *ai_canonname; /* canonical name for nodename */
+      struct sockaddr  *ai_addr; /* binary address */
+      struct addrinfo  *ai_next; /* next structure in linked list */
+ };
+ .Ed
+ .Pp
+ The
+ .Fa nodename
+ and
+ .Fa servname
+ arguments are pointers to null-terminated strings or
+ .Dv NULL .
+ One or both of these two arguments must be a
+ .Pf non Dv -NULL
+ pointer.
+ In the normal client scenario, both the
+ .Fa nodename
+ and
+ .Fa servname
+ are specified.
+ In the normal server scenario, only the
+ .Fa servname
+ is specified.
+ A
+ .Pf non Dv -NULL
+ .Fa nodename
+ string can be either a node name or a numeric host address string
+ .Po
+ i.e., a dotted-decimal IPv4 address or an IPv6 hex address
+ .Pc .
+ A
+ .Pf non Dv -NULL
+ .Fa servname
+ string can be either a service name or a decimal port number.
+ .Pp
+ The caller can optionally pass an
+ .Li addrinfo
+ structure, pointed to by the third argument,
+ to provide hints concerning the type of socket that the caller supports.
+ In this
+ .Fa hints
+ structure all members other than
+ .Fa ai_flags ,
+ .Fa ai_family ,
+ .Fa ai_socktype ,
+ and
+ .Fa ai_protocol
+ must be zero or a
+ .Dv NULL
+ pointer.
+ A value of
+ .Dv PF_UNSPEC
+ for
+ .Fa ai_family
+ means the caller will accept any protocol family.
+ A value of 0 for
+ .Fa ai_socktype
+ means the caller will accept any socket type.
+ A value of 0 for
+ .Fa ai_protocol
+ means the caller will accept any protocol.
+ For example, if the caller handles only TCP and not UDP, then the
+ .Fa ai_socktype
+ member of the hints structure should be set to
+ .Dv SOCK_STREAM
+ when
+ .Fn getaddrinfo
+ is called.
+ If the caller handles only IPv4 and not IPv6, then the
+ .Fa ai_family
+ member of the
+ .Fa hints
+ structure should be set to
+ .Dv PF_INET
+ when
+ .Fn getaddrinfo
+ is called.
+ If the third argument to
+ .Fn getaddrinfo
+ is a
+ .Dv NULL
+ pointer, this is the same as if the caller had filled in an
+ .Li addrinfo
+ structure initialized to zero with
+ .Fa ai_family
+ set to PF_UNSPEC.
+ .Pp
+ Upon successful return a pointer to a linked list of one or more
+ .Li addrinfo
+ structures is returned through the final argument.
+ The caller can process each
+ .Li addrinfo
+ structure in this list by following the
+ .Fa ai_next
+ pointer, until a
+ .Dv NULL
+ pointer is encountered.
+ In each returned
+ .Li addrinfo
+ structure the three members
+ .Fa ai_family ,
+ .Fa ai_socktype ,
+ and
+ .Fa ai_protocol
+ are the corresponding arguments for a call to the
+ .Fn socket
+ function.
+ In each
+ .Li addrinfo
+ structure the
+ .Fa ai_addr
+ member points to a filled-in socket address structure whose length is
+ specified by the
+ .Fa ai_addrlen
+ member.
+ .Pp
+ If the
+ .Dv AI_PASSIVE
+ bit is set in the
+ .Fa ai_flags
+ member of the
+ .Fa hints
+ structure, then the caller plans to use the returned socket address
+ structure in a call to
+ .Fn bind .
+ In this case, if the
+ .Fa nodename
+ argument is a
+ .Dv NULL
+ pointer, then the IP address portion of the socket
+ address structure will be set to
+ .Dv INADDR_ANY
+ for an IPv4 address or
+ .Dv IN6ADDR_ANY_INIT
+ for an IPv6 address.
+ .Pp
+ If the
+ .Dv AI_PASSIVE
+ bit is not set in the
+ .Fa ai_flags
+ member of the
+ .Fa hints
+ structure, then the returned socket address structure will be ready for a
+ call to
+ .Fn connect
+ .Pq for a connection-oriented protocol
+ or either
+ .Fn connect ,
+ .Fn sendto , or
+ .Fn sendmsg
+ .Pq for a connectionless protocol .
+ In this case, if the
+ .Fa nodename
+ argument is a
+ .Dv NULL
+ pointer, then the IP address portion of the
+ socket address structure will be set to the loopback address.
+ .Pp
+ If the
+ .Dv AI_CANONNAME
+ bit is set in the
+ .Fa ai_flags
+ member of the
+ .Fa hints
+ structure, then upon successful return the
+ .Fa ai_canonname
+ member of the first
+ .Li addrinfo
+ structure in the linked list will point to a null-terminated string
+ containing the canonical name of the specified
+ .Fa nodename .
+ .Pp
+ If the
+ .Dv AI_NUMERICHOST
+ bit is set in the
+ .Fa ai_flags
+ member of the
+ .Fa hints
+ structure, then a
+ .Pf non Dv -NULL
+ .Fa nodename
+ string must be a numeric host address string.
+ Otherwise an error of
+ .Dv EAI_NONAME
+ is returned.
+ This flag prevents any type of name resolution service (e.g., the DNS)
+ from being called.                                               
+ .Pp
+ All of the information returned by
+ .Fn getaddrinfo
+ is dynamically allocated:
+ the
+ .Li addrinfo
+ structures, and the socket address structures and canonical node name
+ strings pointed to by the addrinfo structures.
+ To return this information to the system the function
+ Fn freeaddrinfo
+ is called.
+ The
+ .Fa addrinfo
+ structure pointed to by the
+ .Fa ai argument
+ is freed, along with any dynamic storage pointed to by the structure.
+ This operation is repeated until a
+ .Dv NULL
+ .Fa ai_next
+ pointer is encountered.
+ .Pp
+ To aid applications in printing error messages based on the
+ .Dv EAI_xxx
+ codes returned by
+ .Fn getaddrinfo ,
+ .Fn gai_strerror
+ is defined.
+ The argument is one of the
+ .Dv EAI_xxx
+ values defined earlier and the return value points to a string describing
+ the error.
+ If the argument is not one of the
+ .Dv EAI_xxx
+ values, the function still returns a pointer to a string whose contents
+ indicate an unknown error.
+ .Sh FILES
+ .Bl -tag -width /etc/resolv.conf -compact
+ .It Pa /etc/hosts
+ .It Pa /etc/host.conf
+ .It Pa /etc/resolv.conf
+ .El
+ .Sh DIAGNOSTICS
+ Error return status from 
+ .Fn getaddrinfo
+ is zero on success and non-zero on errors.
+ Non-zero error codes are defined in
+ .Li <netdb.h> ,
+ and as follows:
+ .Pp
+ .Bl -tag -width EAI_ADDRFAMILY -compact
+ .It Dv EAI_ADDRFAMILY 
+ address family for nodename not supported
+ .It Dv EAI_AGAIN
+ temporary failure in name resolution
+ .It Dv EAI_BADFLAGS
+ invalid value for ai_flags
+ .It Dv EAI_FAIL
+ non-recoverable failure in name resolution
+ .It Dv EAI_FAMILY
+ ai_family not supported
+ .It Dv EAI_MEMORY
+ memory allocation failure
+ .It Dv EAI_NODATA
+ no address associated with nodename
+ .It Dv EAI_NONAME
+ nodename nor servname provided, or not known
+ .It Dv EAI_SERVICE
+ servname not supported for ai_socktype
+ .It Dv EAI_SOCKTYPE
+ ai_socktype not supported
+ .It Dv EAI_SYSTEM
+ system error returned in errno
+ .El
+ .Pp
+ If called with proper argument,
+ .Fn gai_strerror
+ returns a pointer to a string describing the given error code.
+ If the argument is not one of the
+ .Dv EAI_xxx
+ values, the function still returns a pointer to a string whose contents
+ indicate an unknown error.
+ .Sh SEE ALSO
+ .Xr getnameinfo 3 ,
+ .Xr gethostbyname 3 ,
+ .Xr getservbyname 3 ,
+ .Xr hosts 5 ,
+ .Xr services 5 ,
+ .Xr hostname 7 ,
+ .Xr named 8
+ .Pp
+ R. Gilligan, S.  Thomson, J. Bound, and W. Stevens,
+ ``Basic Socket Interface Extensions for IPv6,'' RFC2133, April 1997.
+ .Sh HISTORY
+ The implementation first appeared in WIDE Hydrangea IPv6 protocol stack kit.
+ .Sh STANDARDS
+ The
+ .Fn getaddrinfo
+ function is defined IEEE POSIX 1003.1g draft specification,
+ and documented in ``Basic Socket Interface Extensions for IPv6''
+ .Pq RFC2133 .
+ .Sh BUGS
+ The text was shamelessly copied from RFC2133.
Index: bind8/src/lib/irs/getaddrinfo.c
diff -c /dev/null bind8/src/lib/irs/getaddrinfo.c:1.1
*** /dev/null	Fri Jun  4 08:02:58 1999
--- bind8/src/lib/irs/getaddrinfo.c	Fri Dec 25 14:20:59 1998
***************
*** 0 ****
--- 1,554 ----
+ /*
+  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 3. Neither the name of the project nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ /*
+  * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator.
+  *
+  * Issues to be discussed:
+  * - Thread safe-ness must be checked.
+  * - Return values.  There are nonstandard return values defined and used
+  *   in the source code.  This is because RFC2133 is silent about which error
+  *   code must be returned for which situation.
+  * - PF_UNSPEC case would be handled in getipnodebyname() with the AI_ALL flag.
+  */
+ 
+ #include <sys/types.h>
+ #include <sys/param.h>
+ #include <sys/sysctl.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ #include <arpa/nameser.h>
+ #include <netdb.h>
+ #include <resolv.h>
+ #include <string.h>
+ #include <stdlib.h>
+ #include <stddef.h>
+ #include <ctype.h>
+ #include <unistd.h>
+ 
+ #ifdef __KAME__
+ # define FAITH
+ #endif
+ 
+ #define SUCCESS 0
+ #define ANY 0
+ #define YES 1
+ #define NO  0
+ 
+ #ifdef FAITH
+ static int translate = NO;
+ static struct in6_addr faith_prefix = IN6ADDR_ANY_INIT;
+ #endif
+ 
+ static const char in_addrany[] = { 0, 0, 0, 0 };
+ static const char in6_addrany[] = {
+ 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+ static const char in_loopback[] = { 127, 0, 0, 1 }; 
+ static const char in6_loopback[] = {
+ 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
+ };
+ 
+ struct sockinet {
+ 	u_char	si_len;
+ 	u_char	si_family;
+ 	u_short	si_port;
+ };
+ 
+ static struct afd {
+ 	int a_af;
+ 	int a_addrlen;
+ 	int a_socklen;
+ 	int a_off;
+ 	const char *a_addrany;
+ 	const char *a_loopback;	
+ } afdl [] = {
+ #define N_INET6 0
+ 	{PF_INET6, sizeof(struct in6_addr),
+ 	 sizeof(struct sockaddr_in6),
+ 	 offsetof(struct sockaddr_in6, sin6_addr),
+ 	 in6_addrany, in6_loopback},
+ #define N_INET  1
+ 	{PF_INET, sizeof(struct in_addr),
+ 	 sizeof(struct sockaddr_in),
+ 	 offsetof(struct sockaddr_in, sin_addr),
+ 	 in_addrany, in_loopback},
+ 	{0, 0, 0, 0, NULL, NULL},
+ };
+ 
+ 
+ static int get_name __P((const char *, struct afd *,
+ 			  struct addrinfo **, char *, struct addrinfo *,
+ 			  int));
+ static int get_addr __P((const char *, int, struct addrinfo **,
+ 			struct addrinfo *, int));
+ static int str_isnumber __P((const char *));
+ 	
+ static char *ai_errlist[] = {
+ 	"success.",
+ 	"address family for hostname not supported.",	/* EAI_ADDRFAMILY */
+ 	"temporary failure in name resolution.",	/* EAI_AGAIN      */
+ 	"invalid value for ai_flags.",		       	/* EAI_BADFLAGS   */
+ 	"non-recoverable failure in name resolution.", 	/* EAI_FAIL       */
+ 	"ai_family not supported.",			/* EAI_FAMILY     */
+ 	"memory allocation failure.", 			/* EAI_MEMORY     */
+ 	"no address associated with hostname.", 	/* EAI_NODATA     */
+ 	"hostname nor servname provided, or not known.",/* EAI_NONAME     */
+ 	"servname not supported for ai_socktype.",	/* EAI_SERVICE    */
+ 	"ai_socktype not supported.", 			/* EAI_SOCKTYPE   */
+ 	"system error returned in errno.", 		/* EAI_SYSTEM     */
+ 	"invalid value for hints.",			/* EAI_BADHINTS	  */
+ 	"resolved protocol is unknown.",		/* EAI_PROTOCOL   */
+ 	"unknown error.", 				/* EAI_MAX        */
+ };
+ 
+ #define GET_CANONNAME(ai, str) \
+ if (pai->ai_flags & AI_CANONNAME) {\
+ 	if (((ai)->ai_canonname = (char *)malloc(strlen(str) + 1)) != NULL) {\
+ 		strcpy((ai)->ai_canonname, (str));\
+ 	} else {\
+ 		error = EAI_MEMORY;\
+ 		goto free;\
+ 	}\
+ }
+ 
+ #define GET_AI(ai, afd, addr, port) {\
+ 	char *p;\
+ 	if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\
+ 					      ((afd)->a_socklen)))\
+ 	    == NULL) goto free;\
+ 	memcpy(ai, pai, sizeof(struct addrinfo));\
+ 	(ai)->ai_addr = (struct sockaddr *)((ai) + 1);\
+ 	memset((ai)->ai_addr, 0, (afd)->a_socklen);\
+ 	(ai)->ai_addr->sa_len = (ai)->ai_addrlen = (afd)->a_socklen;\
+ 	(ai)->ai_addr->sa_family = (ai)->ai_family = (afd)->a_af;\
+ 	((struct sockinet *)(ai)->ai_addr)->si_port = port;\
+ 	p = (char *)((ai)->ai_addr);\
+ 	memcpy(p + (afd)->a_off, (addr), (afd)->a_addrlen);\
+ }
+ 
+ #define ERR(err) { error = (err); goto bad; }
+ 
+ char *
+ gai_strerror(ecode)
+ 	int ecode;
+ {
+ 	if (ecode < 0 || ecode > EAI_MAX)
+ 		ecode = EAI_MAX;
+ 	return ai_errlist[ecode];
+ }
+ 
+ void
+ freeaddrinfo(ai)
+ 	struct addrinfo *ai;
+ {
+ 	struct addrinfo *next;
+ 
+ 	do {
+ 		next = ai->ai_next;
+ 		if (ai->ai_canonname)
+ 			free(ai->ai_canonname);
+ 		/* no need to free(ai->ai_addr) */
+ 		free(ai);
+ 	} while ((ai = next) != NULL);
+ }
+ 
+ static int
+ str_isnumber(p)
+ 	const char *p;
+ {
+ 	char *q = (char *)p;
+ 	while (*q) {
+ 		if (! isdigit(*q))
+ 			return NO;
+ 		q++;
+ 	}
+ 	return YES;
+ }
+ 
+ int
+ getaddrinfo(hostname, servname, hints, res)
+ 	const char *hostname, *servname;
+ 	const struct addrinfo *hints;
+ 	struct addrinfo **res;
+ {
+ 	struct addrinfo sentinel;
+ 	struct addrinfo *top = NULL;
+ 	struct addrinfo *cur;
+ 	int i, error = 0;
+ 	char pton[sizeof(struct in6_addr)];
+ 	struct addrinfo ai;
+ 	struct addrinfo *pai;
+ 	u_short port;
+ 
+ #ifdef FAITH
+ 	static int firsttime = 1;
+ 
+ 	if (firsttime) {
+ 		/* translator hack */
+ 		{
+ 			char *q = getenv("GAI");
+ 			if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1)
+ 				translate = YES;
+ 		}
+ 		firsttime = 0;
+ 	}
+ #endif
+ 
+ 	/* initialize file static vars */
+ 	sentinel.ai_next = NULL;
+ 	cur = &sentinel;
+ 	pai = &ai;
+ 	pai->ai_flags = 0;
+ 	pai->ai_family = PF_UNSPEC;
+ 	pai->ai_socktype = ANY;
+ 	pai->ai_protocol = ANY;
+ 	pai->ai_addrlen = 0;
+ 	pai->ai_canonname = NULL;
+ 	pai->ai_addr = NULL;
+ 	pai->ai_next = NULL;
+ 	port = ANY;
+ 	
+ 	if (hostname == NULL && servname == NULL)
+ 		return EAI_NONAME;
+ 	if (hints) {
+ 		/* error check for hints */
+ 		if (hints->ai_addrlen || hints->ai_canonname ||
+ 		    hints->ai_addr || hints->ai_next)
+ 			ERR(EAI_BADHINTS); /* xxx */
+ 		if (hints->ai_flags & ~AI_MASK)
+ 			ERR(EAI_BADFLAGS);
+ 		if (hints->ai_family != PF_UNSPEC &&
+ 		    hints->ai_family != PF_INET   &&
+ 		    hints->ai_family != PF_INET6)
+ 			ERR(EAI_FAMILY);
+ 		memcpy(pai, hints, sizeof(*pai));
+ 		switch (pai->ai_socktype) {
+ 		case ANY:
+ 			switch (pai->ai_protocol) {
+ 			case ANY:
+ 				break;
+ 			case IPPROTO_UDP:
+ 				pai->ai_socktype = SOCK_DGRAM;
+ 				break;
+ 			case IPPROTO_TCP:
+ 				pai->ai_socktype = SOCK_STREAM;
+ 				break;
+ 			default:
+ 				pai->ai_socktype = SOCK_RAW;
+ 				break;
+ 			}
+ 			break;
+ 		case SOCK_RAW:
+ 			break;
+ 		case SOCK_DGRAM:
+ 			if (pai->ai_protocol != IPPROTO_UDP &&
+ 			    pai->ai_protocol != ANY)
+ 				ERR(EAI_BADHINTS);	/*xxx*/
+ 			pai->ai_protocol = IPPROTO_UDP;
+ 			break;
+ 		case SOCK_STREAM:
+ 			if (pai->ai_protocol != IPPROTO_TCP &&
+ 			    pai->ai_protocol != ANY)
+ 				ERR(EAI_BADHINTS);	/*xxx*/
+ 			pai->ai_protocol = IPPROTO_TCP;
+ 			break;
+ 		default:
+ 			ERR(EAI_SOCKTYPE);
+ 			break;
+ 		}
+ 	}
+ 
+ 	/*
+ 	 * service port
+ 	 */
+ 	if (servname) {
+ 		if (str_isnumber(servname)) {
+ 			if (pai->ai_socktype == ANY) {
+ 				/* caller accept *ANY* socktype */
+ 				pai->ai_socktype = SOCK_DGRAM;
+ 				pai->ai_protocol = IPPROTO_UDP;
+ 			}
+ 			port = htons(atoi(servname));
+ 		} else {
+ 			struct servent *sp;
+ 			char *proto;
+ 
+ 			proto = NULL;
+ 			switch (pai->ai_socktype) {
+ 			case ANY:
+ 				proto = NULL;
+ 				break;
+ 			case SOCK_DGRAM:
+ 				proto = "udp";
+ 				break;
+ 			case SOCK_STREAM:
+ 				proto = "tcp";
+ 				break;
+ 			default:
+ 				fprintf(stderr, "panic!\n");
+ 				break;
+ 			}
+ 			if ((sp = getservbyname(servname, proto)) == NULL)
+ 				ERR(EAI_SERVICE);
+ 			port = sp->s_port;
+ 			if (pai->ai_socktype == ANY)
+ 				if (strcmp(sp->s_proto, "udp") == 0) {
+ 					pai->ai_socktype = SOCK_DGRAM;
+ 					pai->ai_protocol = IPPROTO_UDP;
+ 				} else if (strcmp(sp->s_proto, "tcp") == 0) {
+ 					pai->ai_socktype = SOCK_STREAM;
+ 					pai->ai_protocol = IPPROTO_TCP;
+ 				} else
+ 					ERR(EAI_PROTOCOL);	/*xxx*/
+ 		}
+ 	}
+ 	
+ 	/*
+ 	 * hostname == NULL.
+ 	 * passive socket -> anyaddr (0.0.0.0 or ::)
+ 	 * non-passive socket -> localhost (127.0.0.1 or ::1)
+ 	 */
+ 	if (hostname == NULL) {
+ 		struct afd *afd;
+ 
+ 		for (afd = &afdl[0]; afd->a_af; afd++) {
+ 			if (!(pai->ai_family == PF_UNSPEC
+ 			   || pai->ai_family == afd->a_af)) {
+ 				continue;
+ 			}
+ 
+ 			if (pai->ai_flags & AI_PASSIVE) {
+ 				GET_AI(cur->ai_next, afd, afd->a_addrany, port);
+ 				/* xxx meaningless?
+ 				 * GET_CANONNAME(cur->ai_next, "anyaddr");
+ 				 */
+ 			} else {
+ 				GET_AI(cur->ai_next, afd, afd->a_loopback,
+ 					port);
+ 				GET_CANONNAME(cur->ai_next, "localhost");
+ 			}
+ 			cur = cur->ai_next;
+ 		}
+ 		top = sentinel.ai_next;
+ 		if (top)
+ 			goto good;
+ 		else
+ 			ERR(EAI_FAMILY);
+ 	}
+ 	
+ 	/* hostname as numeric name */
+ 	for (i = 0; afdl[i].a_af; i++) {
+ 		if (inet_pton(afdl[i].a_af, hostname, pton)) {
+ 			u_long v4a;
+ 			u_char pfx;
+ 
+ 			switch (afdl[i].a_af) {
+ 			case AF_INET:
+ 				v4a = ((struct in_addr *)pton)->s_addr;
+ 				if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
+ 					pai->ai_flags &= ~AI_CANONNAME;
+ 				v4a >>= IN_CLASSA_NSHIFT;
+ 				if (v4a == 0 || v4a == IN_LOOPBACKNET)
+ 					pai->ai_flags &= ~AI_CANONNAME;
+ 				break;
+ 			case AF_INET6:
+ 				pfx = ((struct in6_addr *)pton)->s6_addr8[0];
+ 				if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
+ 					pai->ai_flags &= ~AI_CANONNAME;
+ 				break;
+ 			}
+ 			
+ 			if (pai->ai_family == afdl[i].a_af ||
+ 			    pai->ai_family == PF_UNSPEC) {
+ 				if (! (pai->ai_flags & AI_CANONNAME)) {
+ 					GET_AI(top, &afdl[i], pton, port);
+ 					goto good;
+ 				}
+ 				/*
+ 				 * if AI_CANONNAME and if reverse lookup
+ 				 * fail, return ai anyway to pacify
+ 				 * calling application.
+ 				 */
+ 				get_name(pton, &afdl[i], &top, pton, pai, port);
+ 				goto good;
+ 			} else 
+ 				ERR(EAI_FAMILY);	/*xxx*/
+ 		}
+ 	}
+ 
+ 	if (pai->ai_flags & AI_NUMERICHOST)
+ 		ERR(EAI_NONAME);
+ 
+ 	/* hostname as alphabetical name */
+ 	error = get_addr(hostname, pai->ai_family, &top, pai, port);
+ 	if (error == 0) {
+ 		if (top) {
+  good:
+ 			*res = top;
+ 			return SUCCESS;
+ 		} else
+ 			error = EAI_FAIL;
+ 	}
+  free:
+ 	if (top)
+ 		freeaddrinfo(top);
+  bad:
+ 	*res = NULL;
+ 	return error;
+ }
+ 
+ static int
+ get_name(addr, afd, res, numaddr, pai, port0)
+ 	const char *addr;
+ 	struct afd *afd;
+ 	struct addrinfo **res;
+ 	char *numaddr;
+ 	struct addrinfo *pai;
+ 	int port0;
+ {
+ 	u_short port = port0 & 0xffff;
+ 	struct hostent *hp;
+ 	struct addrinfo *cur;
+ 	int error = 0, h_error;
+ 	
+ 	if ((hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error)) &&
+ 	    hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
+ 		GET_AI(cur, afd, hp->h_addr_list[0], port);
+ 		GET_CANONNAME(cur, hp->h_name);
+ 	} else
+ 		GET_AI(cur, afd, numaddr, port);
+ 	
+ 	if (hp)
+ 		freehostent(hp);
+ 	*res = cur;
+ 	return SUCCESS;
+  free:
+ 	if (cur)
+ 		freeaddrinfo(cur);
+ 	if (hp)
+ 		freehostent(hp);
+  /* bad: */
+ 	*res = NULL;
+ 	return error;
+ }
+ 
+ static int
+ get_addr(hostname, af, res, pai, port0)
+ 	const char *hostname;
+ 	int af;
+ 	struct addrinfo **res;
+ 	struct addrinfo *pai;
+ 	int port0;
+ {
+ 	u_short port = port0 & 0xffff;
+ 	struct addrinfo sentinel;
+ 	struct hostent *hp;
+ 	struct addrinfo *top, *cur;
+ 	struct afd *afd;
+ 	int i, error = 0, h_error;
+ 	char *ap;
+ 
+ 	top = NULL;
+ 	sentinel.ai_next = NULL;
+ 	cur = &sentinel;
+ 	if (af == AF_UNSPEC)
+ 		hp = getipnodebyname(hostname, AF_INET6,
+ 				AI_ADDRCONFIG|AI_ALL|AI_V4MAPPED, &h_error);
+ 	else
+ 		hp = getipnodebyname(hostname, af, AI_ADDRCONFIG, &h_error);
+ 	if (hp == NULL) {
+ 		switch (h_error) {
+ 		case HOST_NOT_FOUND:
+ 		case NO_DATA:
+ 			error = EAI_NODATA;
+ 			break;
+ 		case TRY_AGAIN:
+ 			error = EAI_AGAIN;
+ 			break;
+ 		case NO_RECOVERY:
+ 		default:
+ 			error = EAI_FAIL;
+ 			break;
+ 		}
+ 		goto bad;
+ 	}
+ 
+ 	if ((hp->h_name == NULL) || (hp->h_name[0] == 0) ||
+ 	    (hp->h_addr_list[0] == NULL))
+ 		ERR(EAI_FAIL);
+ 	
+ 	for (i = 0; (ap = hp->h_addr_list[i]) != NULL; i++) {
+ 		switch (af) {
+ 		case AF_INET6:
+ 			afd = &afdl[N_INET6];
+ 			break;
+ 		case AF_INET:
+ 			afd = &afdl[N_INET];
+ 			break;
+ 		default:	/* AF_UNSPEC */
+ 			if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) {
+ 				ap += sizeof(struct in6_addr) -
+ 					sizeof(struct in_addr);
+ 				afd = &afdl[N_INET];
+ 			} else
+ 				afd = &afdl[N_INET6];
+ 			break;
+ 		}
+ #ifdef FAITH
+ 		if (translate && afd->a_af == AF_INET) {
+ 			struct in6_addr *in6;
+ 
+ 			GET_AI(cur->ai_next, &afdl[N_INET6], ap, port);
+ 			in6 = &((struct sockaddr_in6 *)cur->ai_next->ai_addr)->sin6_addr;
+ 			memcpy(&in6->s6_addr32[0], &faith_prefix,
+ 			    sizeof(struct in6_addr) - sizeof(struct in_addr));
+ 			memcpy(&in6->s6_addr32[3], ap, sizeof(struct in_addr));
+ 		} else
+ #endif /* FAITH */
+ 		GET_AI(cur->ai_next, afd, ap, port);
+ 		if (cur == &sentinel) {
+ 			top = cur->ai_next;
+ 			GET_CANONNAME(top, hp->h_name);
+ 		}
+ 		cur = cur->ai_next;
+ 	}
+ 	freehostent(hp);
+ 	*res = top;
+ 	return SUCCESS;
+  free:
+ 	if (top)
+ 		freeaddrinfo(top);
+ 	if (hp)
+ 		freehostent(hp);
+  bad:
+ 	*res = NULL;
+ 	return error;
+ }
Index: bind8/src/lib/irs/getnameinfo.3
diff -c /dev/null bind8/src/lib/irs/getnameinfo.3:1.1
*** /dev/null	Fri Jun  4 08:02:59 1999
--- bind8/src/lib/irs/getnameinfo.3	Fri Dec 25 14:20:59 1998
***************
*** 0 ****
--- 1,201 ----
+ .\" Copyright (c) 1983, 1987, 1991, 1993
+ .\"	The Regents of the University of California.  All rights reserved.
+ .\"
+ .\" Redistribution and use in source and binary forms, with or without
+ .\" modification, are permitted provided that the following conditions
+ .\" are met:
+ .\" 1. Redistributions of source code must retain the above copyright
+ .\"    notice, this list of conditions and the following disclaimer.
+ .\" 2. Redistributions in binary form must reproduce the above copyright
+ .\"    notice, this list of conditions and the following disclaimer in the
+ .\"    documentation and/or other materials provided with the distribution.
+ .\" 3. All advertising materials mentioning features or use of this software
+ .\"    must display the following acknowledgement:
+ .\"	This product includes software developed by the University of
+ .\"	California, Berkeley and its contributors.
+ .\" 4. Neither the name of the University nor the names of its contributors
+ .\"    may be used to endorse or promote products derived from this software
+ .\"    without specific prior written permission.
+ .\"
+ .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ .\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ .\" SUCH DAMAGE.
+ .\"
+ .\"     From: @(#)gethostbyname.3	8.4 (Berkeley) 5/25/95
+ .\"     $Id: getnameinfo.3,v 1.1.2.2.4.1 1998/08/30 23:07:25 onoe Exp $
+ .\"
+ .Dd May 25, 1995
+ .Dt GETNAMEINFO 3
+ .Os KAME
+ .Sh NAME
+ .Nm getnameinfo
+ .Nd address-to-nodename translation in protocol-independent manner
+ .Sh SYNOPSIS
+ .Fd #include <sys/socket.h>
+ .Fd #include <netdb.h>
+ .Ft int
+ .Fn getnameinfo "const struct sockaddr *sa" "socklen_t salen" \
+ "char *host" "size_t hostlen" "char *serv" "size_t servlen" "int flags"
+ .Sh DESCRIPTION
+ The
+ .Fn getnameinfo
+ function is defined for protocol-independent address-to-nodename translation.
+ Its functionality is a reverse conversion of
+ .Xr getaddrinfo 3 ,
+ and implements similar functionality with
+ .Xr gethostbyaddr 3 and
+ .Xr getservbyport 3 
+ in more sophisticated manner.
+ .Pp
+ This function looks up an IP address and port number provided by the
+ caller in the DNS and system-specific database, and returns text
+ strings for both in buffers provided by the caller.
+ The function indicates successful completion by a zero return value;
+ a non-zero return value indicates failure.
+ .Pp
+ The first argument,
+ .Fa sa ,
+ points to either a
+ .Fa sockaddr_in
+ structure (for IPv4) or a
+ .Fa sockaddr_in6
+ structure (for IPv6) that holds the IP address and port number.
+ The
+ .Fa salen
+ argument gives the length of the
+ .Fa sockaddr_in
+ or
+ .Fa sockaddr_in6
+ structure.
+ .Pp
+ The function returns the nodename associated with the IP address in
+ the buffer pointed to by the
+ .Fa host
+ argument.
+ The caller provides the size of this buffer via the
+ .Fa hostlen
+ argument.
+ The service name associated with the port number is returned in the buffer
+ pointed to by
+ .Fa serv ,
+ and the
+ .Fa servlen
+ argument gives the length of this buffer.
+ The caller specifies not to return either string by providing a zero
+ value for the
+ .Fa hostlen
+ or
+ .Fa servlen
+ arguments.
+ Otherwise, the caller must provide buffers large enough to hold the
+ nodename and the  service name, including the terminating null characters.
+ .Pp
+ Unfortunately most systems do not provide constants that specify the
+ maximum size of either a fully-qualified domain name or a service name.
+ Therefore to aid the application in allocating buffers for these two
+ returned strings the following constants are defined in
+ .Li <netdb.h> :
+ .Bd -literal -offset
+ #define NI_MAXHOST  1025
+ #define NI_MAXSERV    32
+ .Ed
+ .Pp
+ The first value is actually defined as the constant
+ .Dv MAXDNAME
+ in recent versions of BIND's
+ .Li <arpa/nameser.h>
+ header
+ .Po
+ older versions of BIND define this constant to be 256
+ .Pc
+ and the second is a guess based on the services listed in the current
+ Assigned Numbers RFC.
+ .Pp
+ The final argument is a
+ .Fa flag
+ that changes the default actions of this function.
+ By default the fully-qualified domain name (FQDN) for the host is
+ looked up in the DNS and returned.
+ If the flag bit
+ .Dv NI_NOFQDN
+ is set, only the nodename portion of the FQDN is returned for local hosts.
+ .Pp
+ If the
+ .Fa flag
+ bit
+ .Dv NI_NUMERICHOST
+ is set, or if the host's name cannot be located in the DNS,
+ the numeric form of the host's address is returned instead of its name
+ .Po
+ e.g., by calling
+ .Fn inet_ntop
+ instead of 
+ .Fn getnodebyaddr
+ .Pc .
+ If the
+ .Fa flag
+ bit
+ .Dv NI_NAMEREQD
+ is set, an error is returned if the host's name cannot be located in the DNS.
+ .Pp
+ If the flag bit
+ .Dv NI_NUMERICSERV
+ is set, the numeric form of the service address is returned
+ .Pq e.g., its port number
+ instead of its name.
+ The two
+ .Dv NI_NUMERICxxx
+ flags are required to support the
+ .Li "-n"
+ flag that many commands provide.
+ .Pp
+ A fifth flag bit,
+ .Dv NI_DGRAM ,
+ specifies that the service is a datagram service, and causes
+ .Fn getservbyport
+ to be called with a second argument of "udp" instead of its default of "tcp".
+ This is required for the few ports (512-514)
+ that have different services for UDP and TCP.
+ .Pp
+ These
+ .Dv NI_xxx
+ flags are defined in
+ .Li <netdb.h> .
+ .Sh FILES
+ .Bl -tag -width /etc/resolv.conf -compact
+ .It Pa /etc/hosts
+ .It Pa /etc/host.conf
+ .It Pa /etc/resolv.conf
+ .El
+ .Sh DIAGNOSTICS
+ The function indicates successful completion by a zero return value;
+ a non-zero return value indicates failure.
+ .Sh SEE ALSO
+ .Xr getaddrinfo 3 ,
+ .Xr gethostbyaddr 3 ,
+ .Xr getservbyport 3 ,
+ .Xr hosts 5 ,
+ .Xr services 5 ,
+ .Xr hostname 7 ,
+ .Xr named 8
+ .Pp
+ R. Gilligan, S.  Thomson, J. Bound, and W. Stevens,
+ ``Basic Socket Interface Extensions for IPv6,'' RFC2133, April 1997.
+ .Sh HISTORY
+ The implementation first appeared in WIDE Hydrangea IPv6 protocol stack kit.
+ .Sh STANDARDS
+ The
+ .Fn getaddrinfo
+ function is defined IEEE POSIX 1003.1g draft specification,
+ and documented in ``Basic Socket Interface Extensions for IPv6''
+ .Pq RFC2133 .
+ .Sh BUGS
+ The text was shamelessly copied from RFC2133.
Index: bind8/src/lib/irs/getnameinfo.c
diff -c /dev/null bind8/src/lib/irs/getnameinfo.c:1.1
*** /dev/null	Fri Jun  4 08:03:00 1999
--- bind8/src/lib/irs/getnameinfo.c	Fri Dec 25 14:20:59 1998
***************
*** 0 ****
--- 1,188 ----
+ /*
+  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 3. Neither the name of the project nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ /*
+  * Issues to be discussed:
+  * - Thread safe-ness must be checked
+  * - Return values.  There seems to be no standard for return value (RFC2133)
+  *   but INRIA implementation returns EAI_xxx defined for getaddrinfo().
+  */
+ 
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ #include <arpa/nameser.h>
+ #include <netdb.h>
+ #include <resolv.h>
+ #include <string.h>
+ #include <stddef.h>
+ 
+ #define SUCCESS 0
+ #define ANY 0
+ #define YES 1
+ #define NO  0
+ 
+ static struct afd {
+ 	int a_af;
+ 	int a_addrlen;
+ 	int a_socklen;
+ 	int a_off;
+ } afdl [] = {
+ 	{PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
+ 		offsetof(struct sockaddr_in6, sin6_addr)},
+ 	{PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
+ 		offsetof(struct sockaddr_in, sin_addr)},
+ 	{0, 0, 0},
+ };
+ 
+ struct sockinet {
+ 	u_char	si_len;
+ 	u_char	si_family;
+ 	u_short	si_port;
+ };
+ 
+ #define ENI_NOSOCKET 	0
+ #define ENI_NOSERVNAME	1
+ #define ENI_NOHOSTNAME	2
+ #define ENI_MEMORY	3
+ #define ENI_SYSTEM	4
+ #define ENI_FAMILY	5
+ #define ENI_SALEN	6
+ 
+ int
+ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
+ 	const struct sockaddr *sa;
+ 	size_t salen;
+ 	char *host;
+ 	size_t hostlen;
+ 	char *serv;
+ 	size_t servlen;
+ 	int flags;
+ {
+ 	struct afd *afd;
+ 	struct servent *sp;
+ 	struct hostent *hp;
+ 	u_short port;
+ 	int family, len, i;
+ 	char *addr, *p;
+ 	u_long v4a;
+ 	u_char pfx;
+ 	int h_error;
+ 	static char numserv[512];
+ 	static char numaddr[512];
+ 
+ 	if (sa == NULL)
+ 		return ENI_NOSOCKET;
+ 
+ 	len = sa->sa_len;
+ 	if (len != salen) return ENI_SALEN;
+ 	
+ 	family = sa->sa_family;
+ 	for (i = 0; afdl[i].a_af; i++)
+ 		if (afdl[i].a_af == family) {
+ 			afd = &afdl[i];
+ 			goto found;
+ 		}
+ 	return ENI_FAMILY;
+ 	
+  found:
+ 	if (len != afd->a_socklen) return ENI_SALEN;
+ 	
+ 	port = ((struct sockinet *)sa)->si_port; /* network byte order */
+ 	addr = (char *)sa + afd->a_off;
+ 
+ 	if (serv == NULL || servlen == 0) {
+ 		/* what we should do? */
+ 	} else if (flags & NI_NUMERICSERV) {
+ 		snprintf(numserv, sizeof(numserv), "%d", ntohs(port));
+ 		if (strlen(numserv) > servlen)
+ 			return ENI_MEMORY;
+ 		strcpy(serv, numserv);
+ 	} else {
+ 		sp = getservbyport(port, (flags & NI_DGRAM) ? "udp" : "tcp");
+ 		if (sp) {
+ 			if (strlen(sp->s_name) > servlen)
+ 				return ENI_MEMORY;
+ 			strcpy(serv, sp->s_name);
+ 		} else
+ 			return ENI_NOSERVNAME;
+ 	}
+ 
+ 	switch (sa->sa_family) {
+ 	case AF_INET:
+ 		v4a = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
+ 		if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
+ 			flags |= NI_NUMERICHOST;
+ 		v4a >>= IN_CLASSA_NSHIFT;
+ 		if (v4a == 0 || v4a == IN_LOOPBACKNET)
+ 			flags |= NI_NUMERICHOST;			
+ 		break;
+ 	case AF_INET6:
+ 		pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr8[0];
+ 		if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
+ 			flags |= NI_NUMERICHOST;
+ 		break;
+ 	}
+ 	if (host == NULL || hostlen == 0) {
+ 		/* what should we do? */
+ 	} else if (flags & NI_NUMERICHOST) {
+ 		if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
+ 		    == NULL)
+ 			return ENI_SYSTEM;
+ 		if (strlen(numaddr) > hostlen)
+ 			return ENI_MEMORY;
+ 		strcpy(host, numaddr);
+ 	} else {
+ 		hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error);
+ 
+ 		if (hp) {
+ 			if (flags & NI_NOFQDN) {
+ 				p = strchr(hp->h_name, '.');
+ 				if (p) *p = '\0';
+ 			}
+ 			if (strlen(hp->h_name) > hostlen) {
+ 				freehostent(hp);
+ 				return ENI_MEMORY;
+ 			}
+ 			strcpy(host, hp->h_name);
+ 			freehostent(hp);
+ 		} else {
+ 			if (flags & NI_NAMEREQD)
+ 				return ENI_NOHOSTNAME;
+ 			if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
+ 			    == NULL)
+ 				return ENI_NOHOSTNAME;
+ 			if (strlen(numaddr) > hostlen)
+ 				return ENI_MEMORY;
+ 			strcpy(host, numaddr);
+ 		}
+ 	}
+ 	return SUCCESS;
+ }
Index: bind8/src/lib/irs/lcl_ho.c
diff -c bind8/src/lib/irs/lcl_ho.c:1.1.1.1 bind8/src/lib/irs/lcl_ho.c:1.3
*** bind8/src/lib/irs/lcl_ho.c:1.1.1.1	Fri Sep 25 14:25:04 1998
--- bind8/src/lib/irs/lcl_ho.c	Fri Sep 25 20:48:37 1998
***************
*** 52,58 ****
  /* BIND Id: gethnamaddr.c,v 8.15 1996/05/22 04:56:30 vixie Exp $ */
  
  #if defined(LIBC_SCCS) && !defined(lint)
! static char rcsid[] = "$Id: lcl_ho.c,v 1.15 1997/12/04 04:57:56 halley Exp $";
  #endif /* LIBC_SCCS and not lint */
  
  /* Imports. */
--- 52,58 ----
  /* BIND Id: gethnamaddr.c,v 8.15 1996/05/22 04:56:30 vixie Exp $ */
  
  #if defined(LIBC_SCCS) && !defined(lint)
! static char rcsid[] = "$Id: lcl_ho.c,v 1.2 1998/09/25 08:17:15 k-sugyou Exp $";
  #endif /* LIBC_SCCS and not lint */
  
  /* Imports. */
***************
*** 321,328 ****
--- 321,332 ----
  	if (!(cp = strpbrk(p, " \t")))
  		goto again;
  	*cp++ = '\0';
+ #ifdef INET6
+ 	if (inet_pton(AF_INET6, p, pvt->host_addr) > 0) {
+ #else
  	if ((_res.options & RES_USE_INET6) &&
  	    inet_pton(AF_INET6, p, pvt->host_addr) > 0) {
+ #endif
  		af = AF_INET6;
  		len = IN6ADDRSZ;
  	} else if (inet_aton(p, (struct in_addr *)pvt->host_addr) > 0) {
Index: bind8/src/lib/irs/name6.c
diff -c /dev/null bind8/src/lib/irs/name6.c:1.1
*** /dev/null	Fri Jun  4 08:03:01 1999
--- bind8/src/lib/irs/name6.c	Fri Dec 25 14:20:59 1998
***************
*** 0 ****
--- 1,1409 ----
+ /* $Id: name6.c,v 1.1.2.3.2.7.2.9 1998/10/12 09:44:14 onoe Exp $ */
+ /*
+  *	Atsushi Onoe <onoe@sm.sony.co.jp>
+  */
+ 
+ /*
+  * TODO for thread safe
+  *	use mutex for _hostconf, _hostconf_init if HOSTCONF is defined.
+  *	rewrite resolvers to be thread safe
+  */
+ 
+ #define	MAPPED_ADDR_ENABLED	/* XXX: for __KAME__ */
+ 
+ #include <sys/param.h>
+ #include <sys/socket.h>
+ #include <sys/time.h>
+ #include <netinet/in.h>
+ 
+ #include <netdb.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <unistd.h>
+ #include <arpa/inet.h>
+ #include <arpa/nameser.h>
+ #include <resolv.h>
+ 
+ #ifndef _PATH_HOSTS
+ #define	_PATH_HOSTS	"/etc/hosts"
+ #endif
+ 
+ #ifndef MAXALIASES
+ #define	MAXALIASES	10
+ #endif
+ #ifndef	MAXADDRS
+ #define	MAXADDRS	20
+ #endif
+ #ifndef MAXDNAME
+ #define	MAXDNAME	1025
+ #endif
+ 
+ #define	ADDRLEN(af)	((af) == AF_INET6 ? sizeof(struct in6_addr) : \
+ 					    sizeof(struct in_addr))
+ #define	MAPADDR(ab, ina) {						\
+ 	memcpy(&(ab)->map_inaddr, ina, sizeof(struct in_addr));		\
+ 	memset((ab)->map_zero, 0, sizeof((ab)->map_zero));		\
+ 	memset((ab)->map_one, 0xff, sizeof((ab)->map_one));		\
+ }
+ #define	MAPADDRENABLED(flags) \
+ 	((flags & AI_V4MAPPED) || \
+ 	 ((flags & AI_V4MAPPED_CFG) && _mapped_addr_enabled()))
+ 
+ union inx_addr {
+ 	struct in_addr	in_addr;
+ 	struct in6_addr	in6_addr;
+ 	struct {
+ 		u_char	mau_zero[10];
+ 		u_char	mau_one[2];
+ 		struct in_addr mau_inaddr;
+ 	}		map_addr_un;
+ #define	map_zero	map_addr_un.mau_zero
+ #define	map_one		map_addr_un.mau_one
+ #define	map_inaddr	map_addr_un.mau_inaddr
+ };
+ 
+ static struct hostent *_hpcopy(struct hostent *hp, int *errp);
+ static struct hostent *_hpaddr(int af, const char *name, void *addr, int *errp);
+ static struct hostent *_hpmerge(struct hostent *hp1, struct hostent *hp2, int *errp);
+ static struct hostent *_hpmapv6(struct hostent *hp, int *errp);
+ static struct hostent *_hpsort(struct hostent *hp);
+ static struct hostent *_ghbyname(const char *name, int af, int flags, int *errp);
+ static char *_hgetword(char **pp);
+ static int _mapped_addr_enabled(void);
+ 
+ static FILE *_files_open(int *errp);
+ static struct hostent *_files_ghbyname(const char *name, int af, int *errp);
+ static struct hostent *_files_ghbyaddr(const void *addr, int addrlen, int af, int *errp);
+ static void _files_shent(int stayopen);
+ static void _files_ehent(void);
+ #ifdef DNS
+ static struct hostent *_dns_ghbyname(const char *name, int af, int *errp);
+ static struct hostent *_dns_ghbyaddr(const void *addr, int addrlen, int af, int *errp);
+ static void _dns_shent(int stayopen);
+ static void _dns_ehent(void);
+ #endif /* DNS */
+ #ifdef ICMPNL
+ static struct hostent *_icmp_ghbyaddr(const void *addr, int addrlen, int af, int *errp);
+ #endif /* ICMPNL */
+ 
+ /*
+  * Select order host function.
+  */
+ #define	MAXHOSTCONF	4
+ 
+ #ifndef HOSTCONF
+ # ifdef __FreeBSD__
+ #  define	HOSTCONF	"/etc/host.conf"
+ # endif
+ # ifdef __bsdi__
+ #  define	HOSTCONF	"/etc/irs.conf"
+ #  define	HOSTCONF_KWD	"hosts"
+ # endif
+ # ifdef __NetBSD__
+ #  define	HOSTCONF	"/etc/resolv.conf"
+ #  define	HOSTCONF_KWD	"lookup"
+ # endif
+ # ifdef __sony_news
+ #  define	HOSTCONF	"/etc/nsswitch.conf"
+ #  define	HOSTCONF_KWD	"hosts:"
+ # endif
+ #endif /* !HOSTCONF */
+ 
+ struct _hostconf {
+ 	struct hostent *(*byname)(const char *name, int af, int *errp);
+ 	struct hostent *(*byaddr)(const void *addr, int addrlen, int af, int *errp);
+ };
+ 
+ /* default order */
+ static struct _hostconf _hostconf[MAXHOSTCONF] = {
+ #ifdef DNS
+ 	{ _dns_ghbyname,	_dns_ghbyaddr },
+ #endif /* DNS */
+ 	{ _files_ghbyname,	_files_ghbyaddr },
+ #ifdef ICMPNL
+ 	{ NULL,			_icmp_ghbyaddr },
+ #endif /* ICMPNL */
+ };
+ 
+ #ifdef HOSTCONF
+ static int _hostconf_init_done;
+ static void _hostconf_init(void);
+ 
+ /*
+  * Initialize hostconf structure.
+  */
+ 
+ static void
+ _hostconf_init(void)
+ {
+ 	FILE *fp;
+ 	int n;
+ 	char *p, *line;
+ 	char buf[BUFSIZ];
+ 
+ 	_hostconf_init_done = 1;
+ #ifdef HOSTCONF_KWD
+ 	n = -1;
+ #else /* HOSTCONF_KWD */
+ 	n = 0;
+ #endif /* HOSTCONF_KWD */
+ #ifdef __V6D__
+ 	if ((p = getenv("V6ROOT")) != NULL) {
+ 		strcpy(buf, p);
+ 		strcat(buf, HOSTCONF);
+ 		p = buf;
+ 	} else
+ #endif /* __V6D__ */
+ 	p = HOSTCONF;
+ 	if ((fp = fopen(p, "r")) == NULL)
+ 		return;
+ 	while (n < MAXHOSTCONF && fgets(buf, sizeof(buf), fp)) {
+ 		line = buf;
+ 		if ((p = _hgetword(&line)) == NULL)
+ 			continue;
+ #ifdef HOSTCONF_KWD
+ 		if (strcmp(p, HOSTCONF_KWD) != 0)
+ 			continue;
+ 		if (n < 0)
+ 			n = 0;
+ 		if ((p = _hgetword(&line)) == NULL)
+ 			continue;
+ #endif /* HOSTCONF_KWD */
+ 
+ 		do {
+ 			if (strcmp(p, "hosts") == 0
+ 			||  strcmp(p, "local") == 0
+ 			||  strcmp(p, "file") == 0
+ 			||  strcmp(p, "files") == 0) {
+ 				_hostconf[n].byname = _files_ghbyname;
+ 				_hostconf[n].byaddr = _files_ghbyaddr;
+ 				n++;
+ 			}
+ #ifdef DNS
+ 			else if (strcmp(p, "dns") == 0
+ 			     ||  strcmp(p, "bind") == 0) {
+ 				_hostconf[n].byname = _dns_ghbyname;
+ 				_hostconf[n].byaddr = _dns_ghbyaddr;
+ 				n++;
+ 			}
+ #endif /* DNS */
+ #ifdef ICMPNL
+ 			else if (strcmp(p, "icmp") == 0) {
+ 				_hostconf[n].byname = NULL;
+ 				_hostconf[n].byaddr = _icmp_ghbyaddr;
+ 				n++;
+ 			}
+ #endif /* ICMPNL */
+ 		} while ((p = _hgetword(&line)) != NULL);
+ 	}
+ 	fclose(fp);
+ 	if (n < 0) {
+ 		/* no keyword found. do not change default configuration */
+ 		return;
+ 	}
+ 	for (; n < MAXHOSTCONF; n++) {
+ 		_hostconf[n].byname = NULL;
+ 		_hostconf[n].byaddr = NULL;
+ 	}
+ }
+ #endif /* HOSTCONF */
+ 
+ /*
+  * Check if kernel supports mapped address.
+  *	implementation dependent
+  */
+ #ifdef __KAME__
+ #include <sys/sysctl.h>
+ #endif /* __KAME__ */
+ 
+ static int
+ _mapped_addr_enabled(void)
+ {
+ 	/* implementation dependent check */
+ #if defined(__KAME__) && defined(IPV6CTL_MAPPED_ADDR)
+ 	int mib[4];
+ 	int len, val;
+ 
+ 	mib[0] = CTL_NET;
+ 	mib[1] = PF_INET6;
+ 	mib[2] = IPPROTO_IPV6;
+ 	mib[3] = IPV6CTL_MAPPED_ADDR;
+ 	len = sizeof(val);
+ 	if (sysctl(mib, 4, &val, &len, 0, 0) == 0 && val != 0)
+ 		return 1;
+ #endif /* __KAME__ && IPV6CTL_MAPPED_ADDR */
+ 	return 0;
+ }
+ 
+ /*
+  * Functions defined in draft-ietf-ipngwg-bsd-api-new-02a.txt
+  *	getipnodebyname, getipnodebyaddr, freehostent
+  */
+ 
+ static struct hostent *
+ _ghbyname(const char *name, int af, int flags, int *errp)
+ {
+ 	struct hostent *hp;
+ 	int i;
+ 
+ 	if (flags & AI_ADDRCONFIG) {
+ 		int s;
+ 
+ 		if ((s = socket(af, SOCK_DGRAM, 0)) < 0)
+ 			return NULL;
+ 		/*
+ 		 * TODO:
+ 		 * Note that implementation dependent test for address
+ 		 * configuration should be done everytime called
+ 		 * (or apropriate interval),
+ 		 * because addresses will be dynamically assigned or deleted.
+ 		 */
+ 		close(s);
+ 	}
+ 
+ 	for (i = 0; i < MAXHOSTCONF; i++) {
+ 		if (_hostconf[i].byname
+ 		&&  (hp = (*_hostconf[i].byname)(name, af, errp)) != NULL)
+ 			return hp;
+ 	}
+ 
+ 	return NULL;
+ }
+ 
+ struct hostent *
+ getipnodebyname(const char *name, int af, int flags, int *errp)
+ {
+ 	struct hostent *hp;
+ 	union inx_addr addrbuf;
+ 
+ 	if (af != AF_INET && af != AF_INET6) {
+ 		*errp = NO_RECOVERY;
+ 		return NULL;
+ 	}
+ 
+ 	/* special case for literal address */
+ 	if (inet_pton(AF_INET6, name, &addrbuf) > 0) {
+ 		if (af != AF_INET6) {
+ 			*errp = HOST_NOT_FOUND;
+ 			return NULL;
+ 		}
+ 		return _hpaddr(af, name, &addrbuf, errp);
+ 	}
+ 	if (inet_pton(AF_INET, name, &addrbuf) > 0) {
+ 		if (af != AF_INET) {
+ 			if (MAPADDRENABLED(flags)) {
+ 				MAPADDR(&addrbuf, &addrbuf.in_addr);
+ 			} else {
+ 				*errp = HOST_NOT_FOUND;
+ 				return NULL;
+ 			}
+ 		}
+ 		return _hpaddr(af, name, &addrbuf, errp);
+ 	}
+ 
+ #ifdef HOSTCONF
+ 	if (!_hostconf_init_done)
+ 		_hostconf_init();
+ #endif /* HOSTCONF */
+ 
+ 	*errp = HOST_NOT_FOUND;
+ 	hp = _ghbyname(name, af, flags, errp);
+ 
+ 	if (af == AF_INET6
+ 	&&  ((flags & AI_ALL) || hp == NULL)
+ 	&&  (MAPADDRENABLED(flags))) {
+ 		struct hostent *hp2 = _ghbyname(name, AF_INET, flags, errp);
+ 		if (hp == NULL)
+ 			hp = _hpmapv6(hp2, errp);
+ 		else {
+ 			if (hp2 && strcmp(hp->h_name, hp2->h_name) != 0) {
+ 				freehostent(hp2);
+ 				hp2 = NULL;
+ 			}
+ 			hp = _hpmerge(hp, hp2, errp);
+ 		}
+ 	}
+ 	return _hpsort(hp);
+ }
+ 
+ struct hostent *
+ getipnodebyaddr(const void *src, size_t len, int af, int *errp)
+ {
+ 	struct hostent *hp;
+ 	int i;
+ 	struct in6_addr addrbuf;
+ 
+ 	*errp = HOST_NOT_FOUND;
+ 
+ 	switch (af) {
+ 	case AF_INET:
+ 		if (len != sizeof(struct in_addr)) {
+ 			*errp = NO_RECOVERY;
+ 			return NULL;
+ 		}
+ 		if ((int)src & ~(sizeof(struct in_addr) - 1)) {
+ 			memcpy(&addrbuf, src, len);
+ 			src = &addrbuf;
+ 		}
+ 		if (((struct in_addr *)src)->s_addr == 0)
+ 			return NULL;
+ 		break;
+ 	case AF_INET6:
+ 		if (len != sizeof(struct in6_addr)) {
+ 			*errp = NO_RECOVERY;
+ 			return NULL;
+ 		}
+ 		if ((int)src & ~(sizeof(struct in6_addr) / 2 - 1)) {	/*XXX*/
+ 			memcpy(&addrbuf, src, len);
+ 			src = &addrbuf;
+ 		}
+ 		if (IN6_IS_ADDR_UNSPECIFIED((struct in6_addr *)src))
+ 			return NULL;
+ 		if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)src)
+ 		||  IN6_IS_ADDR_V4COMPAT((struct in6_addr *)src)) {
+ 			src = (char *)src +
+ 			    (sizeof(struct in6_addr) - sizeof(struct in_addr));
+ 			af = AF_INET;
+ 			len = sizeof(struct in_addr);
+ 		}
+ 		break;
+ 	default:
+ 		*errp = NO_RECOVERY;
+ 		return NULL;
+ 	}
+ 
+ #ifdef HOSTCONF
+ 	if (!_hostconf_init_done)
+ 		_hostconf_init();
+ #endif /* HOSTCONF */
+ 	for (i = 0; i < MAXHOSTCONF; i++) {
+ 		if (_hostconf[i].byaddr
+ 		&&  (hp = (*_hostconf[i].byaddr)(src, len, af, errp)) != NULL)
+ 			return hp;
+ 	}
+ 
+ 	return NULL;
+ }
+ 
+ void
+ freehostent(struct hostent *ptr)
+ {
+ 	free(ptr);
+ }
+ 
+ /*
+  * Functions for compatibility.
+  *	gethostbyname, gethostbyname2, gethostbyaddr
+  *	sethostent, endhostent, gethostent
+  */
+ 
+ /* hostent pointer for non thread-safe functions */
+ static struct hostent *saved_hp;
+ 
+ #if 0
+ struct hostent *
+ gethostbyname2(const char *name, int af)
+ {
+ 	union inx_addr addrbuf;
+ 
+ 	if (saved_hp != NULL)
+ 		freehostent(saved_hp);
+ 
+ 	/* special case for literal address */
+ 	/* XXX: use inet_aton to handle nonstandard format for IPv4 */
+ 	if ((af == AF_INET ? inet_aton(name, &addrbuf.in_addr) :
+ 			     inet_pton(af, name, &addrbuf)) > 0)
+ 		return _hpaddr(af, name, &addrbuf, &h_errno);
+ 
+ 	h_errno = HOST_NOT_FOUND;
+ 	saved_hp = _ghbyname(name, af, 0, &h_errno);
+ 
+ 	if (af == AF_INET && saved_hp != NULL) {
+ 		if ((_res.options & RES_INIT) == 0)
+ 			(void)res_init();
+ 		if (_res.options & RES_USE_INET6)
+ 			saved_hp = _hpmapv6(saved_hp, &h_errno);
+ 	}
+ 	return saved_hp;
+ }
+ 
+ struct hostent *
+ gethostbyname(const char *name)
+ {
+ 	struct hostent *hp;
+ 
+ 	if ((_res.options & RES_INIT) == 0)
+ 		(void)res_init();
+ 
+ 	if (_res.options & RES_USE_INET6) {
+ 		hp = gethostbyname2(name, AF_INET6);
+ 		if (hp != NULL)
+ 			return hp;
+ 	}
+ 	return gethostbyname2(name, AF_INET);
+ }
+ 
+ struct hostent *
+ gethostbyaddr(const char *src, int len, int af)
+ {
+ 
+ 	if (saved_hp != NULL)
+ 		freehostent(saved_hp);
+ 	saved_hp = getipnodebyaddr(src, len, af, &h_errno);
+ 	if (af == AF_INET && saved_hp != NULL) {
+ 		if ((_res.options & RES_INIT) == 0)
+ 			(void)res_init();
+ 		if (_res.options & RES_USE_INET6)
+ 			saved_hp = _hpmapv6(saved_hp, &h_errno);
+ 	}
+ 	return saved_hp;
+ }
+ 
+ void
+ sethostent(int stayopen)
+ {
+ 	_files_shent(stayopen);
+ #ifdef DNS
+ 	_dns_shent(stayopen);
+ #endif /* DNS */
+ }
+ 
+ void
+ endhostent(void)
+ {
+ 	_files_ehent();
+ #ifdef DNS
+ 	_dns_ehent();
+ #endif /* DNS */
+ }
+ #endif
+ 
+ /* XXX: should be deprecated */
+ struct hostent *
+ getnodebyname(const char *name, int af, int flags)
+ {
+ 	return getipnodebyname(name, af, flags, &h_errno);
+ }
+ 
+ struct hostent *
+ getnodebyaddr(const void *src, size_t len, int af)
+ {
+ 	return getipnodebyaddr(src, len, af, &h_errno);
+ }
+ 
+ /*
+  * Private utility functions
+  */
+ 
+ /*
+  * _hpcopy: allocate and copy hostent structure
+  */
+ static struct hostent *
+ _hpcopy(struct hostent *hp, int *errp)
+ {
+ 	struct hostent *nhp;
+ 	char *cp, **pp;
+ 	int size, addrsize;
+ 	int nalias = 0, naddr = 0;
+ 	int al_off;
+ 	int i;
+ 
+ 	if (hp == NULL)
+ 		return hp;
+ 
+ 	/* count size to be allocated */
+ 	size = sizeof(struct hostent);
+ 	if (hp->h_name != NULL && *hp->h_name != '\0')
+ 		size += strlen(hp->h_name) + 1;
+ 	if ((pp = hp->h_aliases) != NULL) {
+ 		for (i = 0; *pp != NULL; i++, pp++) {
+ 			if (**pp != '\0') {
+ 				size += strlen(*pp) + 1;
+ 				nalias++;
+ 			}
+ 		}
+ 	}
+ 	/* adjust alignment */
+ 	size = ALIGN(size);
+ 	al_off = size;
+ 	size += sizeof(char *) * (nalias + 1);
+ 	addrsize = ALIGN(hp->h_length);
+ 	if ((pp = hp->h_addr_list) != NULL) {
+ 		while (*pp++ != NULL)
+ 			naddr++;
+ 	}
+ 	size += addrsize * naddr;
+ 	size += sizeof(char *) * (naddr + 1);
+ 
+ 	/* copy */
+ 	if ((nhp = (struct hostent *)malloc(size)) == NULL) {
+ 		*errp = TRY_AGAIN;
+ 		return NULL;
+ 	}
+ 	cp = (char *)&nhp[1];
+ 	if (hp->h_name != NULL && *hp->h_name != '\0') {
+ 		nhp->h_name = cp;
+ 		strcpy(cp, hp->h_name);
+ 		cp += strlen(cp) + 1;
+ 	} else
+ 		nhp->h_name = NULL;
+ 	nhp->h_aliases = (char **)((char *)nhp + al_off);
+ 	if ((pp = hp->h_aliases) != NULL) {
+ 		for (i = 0; *pp != NULL; pp++) {
+ 			if (**pp != '\0') {
+ 				nhp->h_aliases[i++] = cp;
+ 				strcpy(cp, *pp);
+ 				cp += strlen(cp) + 1;
+ 			}
+ 		}
+ 	}
+ 	nhp->h_aliases[nalias] = NULL;
+ 	cp = (char *)&nhp->h_aliases[nalias + 1];
+ 	nhp->h_addrtype = hp->h_addrtype;
+ 	nhp->h_length = hp->h_length;
+ 	nhp->h_addr_list = (char **)cp;
+ 	if ((pp = hp->h_addr_list) != NULL) {
+ 		cp = (char *)&nhp->h_addr_list[naddr + 1];
+ 		for (i = 0; *pp != NULL; pp++) {
+ 			nhp->h_addr_list[i++] = cp;
+ 			memcpy(cp, *pp, hp->h_length);
+ 			cp += addrsize;
+ 		}
+ 	}
+ 	nhp->h_addr_list[naddr] = NULL;
+ 	return nhp;
+ }
+ 
+ /*
+  * _hpaddr: construct hostent structure with one address
+  */
+ static struct hostent *
+ _hpaddr(int af, const char *name, void *addr, int *errp)
+ {
+ 	struct hostent *hp, hpbuf;
+ 	char *addrs[2];
+ 
+ 	hp = &hpbuf;
+ 	hp->h_name = (char *)name;
+ 	hp->h_aliases = NULL;
+ 	hp->h_addrtype = af;
+ 	hp->h_length = ADDRLEN(af);
+ 	hp->h_addr_list = addrs;
+ 	addrs[0] = (char *)addr;
+ 	addrs[1] = NULL;
+ 	return _hpcopy(hp, errp);
+ }
+ 
+ /*
+  * _hpmerge: merge 2 hostent structure, arguments will be freed
+  */
+ static struct hostent *
+ _hpmerge(struct hostent *hp1, struct hostent *hp2, int *errp)
+ {
+ 	int i, j;
+ 	int naddr, nalias;
+ 	char **pp;
+ 	struct hostent *hp, hpbuf;
+ 	char *aliases[MAXALIASES + 1], *addrs[MAXADDRS + 1];
+ 	union inx_addr addrbuf[MAXADDRS];
+ 
+ 	if (hp1 == NULL)
+ 		return hp2;
+ 	if (hp2 == NULL)
+ 		return hp1;
+ 
+ #define	HP(i)	(i == 1 ? hp1 : hp2)
+ 	hp = &hpbuf;
+ 	hp->h_name = (hp1->h_name != NULL ? hp1->h_name : hp2->h_name);
+ 	hp->h_aliases = aliases;
+ 	nalias = 0;
+ 	for (i = 1; i <= 2; i++) {
+ 		if ((pp = HP(i)->h_aliases) == NULL)
+ 			continue;
+ 		for (; nalias < MAXALIASES && *pp != NULL; pp++) {
+ 			/* check duplicates */
+ 			for (j = 0; j < nalias; j++)
+ 				if (strcasecmp(*pp, aliases[j]) == 0)
+ 					break;
+ 			if (j == nalias)
+ 				aliases[nalias++] = *pp;
+ 		}
+ 	}
+ 	aliases[nalias] = NULL;
+ 	if (hp1->h_length != hp2->h_length) {
+ 		hp->h_addrtype = AF_INET6;
+ 		hp->h_length = sizeof(struct in6_addr);
+ 	} else {
+ 		hp->h_addrtype = hp1->h_addrtype;
+ 		hp->h_length = hp1->h_length;
+ 	}
+ 	hp->h_addr_list = addrs;
+ 	naddr = 0;
+ 	for (i = 1; i <= 2; i++) {
+ 		if ((pp = HP(i)->h_addr_list) == NULL)
+ 			continue;
+ 		if (HP(i)->h_length == hp->h_length) {
+ 			while (naddr < MAXADDRS && *pp != NULL)
+ 				addrs[naddr++] = *pp++;
+ 		} else {
+ 			/* copy IPv4 addr as mapped IPv6 addr */
+ 			while (naddr < MAXADDRS && *pp != NULL) {
+ 				MAPADDR(&addrbuf[naddr], *pp++);
+ 				addrs[naddr] = (char *)&addrbuf[naddr];
+ 				naddr++;
+ 			}
+ 		}
+ 	}
+ 	addrs[naddr] = NULL;
+ 	hp = _hpcopy(hp, errp);
+ 	freehostent(hp1);
+ 	freehostent(hp2);
+ 	return hp;
+ }
+ 
+ /*
+  * _hpmapv6: convert IPv4 hostent into IPv4-mapped IPv6 addresses
+  */
+ static struct hostent *
+ _hpmapv6(struct hostent *hp, int *errp)
+ {
+ 	struct hostent *hp6;
+ 
+ 	if (hp == NULL)
+ 		return NULL;
+ 	if (hp->h_addrtype == AF_INET6)
+ 		return hp;
+ 
+ 	/* make dummy hostent to convert IPv6 address */
+ 	if ((hp6 = (struct hostent *)malloc(sizeof(struct hostent))) == NULL) {
+ 		*errp = TRY_AGAIN;
+ 		return NULL;
+ 	}
+ 	hp6->h_name = NULL;
+ 	hp6->h_aliases = NULL;
+ 	hp6->h_addrtype = AF_INET6;
+ 	hp6->h_length = sizeof(struct in6_addr);
+ 	hp6->h_addr_list = NULL;
+ 	return _hpmerge(hp6, hp, errp);
+ }
+ 
+ /*
+  * _hpsort: sort address by sortlist
+  */
+ static struct hostent *
+ _hpsort(struct hostent *hp)
+ {
+ 	int i, j, n;
+ 	u_char *ap, *sp, *mp, **pp;
+ 	char t;
+ 	char order[MAXADDRS];
+ 
+ 	if (hp == NULL || hp->h_addr_list[1] == NULL || _res.nsort == 0)
+ 		return hp;
+ 	for (i = 0; (ap = (u_char *)hp->h_addr_list[i]); i++) {
+ 		for (j = 0; j < _res.nsort; j++) {
+ 			if (_res_ext.sort_list[j].af != hp->h_addrtype)
+ 				continue;
+ 			sp = (u_char *)&_res_ext.sort_list[j].addr;
+ 			mp = (u_char *)&_res_ext.sort_list[j].mask;
+ 			for (n = 0; n < hp->h_length; n++) {
+ 				if ((ap[n] & mp[n]) != sp[n])
+ 					break;
+ 			}
+ 			if (n == hp->h_length)
+ 				break;
+ 		}
+ 		order[i] = j;
+ 	}
+ 	n = i;
+ 	pp = (u_char **)hp->h_addr_list;
+ 	for (i = 0; i < n - 1; i++) {
+ 		for (j = i + 1; j < n; j++) {
+ 			if (order[i] > order[j]) {
+ 				ap = pp[i];
+ 				pp[i] = pp[j];
+ 				pp[j] = ap;
+ 				t = order[i];
+ 				order[i] = order[j];
+ 				order[j] = t;
+ 			}
+ 		}
+ 	}
+ 	return hp;
+ }
+ 
+ static char *
+ _hgetword(char **pp)
+ {
+ 	char c, *p, *ret;
+ 	const char *sp;
+ 	static const char sep[] = "# \t\n";
+ 
+ 	ret = NULL;
+ 	for (p = *pp; (c = *p) != '\0'; p++) {
+ 		for (sp = sep; *sp != '\0'; sp++) {
+ 			if (c == *sp)
+ 				break;
+ 		}
+ 		if (c == '#')
+ 			p[1] = '\0';	/* ignore rest of line */
+ 		if (ret == NULL) {
+ 			if (*sp == '\0')
+ 				ret = p;
+ 		} else {
+ 			if (*sp != '\0') {
+ 				*p++ = '\0';
+ 				break;
+ 			}
+ 		}
+ 	}
+ 	*pp = p;
+ 	if (ret == NULL || *ret == '\0')
+ 		return NULL;
+ 	return ret;
+ }
+ 
+ /*
+  * FILES (/etc/hosts)
+  */
+ 
+ static FILE *
+ _files_open(int *errp)
+ {
+ 	FILE *fp;
+ #ifdef __V6D__
+ 	char *p;
+ 	char path[BUFSIZ];
+ 
+ 	if ((p = getenv("V6ROOT")) != NULL) {
+ 		strcpy(path, p);
+ 		strcat(path, _PATH_HOSTS);
+ 		fp = fopen(path, "r");
+ 	} else
+ #endif /* __V6D__ */
+ 	fp = fopen(_PATH_HOSTS, "r");
+ 	if (fp == NULL)
+ 		*errp = NO_RECOVERY;
+ 	return fp;
+ }
+ 
+ static struct hostent *
+ _files_ghbyname(const char *name, int af, int *errp)
+ {
+ 	int match, nalias;
+ 	char *p, *line, *addrstr, *cname;
+ 	FILE *fp;
+ 	struct hostent *rethp, *hp, hpbuf;
+ 	char *aliases[MAXALIASES + 1], *addrs[2];
+ 	union inx_addr addrbuf;
+ 	char buf[BUFSIZ];
+ 
+ 	if ((fp = _files_open(errp)) == NULL)
+ 		return NULL;
+ 	rethp = hp = NULL;
+ 
+ 	while (fgets(buf, sizeof(buf), fp)) {
+ 		line = buf;
+ 		if ((addrstr = _hgetword(&line)) == NULL
+ 		||  (cname = _hgetword(&line)) == NULL)
+ 			continue;
+ 		match = (strcasecmp(cname, name) == 0);
+ 		nalias = 0;
+ 		while ((p = _hgetword(&line)) != NULL) {
+ 			if (!match)
+ 				match = (strcasecmp(p, name) == 0);
+ 			if (nalias < MAXALIASES)
+ 				aliases[nalias++] = p;
+ 		}
+ 		if (!match)
+ 			continue;
+ 		if (inet_pton(af, addrstr, &addrbuf) <= 0) {
+ 			*errp = NO_DATA;	/* name found */
+ 			continue;
+ 		}
+ 		hp = &hpbuf;
+ 		hp->h_name = cname;
+ 		hp->h_aliases = aliases;
+ 		aliases[nalias] = NULL;
+ 		hp->h_addrtype = af;
+ 		hp->h_length = ADDRLEN(af);
+ 		hp->h_addr_list = addrs;
+ 		addrs[0] = (char *)&addrbuf;
+ 		addrs[1] = NULL;
+ 		hp = _hpcopy(hp, errp);
+ 		rethp = _hpmerge(rethp, hp, errp);
+ 	}
+ 	fclose(fp);
+ 	return rethp;
+ }
+ 
+ static struct hostent *
+ _files_ghbyaddr(const void *addr, int addrlen, int af, int *errp)
+ {
+ 	int nalias;
+ 	char *p, *line;
+ 	FILE *fp;
+ 	struct hostent *hp, hpbuf;
+ 	char *aliases[MAXALIASES + 1], *addrs[2];
+ 	union inx_addr addrbuf;
+ 	char buf[BUFSIZ];
+ 
+ 	if ((fp = _files_open(errp)) == NULL)
+ 		return NULL;
+ 	hp = NULL;
+ 	while (fgets(buf, sizeof(buf), fp)) {
+ 		line = buf;
+ 		if ((p = _hgetword(&line)) == NULL
+ 		||  inet_pton(af, p, &addrbuf) <= 0
+ 		||  memcmp(addr, &addrbuf, addrlen) != 0
+ 		||  (p = _hgetword(&line)) == NULL)
+ 			continue;
+ 		hp = &hpbuf;
+ 		hp->h_name = p;
+ 		hp->h_aliases = aliases;
+ 		nalias = 0;
+ 		while ((p = _hgetword(&line)) != NULL) {
+ 			if (nalias < MAXALIASES)
+ 				aliases[nalias++] = p;
+ 		}
+ 		aliases[nalias] = NULL;
+ 		hp->h_addrtype = af;
+ 		hp->h_length = addrlen;
+ 		hp->h_addr_list = addrs;
+ 		addrs[0] = (char *)&addrbuf;
+ 		addrs[1] = NULL;
+ 		hp = _hpcopy(hp, errp);
+ 		break;
+ 	}
+ 	fclose(fp);
+ 	return hp;
+ }
+ 
+ /* compatibility */
+ static FILE *_files_fp;
+ 
+ static void
+ _files_shent(int stayopen)
+ {
+ 
+ 	if (_files_fp == NULL) {
+ 		_files_fp = _files_open(&h_errno);
+ 	} else
+ 		rewind(_files_fp);
+ }
+ 
+ static void
+ _files_ehent(void)
+ {
+ 	if (_files_fp != NULL) {
+ 		fclose(_files_fp);
+ 		_files_fp = NULL;
+ 	}
+ }
+ 
+ /* global function */
+ #if 0
+ struct hostent *
+ gethostent(void)
+ {
+ 	int af, nalias;
+ 	char *p, *line;
+ 	struct hostent *hp, hpbuf;
+ 	char *aliases[MAXALIASES + 1], *addrs[2];
+ 	union inx_addr addrbuf;
+ 	char buf[BUFSIZ];
+ 
+ 	if (_files_fp == NULL) {
+ 		if ((_files_fp = _files_open(&h_errno)) == NULL)
+ 			return NULL;
+ 	}
+ 	if (saved_hp != NULL) {
+ 		freehostent(saved_hp);
+ 		saved_hp = NULL;
+ 	}
+ 	while (fgets(buf, sizeof(buf), _files_fp)) {
+ 		line = buf;
+ 		if ((p = _hgetword(&line)) == NULL)
+ 			continue;
+ 		if (inet_pton((af = AF_INET), p, &addrbuf) <= 0) {
+ #ifdef notdef
+ 			/*
+ 			 * For compatibility, gethostent should not return
+ 			 * IPv6 addresses.
+ 			 */
+ 			if (inet_pton((af = AF_INET6), p, &addrbuf) <= 0)
+ #endif
+ 				continue;
+ 		}
+ 		if ((p = _hgetword(&line)) == NULL)
+ 			continue;
+ 		hp = &hpbuf;
+ 		hp->h_name = p;
+ 		hp->h_aliases = aliases;
+ 		nalias = 0;
+ 		while ((p = _hgetword(&line)) != NULL) {
+ 			if (nalias < MAXALIASES)
+ 				aliases[nalias++] = p;
+ 		}
+ 		aliases[nalias] = NULL;
+ 		hp->h_addrtype = af;
+ 		hp->h_length = ADDRLEN(af);
+ 		hp->h_addr_list = addrs;
+ 		addrs[0] = (char *)&addrbuf;
+ 		addrs[1] = NULL;
+ 		saved_hp = _hpcopy(hp, &h_errno);
+ 		break;
+ 	}
+ 	return saved_hp;
+ }
+ #endif
+ 
+ #ifdef DNS
+ 
+ #include <arpa/nameser.h>
+ #include <resolv.h>
+ 
+ #ifdef DEBUG
+ #define	DNS_ASSERT(X)	if (!(X)) { fprintf(stderr, "ASSFAIL: %s %d: %s\n", __FILE__, __LINE__, #X); goto badanswer; }
+ #else
+ #define	DNS_ASSERT(X)	if (!(X)) { goto badanswer; }
+ #endif
+ 
+ static struct hostent *
+ _dns_ghbyname(const char *name, int af, int *errp)
+ {
+ 	int n;
+ 	u_char answer[BUFSIZ];
+ 	char tbuf[MAXDNAME+1];
+ 	HEADER *hp;
+ 	u_char *cp, *eom;
+ 	int qtype;
+ 	int type, class, ancount, qdcount;
+ 	u_long ttl;
+ 	char hostbuf[BUFSIZ];
+ 	char *bp;
+ 	char *alist[MAXALIASES];
+ 	char *hlist[MAXADDRS];
+ 	struct hostent hbuf;
+ 	int buflen;
+ 	int na, nh;
+ 
+ 	if ((_res.options & RES_INIT) == 0) {
+ 		if (res_init() < 0) {
+ 			*errp = h_errno;
+ 			return NULL;
+ 		}
+ 	}
+ 	hbuf.h_aliases = alist;
+ 	hbuf.h_addrtype = af;
+ 	hbuf.h_length = ADDRLEN(af);
+ 	hbuf.h_addr_list = hlist;
+ 	na = nh = 0;
+ 
+ 	qtype = (af == AF_INET6 ? T_AAAA : T_A);
+ 	n = res_search(name, C_IN, qtype, answer, sizeof(answer));
+ 	if (n < 0) {
+ 		*errp = h_errno;
+ 		return NULL;
+ 	}
+ 	hp = (HEADER *)answer;
+ 	eom = answer + n;
+ 	ancount = ntohs(hp->ancount);
+ 	qdcount = ntohs(hp->qdcount);
+ 	DNS_ASSERT(qdcount == 1);
+ 	cp = answer + sizeof(HEADER);
+ 	bp = hostbuf;
+ 	buflen = sizeof(hostbuf);
+ 
+ 	n = dn_expand(answer, eom, cp, bp, buflen);
+ 	DNS_ASSERT(n >= 0);
+ 	cp += n + QFIXEDSZ;
+ 	hbuf.h_name = bp;
+ 	n = strlen(bp) + 1;
+ 	bp += n;
+ 	buflen -= n;
+ 	while (ancount-- > 0 && cp < eom) {
+ 		n = dn_expand(answer, eom, cp, bp, buflen);
+ 		DNS_ASSERT(n >= 0);
+ 		cp += n;		/* name */
+ 		type = _getshort(cp);
+ 		cp += 2;		/* type */
+ 		class = _getshort(cp);
+ 		cp += 2;		/* class */
+ 		ttl = _getlong(cp);
+ 		cp += 4;		/* ttl */
+ 		n = _getshort(cp);
+ 		cp += 2;		/* len */
+ 		DNS_ASSERT(class == C_IN);
+ 		switch (type) {
+ 		case T_CNAME:
+ 			if (na >= MAXALIASES-1) {
+ 				cp += n;
+ 				break;
+ 			}
+ 			n = dn_expand(answer, eom, cp, tbuf, sizeof(tbuf));
+ 			DNS_ASSERT(n >= 0);
+ 			cp += n;
+ 			/* alias */
+ 			alist[na++] = bp;
+ 			n = strlen(bp) + 1;
+ 			bp += n;
+ 			buflen -= n;
+ 			/* canon */
+ 			n = strlen(tbuf) + 1;
+ 			DNS_ASSERT(n < buflen);
+ 			strcpy(bp, tbuf);
+ 			hbuf.h_name = bp;
+ 			bp += n;
+ 			buflen -= n;
+ 			break;
+ 		case T_A:
+ 		case T_AAAA:
+ 			DNS_ASSERT(type == qtype);
+ 			bp = (char *)ALIGN(bp);
+ 			DNS_ASSERT(n == hbuf.h_length);
+ 			DNS_ASSERT(n < buflen);
+ 			if (nh < MAXADDRS-1) {
+ 				hlist[nh++] = bp;
+ 				memcpy(bp, cp, n);
+ 				bp += n;
+ 				buflen -= n;
+ 			}
+ 			cp += n;
+ 			break;
+ 		default:
+ 			DNS_ASSERT(0);
+ 			cp += n;
+ 			break;
+ 		}
+ 	}
+ 	if (nh == 0) {
+   badanswer:
+ 		*errp = NO_RECOVERY;
+ 		return NULL;
+ 	}
+ 	alist[na] = NULL;
+ 	hlist[nh] = NULL;
+ 	return _hpcopy(&hbuf, errp);
+ }
+ 
+ static struct hostent *
+ _dns_ghbyaddr(const void *addr, int addrlen, int af, int *errp)
+ {
+ 	int n;
+ 	u_char answer[BUFSIZ];
+ 	HEADER *hp;
+ 	u_char c, *cp, *eom;
+ 	int type, class, ancount, qdcount;
+ 	u_long ttl;
+ 	char hostbuf[BUFSIZ];
+ 	char *bp;
+ 	char *alist[MAXALIASES];
+ 	char *hlist[2];
+ 	struct hostent hbuf;
+ 	int buflen;
+ 	int na;
+ 	static const char hex[] = "0123456789abcdef";
+ 
+ 	/* XXX */
+ 	if (af == AF_INET6 && IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)addr))
+ 		return NULL;
+ 
+ 	if ((_res.options & RES_INIT) == 0) {
+ 		if (res_init() < 0) {
+ 			*errp = h_errno;
+ 			return NULL;
+ 		}
+ 	}
+ 	hbuf.h_name = NULL;
+ 	hbuf.h_aliases = alist;
+ 	hbuf.h_addrtype = af;
+ 	hbuf.h_length = addrlen;
+ 	hbuf.h_addr_list = hlist;
+ 	hlist[0] = (char *)addr;
+ 	hlist[1] = NULL;
+ 	na = 0;
+ 
+ 	n = 0;
+ 	bp = hostbuf;
+ 	cp = (u_char *)addr+addrlen-1;
+ 	if (af == AF_INET6) {
+ 		for (; n < addrlen; n++, cp--) {
+ 			c = *cp;
+ 			*bp++ = hex[c & 0xf];
+ 			*bp++ = '.';
+ 			*bp++ = hex[c >> 4];
+ 			*bp++ = '.';
+ 		}
+ 		strcpy(bp, "ip6.int");
+ 	} else {
+ 		for (; n < addrlen; n++, cp--) {
+ 			c = *cp;
+ 			if (c >= 100)
+ 				*bp++ = '0' + c / 100;
+ 			if (c >= 10)
+ 				*bp++ = '0' + (c % 100) / 10;
+ 			*bp++ = '0' + c % 10;
+ 			*bp++ = '.';
+ 		}
+ 		strcpy(bp, "in-addr.arpa");
+ 	}
+ 
+ 	n = res_query(hostbuf, C_IN, T_PTR, answer, sizeof(answer));
+ 	if (n < 0) {
+ 		*errp = h_errno;
+ 		return NULL;
+ 	}
+ 	hp = (HEADER *)answer;
+ 	eom = answer + n;
+ 	ancount = ntohs(hp->ancount);
+ 	qdcount = ntohs(hp->qdcount);
+ 	DNS_ASSERT(qdcount == 1);
+ 	cp = answer + sizeof(HEADER);
+ 	bp = hostbuf;
+ 	buflen = sizeof(hostbuf);
+ 
+ 	n = dn_expand(answer, eom, cp, bp, buflen);
+ 	DNS_ASSERT(n >= 0);
+ 	cp += n + QFIXEDSZ;
+ 	while (ancount-- > 0 && cp < eom) {
+ 		n = dn_expand(answer, eom, cp, bp, buflen);
+ 		DNS_ASSERT(n >= 0);
+ 		cp += n;		/* name */
+ 		type = _getshort(cp);
+ 		cp += 2;		/* type */
+ 		class = _getshort(cp);
+ 		cp += 2;		/* class */
+ 		ttl = _getlong(cp);
+ 		cp += 4;		/* ttl */
+ 		n = _getshort(cp);
+ 		cp += 2;		/* len */
+ 		DNS_ASSERT(class == C_IN);
+ 		switch (type) {
+ 		case T_PTR:
+ 			n = dn_expand(answer, eom, cp, bp, buflen);
+ 			DNS_ASSERT(n >= 0);
+ 			cp += n;
+ 			if (na >= MAXALIASES-1)
+ 				break;
+ 			if (hbuf.h_name == NULL)
+ 				hbuf.h_name = bp;
+ 			else
+ 				alist[na++] = bp;
+ 			n = strlen(bp) + 1;
+ 			bp += n;
+ 			buflen -= n;
+ 			break;
+ 		case T_CNAME:
+ 			cp += n;
+ 			break;
+ 		default:
+   badanswer:
+ 			*errp = NO_RECOVERY;
+ 			return NULL;
+ 		}
+ 	}
+ 	if (hbuf.h_name == NULL) {
+ 		*errp = h_errno;
+ 		return NULL;
+ 	}
+ 	alist[na] = NULL;
+ 	return _hpcopy(&hbuf, errp);
+ }
+ 
+ static void
+ _dns_shent(int stayopen)
+ {
+ 	if ((_res.options & RES_INIT) == 0) {
+ 		if (res_init() < 0)
+ 			return;
+ 	}
+ 	if (stayopen)
+ 		_res.options |= RES_STAYOPEN | RES_USEVC;
+ }
+ 
+ static void
+ _dns_ehent(void)
+ {
+ 	_res.options &= ~(RES_STAYOPEN | RES_USEVC);
+ 	res_close();
+ }
+ #endif /* DNS */
+ 
+ #ifdef ICMPNL
+ 
+ /*
+  * experimental:
+  *	draft-ietf-ipngwg-icmp-namelookups-02.txt
+  *	ifindex is assumed to be encoded in addr.
+  */
+ #include <sys/uio.h>
+ #include <netinet/ip6.h>
+ #include <netinet/icmp6.h>
+ 
+ struct _icmp_host_cache {
+ 	struct _icmp_host_cache *hc_next;
+ 	int hc_ifindex;
+ 	struct in6_addr hc_addr;
+ 	char *hc_name;
+ };
+ 
+ static char *
+ _icmp_fqdn_query(const struct in6_addr *addr, int ifindex)
+ {
+ 	int s;
+ 	struct icmp6_filter filter;
+ 	struct msghdr msg;
+ 	struct cmsghdr *cmsg;
+ 	struct in6_pktinfo *pkt;
+ 	char cbuf[256];
+ 	char buf[1024];
+ 	int cc;
+ 	struct icmp6_fqdn_query *fq;
+ 	struct icmp6_fqdn_reply *fr;
+ 	struct _icmp_host_cache *hc;
+ 	struct sockaddr_in6 sin6;
+ 	struct iovec iov;
+ 	fd_set s_fds, fds;
+ 	struct timeval tout;
+ 	int len;
+ 	char *name;
+ 	static int pid;
+ 	static struct _icmp_host_cache *hc_head;
+ 
+ 	for (hc = hc_head; hc; hc = hc->hc_next) {
+ 		if (hc->hc_ifindex == ifindex
+ 		&&  IN6_ARE_ADDR_EQUAL(&hc->hc_addr, addr))
+ 			return hc->hc_name;
+ 	}
+ 
+ 	if (pid == 0)
+ 		pid = getpid();
+ 
+ 	ICMP6_FILTER_SETBLOCKALL(&filter);
+ 	ICMP6_FILTER_SETPASS(ICMP6_FQDN_REPLY, &filter);
+ 
+ 	FD_ZERO(&s_fds);
+ 	tout.tv_sec = 0;
+ 	tout.tv_usec = 200000;	/*XXX: 200ms*/
+ 
+ 	fq = (struct icmp6_fqdn_query *)buf;
+ 	fq->icmp6_fqdn_type = ICMP6_FQDN_QUERY;
+ 	fq->icmp6_fqdn_code = 0;
+ 	fq->icmp6_fqdn_cksum = 0;
+ 	fq->icmp6_fqdn_id = (u_short)pid;
+ 	fq->icmp6_fqdn_unused = 0;
+ 	fq->icmp6_fqdn_cookie[0] = 0;
+ 	fq->icmp6_fqdn_cookie[1] = 0;
+ 
+ 	memset(&sin6, 0, sizeof(sin6));
+ 	sin6.sin6_family = AF_INET6;
+ 	sin6.sin6_addr = *addr;
+ 
+ 	memset(&msg, 0, sizeof(msg));
+ 	msg.msg_name = (caddr_t)&sin6;
+ 	msg.msg_namelen = sizeof(sin6);
+ 	msg.msg_iov = &iov;
+ 	msg.msg_iovlen = 1;
+ 	msg.msg_control = NULL;
+ 	msg.msg_controllen = 0;
+ 	iov.iov_base = (caddr_t)buf;
+ 	iov.iov_len = sizeof(struct icmp6_fqdn_query);
+ 
+ 	if (ifindex) {
+ 		msg.msg_control = cbuf;
+ 		msg.msg_controllen = sizeof(cbuf);
+ 		cmsg = CMSG_FIRSTHDR(&msg);
+ 		cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
+ 		cmsg->cmsg_level = IPPROTO_IPV6;
+ 		cmsg->cmsg_type = IPV6_PKTINFO;
+ 		pkt = (struct in6_pktinfo *)&cmsg[1];
+ 		memset(&pkt->ipi6_addr, 0, sizeof(struct in6_addr));
+ 		pkt->ipi6_ifindex = ifindex;
+ 		cmsg = CMSG_NXTHDR(&msg, cmsg);
+ 		msg.msg_controllen = (char *)cmsg - cbuf;
+ 	}
+ 
+ 	if ((s = socket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0)
+ 		return NULL;
+ 	(void)setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER,
+ 			 (char *)&filter, sizeof(filter));
+ 	cc = sendmsg(s, &msg, 0);
+ 	if (cc < 0) {
+ 		close(s);
+ 		return NULL;
+ 	}
+ 	FD_SET(s, &s_fds);
+ 	for (;;) {
+ 		fds = s_fds;
+ 		if (select(s + 1, &fds, NULL, NULL, &tout) <= 0) {
+ 			close(s);
+ 			return NULL;
+ 		}
+ 		len = sizeof(sin6);
+ 		cc = recvfrom(s, buf, sizeof(buf), 0,
+ 			      (struct sockaddr *)&sin6, &len);
+ 		if (cc <= 0) {
+ 			close(s);
+ 			return NULL;
+ 		}
+ 		if (cc < sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr))
+ 			continue;
+ 		if (!IN6_ARE_ADDR_EQUAL(addr, &sin6.sin6_addr))
+ 			continue;
+ 		fr = (struct icmp6_fqdn_reply *)(buf + sizeof(struct ip6_hdr));
+ 		if (fr->icmp6_fqdn_type == ICMP6_FQDN_REPLY)
+ 			break;
+ 	}
+ 	close(s);
+ 	if (fr->icmp6_fqdn_cookie[1] != 0) {
+ 		/* rfc1788 type */
+ 		name = buf + sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr) + 4;
+ 		len = (buf + cc) - name;
+ 	} else {
+ 		len = fr->icmp6_fqdn_namelen;
+ 		name = fr->icmp6_fqdn_name;
+ 	}
+ 	if (len <= 0)
+ 		return NULL;
+ 	name[len] = 0;
+ 
+ 	if ((hc = (struct _icmp_host_cache *)malloc(sizeof(*hc))) == NULL)
+ 		return NULL;
+ 	/* XXX: limit number of cached entries */
+ 	hc->hc_ifindex = ifindex;
+ 	hc->hc_addr = *addr;
+ 	hc->hc_name = strdup(name);
+ 	hc->hc_next = hc_head;
+ 	hc_head = hc;
+ 	return hc->hc_name;
+ }
+ 
+ static struct hostent *
+ _icmp_ghbyaddr(const void *addr, int addrlen, int af, int *errp)
+ {
+ 	char *hname;
+ 	int ifindex;
+ 	struct in6_addr addr6;
+ 
+ 	if (af != AF_INET6) {
+ 		/*
+ 		 * Note: rfc1788 defines Who Are You for IPv4,
+ 		 * but no one implements it.
+ 		 */
+ 		return NULL;
+ 	}
+ 
+ 	memcpy(&addr6, addr, addrlen);
+ 	ifindex = (addr6.s6_addr[2] << 8) | addr6.s6_addr[3];
+ 	addr6.s6_addr[2] = addr6.s6_addr[3] = 0;
+ 
+ 	if (!IN6_IS_ADDR_LINKLOCAL(&addr6))
+ 		return NULL;	/*XXX*/
+ 
+ 	if ((hname = _icmp_fqdn_query(&addr6, ifindex)) == NULL)
+ 		return NULL;
+ 	return _hpaddr(af, hname, &addr6, errp);
+ }
+ #endif /* ICMPNL */
Index: bind8/src/lib/isc/Makefile
diff -c bind8/src/lib/isc/Makefile:1.1.1.1 bind8/src/lib/isc/Makefile:1.2
*** bind8/src/lib/isc/Makefile:1.1.1.1	Fri Sep 25 14:25:05 1998
--- bind8/src/lib/isc/Makefile	Fri Sep 25 17:17:17 1998
***************
*** 13,19 ****
  # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  # SOFTWARE.
  
! # $Id: Makefile,v 8.15 1997/12/03 22:36:08 halley Exp $
  
  # these are only appropriate for BSD 4.4 or derivatives, and are used in
  # development.  normal builds will be done in the top level directory and
--- 13,19 ----
  # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  # SOFTWARE.
  
! # $Id: Makefile,v 1.1.1.1 1998/09/25 05:25:05 k-sugyou Exp $
  
  # these are only appropriate for BSD 4.4 or derivatives, and are used in
  # development.  normal builds will be done in the top level directory and
***************
*** 26,37 ****
  CC= cc
  LD= ld
  SHELL= /bin/sh
! CDEBUG= -g
  TOP= ../..
  INCL = ${TOP}/include
  PORTINCL = ${TOP}/port/${SYSTYPE}/include
  LIBBIND = ${TOP}/lib/libbind.${A}
! CFLAGS=	${CDEBUG} -I${PORTINCL} -I${INCL}
  LD_LIBFLAGS= -x -r
  AR= ar cruv
  RANLIB= ranlib
--- 26,38 ----
  CC= cc
  LD= ld
  SHELL= /bin/sh
! CDEBUG= -g -DINET6
  TOP= ../..
  INCL = ${TOP}/include
+ INET6_INCLUDE =
  PORTINCL = ${TOP}/port/${SYSTYPE}/include
  LIBBIND = ${TOP}/lib/libbind.${A}
! CFLAGS=	${CDEBUG} ${INET6_INCLUDE} -I${PORTINCL} -I${INCL}
  LD_LIBFLAGS= -x -r
  AR= ar cruv
  RANLIB= ranlib
Index: bind8/src/lib/isc/ev_connects.c
diff -c bind8/src/lib/isc/ev_connects.c:1.1.1.1 bind8/src/lib/isc/ev_connects.c:1.1.1.1.2.1
*** bind8/src/lib/isc/ev_connects.c:1.1.1.1	Fri Sep 25 14:25:05 1998
--- bind8/src/lib/isc/ev_connects.c	Tue Jun  1 22:10:47 1999
***************
*** 250,264 ****
  listener(evContext opaqueCtx, void *uap, int fd, int evmask) {
  	evContext_p *ctx = opaqueCtx.opaque;
  	evConn *conn = uap;
  	struct sockaddr la, ra;
  	int new, lalen, ralen;
  
  	REQUIRE((evmask & EV_READ) != 0);
  	ralen = sizeof ra;
! 	new = accept(fd, &ra, &ralen);
  	if (new >= 0) {
  		lalen = sizeof la;
! 		if (getsockname(new, &la, &lalen) < 0) {
  			int save = errno;
  
  			(void) close(new);
--- 250,268 ----
  listener(evContext opaqueCtx, void *uap, int fd, int evmask) {
  	evContext_p *ctx = opaqueCtx.opaque;
  	evConn *conn = uap;
+ #ifdef INET6
+ 	struct sockaddr_storage la, ra;
+ #else
  	struct sockaddr la, ra;
+ #endif
  	int new, lalen, ralen;
  
  	REQUIRE((evmask & EV_READ) != 0);
  	ralen = sizeof ra;
! 	new = accept(fd, (struct sockaddr *)&ra, &ralen);
  	if (new >= 0) {
  		lalen = sizeof la;
! 		if (getsockname(new, (struct sockaddr *)&la, &lalen) < 0) {
  			int save = errno;
  
  			(void) close(new);
***************
*** 274,280 ****
--- 278,288 ----
  connector(evContext opaqueCtx, void *uap, int fd, int evmask) {
  	evContext_p *ctx = opaqueCtx.opaque;
  	evConn *conn = uap;
+ #ifdef INET6
+ 	struct sockaddr_storage la, ra;
+ #else
  	struct sockaddr la, ra;
+ #endif
  	int lalen, ralen;
  	char buf[1];
  	void *conn_uap;
***************
*** 304,311 ****
  #else
  	    read(fd, buf, 0) < 0 ||
  #endif
! 	    getsockname(fd, &la, &lalen) < 0 ||
! 	    getpeername(fd, &ra, &ralen) < 0) {
  		int save = errno;
  
  		(void) close(fd);	/* XXX closing caller's fd */
--- 312,319 ----
  #else
  	    read(fd, buf, 0) < 0 ||
  #endif
! 	    getsockname(fd, (struct sockaddr *)&la, &lalen) < 0 ||
! 	    getpeername(fd, (struct sockaddr *)&ra, &ralen) < 0) {
  		int save = errno;
  
  		(void) close(fd);	/* XXX closing caller's fd */
Index: bind8/src/lib/nameser/Makefile
diff -c bind8/src/lib/nameser/Makefile:1.1.1.1 bind8/src/lib/nameser/Makefile:1.2
*** bind8/src/lib/nameser/Makefile:1.1.1.1	Fri Sep 25 14:25:05 1998
--- bind8/src/lib/nameser/Makefile	Fri Sep 25 17:17:18 1998
***************
*** 15,21 ****
  # SOFTWARE.
  #
  
! # $Id: Makefile,v 8.7 1997/05/21 19:32:08 halley Exp $
  
  # these are only appropriate for BSD 4.4 or derivatives, and are used in
  # development.  normal builds will be done in the top level directory and
--- 15,21 ----
  # SOFTWARE.
  #
  
! # $Id: Makefile,v 1.1.1.1 1998/09/25 05:25:05 k-sugyou Exp $
  
  # these are only appropriate for BSD 4.4 or derivatives, and are used in
  # development.  normal builds will be done in the top level directory and
***************
*** 28,39 ****
  CC= cc
  LD= ld
  SHELL= /bin/sh
! CDEBUG= -g
  TOP= ../..
  INCL = ${TOP}/include
  PORTINCL = ${TOP}/port/${SYSTYPE}/include
  LIBBIND = ${TOP}/lib/libbind.${A}
! CFLAGS=	${CDEBUG} -I${PORTINCL} -I${INCL}
  LD_LIBFLAGS= -x -r
  AR= ar cruv
  RANLIB= ranlib
--- 28,40 ----
  CC= cc
  LD= ld
  SHELL= /bin/sh
! CDEBUG= -g -DINET6
  TOP= ../..
  INCL = ${TOP}/include
+ INET6_INCLUDE =
  PORTINCL = ${TOP}/port/${SYSTYPE}/include
  LIBBIND = ${TOP}/lib/libbind.${A}
! CFLAGS=	${CDEBUG} ${INET6_INCLUDE} -I${PORTINCL} -I${INCL}
  LD_LIBFLAGS= -x -r
  AR= ar cruv
  RANLIB= ranlib
Index: bind8/src/lib/resolv/Makefile
diff -c bind8/src/lib/resolv/Makefile:1.1.1.1 bind8/src/lib/resolv/Makefile:1.2
*** bind8/src/lib/resolv/Makefile:1.1.1.1	Fri Sep 25 14:25:05 1998
--- bind8/src/lib/resolv/Makefile	Fri Sep 25 17:17:21 1998
***************
*** 13,19 ****
  # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  # SOFTWARE.
  
! # $Id: Makefile,v 8.17 1997/05/21 19:32:09 halley Exp $
  
  # these are only appropriate for BSD 4.4 or derivatives, and are used in
  # development.  normal builds will be done in the top level directory and
--- 13,19 ----
  # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  # SOFTWARE.
  
! # $Id: Makefile,v 1.1.1.1 1998/09/25 05:25:05 k-sugyou Exp $
  
  # these are only appropriate for BSD 4.4 or derivatives, and are used in
  # development.  normal builds will be done in the top level directory and
***************
*** 26,37 ****
  CC= cc
  LD= ld
  SHELL= /bin/sh
! CDEBUG= -g
  TOP= ../..
  INCL = ${TOP}/include
  PORTINCL = ${TOP}/port/${SYSTYPE}/include
  LIBBIND = ${TOP}/lib/libbind.${A}
! CFLAGS=	${CDEBUG} -I${PORTINCL} -I${INCL}
  LD_LIBFLAGS= -x -r
  AR= ar cruv
  RANLIB= ranlib
--- 26,38 ----
  CC= cc
  LD= ld
  SHELL= /bin/sh
! CDEBUG= -g -DINET6
  TOP= ../..
  INCL = ${TOP}/include
+ INET6_INCLUDE =
  PORTINCL = ${TOP}/port/${SYSTYPE}/include
  LIBBIND = ${TOP}/lib/libbind.${A}
! CFLAGS=	${CDEBUG} ${INET6_INCLUDE} -I${PORTINCL} -I${INCL}
  LD_LIBFLAGS= -x -r
  AR= ar cruv
  RANLIB= ranlib
Index: bind8/src/lib/resolv/res_init.c
diff -c bind8/src/lib/resolv/res_init.c:1.1.1.1 bind8/src/lib/resolv/res_init.c:1.4
*** bind8/src/lib/resolv/res_init.c:1.1.1.1	Fri Sep 25 14:25:05 1998
--- bind8/src/lib/resolv/res_init.c	Sun Nov 29 22:50:02 1998
***************
*** 70,76 ****
  
  #if defined(LIBC_SCCS) && !defined(lint)
  static char sccsid[] = "@(#)res_init.c	8.1 (Berkeley) 6/7/93";
! static char rcsid[] = "$Id: res_init.c,v 8.7 1996/11/18 09:10:04 vixie Exp $";
  #endif /* LIBC_SCCS and not lint */
  
  #include "port_before.h"
--- 70,76 ----
  
  #if defined(LIBC_SCCS) && !defined(lint)
  static char sccsid[] = "@(#)res_init.c	8.1 (Berkeley) 6/7/93";
! static char rcsid[] = "$Id: res_init.c,v 1.3 1998/09/25 11:48:41 k-sugyou Exp $";
  #endif /* LIBC_SCCS and not lint */
  
  #include "port_before.h"
***************
*** 115,120 ****
--- 115,123 ----
  	= { RES_TIMEOUT, }	/* Motorola, et al. */
  # endif
          ;
+ #ifdef INET6
+ struct __res_state_ext _res_ext;
+ #endif
  
  
  /*
***************
*** 154,159 ****
--- 157,166 ----
  #ifndef RFC1535
  	int dots;
  #endif
+ #ifdef INET6
+ 	struct sockaddr_in *sin;
+ 	struct sockaddr_in6 *sin6;
+ #endif
  
  	/*
  	 * These three fields used to be statically initialized.  This made
***************
*** 188,200 ****
  	if (!_res.id)
  		_res.id = res_randomid();
  
! #ifdef USELOOPBACK
! 	_res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
  #else
  	_res.nsaddr.sin_addr.s_addr = INADDR_ANY;
! #endif
  	_res.nsaddr.sin_family = AF_INET;
  	_res.nsaddr.sin_port = htons(NAMESERVER_PORT);
  	_res.nscount = 1;
  	_res.ndots = 1;
  	_res.pfcode = 0;
--- 195,217 ----
  	if (!_res.id)
  		_res.id = res_randomid();
  
! #ifdef INET6
! 	sin6 = (struct sockaddr_in6 *)&_res_ext.nsaddr_list[0];
! 	memset(sin6, 0, sizeof(*sin6));
! # ifdef USELOOPBACK
! 	sin6->sin6_addr.s6_addr32[15] = 0x01;
! # endif
! 	sin6->sin6_family = AF_INET6;
! 	sin6->sin6_port = htons(NAMESERVER_PORT);
  #else
+ # ifdef USELOOPBACK
+ 	_res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
+ # else
  	_res.nsaddr.sin_addr.s_addr = INADDR_ANY;
! # endif
  	_res.nsaddr.sin_family = AF_INET;
  	_res.nsaddr.sin_port = htons(NAMESERVER_PORT);
+ #endif /*INET6*/
  	_res.nscount = 1;
  	_res.ndots = 1;
  	_res.pfcode = 0;
***************
*** 298,307 ****
  		/* read nameservers to query */
  		if (MATCH(buf, "nameserver") && nserv < MAXNS) {
  		    struct in_addr a;
! 
  		    cp = buf + sizeof("nameserver") - 1;
  		    while (*cp == ' ' || *cp == '\t')
  			cp++;
  		    if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) {
  			_res.nsaddr_list[nserv].sin_addr = a;
  			_res.nsaddr_list[nserv].sin_family = AF_INET;
--- 315,348 ----
  		/* read nameservers to query */
  		if (MATCH(buf, "nameserver") && nserv < MAXNS) {
  		    struct in_addr a;
! #ifdef INET6
! 		    struct in6_addr a6;
! #endif
  		    cp = buf + sizeof("nameserver") - 1;
  		    while (*cp == ' ' || *cp == '\t')
  			cp++;
+ #ifdef INET6
+ 		    if ((*cp != '\0') && (*cp != '\n')) {
+ 		        if (cp[strlen(cp)-1] == '\n')
+ 				cp[strlen(cp)-1] = '\0'; 
+ 			if (inet_pton(AF_INET6,cp, &a6)) {
+ 			    sin6 = (struct sockaddr_in6 *)&_res_ext.nsaddr_list[nserv];
+ 			    memset(sin6, 0, sizeof(*sin6));
+ 			    sin6->sin6_addr = a6;
+ 			    sin6->sin6_family = AF_INET6;
+ 			    sin6->sin6_port = htons(NAMESERVER_PORT);
+ 			    nserv++;
+ 			} else if (inet_aton(cp, &a)) {
+ 			    sin = (struct sockaddr_in *)&_res_ext.nsaddr_list[nserv];
+ 			    memset(sin, 0, sizeof(*sin));
+ 			    sin->sin_addr = a;
+ 			    sin->sin_family = AF_INET;
+ 			    sin->sin_port = htons(NAMESERVER_PORT);
+ 			    _res.nsaddr_list[nserv] = *sin;
+ 			    nserv++;
+ 			}
+ 		    }
+ #else
  		    if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) {
  			_res.nsaddr_list[nserv].sin_addr = a;
  			_res.nsaddr_list[nserv].sin_family = AF_INET;
***************
*** 309,314 ****
--- 350,356 ----
  				htons(NAMESERVER_PORT);
  			nserv++;
  		    }
+ #endif
  		    continue;
  		}
  #ifdef RESOLVSORT
Index: bind8/src/lib/resolv/res_send.c
diff -c bind8/src/lib/resolv/res_send.c:1.1.1.1 bind8/src/lib/resolv/res_send.c:1.3
*** bind8/src/lib/resolv/res_send.c:1.1.1.1	Fri Sep 25 14:25:05 1998
--- bind8/src/lib/resolv/res_send.c	Sun Nov 29 22:50:03 1998
***************
*** 70,76 ****
  
  #if defined(LIBC_SCCS) && !defined(lint)
  static char sccsid[] = "@(#)res_send.c	8.1 (Berkeley) 6/4/93";
! static char rcsid[] = "$Id: res_send.c,v 8.20 1998/04/06 23:27:51 halley Exp $";
  #endif /* LIBC_SCCS and not lint */
  
  /*
--- 70,76 ----
  
  #if defined(LIBC_SCCS) && !defined(lint)
  static char sccsid[] = "@(#)res_send.c	8.1 (Berkeley) 6/4/93";
! static char rcsid[] = "$Id: res_send.c,v 1.2 1998/09/25 08:17:23 k-sugyou Exp $";
  #endif /* LIBC_SCCS and not lint */
  
  /*
***************
*** 177,190 ****
   */
  int
  res_isourserver(const struct sockaddr_in *inp) {
- 	struct sockaddr_in ina;
  	int ns, ret;
  
  	ina = *inp;
  	ret = 0;
  	for (ns = 0;  ns < _res.nscount;  ns++) {
  		const struct sockaddr_in *srv = &_res.nsaddr_list[ns];
! 
  		if (srv->sin_family == ina.sin_family &&
  		    srv->sin_port == ina.sin_port &&
  		    (srv->sin_addr.s_addr == INADDR_ANY ||
--- 177,227 ----
   */
  int
  res_isourserver(const struct sockaddr_in *inp) {
  	int ns, ret;
+ #ifdef INET6
+ 	const struct sockaddr_in *srv;
+ 	const struct sockaddr_in6 *srv6;
+ 	const struct sockaddr_in6 *inp6;
  
+ 	ret = 0;
+ 	switch (inp->sin_family) {
+ 	case AF_INET:
+ 		for (ns = 0; ns < _res.nscount; ns++) {
+ 			srv = (struct sockaddr_in *)&_res_ext.nsaddr_list[ns];
+ 			if (srv->sin_family == inp->sin_family &&
+ 			    srv->sin_port == inp->sin_port &&
+ 			    (srv->sin_addr.s_addr == INADDR_ANY ||
+ 			     srv->sin_addr.s_addr == inp->sin_addr.s_addr)) {
+ 				ret++;
+ 				break;
+ 			}
+ 		}
+ 		break;
+ 	case AF_INET6:
+ 		inp6 = (struct sockaddr_in6 *)inp;
+ 		for (ns = 0; ns < _res.nscount; ns++) {
+ 			srv6 = (struct sockaddr_in6 *)&_res_ext.nsaddr_list[ns];
+ 			if (srv6->sin6_family == inp6->sin6_family &&
+ 			    srv6->sin6_port == inp6->sin6_port &&
+ 			    (IN6_IS_ADDR_UNSPECIFIED(&srv6->sin6_addr) ||
+ 			     IN6_ARE_ADDR_EQUAL(&srv6->sin6_addr, &inp6->sin6_addr))) {
+ 				ret++;
+ 				break;
+ 			}
+ 		}
+ 		break;
+ 	}
+ #else
+ 	struct sockaddr_in ina;
+ 
  	ina = *inp;
  	ret = 0;
  	for (ns = 0;  ns < _res.nscount;  ns++) {
+ #ifdef INET6
+ 		const struct sockaddr *srv = &_res_ext.nsaddr_list[ns];
+ #else
  		const struct sockaddr_in *srv = &_res.nsaddr_list[ns];
! #endif
  		if (srv->sin_family == ina.sin_family &&
  		    srv->sin_port == ina.sin_port &&
  		    (srv->sin_addr.s_addr == INADDR_ANY ||
***************
*** 193,198 ****
--- 230,236 ----
  			break;
  		}
  	}
+ #endif
  	return (ret);
  }
  
***************
*** 290,295 ****
--- 328,336 ----
  	HEADER *anhp = (HEADER *) ans;
  	int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns, n;
  	u_int badns;	/* XXX NSMAX can't exceed #/bits in this variable */
+ #ifdef INET6
+ 	char vname[INET6_ADDRSTRLEN];
+ #endif
  
  	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
  		/* errno should have been set by res_init() in this case. */
***************
*** 312,318 ****
--- 353,364 ----
  	 */
  	for (try = 0; try < _res.retry; try++) {
  	    for (ns = 0; ns < _res.nscount; ns++) {
+ #ifdef INET6
+ 		struct sockaddr *nsap = 
+ 		  (struct sockaddr *)&_res_ext.nsaddr_list[ns];
+ #else
  		struct sockaddr_in *nsap = &_res.nsaddr_list[ns];
+ #endif
   same_ns:
  		if (badns & (1 << ns)) {
  			res_close();
***************
*** 325,332 ****
--- 371,384 ----
  			do {
  				res_sendhookact act;
  
+ #ifdef INET6
+ 				act = (*Qhook)((struct sockaddr_in **)&nsap,
+ 					       &buf, &buflen,
+ 					       ans, anssiz, &resplen);
+ #else
  				act = (*Qhook)(&nsap, &buf, &buflen,
  					       ans, anssiz, &resplen);
+ #endif
  				switch (act) {
  				case res_goahead:
  					done = 1;
***************
*** 349,357 ****
--- 401,424 ----
  			} while (!done);
  		}
  
+ #ifdef INET6
+ 		if (nsap->sa_family == AF_INET6) {
+ 			inet_ntop(AF_INET6,
+ 				  &((struct sockaddr_in6 *)nsap)->sin6_addr,
+ 				  vname, sizeof(vname));
+ 			Dprint(_res.options & RES_DEBUG,
+ 		       (stdout, ";; Querying server (# %d) address = %s\n",
+ 				ns + 1, vname));
+ 		} else {
+ 			Dprint(_res.options & RES_DEBUG,
+ 	       (stdout, ";; Querying server (# %d) address = %s\n",
+ 		ns + 1, inet_ntoa(((struct sockaddr_in *)nsap)->sin_addr)));
+ 		}
+ #else
  		Dprint(_res.options & RES_DEBUG,
  		       (stdout, ";; Querying server (# %d) address = %s\n",
  			ns + 1, inet_ntoa(nsap->sin_addr)));
+ #endif
  
  		if (v_circuit) {
  			int truncated;
***************
*** 369,381 ****
--- 436,481 ----
  				if (s >= 0)
  					res_close();
  
+ #ifdef INET6
+ 				if (nsap->sa_family == AF_INET6) {
+ 					printf("socket 6\n");
+ 					s = socket(PF_INET6, SOCK_STREAM, 0);
+ 				} else {
+ 					printf("socket 4\n");
+ 					s = socket(PF_INET, SOCK_STREAM, 0);
+ 				}
+ #else
  				s = socket(PF_INET, SOCK_STREAM, 0);
+ #endif
  				if (s < 0) {
  					terrno = errno;
  					Perror(stderr, "socket(vc)", errno);
  					return (-1);
  				}
  				errno = 0;
+ #ifdef INET6
+ 				if (nsap->sa_family == AF_INET6) {
+ 					if (connect(s, (struct sockaddr *)nsap,
+ 					    sizeof(struct sockaddr_in6)) < 0) {
+ 						terrno = errno;
+ 						Aerror(stderr, "connect/vc",
+ 						       errno, *nsap);
+ 						badns |= (1 << ns);
+ 						res_close();
+ 						goto next_ns;
+ 					}
+ 				} else {
+ 					if (connect(s, (struct sockaddr *)nsap,
+ 					    sizeof(struct sockaddr_in)) < 0) {
+ 						terrno = errno;
+ 						Aerror(stderr, "connect/vc",
+ 						       errno, *nsap);
+ 						badns |= (1 << ns);
+ 						res_close();
+ 						goto next_ns;
+ 					}
+ 				}
+ #else
  				if (connect(s, (struct sockaddr *)nsap,
  					    sizeof *nsap) < 0) {
  					terrno = errno;
***************
*** 385,390 ****
--- 485,491 ----
  					res_close();
  					goto next_ns;
  				}
+ #endif
  				vc = 1;
  			}
  			/*
***************
*** 505,517 ****
--- 606,630 ----
  			 */
  			struct timeval timeout;
  			fd_set dsmask;
+ #ifdef INET6
+ 			struct sockaddr_storage from;
+ #else
  			struct sockaddr_in from;
+ #endif
  			int fromlen;
  
  			if ((s < 0) || vc) {
  				if (vc)
  					res_close();
+ #ifdef INET6
+ 				if (nsap->sa_family == AF_INET6) {
+ 					s = socket(PF_INET6, SOCK_DGRAM, 0);
+ 				} else {
+ 					s = socket(PF_INET, SOCK_DGRAM, 0);
+ 				}
+ #else
  				s = socket(PF_INET, SOCK_DGRAM, 0);
+ #endif
  				if (s < 0) {
  #ifndef CAN_RECONNECT
   bad_dg_sock:
***************
*** 544,549 ****
--- 657,675 ----
  				 * receive a response from another server.
  				 */
  				if (!connected) {
+ #ifdef INET6
+ 					int lsize = nsap->sa_family == AF_INET6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);  
+ 					if (connect(s, (struct sockaddr *)nsap,
+ 						   lsize
+ 						    ) < 0) {
+ 						Aerror(stderr,
+ 						       "connect(dg)",
+ 						       errno, *nsap);
+ 						badns |= (1 << ns);
+ 						res_close();
+ 						goto next_ns;
+ 					}
+ #else
  					if (connect(s, (struct sockaddr *)nsap,
  						    sizeof *nsap
  						    ) < 0) {
***************
*** 554,559 ****
--- 680,686 ----
  						res_close();
  						goto next_ns;
  					}
+ #endif
  					connected = 1;
  				}
                                if (send(s, (char*)buf, buflen, 0) != buflen) {
***************
*** 641,647 ****
  				goto next_ns;
  			}
  			errno = 0;
! 			fromlen = sizeof(struct sockaddr_in);
  			resplen = recvfrom(s, (char*)ans, anssiz, 0,
  					   (struct sockaddr *)&from, &fromlen);
  			if (resplen <= 0) {
--- 768,774 ----
  				goto next_ns;
  			}
  			errno = 0;
! 			fromlen = sizeof(from);
  			resplen = recvfrom(s, (char*)ans, anssiz, 0,
  					   (struct sockaddr *)&from, &fromlen);
  			if (resplen <= 0) {
***************
*** 676,682 ****
  			}
  #ifdef CHECK_SRVR_ADDR
  			if (!(_res.options & RES_INSECURE1) &&
! 			    !res_isourserver(&from)) {
  				/*
  				 * response from wrong server? ignore it.
  				 * XXX - potential security hazard could
--- 803,809 ----
  			}
  #ifdef CHECK_SRVR_ADDR
  			if (!(_res.options & RES_INSECURE1) &&
! 			    !res_isourserver((struct sockaddr_in *)&from)) {
  				/*
  				 * response from wrong server? ignore it.
  				 * XXX - potential security hazard could
Index: bind8/src/lib/resolv/res_update.c
diff -c bind8/src/lib/resolv/res_update.c:1.1.1.1 bind8/src/lib/resolv/res_update.c:1.3
*** bind8/src/lib/resolv/res_update.c:1.1.1.1	Fri Sep 25 14:25:05 1998
--- bind8/src/lib/resolv/res_update.c	Sun Nov 29 22:50:05 1998
***************
*** 1,5 ****
  #if !defined(lint) && !defined(SABER)
! static char rcsid[] = "$Id: res_update.c,v 1.14 1998/03/10 22:04:48 halley Exp $";
  #endif /* not lint */
  
  /*
--- 1,5 ----
  #if !defined(lint) && !defined(SABER)
! static char rcsid[] = "$Id: res_update.c,v 1.2 1998/09/25 08:17:24 k-sugyou Exp $";
  #endif /* not lint */
  
  /*
***************
*** 491,501 ****
--- 491,513 ----
  				break;
  			}
  		}
+ #ifdef INET6
  		for (i = 0; i < MAXNS; i++) {
+ 			struct sockaddr_in *sin;
+ 			sin = (struct sockaddr_in *)&_res_ext.nsaddr_list[i];
+ 			memset(sin, 0, sizeof(*sin));
+ 			sin->sin_addr = zptr->z_ns[i].nsaddr1;
+ 			sin->sin_family = AF_INET;
+ 			sin->sin_port = htons(NAMESERVER_PORT);
+ 			_res.nsaddr_list[i] = *sin;
+ 		}
+ #else
+ 		for (i = 0; i < MAXNS; i++) {
  			_res.nsaddr_list[i].sin_addr = zptr->z_ns[i].nsaddr1;
  			_res.nsaddr_list[i].sin_family = AF_INET;
  			_res.nsaddr_list[i].sin_port = htons(NAMESERVER_PORT);
  		}
+ #endif
  		_res.nscount = (zptr->z_nscount < MAXNS) ? 
  					zptr->z_nscount : MAXNS;
  		n = res_send(packet, n, answer, sizeof(answer));
Index: bind8/src/port/bsdos/Makefile.set
diff -c bind8/src/port/bsdos/Makefile.set:1.1.1.1 bind8/src/port/bsdos/Makefile.set:1.2.2.1
*** bind8/src/port/bsdos/Makefile.set:1.1.1.1	Fri Sep 25 14:25:07 1998
--- bind8/src/port/bsdos/Makefile.set	Tue Jun  1 12:24:47 1999
***************
*** 1,5 ****
  'CC=shlicc'
! 'CDEBUG=-O -g'
  'DESTBIN=/usr/bin'
  'DESTSBIN=/usr/sbin'
  'DESTEXEC=/usr/libexec'
--- 1,5 ----
  'CC=shlicc'
! 'CDEBUG=-O -g -DINET6 -Dss_family=__ss_family -Dss_len=__ss_len'
  'DESTBIN=/usr/bin'
  'DESTSBIN=/usr/sbin'
  'DESTEXEC=/usr/libexec'
Index: bind8/src/port/freebsd/Makefile.set
diff -c bind8/src/port/freebsd/Makefile.set:1.1.1.1 bind8/src/port/freebsd/Makefile.set:1.2.2.1
*** bind8/src/port/freebsd/Makefile.set:1.1.1.1	Fri Sep 25 14:25:08 1998
--- bind8/src/port/freebsd/Makefile.set	Tue Jun  1 12:24:48 1999
***************
*** 1,5 ****
  'CC=cc'
! 'CDEBUG=-O2 -g'
  'DESTBIN=/usr/bin'
  'DESTSBIN=/usr/sbin'
  'DESTEXEC=/usr/libexec'
--- 1,5 ----
  'CC=cc'
! 'CDEBUG=-O2 -g -DINET6 -Dss_family=__ss_family -Dss_len=__ss_len'
  'DESTBIN=/usr/bin'
  'DESTSBIN=/usr/sbin'
  'DESTEXEC=/usr/libexec'
Index: bind8/src/port/netbsd/Makefile.set
diff -c bind8/src/port/netbsd/Makefile.set:1.1.1.1 bind8/src/port/netbsd/Makefile.set:1.2.2.1
*** bind8/src/port/netbsd/Makefile.set:1.1.1.1	Fri Sep 25 14:25:11 1998
--- bind8/src/port/netbsd/Makefile.set	Tue Jun  1 12:24:49 1999
***************
*** 1,5 ****
  'CC=cc'
! 'CDEBUG=-O2 -g'
  'DESTBIN=/usr/bin'
  'DESTSBIN=/usr/sbin'
  'DESTEXEC=/usr/libexec'
--- 1,5 ----
  'CC=cc'
! 'CDEBUG=-O2 -g -DINET6 -Dss_family=__ss_family -Dss_len=__ss_len'
  'DESTBIN=/usr/bin'
  'DESTSBIN=/usr/sbin'
  'DESTEXEC=/usr/libexec'
