diff -pruN /home/reed/src/isc/libbind/libbind/resolv/__dn_comp.c /usr/src/lib/libc/resolv/__dn_comp.c
--- /home/reed/src/isc/libbind/libbind/resolv/__dn_comp.c	1969-12-31 18:00:00.000000000 -0600
+++ /usr/src/lib/libc/resolv/__dn_comp.c	2012-10-24 08:34:37.000000000 -0500
@@ -0,0 +1,34 @@
+/*	$NetBSD: __dn_comp.c,v 1.5 2007/01/17 16:39:20 seanb Exp $	*/
+
+/*
+ * written by matthew green, 22/04/97.
+ * public domain.
+ */
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: __dn_comp.c,v 1.5 2007/01/17 16:39:20 seanb Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#if defined(__indr_reference)
+__indr_reference(__dn_comp,dn_comp)
+#else
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <resolv.h>
+
+/* XXX THIS IS A MESS!  SEE <resolv.h> XXX */
+
+#undef dn_comp
+int	dn_comp(const char *, u_char *, int, u_char **, u_char **);
+
+int
+dn_comp(const char *exp_dn, u_char *comp_dn, int length, u_char **dnptrs,
+    u_char **lastdnptr)
+{
+
+	return __dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr);
+}
+
+#endif
diff -pruN /home/reed/src/isc/libbind/libbind/resolv/__res_close.c /usr/src/lib/libc/resolv/__res_close.c
--- /home/reed/src/isc/libbind/libbind/resolv/__res_close.c	1969-12-31 18:00:00.000000000 -0600
+++ /usr/src/lib/libc/resolv/__res_close.c	2005-09-12 20:44:10.000000000 -0500
@@ -0,0 +1,33 @@
+/*	$NetBSD: __res_close.c,v 1.4 2005/09/13 01:44:10 christos Exp $	*/
+
+/*
+ * written by matthew green, 22/04/97.
+ * public domain.
+ */
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: __res_close.c,v 1.4 2005/09/13 01:44:10 christos Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#if defined(__indr_reference)
+__indr_reference(__res_close, res_close)
+#else
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <resolv.h>
+
+/* XXX THIS IS A MESS!  SEE <resolv.h> XXX */
+
+#undef res_close
+void	res_close(void);
+
+void
+res_close(void)
+{
+
+	__res_close();
+}
+
+#endif
diff -pruN /home/reed/src/isc/libbind/libbind/resolv/__res_send.c /usr/src/lib/libc/resolv/__res_send.c
--- /home/reed/src/isc/libbind/libbind/resolv/__res_send.c	1969-12-31 18:00:00.000000000 -0600
+++ /usr/src/lib/libc/resolv/__res_send.c	2005-09-12 20:44:10.000000000 -0500
@@ -0,0 +1,33 @@
+/*	$NetBSD: __res_send.c,v 1.4 2005/09/13 01:44:10 christos Exp $	*/
+
+/*
+ * written by matthew green, 22/04/97.
+ * public domain.
+ */
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: __res_send.c,v 1.4 2005/09/13 01:44:10 christos Exp $");
+#endif
+
+#if defined(__indr_reference)
+__indr_reference(__res_send, res_send)
+#else
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <resolv.h>
+
+/* XXX THIS IS A MESS!  SEE <resolv.h> XXX */
+
+#undef res_send
+int	res_send(const u_char *, int, u_char *, int);
+
+int
+res_send(const u_char *buf, int buflen, u_char *ans, int anssiz)
+{
+
+	return __res_send(buf, buflen, ans, anssiz);
+}
+
+#endif
diff -pruN /home/reed/src/isc/libbind/libbind/resolv/h_errno.c /usr/src/lib/libc/resolv/h_errno.c
--- /home/reed/src/isc/libbind/libbind/resolv/h_errno.c	1969-12-31 18:00:00.000000000 -0600
+++ /usr/src/lib/libc/resolv/h_errno.c	2012-10-24 08:34:37.000000000 -0500
@@ -0,0 +1,58 @@
+/*	$NetBSD: h_errno.c,v 1.3 2008/06/21 20:41:48 christos Exp $	*/
+
+/*-
+ * Copyright (c) 2004 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: h_errno.c,v 1.3 2008/06/21 20:41:48 christos Exp $");
+#endif
+
+#include <sys/types.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include <netdb.h>
+
+#undef h_errno
+
+extern int h_errno;
+extern struct __res_state _nres;
+
+int *
+__h_errno(void)
+{
+	return &_nres.res_h_errno;
+}
+
+void
+__h_errno_set(res_state res, int err)
+{
+	h_errno = res->res_h_errno = err;
+}
diff -pruN /home/reed/src/isc/libbind/libbind/resolv/herror.c /usr/src/lib/libc/resolv/herror.c
--- /home/reed/src/isc/libbind/libbind/resolv/herror.c	2013-06-05 09:33:54.000000000 -0500
+++ /usr/src/lib/libc/resolv/herror.c	2013-06-05 09:26:14.000000000 -0500
@@ -1,3 +1,5 @@
+/*	$NetBSD: herror.c,v 1.9 2012/03/13 21:13:43 christos Exp $	*/
+
 /*
  * Copyright (c) 1987, 1993
  *    The Regents of the University of California.  All rights reserved.
@@ -10,7 +12,11 @@
  * 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 University nor the names of its contributors
+ * 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.
  * 
@@ -44,13 +50,19 @@
  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <sys/cdefs.h>
 #if defined(LIBC_SCCS) && !defined(lint)
+#ifdef notdef
 static const char sccsid[] = "@(#)herror.c	8.1 (Berkeley) 6/4/93";
-static const char rcsid[] = "$Id: herror.c,v 1.5 2013-01-06 23:14:54 marka Exp $";
+static const char rcsid[] = "Id: herror.c,v 1.4 2005/04/27 04:56:41 sra Exp";
+#else
+__RCSID("$NetBSD: herror.c,v 1.9 2012/03/13 21:13:43 christos Exp $");
+#endif
 #endif /* LIBC_SCCS and not lint */
 
 #include "port_before.h"
 
+#include "namespace.h"
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/uio.h>
@@ -62,7 +74,6 @@ static const char rcsid[] = "$Id: herror
 #include <resolv.h>
 #include <string.h>
 #include <unistd.h>
-#include <irs.h>
 
 #include "port_after.h"
 
@@ -80,6 +91,10 @@ int	h_nerr = { sizeof h_errlist / sizeof
 int	h_errno;
 #endif
 
+#ifdef __weak_alias
+__weak_alias(herror,_herror)
+#endif
+
 /*%
  * herror --
  *	print the error indicated by the h_errno value.
@@ -106,7 +121,7 @@ herror(const char *s) {
 	DE_CONST("\n", t);
 	v->iov_base = t;
 	v->iov_len = 1;
-	writev(STDERR_FILENO, iov, (v - iov) + 1);
+	(void)writev(STDERR_FILENO, iov, (int)((v - iov) + 1));
 }
 
 /*%
diff -pruN /home/reed/src/isc/libbind/libbind/resolv/mtctxres.c /usr/src/lib/libc/resolv/mtctxres.c
--- /home/reed/src/isc/libbind/libbind/resolv/mtctxres.c	2006-03-09 17:57:56.000000000 -0600
+++ /usr/src/lib/libc/resolv/mtctxres.c	2012-10-24 08:34:38.000000000 -0500
@@ -1,3 +1,5 @@
+/*	$NetBSD: mtctxres.c,v 1.4 2007/03/30 20:40:52 ghen Exp $	*/
+
 #include <port_before.h>
 #ifdef DO_PTHREADS
 #include <pthread.h>
@@ -7,7 +9,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <resolv_mt.h>
-#include <irs.h>
 #include <port_after.h>
 
 #ifdef DO_PTHREADS
diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_comp.c /usr/src/lib/libc/resolv/res_comp.c
--- /home/reed/src/isc/libbind/libbind/resolv/res_comp.c	2013-06-05 09:33:54.000000000 -0500
+++ /usr/src/lib/libc/resolv/res_comp.c	2013-06-05 09:26:14.000000000 -0500
@@ -1,3 +1,5 @@
+/*	$NetBSD: res_comp.c,v 1.12 2012/03/13 21:13:43 christos Exp $	*/
+
 /*
  * Copyright (c) 1985, 1993
  *    The Regents of the University of California.  All rights reserved.
@@ -10,7 +12,11 @@
  * 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 University nor the names of its contributors
+ * 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.
  * 
@@ -63,17 +69,24 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
-
+#include <sys/cdefs.h>
 #if defined(LIBC_SCCS) && !defined(lint)
+#ifdef notdef
 static const char sccsid[] = "@(#)res_comp.c	8.1 (Berkeley) 6/4/93";
-static const char rcsid[] = "$Id: res_comp.c,v 1.6 2013-01-06 23:14:54 marka Exp $";
+static const char rcsid[] = "Id: res_comp.c,v 1.5 2005/07/28 06:51:50 marka Exp";
+#else
+__RCSID("$NetBSD: res_comp.c,v 1.12 2012/03/13 21:13:43 christos Exp $");
+#endif
 #endif /* LIBC_SCCS and not lint */
 
 #include "port_before.h"
+
+#include "namespace.h"
 #include <sys/types.h>
 #include <sys/param.h>
 #include <netinet/in.h>
 #include <arpa/nameser.h>
+#include <assert.h>
 #include <ctype.h>
 #include <resolv.h>
 #include <stdio.h>
@@ -81,6 +94,18 @@ static const char rcsid[] = "$Id: res_co
 #include <unistd.h>
 #include "port_after.h"
 
+#ifdef __weak_alias
+__weak_alias(dn_expand,_dn_expand)
+__weak_alias(dn_comp,__dn_comp)
+#if 0
+__weak_alias(dn_skipname,__dn_skipname)
+__weak_alias(res_hnok,__res_hnok)
+__weak_alias(res_ownok,__res_ownok)
+__weak_alias(res_mailok,__res_mailok)
+__weak_alias(res_dnok,__res_dnok)
+#endif
+#endif
+
 /*%
  * Expand compressed domain name 'src' to full domain name.
  *
@@ -111,8 +136,8 @@ dn_comp(const char *src, u_char *dst, in
 	u_char **dnptrs, u_char **lastdnptr)
 {
 	return (ns_name_compress(src, dst, (size_t)dstsiz,
-				 (const u_char **)dnptrs,
-				 (const u_char **)lastdnptr));
+				 (void *)dnptrs,
+				 (void *)lastdnptr));
 }
 
 /*%
@@ -124,7 +149,8 @@ dn_skipname(const u_char *ptr, const u_c
 
 	if (ns_name_skip(&ptr, eom) == -1)
 		return (-1);
-	return (ptr - saveptr);
+	_DIAGASSERT(__type_fit(int, ptr - saveptr));
+	return (int)(ptr - saveptr);
 }
 
 /*%
@@ -156,7 +182,7 @@ res_hnok(const char *dn) {
 		int nch = *dn++;
 
 		if (periodchar(ch)) {
-			(void)NULL;
+			;
 		} else if (periodchar(pch)) {
 			if (!borderchar(ch))
 				return (0);
diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_compat.c /usr/src/lib/libc/resolv/res_compat.c
--- /home/reed/src/isc/libbind/libbind/resolv/res_compat.c	1969-12-31 18:00:00.000000000 -0600
+++ /usr/src/lib/libc/resolv/res_compat.c	2012-10-24 08:34:38.000000000 -0500
@@ -0,0 +1,76 @@
+/*	$NetBSD: res_compat.c,v 1.3 2009/11/22 18:04:37 mbalmer Exp $	*/
+
+/*-
+ * Copyright (c) 2004 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: res_compat.c,v 1.3 2009/11/22 18:04:37 mbalmer Exp $");
+#endif
+
+#include <sys/types.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <string.h>
+#define __OLD_RES_STATE
+#include <resolv.h>
+
+#undef _res
+
+/*
+ * Binary Compatibility; this symbol does not appear in a header file
+ * Most userland programs use this to set res_options before res_init()
+ * is called. There are hooks to res_init() to consult the data in this
+ * structure. The hooks are provided indirectly by the two functions below.
+ * We depend on the fact the first 440 [32 bit machines] bytes are
+ * shared between the two structures.
+ */
+#ifndef __BIND_NOSTATIC 
+struct __res_state _res
+#if defined(__BIND_RES_TEXT)
+	= { RES_TIMEOUT, }      /* Motorola, et al. */
+# endif 
+;
+
+void *__res_get_old_state(void);
+void __res_put_old_state(void *);
+
+void *
+__res_get_old_state(void)
+{
+	return &_res;
+}
+
+void
+__res_put_old_state(void *res)
+{
+	(void)memcpy(&_res, res, sizeof(_res));
+}
+#endif
diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_data.c /usr/src/lib/libc/resolv/res_data.c
--- /home/reed/src/isc/libbind/libbind/resolv/res_data.c	2009-01-20 19:28:19.000000000 -0600
+++ /usr/src/lib/libc/resolv/res_data.c	2012-10-24 08:34:38.000000000 -0500
@@ -1,3 +1,5 @@
+/*	$NetBSD: res_data.c,v 1.14 2009/10/24 05:35:37 christos Exp $	*/
+
 /*
  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
  * Copyright (c) 1995-1999 by Internet Software Consortium.
@@ -15,12 +17,18 @@
  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <sys/cdefs.h>
 #if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: res_data.c,v 1.7 2008/12/11 09:59:00 marka Exp $";
+#ifdef notdef
+static const char rcsid[] = "Id: res_data.c,v 1.7 2008/12/11 09:59:00 marka Exp";
+#else
+__RCSID("$NetBSD: res_data.c,v 1.14 2009/10/24 05:35:37 christos Exp $");
+#endif
 #endif /* LIBC_SCCS and not lint */
 
 #include "port_before.h"
 
+#include "namespace.h"
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/socket.h>
@@ -41,6 +49,29 @@ static const char rcsid[] = "$Id: res_da
 
 #include "port_after.h"
 
+#include "res_private.h"
+
+#ifdef __weak_alias
+__weak_alias(res_init,_res_init)
+__weak_alias(res_mkquery,_res_mkquery)
+__weak_alias(res_query,_res_query)
+__weak_alias(res_search,_res_search)
+__weak_alias(res_send,__res_send)
+__weak_alias(res_close,__res_close)
+/* XXX: these leaked in the old bind8 libc */
+__weak_alias(res_querydomain,__res_querydomain)
+__weak_alias(res_send_setqhook,__res_send_setqhook)
+__weak_alias(res_send_setrhook,__res_send_setrhook)
+#if 0
+__weak_alias(p_query,__p_query)
+__weak_alias(fp_query,__fp_query)
+__weak_alias(fp_nquery,__fp_nquery)
+__weak_alias(res_isourserver,__res_isourserver)
+__weak_alias(res_opt,_res_opt)
+__weak_alias(hostalias,__hostalias)
+#endif
+#endif
+
 const char *_res_opcodes[] = {
 	"QUERY",
 	"IQUERY",
@@ -69,25 +100,34 @@ const char *_res_sectioncodes[] = {
 };
 #endif
 
-#undef _res
-#ifndef __BIND_NOSTATIC
-struct __res_state _res
-# if defined(__BIND_RES_TEXT)
-	= { RES_TIMEOUT, }	/*%< Motorola, et al. */
-# endif
-        ;
-
-#if defined(DO_PTHREADS) || defined(__linux)
-#define _res (*__res_state())
-#endif
+#ifndef __BIND_NOSTATIC 
+extern struct __res_state _nres;
 
 /* Proto. */
 
-int  res_ourserver_p(const res_state, const struct sockaddr_in *);
+int  res_ourserver_p(const res_state, const struct sockaddr *);
 
 int
 res_init(void) {
-	extern int __res_vinit(res_state, int);
+	int rv;
+#ifdef COMPAT__RES
+	/*
+	 * Compatibility with program that were accessing _res directly
+	 * to set options. We keep another struct res that is the same
+	 * size as the original res structure, and then copy fields to
+	 * it so that we achieve the same initialization
+	 */
+	extern void *__res_get_old_state(void);
+	extern void __res_put_old_state(void *);
+	res_state ores = __res_get_old_state();
+
+	if (ores->options != 0)
+		_nres.options = ores->options;
+	if (ores->retrans != 0)
+		_nres.retrans = ores->retrans;
+	if (ores->retry != 0)
+		_nres.retry = ores->retry;
+#endif
 
 	/*
 	 * These three fields used to be statically initialized.  This made
@@ -102,27 +142,31 @@ res_init(void) {
 	 * so one can safely assume that the applications were already getting
 	 * unexpected results.
 	 *
-	 * _res.options is tricky since some apps were known to diddle the bits
+	 * _nres.options is tricky since some apps were known to diddle the bits
 	 * before res_init() was first called. We can't replicate that semantic
 	 * with dynamic initialization (they may have turned bits off that are
 	 * set in RES_DEFAULT).  Our solution is to declare such applications
 	 * "broken".  They could fool us by setting RES_INIT but none do (yet).
 	 */
-	if (!_res.retrans)
-		_res.retrans = RES_TIMEOUT;
-	if (!_res.retry)
-		_res.retry = 4;
-	if (!(_res.options & RES_INIT))
-		_res.options = RES_DEFAULT;
+	if (!_nres.retrans)
+		_nres.retrans = RES_TIMEOUT;
+	if (!_nres.retry)
+		_nres.retry = 4;
+	if (!(_nres.options & RES_INIT))
+		_nres.options = RES_DEFAULT;
 
 	/*
 	 * This one used to initialize implicitly to zero, so unless the app
 	 * has set it to something in particular, we can randomize it now.
 	 */
-	if (!_res.id)
-		_res.id = res_nrandomid(&_res);
+	if (!_nres.id)
+		_nres.id = res_nrandomid(&_nres);
 
-	return (__res_vinit(&_res, 1));
+	rv = __res_vinit(&_nres, 1);
+#ifdef COMPAT__RES
+	__res_put_old_state(&_nres);
+#endif
+	return rv;
 }
 
 void
@@ -137,10 +181,10 @@ fp_query(const u_char *msg, FILE *file) 
 
 void
 fp_nquery(const u_char *msg, int len, FILE *file) {
-	if ((_res.options & RES_INIT) == 0U && res_init() == -1)
+	if ((_nres.options & RES_INIT) == 0U && res_init() == -1)
 		return;
 
-	res_pquery(&_res, msg, len, file);
+	res_pquery(&_nres, msg, len, file);
 }
 
 int
@@ -153,24 +197,26 @@ res_mkquery(int op,			/*!< opcode of que
 	    u_char *buf,		/*!< buffer to put query  */
 	    int buflen)			/*!< size of buffer  */
 {
-	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
-		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
+	if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
+		RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL);
 		return (-1);
 	}
-	return (res_nmkquery(&_res, op, dname, class, type,
+	return (res_nmkquery(&_nres, op, dname, class, type,
 			     data, datalen,
 			     newrr_in, buf, buflen));
 }
 
+#ifdef _LIBRESOLV
 int
 res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) {
-	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
-		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
+	if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
+		RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL);
 		return (-1);
 	}
 
-	return (res_nmkupdate(&_res, rrecp_in, buf, buflen));
+	return (res_nmkupdate(&_nres, rrecp_in, buf, buflen));
 }
+#endif
 
 int
 res_query(const char *name,	/*!< domain name  */
@@ -178,64 +224,68 @@ res_query(const char *name,	/*!< domain 
 	  u_char *answer,	/*!< buffer to put answer  */
 	  int anslen)		/*!< size of answer buffer  */
 {
-	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
-		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
+	if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
+		RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL);
 		return (-1);
 	}
-	return (res_nquery(&_res, name, class, type, answer, anslen));
+	return (res_nquery(&_nres, name, class, type, answer, anslen));
 }
 
 void
 res_send_setqhook(res_send_qhook hook) {
-	_res.qhook = hook;
+	_nres.qhook = hook;
 }
 
 void
 res_send_setrhook(res_send_rhook hook) {
-	_res.rhook = hook;
+	_nres.rhook = hook;
 }
 
 int
 res_isourserver(const struct sockaddr_in *inp) {
-	return (res_ourserver_p(&_res, inp));
+	return (res_ourserver_p(&_nres, (const struct sockaddr *)(const void *)inp));
 }
 
 int
 res_send(const u_char *buf, int buflen, u_char *ans, int anssiz) {
-	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
+	if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
 		/* errno should have been set by res_init() in this case. */
 		return (-1);
 	}
 
-	return (res_nsend(&_res, buf, buflen, ans, anssiz));
+	return (res_nsend(&_nres, buf, buflen, ans, anssiz));
 }
 
+#ifdef _LIBRESOLV
 int
 res_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key,
 	       u_char *ans, int anssiz)
 {
-	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
+	if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
 		/* errno should have been set by res_init() in this case. */
 		return (-1);
 	}
 
-	return (res_nsendsigned(&_res, buf, buflen, key, ans, anssiz));
+	return (res_nsendsigned(&_nres, buf, buflen, key, ans, anssiz));
 }
+#endif
 
 void
 res_close(void) {
-	res_nclose(&_res);
+	res_nclose(&_nres);
 }
 
+#ifdef _LIBRESOLV
 int
 res_update(ns_updrec *rrecp_in) {
-	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
-		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
+	if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
+		RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL);
 		return (-1);
 	}
 
-	return (res_nupdate(&_res, rrecp_in, NULL));
+	return (res_nupdate(&_nres, rrecp_in, NULL));
 }
+#endif
 
 int
 res_search(const char *name,	/*!< domain name  */
@@ -243,12 +293,12 @@ res_search(const char *name,	/*!< domain
 	   u_char *answer,	/*!< buffer to put answer  */
 	   int anslen)		/*!< size of answer  */
 {
-	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
-		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
+	if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
+		RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL);
 		return (-1);
 	}
 
-	return (res_nsearch(&_res, name, class, type, answer, anslen));
+	return (res_nsearch(&_nres, name, class, type, answer, anslen));
 }
 
 int
@@ -258,31 +308,37 @@ res_querydomain(const char *name,
 		u_char *answer,		/*!< buffer to put answer  */
 		int anslen)		/*!< size of answer  */
 {
-	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
-		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
+	if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
+		RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL);
 		return (-1);
 	}
 
-	return (res_nquerydomain(&_res, name, domain,
+	return (res_nquerydomain(&_nres, name, domain,
 				 class, type,
 				 answer, anslen));
 }
 
+int
+res_opt(int a, u_char *b, int c, int d)
+{
+	return res_nopt(&_nres, a, b, c, d);
+}
+
 u_int
 res_randomid(void) {
-	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
+	if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
 		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
-		return (-1);
+		return (u_int)-1;
 	}
 
-	return (res_nrandomid(&_res));
+	return (res_nrandomid(&_nres));
 }
 
 const char *
 hostalias(const char *name) {
 	static char abuf[MAXDNAME];
 
-	return (res_hostalias(&_res, name, abuf, sizeof abuf));
+	return (res_hostalias(&_nres, name, abuf, sizeof abuf));
 }
 
 #ifdef ultrix
@@ -290,12 +346,12 @@ int
 local_hostname_length(const char *hostname) {
 	int len_host, len_domain;
 
-	if (!*_res.defdname)
+	if (!*_nres.defdname)
 		res_init();
 	len_host = strlen(hostname);
-	len_domain = strlen(_res.defdname);
+	len_domain = strlen(_nres.defdname);
 	if (len_host > len_domain &&
-	    !strcasecmp(hostname + len_host - len_domain, _res.defdname) &&
+	    !strcasecmp(hostname + len_host - len_domain, _nres.defdname) &&
 	    hostname[len_host - len_domain - 1] == '.')
 		return (len_host - len_domain - 1);
 	return (0);
diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_debug.c /usr/src/lib/libc/resolv/res_debug.c
--- /home/reed/src/isc/libbind/libbind/resolv/res_debug.c	2013-06-05 09:33:54.000000000 -0500
+++ /usr/src/lib/libc/resolv/res_debug.c	2013-06-05 09:26:14.000000000 -0500
@@ -1,3 +1,5 @@
+/*	$NetBSD: res_debug.c,v 1.13 2012/06/25 22:32:45 abs Exp $	*/
+
 /*
  * Portions Copyright (C) 2004, 2005, 2008, 2009  Internet Systems Consortium, Inc. ("ISC")
  * Portions Copyright (C) 1996-2003  Internet Software Consortium.
@@ -27,7 +29,11 @@
  * 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 University nor the names of its contributors
+ * 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.
  *
@@ -89,13 +95,19 @@
  * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
  */
 
+#include <sys/cdefs.h>
 #if defined(LIBC_SCCS) && !defined(lint)
+#ifdef notdef
 static const char sccsid[] = "@(#)res_debug.c	8.1 (Berkeley) 6/4/93";
-static const char rcsid[] = "$Id: res_debug.c,v 1.20 2013-01-06 23:14:54 marka Exp $";
+static const char rcsid[] = "Id: res_debug.c,v 1.19 2009/02/26 11:20:20 tbox Exp";
+#else
+__RCSID("$NetBSD: res_debug.c,v 1.13 2012/06/25 22:32:45 abs Exp $");
+#endif
 #endif /* LIBC_SCCS and not lint */
 
 #include "port_before.h"
 
+#include "namespace.h"
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/socket.h>
@@ -104,6 +116,7 @@ static const char rcsid[] = "$Id: res_de
 #include <arpa/inet.h>
 #include <arpa/nameser.h>
 
+#include <assert.h>
 #include <ctype.h>
 #include <errno.h>
 #include <math.h>
@@ -126,6 +139,15 @@ static const char rcsid[] = "$Id: res_de
 extern const char *_res_opcodes[];
 extern const char *_res_sectioncodes[];
 
+#if 0
+#ifdef __weak_alias
+__weak_alias(res_pquery,__res_pquery)
+__weak_alias(res_nametoclass,__res_nametoclass)
+__weak_alias(res_nametotype,__res_nametotype)
+#endif
+#endif
+
+#ifndef _LIBC
 /*%
  * Print the current options.
  */
@@ -139,6 +161,7 @@ fp_resstat(const res_state statp, FILE *
 			fprintf(file, " %s", p_option(mask));
 	putc('\n', file);
 }
+#endif
 
 static void
 do_section(const res_state statp,
@@ -154,11 +177,11 @@ do_section(const res_state statp,
 	/*
 	 * Print answer records.
 	 */
-	sflag = (statp->pfcode & pflag);
+	sflag = (int)(statp->pfcode & pflag);
 	if (statp->pfcode && !sflag)
 		return;
 
-	buf = malloc(buflen);
+	buf = malloc((size_t)buflen);
 	if (buf == NULL) {
 		fprintf(file, ";; memory allocation failure\n");
 		return;
@@ -185,11 +208,14 @@ do_section(const res_state statp,
 				p_type(ns_rr_type(rr)),
 				p_class(ns_rr_class(rr)));
 		else if (section == ns_s_ar && ns_rr_type(rr) == ns_t_opt) {
-			u_int16_t optcode, optlen, rdatalen = ns_rr_rdlen(rr);
-			u_int32_t ttl = ns_rr_ttl(rr);
+			size_t rdatalen, ttl;
+			uint16_t optcode, optlen;
+
+			rdatalen = ns_rr_rdlen(rr);
+			ttl = ns_rr_ttl(rr);
 
 			fprintf(file,
-				"; EDNS: version: %u, udp=%u, flags=%04x\n",
+				"; EDNS: version: %zu, udp=%u, flags=%04zx\n",
 				(ttl>>16)&0xff, ns_rr_class(rr), ttl&0xffff);
 
 			while (rdatalen >= 4) {
@@ -237,13 +263,13 @@ do_section(const res_state statp,
 			}
 		} else {
 			n = ns_sprintrr(handle, &rr, NULL, NULL,
-					buf, buflen);
+					buf, (u_int)buflen);
 			if (n < 0) {
 				if (errno == ENOSPC) {
 					free(buf);
 					buf = NULL;
 					if (buflen < 131072)
-						buf = malloc(buflen += 1024);
+						buf = malloc((size_t)(buflen += 1024));
 					if (buf == NULL) {
 						fprintf(file,
 					      ";; memory allocation failure\n");
@@ -293,7 +319,7 @@ res_pquery(const res_state statp, const 
 	if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEADX) || rcode)
 		fprintf(file,
 			";; ->>HEADER<<- opcode: %s, status: %s, id: %d\n",
-			_res_opcodes[opcode], p_rcode(rcode), id);
+			_res_opcodes[opcode], p_rcode((int)rcode), id);
 	if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEADX))
 		putc(';', file);
 	if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEAD2)) {
@@ -317,13 +343,13 @@ res_pquery(const res_state statp, const 
 	}
 	if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEAD1)) {
 		fprintf(file, "; %s: %d",
-			p_section(ns_s_qd, opcode), qdcount);
+			p_section(ns_s_qd, (int)opcode), qdcount);
 		fprintf(file, ", %s: %d",
-			p_section(ns_s_an, opcode), ancount);
+			p_section(ns_s_an, (int)opcode), ancount);
 		fprintf(file, ", %s: %d",
-			p_section(ns_s_ns, opcode), nscount);
+			p_section(ns_s_ns, (int)opcode), nscount);
 		fprintf(file, ", %s: %d",
-			p_section(ns_s_ar, opcode), arcount);
+			p_section(ns_s_ar, (int)opcode), arcount);
 	}
 	if ((!statp->pfcode) || (statp->pfcode &
 		(RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
@@ -346,7 +372,7 @@ p_cdnname(const u_char *cp, const u_char
 	char name[MAXDNAME];
 	int n;
 
-	if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0)
+	if ((n = dn_expand(msg, msg + len, cp, name, (int)sizeof name)) < 0)
 		return (NULL);
 	if (name[0] == '\0')
 		putc('.', file);
@@ -365,19 +391,17 @@ p_cdname(const u_char *cp, const u_char 
    length supplied).  */
 
 const u_char *
-p_fqnname(cp, msg, msglen, name, namelen)
-	const u_char *cp, *msg;
-	int msglen;
-	char *name;
-	int namelen;
+p_fqnname(const u_char *cp, const u_char *msg, int msglen, char *name,
+    int namelen)
 {
-	int n, newlen;
+	int n;
+	size_t newlen;
 
 	if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0)
 		return (NULL);
 	newlen = strlen(name);
 	if (newlen == 0 || name[newlen - 1] != '.') {
-		if (newlen + 1 >= namelen)	/*%< Lack space for final dot */
+		if ((int)newlen + 1 >= namelen)	/*%< Lack space for final dot */
 			return (NULL);
 		else
 			strcpy(name + newlen, ".");
@@ -392,7 +416,7 @@ p_fqname(const u_char *cp, const u_char 
 	char name[MAXDNAME];
 	const u_char *n;
 
-	n = p_fqnname(cp, msg, MAXCDNAME, name, sizeof name);
+	n = p_fqnname(cp, msg, MAXCDNAME, name, (int)sizeof name);
 	if (n == NULL)
 		return (NULL);
 	fputs(name, file);
@@ -553,7 +577,7 @@ const struct res_sym __p_rcode_syms[] = 
 
 int
 sym_ston(const struct res_sym *syms, const char *name, int *success) {
-	for ((void)NULL; syms->name != 0; syms++) {
+	for (; syms->name != 0; syms++) {
 		if (strcasecmp (name, syms->name) == 0) {
 			if (success)
 				*success = 1;
@@ -569,7 +593,7 @@ const char *
 sym_ntos(const struct res_sym *syms, int number, int *success) {
 	char *unname = sym_ntos_unname;
 
-	for ((void)NULL; syms->name != 0; syms++) {
+	for (; syms->name != 0; syms++) {
 		if (number == syms->number) {
 			if (success)
 				*success = 1;
@@ -587,7 +611,7 @@ const char *
 sym_ntop(const struct res_sym *syms, int number, int *success) {
 	char *unname = sym_ntop_unname;
 
-	for ((void)NULL; syms->name != 0; syms++) {
+	for (; syms->name != 0; syms++) {
 		if (number == syms->number) {
 			if (success)
 				*success = 1;
@@ -705,7 +729,7 @@ const char *
 p_time(u_int32_t value) {
 	char *nbuf = p_time_nbuf;
 
-	if (ns_format_ttl(value, nbuf, sizeof nbuf) < 0)
+	if (ns_format_ttl((u_long)value, nbuf, sizeof nbuf) < 0)
 		sprintf(nbuf, "%u", value);
 	return (nbuf);
 }
@@ -727,7 +751,7 @@ p_sockun(union res_sockaddr_union u, cha
 
 	switch (u.sin.sin_family) {
 	case AF_INET:
-		inet_ntop(AF_INET, &u.sin.sin_addr, ret, sizeof ret);
+		inet_ntop(AF_INET, &u.sin.sin_addr, ret, (socklen_t)sizeof ret);
 		break;
 #ifdef HAS_INET6_STRUCTS
 	case AF_INET6:
@@ -756,8 +780,7 @@ static unsigned int poweroften[10] = {1,
 
 /*% takes an XeY precision/size value, returns a string representation. */
 static const char *
-precsize_ntoa(prec)
-	u_int8_t prec;
+precsize_ntoa(u_int32_t prec)
 {
 	char *retbuf = precsize_ntoa_retbuf;
 	unsigned long val;
@@ -910,9 +933,7 @@ latlon2ul(const char **latlonstrptr, int
  * converts a zone file representation in a string to an RDATA on-the-wire
  * representation. */
 int
-loc_aton(ascii, binary)
-	const char *ascii;
-	u_char *binary;
+loc_aton(const char *ascii, u_char *binary)
 {
 	const char *cp, *maxcp;
 	u_char *bcp;
@@ -1021,9 +1042,7 @@ loc_aton(ascii, binary)
 
 /*% takes an on-the-wire LOC RR and formats it in a human readable format. */
 const char *
-loc_ntoa(binary, ascii)
-	const u_char *binary;
-	char *ascii;
+loc_ntoa(const u_char *binary, char *ascii)
 {
 	static const char *error = "?";
 	static char tmpbuf[sizeof
@@ -1105,9 +1124,9 @@ loc_ntoa(binary, ascii)
 	altfrac = altval % 100;
 	altmeters = (altval / 100);
 
-	sizestr = strdup(precsize_ntoa(sizeval));
-	hpstr = strdup(precsize_ntoa(hpval));
-	vpstr = strdup(precsize_ntoa(vpval));
+	sizestr = strdup(precsize_ntoa((u_int32_t)sizeval));
+	hpstr = strdup(precsize_ntoa((u_int32_t)hpval));
+	vpstr = strdup(precsize_ntoa((u_int32_t)vpval));
 
 	sprintf(ascii,
 	    "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %s%d.%.2dm %sm %sm %sm",
@@ -1132,7 +1151,7 @@ loc_ntoa(binary, ascii)
 /*% Return the number of DNS hierarchy levels in the name. */
 int
 dn_count_labels(const char *name) {
-	int i, len, count;
+	size_t len, i, count;
 
 	len = strlen(name);
 	for (i = 0, count = 0; i < len; i++) {
@@ -1151,7 +1170,8 @@ dn_count_labels(const char *name) {
 	/* count to include last label */
 	if (len > 0 && name[len-1] != '.')
 		count++;
-	return (count);
+	_DIAGASSERT(__type_fit(int, count));
+	return (int)count;
 }
 
 /*%
@@ -1160,21 +1180,22 @@ dn_count_labels(const char *name) {
  */
 char *
 p_secstodate (u_long secs) {
+	/* XXX nonreentrant */
 	char *output = p_secstodate_output;
-	time_t clock = secs;
-	struct tm *time;
+	time_t myclock = secs;
+	struct tm *mytime;
 #ifdef HAVE_TIME_R
 	struct tm res;
-
-	time = gmtime_r(&clock, &res);
+	
+	mytime = gmtime_r(&myclock, &res);
 #else
-	time = gmtime(&clock);
+	mytime = gmtime(&myclock);
 #endif
-	time->tm_year += 1900;
-	time->tm_mon += 1;
+	mytime->tm_year += 1900;
+	mytime->tm_mon += 1;
 	sprintf(output, "%04d%02d%02d%02d%02d%02d",
-		time->tm_year, time->tm_mon, time->tm_mday,
-		time->tm_hour, time->tm_min, time->tm_sec);
+		mytime->tm_year, mytime->tm_mon, mytime->tm_mday,
+		mytime->tm_hour, mytime->tm_min, mytime->tm_sec);
 	return (output);
 }
 
@@ -1198,7 +1219,7 @@ res_nametoclass(const char *buf, int *su
  done:
 	if (successp)
 		*successp = success;
-	return (result);
+	return (u_int16_t)(result);
 }
 
 u_int16_t
@@ -1221,7 +1242,7 @@ res_nametotype(const char *buf, int *suc
  done:
 	if (successp)
 		*successp = success;
-	return (result);
+	return (u_int16_t)(result);
 }
 
 /*! \file */
diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_debug.h /usr/src/lib/libc/resolv/res_debug.h
--- /home/reed/src/isc/libbind/libbind/resolv/res_debug.h	2005-04-26 23:56:41.000000000 -0500
+++ /usr/src/lib/libc/resolv/res_debug.h	2013-06-05 09:26:14.000000000 -0500
@@ -1,3 +1,5 @@
+/*	$NetBSD: res_debug.h,v 1.2 2012/03/13 21:13:43 christos Exp $	*/
+
 /*
  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
  * Copyright (c) 1999 by Internet Software Consortium.
@@ -27,7 +29,7 @@
 #   define Dprint(cond, args) if (cond) {fprintf args;} else {}
 #   define DprintQ(cond, args, query, size) if (cond) {\
 			fprintf args;\
-			res_pquery(statp, query, size, stdout);\
+			res_pquery(statp, (query), (int)(size), stdout);\
 		} else {}
 #endif
 
diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_findzonecut.c /usr/src/lib/libc/resolv/res_findzonecut.c
--- /home/reed/src/isc/libbind/libbind/resolv/res_findzonecut.c	2005-10-10 19:10:16.000000000 -0500
+++ /usr/src/lib/libc/resolv/res_findzonecut.c	1969-12-31 18:00:00.000000000 -0600
@@ -1,722 +0,0 @@
-#if !defined(lint) && !defined(SABER)
-static const char rcsid[] = "$Id: res_findzonecut.c,v 1.10 2005/10/11 00:10:16 marka Exp $";
-#endif /* not lint */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1999 by Internet Software Consortium.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* Import. */
-
-#include "port_before.h"
-
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <arpa/nameser.h>
-
-#include <errno.h>
-#include <limits.h>
-#include <netdb.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <isc/list.h>
-
-#include "port_after.h"
-
-#include <resolv.h>
-
-/* Data structures. */
-
-typedef struct rr_a {
-	LINK(struct rr_a)	link;
-	union res_sockaddr_union addr;
-} rr_a;
-typedef LIST(rr_a) rrset_a;
-
-typedef struct rr_ns {
-	LINK(struct rr_ns)	link;
-	const char *		name;
-	unsigned int		flags;
-	rrset_a			addrs;
-} rr_ns;
-typedef LIST(rr_ns) rrset_ns;
-
-#define	RR_NS_HAVE_V4		0x01
-#define	RR_NS_HAVE_V6		0x02
-
-/* Forward. */
-
-static int	satisfy(res_state, const char *, rrset_ns *,
-			union res_sockaddr_union *, int);
-static int	add_addrs(res_state, rr_ns *,
-			  union res_sockaddr_union *, int);
-static int	get_soa(res_state, const char *, ns_class, int,
-			char *, size_t, char *, size_t,
-			rrset_ns *);
-static int	get_ns(res_state, const char *, ns_class, int, rrset_ns *);
-static int	get_glue(res_state, ns_class, int, rrset_ns *);
-static int	save_ns(res_state, ns_msg *, ns_sect,
-			const char *, ns_class, int, rrset_ns *);
-static int	save_a(res_state, ns_msg *, ns_sect,
-		       const char *, ns_class, int, rr_ns *);
-static void	free_nsrrset(rrset_ns *);
-static void	free_nsrr(rrset_ns *, rr_ns *);
-static rr_ns *	find_ns(rrset_ns *, const char *);
-static int	do_query(res_state, const char *, ns_class, ns_type,
-			 u_char *, ns_msg *);
-static void	res_dprintf(const char *, ...) ISC_FORMAT_PRINTF(1, 2);
-
-/* Macros. */
-
-#define DPRINTF(x) do {\
-		int save_errno = errno; \
-		if ((statp->options & RES_DEBUG) != 0U) res_dprintf x; \
-		errno = save_errno; \
-	} while (0)
-
-/* Public. */
-
-/*%
- *	find enclosing zone for a <dname,class>, and some server addresses
- *
- * parameters:
- *\li	res - resolver context to work within (is modified)
- *\li	dname - domain name whose enclosing zone is desired
- *\li	class - class of dname (and its enclosing zone)
- *\li	zname - found zone name
- *\li	zsize - allocated size of zname
- *\li	addrs - found server addresses
- *\li	naddrs - max number of addrs
- *
- * return values:
- *\li	< 0 - an error occurred (check errno)
- *\li	= 0 - zname is now valid, but addrs[] wasn't changed
- *\li	> 0 - zname is now valid, and return value is number of addrs[] found
- *
- * notes:
- *\li	this function calls res_nsend() which means it depends on correctly
- *	functioning recursive nameservers (usually defined in /etc/resolv.conf
- *	or its local equivilent).
- *
- *\li	we start by asking for an SOA<dname,class>.  if we get one as an
- *	answer, that just means <dname,class> is a zone top, which is fine.
- *	more than likely we'll be told to go pound sand, in the form of a
- *	negative answer.
- *
- *\li	note that we are not prepared to deal with referrals since that would
- *	only come from authority servers and our correctly functioning local
- *	recursive server would have followed the referral and got us something
- *	more definite.
- *
- *\li	if the authority section contains an SOA, this SOA should also be the
- *	closest enclosing zone, since any intermediary zone cuts would've been
- *	returned as referrals and dealt with by our correctly functioning local
- *	recursive name server.  but an SOA in the authority section should NOT
- *	match our dname (since that would have been returned in the answer
- *	section).  an authority section SOA has to be "above" our dname.
- *
- *\li	however, since authority section SOA's were once optional, it's
- *	possible that we'll have to go hunting for the enclosing SOA by
- *	ripping labels off the front of our dname -- this is known as "doing
- *	it the hard way."
- *
- *\li	ultimately we want some server addresses, which are ideally the ones
- *	pertaining to the SOA.MNAME, but only if there is a matching NS RR.
- *	so the second phase (after we find an SOA) is to go looking for the
- *	NS RRset for that SOA's zone.
- *
- *\li	no answer section processed by this code is allowed to contain CNAME
- *	or DNAME RR's.  for the SOA query this means we strip a label and
- *	keep going.  for the NS and A queries this means we just give up.
- */
-
-int
-res_findzonecut(res_state statp, const char *dname, ns_class class, int opts,
-		char *zname, size_t zsize, struct in_addr *addrs, int naddrs)
-{
-	int result, i;
-	union res_sockaddr_union *u;
-
-	
-	opts |= RES_IPV4ONLY;
-	opts &= ~RES_IPV6ONLY;
-
-	u = calloc(naddrs, sizeof(*u));
-	if (u == NULL)
-		return(-1);
-
-	result = res_findzonecut2(statp, dname, class, opts, zname, zsize,
-				  u, naddrs);
-
-	for (i = 0; i < result; i++) {
-		addrs[i] = u[i].sin.sin_addr;
-	}
-	free(u);
-	return (result);
-}
-
-int
-res_findzonecut2(res_state statp, const char *dname, ns_class class, int opts,
-		 char *zname, size_t zsize, union res_sockaddr_union *addrs,
-		 int naddrs)
-{
-	char mname[NS_MAXDNAME];
-	u_long save_pfcode;
-	rrset_ns nsrrs;
-	int n;
-
-	DPRINTF(("START dname='%s' class=%s, zsize=%ld, naddrs=%d",
-		 dname, p_class(class), (long)zsize, naddrs));
-	save_pfcode = statp->pfcode;
-	statp->pfcode |= RES_PRF_HEAD2 | RES_PRF_HEAD1 | RES_PRF_HEADX |
-			 RES_PRF_QUES | RES_PRF_ANS |
-			 RES_PRF_AUTH | RES_PRF_ADD;
-	INIT_LIST(nsrrs);
-
-	DPRINTF(("get the soa, and see if it has enough glue"));
-	if ((n = get_soa(statp, dname, class, opts, zname, zsize,
-			 mname, sizeof mname, &nsrrs)) < 0 ||
-	    ((opts & RES_EXHAUSTIVE) == 0 &&
-	     (n = satisfy(statp, mname, &nsrrs, addrs, naddrs)) > 0))
-		goto done;
-
-	DPRINTF(("get the ns rrset and see if it has enough glue"));
-	if ((n = get_ns(statp, zname, class, opts, &nsrrs)) < 0 ||
-	    ((opts & RES_EXHAUSTIVE) == 0 &&
-	     (n = satisfy(statp, mname, &nsrrs, addrs, naddrs)) > 0))
-		goto done;
-
-	DPRINTF(("get the missing glue and see if it's finally enough"));
-	if ((n = get_glue(statp, class, opts, &nsrrs)) >= 0)
-		n = satisfy(statp, mname, &nsrrs, addrs, naddrs);
-
- done:
-	DPRINTF(("FINISH n=%d (%s)", n, (n < 0) ? strerror(errno) : "OK"));
-	free_nsrrset(&nsrrs);
-	statp->pfcode = save_pfcode;
-	return (n);
-}
-
-/* Private. */
-
-static int
-satisfy(res_state statp, const char *mname, rrset_ns *nsrrsp,
-	union res_sockaddr_union *addrs, int naddrs)
-{
-	rr_ns *nsrr;
-	int n, x;
-
-	n = 0;
-	nsrr = find_ns(nsrrsp, mname);
-	if (nsrr != NULL) {
-		x = add_addrs(statp, nsrr, addrs, naddrs);
-		addrs += x;
-		naddrs -= x;
-		n += x;
-	}
-	for (nsrr = HEAD(*nsrrsp);
-	     nsrr != NULL && naddrs > 0;
-	     nsrr = NEXT(nsrr, link))
-		if (ns_samename(nsrr->name, mname) != 1) {
-			x = add_addrs(statp, nsrr, addrs, naddrs);
-			addrs += x;
-			naddrs -= x;
-			n += x;
-		}
-	DPRINTF(("satisfy(%s): %d", mname, n));
-	return (n);
-}
-
-static int
-add_addrs(res_state statp, rr_ns *nsrr,
-	  union res_sockaddr_union *addrs, int naddrs)
-{
-	rr_a *arr;
-	int n = 0;
-
-	for (arr = HEAD(nsrr->addrs); arr != NULL; arr = NEXT(arr, link)) {
-		if (naddrs <= 0)
-			return (0);
-		*addrs++ = arr->addr;
-		naddrs--;
-		n++;
-	}
-	DPRINTF(("add_addrs: %d", n));
-	return (n);
-}
-
-static int
-get_soa(res_state statp, const char *dname, ns_class class, int opts,
-	char *zname, size_t zsize, char *mname, size_t msize,
-	rrset_ns *nsrrsp)
-{
-	char tname[NS_MAXDNAME];
-	u_char *resp = NULL;
-	int n, i, ancount, nscount;
-	ns_sect sect;
-	ns_msg msg;
-	u_int rcode;
-
-	/*
-	 * Find closest enclosing SOA, even if it's for the root zone.
-	 */
-
-	/* First canonicalize dname (exactly one unescaped trailing "."). */
-	if (ns_makecanon(dname, tname, sizeof tname) < 0)
-		goto cleanup;
-	dname = tname;
-
-	resp = malloc(NS_MAXMSG);
-	if (resp == NULL)
-		goto cleanup;
-
-	/* Now grovel the subdomains, hunting for an SOA answer or auth. */
-	for (;;) {
-		/* Leading or inter-label '.' are skipped here. */
-		while (*dname == '.')
-			dname++;
-
-		/* Is there an SOA? */
-		n = do_query(statp, dname, class, ns_t_soa, resp, &msg);
-		if (n < 0) {
-			DPRINTF(("get_soa: do_query('%s', %s) failed (%d)",
-				 dname, p_class(class), n));
-			goto cleanup;
-		}
-		if (n > 0) {
-			DPRINTF(("get_soa: CNAME or DNAME found"));
-			sect = ns_s_max, n = 0;
-		} else {
-			rcode = ns_msg_getflag(msg, ns_f_rcode);
-			ancount = ns_msg_count(msg, ns_s_an);
-			nscount = ns_msg_count(msg, ns_s_ns);
-			if (ancount > 0 && rcode == ns_r_noerror)
-				sect = ns_s_an, n = ancount;
-			else if (nscount > 0)
-				sect = ns_s_ns, n = nscount;
-			else
-				sect = ns_s_max, n = 0;
-		}
-		for (i = 0; i < n; i++) {
-			const char *t;
-			const u_char *rdata;
-			ns_rr rr;
-
-			if (ns_parserr(&msg, sect, i, &rr) < 0) {
-				DPRINTF(("get_soa: ns_parserr(%s, %d) failed",
-					 p_section(sect, ns_o_query), i));
-				goto cleanup;
-			}
-			if (ns_rr_type(rr) == ns_t_cname ||
-			    ns_rr_type(rr) == ns_t_dname)
-				break;
-			if (ns_rr_type(rr) != ns_t_soa ||
-			    ns_rr_class(rr) != class)
-				continue;
-			t = ns_rr_name(rr);
-			switch (sect) {
-			case ns_s_an:
-				if (ns_samedomain(dname, t) == 0) {
-					DPRINTF(
-				    ("get_soa: ns_samedomain('%s', '%s') == 0",
-						dname, t)
-						);
-					errno = EPROTOTYPE;
-					goto cleanup;
-				}
-				break;
-			case ns_s_ns:
-				if (ns_samename(dname, t) == 1 ||
-				    ns_samedomain(dname, t) == 0) {
-					DPRINTF(
-		       ("get_soa: ns_samename() || !ns_samedomain('%s', '%s')",
-						dname, t)
-						);
-					errno = EPROTOTYPE;
-					goto cleanup;
-				}
-				break;
-			default:
-				abort();
-			}
-			if (strlen(t) + 1 > zsize) {
-				DPRINTF(("get_soa: zname(%lu) too small (%lu)",
-					 (unsigned long)zsize,
-					 (unsigned long)strlen(t) + 1));
-				errno = EMSGSIZE;
-				goto cleanup;
-			}
-			strcpy(zname, t);
-			rdata = ns_rr_rdata(rr);
-			if (ns_name_uncompress(resp, ns_msg_end(msg), rdata,
-					       mname, msize) < 0) {
-				DPRINTF(("get_soa: ns_name_uncompress failed")
-					);
-				goto cleanup;
-			}
-			if (save_ns(statp, &msg, ns_s_ns,
-				    zname, class, opts, nsrrsp) < 0) {
-				DPRINTF(("get_soa: save_ns failed"));
-				goto cleanup;
-			}
-			free(resp);
-			return (0);
-		}
-
-		/* If we're out of labels, then not even "." has an SOA! */
-		if (*dname == '\0')
-			break;
-
-		/* Find label-terminating "."; top of loop will skip it. */
-		while (*dname != '.') {
-			if (*dname == '\\')
-				if (*++dname == '\0') {
-					errno = EMSGSIZE;
-					goto cleanup;
-				}
-			dname++;
-		}
-	}
-	DPRINTF(("get_soa: out of labels"));
-	errno = EDESTADDRREQ;
- cleanup:
-	if (resp != NULL)
-		free(resp);
-	return (-1);
-}
-
-static int
-get_ns(res_state statp, const char *zname, ns_class class, int opts,
-      rrset_ns *nsrrsp)
-{
-	u_char *resp;
-	ns_msg msg;
-	int n;
-
-	resp = malloc(NS_MAXMSG);
-	if (resp == NULL)
-		return (-1);
-
-	/* Go and get the NS RRs for this zone. */
-	n = do_query(statp, zname, class, ns_t_ns, resp, &msg);
-	if (n != 0) {
-		DPRINTF(("get_ns: do_query('%s', %s) failed (%d)",
-			 zname, p_class(class), n));
-		free(resp);
-		return (-1);
-	}
-
-	/* Remember the NS RRs and associated A RRs that came back. */
-	if (save_ns(statp, &msg, ns_s_an, zname, class, opts, nsrrsp) < 0) {
-		DPRINTF(("get_ns save_ns('%s', %s) failed",
-			 zname, p_class(class)));
-		free(resp);
-		return (-1);
-	}
-
-	free(resp);
-	return (0);
-}
-
-static int
-get_glue(res_state statp, ns_class class, int opts, rrset_ns *nsrrsp) {
-	rr_ns *nsrr, *nsrr_n;
-	u_char *resp;
-
-	resp = malloc(NS_MAXMSG);
-	if (resp == NULL)
-		return(-1);
-
-	/* Go and get the A RRs for each empty NS RR on our list. */
-	for (nsrr = HEAD(*nsrrsp); nsrr != NULL; nsrr = nsrr_n) {
-		ns_msg msg;
-		int n;
-
-		nsrr_n = NEXT(nsrr, link);
-
-		if ((nsrr->flags & RR_NS_HAVE_V4) == 0) {
-			n = do_query(statp, nsrr->name, class, ns_t_a,
-				     resp, &msg);
-			if (n < 0) {
-				DPRINTF(
-				       ("get_glue: do_query('%s', %s') failed",
-					nsrr->name, p_class(class)));
-				goto cleanup;
-			}
-			if (n > 0) {
-				DPRINTF((
-			"get_glue: do_query('%s', %s') CNAME or DNAME found",
-					 nsrr->name, p_class(class)));
-			}
-			if (save_a(statp, &msg, ns_s_an, nsrr->name, class,
-				   opts, nsrr) < 0) {
-				DPRINTF(("get_glue: save_r('%s', %s) failed",
-					 nsrr->name, p_class(class)));
-				goto cleanup;
-			}
-		}
-
-		if ((nsrr->flags & RR_NS_HAVE_V6) == 0) {
-			n = do_query(statp, nsrr->name, class, ns_t_aaaa,
-				     resp, &msg);
-			if (n < 0) {
-				DPRINTF(
-				       ("get_glue: do_query('%s', %s') failed",
-					nsrr->name, p_class(class)));
-				goto cleanup;
-			}
-			if (n > 0) {
-				DPRINTF((
-			"get_glue: do_query('%s', %s') CNAME or DNAME found",
-					 nsrr->name, p_class(class)));
-			}
-			if (save_a(statp, &msg, ns_s_an, nsrr->name, class,
-				   opts, nsrr) < 0) {
-				DPRINTF(("get_glue: save_r('%s', %s) failed",
-					 nsrr->name, p_class(class)));
-				goto cleanup;
-			}
-		}
-
-		/* If it's still empty, it's just chaff. */
-		if (EMPTY(nsrr->addrs)) {
-			DPRINTF(("get_glue: removing empty '%s' NS",
-				 nsrr->name));
-			free_nsrr(nsrrsp, nsrr);
-		}
-	}
-	free(resp);
-	return (0);
-
- cleanup:
-	free(resp);
-	return (-1);
-}
-
-static int
-save_ns(res_state statp, ns_msg *msg, ns_sect sect,
-	const char *owner, ns_class class, int opts,
-	rrset_ns *nsrrsp)
-{
-	int i;
-
-	for (i = 0; i < ns_msg_count(*msg, sect); i++) {
-		char tname[MAXDNAME];
-		const u_char *rdata;
-		rr_ns *nsrr;
-		ns_rr rr;
-
-		if (ns_parserr(msg, sect, i, &rr) < 0) {
-			DPRINTF(("save_ns: ns_parserr(%s, %d) failed",
-				 p_section(sect, ns_o_query), i));
-			return (-1);
-		}
-		if (ns_rr_type(rr) != ns_t_ns ||
-		    ns_rr_class(rr) != class ||
-		    ns_samename(ns_rr_name(rr), owner) != 1)
-			continue;
-		nsrr = find_ns(nsrrsp, ns_rr_name(rr));
-		if (nsrr == NULL) {
-			nsrr = malloc(sizeof *nsrr);
-			if (nsrr == NULL) {
-				DPRINTF(("save_ns: malloc failed"));
-				return (-1);
-			}
-			rdata = ns_rr_rdata(rr);
-			if (ns_name_uncompress(ns_msg_base(*msg),
-					       ns_msg_end(*msg), rdata,
-					       tname, sizeof tname) < 0) {
-				DPRINTF(("save_ns: ns_name_uncompress failed")
-					);
-				free(nsrr);
-				return (-1);
-			}
-			nsrr->name = strdup(tname);
-			if (nsrr->name == NULL) {
-				DPRINTF(("save_ns: strdup failed"));
-				free(nsrr);
-				return (-1);
-			}
-			INIT_LINK(nsrr, link);
-			INIT_LIST(nsrr->addrs);
-			nsrr->flags = 0;
-			APPEND(*nsrrsp, nsrr, link);
-		}
-		if (save_a(statp, msg, ns_s_ar,
-			   nsrr->name, class, opts, nsrr) < 0) {
-			DPRINTF(("save_ns: save_r('%s', %s) failed",
-				 nsrr->name, p_class(class)));
-			return (-1);
-		}
-	}
-	return (0);
-}
-
-static int
-save_a(res_state statp, ns_msg *msg, ns_sect sect,
-       const char *owner, ns_class class, int opts,
-       rr_ns *nsrr)
-{
-	int i;
-
-	for (i = 0; i < ns_msg_count(*msg, sect); i++) {
-		ns_rr rr;
-		rr_a *arr;
-
-		if (ns_parserr(msg, sect, i, &rr) < 0) {
-			DPRINTF(("save_a: ns_parserr(%s, %d) failed",
-				 p_section(sect, ns_o_query), i));
-			return (-1);
-		}
-		if ((ns_rr_type(rr) != ns_t_a &&
-		     ns_rr_type(rr) != ns_t_aaaa) ||
-		    ns_rr_class(rr) != class ||
-		    ns_samename(ns_rr_name(rr), owner) != 1 ||
-		    ns_rr_rdlen(rr) != NS_INADDRSZ)
-			continue;
-		if ((opts & RES_IPV6ONLY) != 0 && ns_rr_type(rr) != ns_t_aaaa)
-			continue;
-		if ((opts & RES_IPV4ONLY) != 0 && ns_rr_type(rr) != ns_t_a)
-			continue;
-		arr = malloc(sizeof *arr);
-		if (arr == NULL) {
-			DPRINTF(("save_a: malloc failed"));
-			return (-1);
-		}
-		INIT_LINK(arr, link);
-		memset(&arr->addr, 0, sizeof(arr->addr));
-		switch (ns_rr_type(rr)) {
-		case ns_t_a:
-			arr->addr.sin.sin_family = AF_INET;
-#ifdef HAVE_SA_LEN
-			arr->addr.sin.sin_len = sizeof(arr->addr.sin);
-#endif
-			memcpy(&arr->addr.sin.sin_addr, ns_rr_rdata(rr),
-			       NS_INADDRSZ);
-			arr->addr.sin.sin_port = htons(NAMESERVER_PORT);
-			nsrr->flags |= RR_NS_HAVE_V4;
-			break;
-		case ns_t_aaaa:
-			arr->addr.sin6.sin6_family = AF_INET6;
-#ifdef HAVE_SA_LEN
-			arr->addr.sin6.sin6_len = sizeof(arr->addr.sin6);
-#endif
-			memcpy(&arr->addr.sin6.sin6_addr, ns_rr_rdata(rr), 16);
-			arr->addr.sin.sin_port = htons(NAMESERVER_PORT);
-			nsrr->flags |= RR_NS_HAVE_V6;
-			break;
-		default:
-			abort();
-		}
-		APPEND(nsrr->addrs, arr, link);
-	}
-	return (0);
-}
-
-static void
-free_nsrrset(rrset_ns *nsrrsp) {
-	rr_ns *nsrr;
-
-	while ((nsrr = HEAD(*nsrrsp)) != NULL)
-		free_nsrr(nsrrsp, nsrr);
-}
-
-static void
-free_nsrr(rrset_ns *nsrrsp, rr_ns *nsrr) {
-	rr_a *arr;
-	char *tmp;
-
-	while ((arr = HEAD(nsrr->addrs)) != NULL) {
-		UNLINK(nsrr->addrs, arr, link);
-		free(arr);
-	}
-	DE_CONST(nsrr->name, tmp);
-	free(tmp);
-	UNLINK(*nsrrsp, nsrr, link);
-	free(nsrr);
-}
-
-static rr_ns *
-find_ns(rrset_ns *nsrrsp, const char *dname) {
-	rr_ns *nsrr;
-
-	for (nsrr = HEAD(*nsrrsp); nsrr != NULL; nsrr = NEXT(nsrr, link))
-		if (ns_samename(nsrr->name, dname) == 1)
-			return (nsrr);
-	return (NULL);
-}
-
-static int
-do_query(res_state statp, const char *dname, ns_class class, ns_type qtype,
-	 u_char *resp, ns_msg *msg)
-{
-	u_char req[NS_PACKETSZ];
-	int i, n;
-
-	n = res_nmkquery(statp, ns_o_query, dname, class, qtype,
-			 NULL, 0, NULL, req, NS_PACKETSZ);
-	if (n < 0) {
-		DPRINTF(("do_query: res_nmkquery failed"));
-		return (-1);
-	}
-	n = res_nsend(statp, req, n, resp, NS_MAXMSG);
-	if (n < 0) {
-		DPRINTF(("do_query: res_nsend failed"));
-		return (-1);
-	}
-	if (n == 0) {
-		DPRINTF(("do_query: res_nsend returned 0"));
-		errno = EMSGSIZE;
-		return (-1);
-	}
-	if (ns_initparse(resp, n, msg) < 0) {
-		DPRINTF(("do_query: ns_initparse failed"));
-		return (-1);
-	}
-	n = 0;
-	for (i = 0; i < ns_msg_count(*msg, ns_s_an); i++) {
-		ns_rr rr;
-
-		if (ns_parserr(msg, ns_s_an, i, &rr) < 0) {
-			DPRINTF(("do_query: ns_parserr failed"));
-			return (-1);
-		}
-		n += (ns_rr_class(rr) == class &&
-		      (ns_rr_type(rr) == ns_t_cname ||
-		       ns_rr_type(rr) == ns_t_dname));
-	}
-	return (n);
-}
-
-static void
-res_dprintf(const char *fmt, ...) {
-	va_list ap;
-
-	va_start(ap, fmt);
-	fputs(";; res_findzonecut: ", stderr);
-	vfprintf(stderr, fmt, ap);
-	fputc('\n', stderr);
-	va_end(ap);
-}
-
-/*! \file */
diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_init.c /usr/src/lib/libc/resolv/res_init.c
--- /home/reed/src/isc/libbind/libbind/resolv/res_init.c	2013-04-04 17:43:30.000000000 -0500
+++ /usr/src/lib/libc/resolv/res_init.c	2013-06-05 09:26:14.000000000 -0500
@@ -1,3 +1,5 @@
+/*	$NetBSD: res_init.c,v 1.26 2012/09/09 18:04:26 christos Exp $	*/
+
 /*
  * Copyright (c) 1985, 1989, 1993
  *    The Regents of the University of California.  All rights reserved.
@@ -10,7 +12,11 @@
  * 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 University nor the names of its contributors
+ * 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.
  * 
@@ -64,17 +70,25 @@
  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <sys/cdefs.h>
 #if defined(LIBC_SCCS) && !defined(lint)
+#ifdef notdef
 static const char sccsid[] = "@(#)res_init.c	8.1 (Berkeley) 6/7/93";
-static const char rcsid[] = "$Id: res_init.c,v 1.29 2013-01-06 23:14:54 marka Exp $";
+static const char rcsid[] = "Id: res_init.c,v 1.26 2008/12/11 09:59:00 marka Exp";
+#else
+__RCSID("$NetBSD: res_init.c,v 1.26 2012/09/09 18:04:26 christos Exp $");
+#endif
 #endif /* LIBC_SCCS and not lint */
 
 #include "port_before.h"
 
+#include "namespace.h"
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/socket.h>
+#include <sys/stat.h>
 #include <sys/time.h>
+#include <sys/event.h>
 
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -85,8 +99,12 @@ static const char rcsid[] = "$Id: res_in
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <fcntl.h>
 #include <netdb.h>
 
+#define HAVE_MD5
+#include <md5.h>
+
 #ifndef HAVE_MD5
 # include "../dst/md5.h"
 #else
@@ -100,31 +118,50 @@ static const char rcsid[] = "$Id: res_in
 
 #include "port_after.h"
 
+#if 0
+#ifdef __weak_alias
+__weak_alias(res_ninit,_res_ninit)
+__weak_alias(res_randomid,__res_randomid)
+__weak_alias(res_nclose,_res_nclose)
+__weak_alias(res_ndestroy,_res_ndestroy)
+__weak_alias(res_get_nibblesuffix,__res_get_nibblesuffix)
+__weak_alias(res_get_nibblesuffix2,__res_get_nibblesuffix2)
+__weak_alias(res_getservers,__res_getservers)
+__weak_alias(res_setservers,__res_setservers)
+#endif
+#endif
+
+
 /* ensure that sockaddr_in6 and IN6ADDR_ANY_INIT are declared / defined */
 #include <resolv.h>
 
 #include "res_private.h"
 
-/*% Options.  Should all be left alone. */
 #define RESOLVSORT
+/*% Options.  Should all be left alone. */
+#ifndef DEBUG
 #define DEBUG
+#endif
 
 #ifdef SOLARIS2
 #include <sys/systeminfo.h>
 #endif
 
-static void res_setoptions __P((res_state, const char *, const char *));
+static void res_setoptions(res_state, const char *, const char *);
 
 #ifdef RESOLVSORT
 static const char sort_mask[] = "/&";
 #define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL)
-static u_int32_t net_mask __P((struct in_addr));
+static uint32_t net_mask(struct in_addr);
 #endif
 
 #if !defined(isascii)	/*%< XXX - could be a function */
 # define isascii(c) (!(c & 0200))
 #endif
 
+static struct timespec __res_conf_time;
+static const struct timespec ts = { 0, 0 };
+
 /*
  * Resolver state default settings.
  */
@@ -152,8 +189,6 @@ static u_int32_t net_mask __P((struct in
  */
 int
 res_ninit(res_state statp) {
-	extern int __res_vinit(res_state, int);
-
 	return (__res_vinit(statp, 0));
 }
 
@@ -176,16 +211,18 @@ __res_vinit(res_state statp, int preinit
 	int maxns = MAXNS;
 
 	RES_SET_H_ERRNO(statp, 0);
-	if (statp->_u._ext.ext != NULL)
+
+	if ((statp->options & RES_INIT) != 0U)
 		res_ndestroy(statp);
 
 	if (!preinit) {
 		statp->retrans = RES_TIMEOUT;
 		statp->retry = RES_DFLRETRY;
 		statp->options = RES_DEFAULT;
-		res_rndinit(statp);
-		statp->id = res_nrandomid(statp);
 	}
+	statp->_rnd = malloc(16);
+	res_rndinit(statp);
+	statp->id = res_nrandomid(statp);
 
 	memset(u, 0, sizeof(u));
 #ifdef USELOOPBACK
@@ -262,9 +299,8 @@ __res_vinit(res_state statp, int preinit
 				buf[0] = '.';
 			cp = strchr(buf, '.');
 			cp = (cp == NULL) ? buf : (cp + 1);
-			strncpy(statp->defdname, cp,
-				sizeof(statp->defdname) - 1);
-			statp->defdname[sizeof(statp->defdname) - 1] = '\0';
+			(void)strlcpy(statp->defdname, cp,
+			    sizeof(statp->defdname));
 		}
 	}
 #endif	/* SOLARIS2 */
@@ -310,9 +346,12 @@ __res_vinit(res_state statp, int preinit
 	 line[sizeof(name) - 1] == '\t'))
 
 	nserv = 0;
-	if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
+	if ((fp = fopen(_PATH_RESCONF, "re")) != NULL) {
+	    struct stat st;
+	    struct kevent kc;
+
 	    /* read the config file */
-	    while (fgets(buf, sizeof(buf), fp) != NULL) {
+	    while (fgets(buf, (int)sizeof(buf), fp) != NULL) {
 		/* skip comments */
 		if (*buf == ';' || *buf == '#')
 			continue;
@@ -458,7 +497,19 @@ __res_vinit(res_state statp, int preinit
 #ifdef RESOLVSORT
 	    statp->nsort = nsort;
 #endif
+	    statp->_u._ext.ext->resfd = dup(fileno(fp));
 	    (void) fclose(fp);
+	    if (fstat(statp->_u._ext.ext->resfd, &st) != -1)
+		    __res_conf_time = statp->_u._ext.ext->res_conf_time =
+			st.st_mtimespec;
+	    statp->_u._ext.ext->kq = kqueue1(O_CLOEXEC);
+	    EV_SET(&kc, statp->_u._ext.ext->resfd, EVFILT_VNODE,
+		EV_ADD|EV_ENABLE|EV_CLEAR, NOTE_DELETE|NOTE_WRITE| NOTE_EXTEND|
+		NOTE_ATTRIB|NOTE_LINK|NOTE_RENAME|NOTE_REVOKE, 0, 0);
+	    (void)kevent(statp->_u._ext.ext->kq, &kc, 1, NULL, 0, &ts);
+	} else {
+	    statp->_u._ext.ext->kq = -1;
+	    statp->_u._ext.ext->resfd = -1;
 	}
 /*
  * Last chance to get a nameserver.  This should not normally
@@ -509,11 +560,45 @@ __res_vinit(res_state statp, int preinit
 	return (statp->res_h_errno);
 }
 
+int
+res_check(res_state statp, struct timespec *mtime)
+{
+	/*
+	 * If the times are equal, then we check if there
+	 * was a kevent related to resolv.conf and reload.
+	 * If the times are not equal, then we don't bother
+	 * to check the kevent, because another thread already
+	 * did, loaded and changed the time.
+	 */
+	if (timespeccmp(&statp->_u._ext.ext->res_conf_time,
+	    &__res_conf_time, ==)) {
+		struct kevent ke;
+		if (statp->_u._ext.ext->kq == -1)
+			goto out;
+
+		switch (kevent(statp->_u._ext.ext->kq, NULL, 0, &ke, 1, &ts)) {
+		case 0:
+		case -1:
+out:
+			if (mtime)
+				*mtime = __res_conf_time;
+			return 0;
+		default:
+			break;
+		}
+	}
+	(void)__res_vinit(statp, 0);
+	if (mtime)
+		*mtime = __res_conf_time;
+	return 1;
+}
+
 static void
 res_setoptions(res_state statp, const char *options, const char *source)
 {
 	const char *cp = options;
 	int i;
+	size_t j;
 	struct __res_state_ext *ext = statp->_u._ext.ext;
 
 #ifdef DEBUG
@@ -590,11 +675,12 @@ res_setoptions(res_state statp, const ch
 			statp->options |= RES_USE_INET6;
 		} else if (!strncmp(cp, "rotate", sizeof("rotate") - 1)) {
 			statp->options |= RES_ROTATE;
-		} else if (!strncmp(cp, "blast", sizeof("blast") - 1)) {
-			statp->options |= RES_BLAST;
 		} else if (!strncmp(cp, "no-check-names",
 				    sizeof("no-check-names") - 1)) {
 			statp->options |= RES_NOCHECKNAME;
+		} else if (!strncmp(cp, "check-names",
+				    sizeof("check-names") - 1)) {
+			statp->options &= ~RES_NOCHECKNAME;
 		}
 #ifdef RES_USE_EDNS0
 		else if (!strncmp(cp, "edns0", sizeof("edns0") - 1)) {
@@ -608,17 +694,17 @@ res_setoptions(res_state statp, const ch
 			if (ext == NULL)
 				goto skip;
 			cp += sizeof("nibble:") - 1;
-			i = MIN(strcspn(cp, " \t"), sizeof(ext->nsuffix) - 1);
-			strncpy(ext->nsuffix, cp, i);
-			ext->nsuffix[i] = '\0';
+			j = MIN(strcspn(cp, " \t"), sizeof(ext->nsuffix) - 1);
+			strncpy(ext->nsuffix, cp, j);
+			ext->nsuffix[j] = '\0';
 		}
 		else if (!strncmp(cp, "nibble2:", sizeof("nibble2:") - 1)) {
 			if (ext == NULL)
 				goto skip;
 			cp += sizeof("nibble2:") - 1;
-			i = MIN(strcspn(cp, " \t"), sizeof(ext->nsuffix2) - 1);
-			strncpy(ext->nsuffix2, cp, i);
-			ext->nsuffix2[i] = '\0';
+			j = MIN(strcspn(cp, " \t"), sizeof(ext->nsuffix2) - 1);
+			strncpy(ext->nsuffix2, cp, j);
+			ext->nsuffix2[j] = '\0';
 		}
 		else if (!strncmp(cp, "v6revmode:", sizeof("v6revmode:") - 1)) {
 			cp += sizeof("v6revmode:") - 1;
@@ -642,11 +728,10 @@ res_setoptions(res_state statp, const ch
 
 #ifdef RESOLVSORT
 /* XXX - should really support CIDR which means explicit masks always. */
-static u_int32_t
-net_mask(in)		/*!< XXX - should really use system's version of this  */
-	struct in_addr in;
+static uint32_t
+net_mask(struct in_addr in) /*!< XXX - should really use system's version of this  */
 {
-	register u_int32_t i = ntohl(in.s_addr);
+	register uint32_t i = ntohl(in.s_addr);
 
 	if (IN_CLASSA(i))
 		return (htonl(IN_CLASSA_NET));
@@ -656,43 +741,48 @@ net_mask(in)		/*!< XXX - should really u
 }
 #endif
 
+static u_char srnd[16];
+
 void
 res_rndinit(res_state statp)
 {
 	struct timeval now;
-	u_int32_t u32;
-	u_int16_t u16;
+	uint32_t u32;
+	uint16_t u16;
+	u_char *rnd = statp->_rnd == NULL ? srnd : statp->_rnd;
 
 	gettimeofday(&now, NULL);
-	u32 = now.tv_sec;
-	memcpy(statp->_u._ext._rnd, &u32, 4);
+	u32 = (uint32_t)now.tv_sec;
+	memcpy(rnd, &u32, 4);
 	u32 = now.tv_usec;
-	memcpy(statp->_u._ext._rnd + 4, &u32, 4);
-	u32 += now.tv_sec;
-	memcpy(statp->_u._ext._rnd + 8, &u32, 4);
+	memcpy(rnd + 4, &u32, 4);
+	u32 += (uint32_t)now.tv_sec;
+	memcpy(rnd + 8, &u32, 4);
 	u16 = getpid();
-	memcpy(statp->_u._ext._rnd + 12, &u16, 2);
+	memcpy(rnd + 12, &u16, 2);
 }
 
 u_int
-res_nrandomid(res_state statp) {
+res_nrandomid(res_state statp)
+{
 	struct timeval now;
-	u_int16_t u16;
+	uint16_t u16;
 	MD5_CTX ctx;
+	u_char *rnd = statp->_rnd == NULL ? srnd : statp->_rnd;
 
 	gettimeofday(&now, NULL);
-	u16 = (u_int16_t) (now.tv_sec ^ now.tv_usec);
-	memcpy(statp->_u._ext._rnd + 14, &u16, 2);
+	u16 = (uint16_t) (now.tv_sec ^ now.tv_usec);
+	memcpy(rnd + 14, &u16, 2);
 #ifndef HAVE_MD5
 	MD5_Init(&ctx);
-	MD5_Update(&ctx, statp->_u._ext._rnd, 16);
-	MD5_Final(statp->_u._ext._rnd, &ctx);
+	MD5_Update(&ctx, rnd, 16);
+	MD5_Final(rnd, &ctx);
 #else
 	MD5Init(&ctx);
-	MD5Update(&ctx, statp->_u._ext._rnd, 16);
-	MD5Final(statp->_u._ext._rnd, &ctx);
+	MD5Update(&ctx, rnd, 16);
+	MD5Final(rnd, &ctx);
 #endif
-	memcpy(&u16, statp->_u._ext._rnd + 14, 2);
+	memcpy(&u16, rnd + 14, 2);
 	return ((u_int) u16);
 }
 
@@ -704,7 +794,8 @@ res_nrandomid(res_state statp) {
  * This routine is not expected to be user visible.
  */
 void
-res_nclose(res_state statp) {
+res_nclose(res_state statp)
+{
 	int ns;
 
 	if (statp->_vcsock >= 0) { 
@@ -721,30 +812,43 @@ res_nclose(res_state statp) {
 }
 
 void
-res_ndestroy(res_state statp) {
+res_ndestroy(res_state statp)
+{
 	res_nclose(statp);
-	if (statp->_u._ext.ext != NULL)
+	if (statp->_u._ext.ext != NULL) {
+		if (statp->_u._ext.ext->kq != -1)
+			(void)close(statp->_u._ext.ext->kq);
+		if (statp->_u._ext.ext->resfd != -1)
+			(void)close(statp->_u._ext.ext->resfd);
 		free(statp->_u._ext.ext);
+		statp->_u._ext.ext = NULL;
+	}
+	if (statp->_rnd != NULL) {
+		free(statp->_rnd);
+		statp->_rnd = NULL;
+	}
 	statp->options &= ~RES_INIT;
-	statp->_u._ext.ext = NULL;
 }
 
 const char *
-res_get_nibblesuffix(res_state statp) {
+res_get_nibblesuffix(res_state statp)
+{
 	if (statp->_u._ext.ext)
 		return (statp->_u._ext.ext->nsuffix);
 	return ("ip6.arpa");
 }
 
 const char *
-res_get_nibblesuffix2(res_state statp) {
+res_get_nibblesuffix2(res_state statp)
+{
 	if (statp->_u._ext.ext)
 		return (statp->_u._ext.ext->nsuffix2);
 	return ("ip6.int");
 }
 
 void
-res_setservers(res_state statp, const union res_sockaddr_union *set, int cnt) {
+res_setservers(res_state statp, const union res_sockaddr_union *set, int cnt)
+{
 	int i, nserv;
 	size_t size;
 
@@ -795,10 +899,11 @@ res_setservers(res_state statp, const un
 }
 
 int
-res_getservers(res_state statp, union res_sockaddr_union *set, int cnt) {
+res_getservers(res_state statp, union res_sockaddr_union *set, int cnt)
+{
 	int i;
 	size_t size;
-	u_int16_t family;
+	uint16_t family;
 
 	for (i = 0; i < statp->nscount && i < cnt; i++) {
 		if (statp->_u._ext.ext)
diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_mkquery.c /usr/src/lib/libc/resolv/res_mkquery.c
--- /home/reed/src/isc/libbind/libbind/resolv/res_mkquery.c	2013-06-05 09:33:54.000000000 -0500
+++ /usr/src/lib/libc/resolv/res_mkquery.c	2013-06-05 09:26:14.000000000 -0500
@@ -1,3 +1,5 @@
+/*	$NetBSD: res_mkquery.c,v 1.13 2012/03/13 21:13:43 christos Exp $	*/
+
 /*
  * Portions Copyright (C) 2004, 2005, 2008  Internet Systems Consortium, Inc. ("ISC")
  * Portions Copyright (C) 1996, 1997, 1988, 1999, 2001, 2003  Internet Software Consortium.
@@ -27,7 +29,11 @@
  * 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 University nor the names of its contributors
+ * 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.
  *
@@ -64,24 +70,41 @@
  * SOFTWARE.
  */
 
+#include <sys/cdefs.h>
 #if defined(LIBC_SCCS) && !defined(lint)
+#ifdef notdef
 static const char sccsid[] = "@(#)res_mkquery.c	8.1 (Berkeley) 6/4/93";
-static const char rcsid[] = "$Id: res_mkquery.c,v 1.11 2013-01-06 23:14:54 marka Exp $";
+static const char rcsid[] = "Id: res_mkquery.c,v 1.10 2008/12/11 09:59:00 marka Exp";
+#else
+__RCSID("$NetBSD: res_mkquery.c,v 1.13 2012/03/13 21:13:43 christos Exp $");
+#endif
 #endif /* LIBC_SCCS and not lint */
 
 #include "port_before.h"
+
+#include "namespace.h"
 #include <sys/types.h>
 #include <sys/param.h>
 #include <netinet/in.h>
 #include <arpa/nameser.h>
+#include <assert.h>
 #include <netdb.h>
 #include <resolv.h>
 #include <stdio.h>
 #include <string.h>
 #include "port_after.h"
 
+#if 0
+#ifdef __weak_alias
+__weak_alias(res_nmkquery,_res_nmkquery)
+__weak_alias(res_nopt,_res_nopt)
+#endif
+#endif
+
 /* Options.  Leave them on. */
+#ifndef DEBUG
 #define DEBUG
+#endif
 
 extern const char *_res_opcodes[];
 
@@ -118,7 +141,7 @@ res_nmkquery(res_state statp,
 	if ((buf == NULL) || (buflen < HFIXEDSZ))
 		return (-1);
 	memset(buf, 0, HFIXEDSZ);
-	hp = (HEADER *) buf;
+	hp = (HEADER *)(void *)buf;
 	statp->id = res_nrandomid(statp);
 	hp->id = htons(statp->id);
 	hp->opcode = op;
@@ -138,7 +161,7 @@ res_nmkquery(res_state statp,
 	case NS_NOTIFY_OP:
 		if (ep - cp < QFIXEDSZ)
 			return (-1);
-		if ((n = dn_comp(dname, cp, ep - cp - QFIXEDSZ, dnptrs,
+		if ((n = dn_comp(dname, cp, (int)(ep - cp - QFIXEDSZ), dnptrs,
 		    lastdnptr)) < 0)
 			return (-1);
 		cp += n;
@@ -154,7 +177,7 @@ res_nmkquery(res_state statp,
 		 */
 		if ((ep - cp) < RRFIXEDSZ)
 			return (-1);
-		n = dn_comp((const char *)data, cp, ep - cp - RRFIXEDSZ,
+		n = dn_comp((const char *)data, cp, (int)(ep - cp - RRFIXEDSZ),
 			    dnptrs, lastdnptr);
 		if (n < 0)
 			return (-1);
@@ -186,7 +209,7 @@ res_nmkquery(res_state statp,
 		ns_put16(datalen, cp);
 		cp += INT16SZ;
 		if (datalen) {
-			memcpy(cp, data, datalen);
+			memcpy(cp, data, (size_t)datalen);
 			cp += datalen;
 		}
 		hp->ancount = htons(1);
@@ -195,7 +218,8 @@ res_nmkquery(res_state statp,
 	default:
 		return (-1);
 	}
-	return (cp - buf);
+	_DIAGASSERT(__type_fit(int, cp - buf));
+	return (int)(cp - buf);
 }
 
 #ifdef RES_USE_EDNS0
@@ -217,7 +241,7 @@ res_nopt(res_state statp,
 		printf(";; res_nopt()\n");
 #endif
 
-	hp = (HEADER *) buf;
+	hp = (HEADER *)(void *)buf;
 	cp = buf + n0;
 	ep = buf + buflen;
 
@@ -247,7 +271,8 @@ res_nopt(res_state statp,
 
 	hp->arcount = htons(ntohs(hp->arcount) + 1);
 
-	return (cp - buf);
+	_DIAGASSERT(__type_fit(int, cp - buf));
+	return (int)(cp - buf);
 }
 
 /*
@@ -287,13 +312,15 @@ res_nopt_rdata(res_state statp,
 	ns_put16(len, cp);
 	cp += INT16SZ;
 
-	memcpy(cp, data, len);
+	memcpy(cp, data, (size_t)len);
 	cp += len;
 
-	len = cp - rdata;
+	_DIAGASSERT(__type_fit(u_short, cp - rdata));
+	len = (u_short)(cp - rdata);
 	ns_put16(len, rdata - 2);	/* Update RDLEN field */
 
-	return (cp - buf);
+	_DIAGASSERT(__type_fit(int, cp - buf));
+	return (int)(cp - buf);
 }
 #endif
 
diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_mkupdate.c /usr/src/lib/libc/resolv/res_mkupdate.c
--- /home/reed/src/isc/libbind/libbind/resolv/res_mkupdate.c	2009-01-20 19:28:19.000000000 -0600
+++ /usr/src/lib/libc/resolv/res_mkupdate.c	1969-12-31 18:00:00.000000000 -0600
@@ -1,1163 +0,0 @@
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1996-1999 by Internet Software Consortium.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*! \file
- * \brief
- * Based on the Dynamic DNS reference implementation by Viraj Bais
- * &lt;viraj_bais@ccm.fm.intel.com>
- */
-
-#if !defined(lint) && !defined(SABER)
-static const char rcsid[] = "$Id: res_mkupdate.c,v 1.10 2008/12/11 09:59:00 marka Exp $";
-#endif /* not lint */
-
-#include "port_before.h"
-
-#include <sys/types.h>
-#include <sys/param.h>
-
-#include <netinet/in.h>
-#include <arpa/nameser.h>
-#include <arpa/inet.h>
-
-#include <errno.h>
-#include <limits.h>
-#include <netdb.h>
-#include <resolv.h>
-#include <res_update.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <ctype.h>
-
-#include "port_after.h"
-
-/* Options.  Leave them on. */
-#define DEBUG
-#define MAXPORT 1024
-
-static int getnum_str(u_char **, u_char *);
-static int gethexnum_str(u_char **, u_char *);
-static int getword_str(char *, int, u_char **, u_char *);
-static int getstr_str(char *, int, u_char **, u_char *);
-
-#define ShrinkBuffer(x)  if ((buflen -= x) < 0) return (-2);
-
-/* Forward. */
-
-int res_protocolnumber(const char *);
-int res_servicenumber(const char *);
-
-/*%
- * Form update packets.
- * Returns the size of the resulting packet if no error
- *
- * On error,
- *	returns 
- *\li              -1 if error in reading a word/number in rdata
- *		   portion for update packets
- *\li		-2 if length of buffer passed is insufficient
- *\li		-3 if zone section is not the first section in
- *		   the linked list, or section order has a problem
- *\li		-4 on a number overflow
- *\li		-5 unknown operation or no records
- */
-int
-res_nmkupdate(res_state statp, ns_updrec *rrecp_in, u_char *buf, int buflen) {
-	ns_updrec *rrecp_start = rrecp_in;
-	HEADER *hp;
-	u_char *cp, *sp2, *startp, *endp;
-	int n, i, soanum, multiline;
-	ns_updrec *rrecp;
-	struct in_addr ina;
-	struct in6_addr in6a;
-        char buf2[MAXDNAME];
-	u_char buf3[MAXDNAME];
-	int section, numrrs = 0, counts[ns_s_max];
-	u_int16_t rtype, rclass;
-	u_int32_t n1, rttl;
-	u_char *dnptrs[20], **dpp, **lastdnptr;
-	int siglen, keylen, certlen;
-
-	/*
-	 * Initialize header fields.
-	 */
-	if ((buf == NULL) || (buflen < HFIXEDSZ))
-		return (-1);
-	memset(buf, 0, HFIXEDSZ);
-	hp = (HEADER *) buf;
-	statp->id = res_nrandomid(statp);
-	hp->id = htons(statp->id);
-	hp->opcode = ns_o_update;
-	hp->rcode = NOERROR;
-	cp = buf + HFIXEDSZ;
-	buflen -= HFIXEDSZ;
-	dpp = dnptrs;
-	*dpp++ = buf;
-	*dpp++ = NULL;
-	lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
-
-	if (rrecp_start == NULL)
-		return (-5);
-	else if (rrecp_start->r_section != S_ZONE)
-		return (-3);
-
-	memset(counts, 0, sizeof counts);
-	for (rrecp = rrecp_start; rrecp; rrecp = NEXT(rrecp, r_glink)) {
-		numrrs++;
-                section = rrecp->r_section;
-		if (section < 0 || section >= ns_s_max)
-			return (-1);
-		counts[section]++;
-		for (i = section + 1; i < ns_s_max; i++)
-			if (counts[i])
-				return (-3);
-		rtype = rrecp->r_type;
-		rclass = rrecp->r_class;
-		rttl = rrecp->r_ttl;
-		/* overload class and type */
-		if (section == S_PREREQ) {
-			rttl = 0;
-			switch (rrecp->r_opcode) {
-			case YXDOMAIN:
-				rclass = C_ANY;
-				rtype = T_ANY;
-				rrecp->r_size = 0;
-				break;
-			case NXDOMAIN:
-				rclass = C_NONE;
-				rtype = T_ANY;
-				rrecp->r_size = 0;
-				break;
-			case NXRRSET:
-				rclass = C_NONE;
-				rrecp->r_size = 0;
-				break;
-			case YXRRSET:
-				if (rrecp->r_size == 0)
-					rclass = C_ANY;
-				break;
-			default:
-				fprintf(stderr,
-					"res_mkupdate: incorrect opcode: %d\n",
-					rrecp->r_opcode);
-				fflush(stderr);
-				return (-1);
-			}
-		} else if (section == S_UPDATE) {
-			switch (rrecp->r_opcode) {
-			case DELETE:
-				rclass = rrecp->r_size == 0 ? C_ANY : C_NONE;
-				break;
-			case ADD:
-				break;
-			default:
-				fprintf(stderr,
-					"res_mkupdate: incorrect opcode: %d\n",
-					rrecp->r_opcode);
-				fflush(stderr);
-				return (-1);
-			}
-		}
-
-		/*
-		 * XXX	appending default domain to owner name is omitted,
-		 *	fqdn must be provided
-		 */
-		if ((n = dn_comp(rrecp->r_dname, cp, buflen, dnptrs,
-				 lastdnptr)) < 0)
-			return (-1);
-		cp += n;
-		ShrinkBuffer(n + 2*INT16SZ);
-		PUTSHORT(rtype, cp);
-		PUTSHORT(rclass, cp);
-		if (section == S_ZONE) {
-			if (numrrs != 1 || rrecp->r_type != T_SOA)
-				return (-3);
-			continue;
-		}
-		ShrinkBuffer(INT32SZ + INT16SZ);
-		PUTLONG(rttl, cp);
-		sp2 = cp;  /*%< save pointer to length byte */
-		cp += INT16SZ;
-		if (rrecp->r_size == 0) {
-			if (section == S_UPDATE && rclass != C_ANY)
-				return (-1);
-			else {
-				PUTSHORT(0, sp2);
-				continue;
-			}
-		}
-		startp = rrecp->r_data;
-		endp = startp + rrecp->r_size - 1;
-		/* XXX this should be done centrally. */
-		switch (rrecp->r_type) {
-		case T_A:
-			if (!getword_str(buf2, sizeof buf2, &startp, endp))
-				return (-1);
-			if (!inet_aton(buf2, &ina))
-				return (-1);
-			n1 = ntohl(ina.s_addr);
-			ShrinkBuffer(INT32SZ);
-			PUTLONG(n1, cp);
-			break;
-		case T_CNAME:
-		case T_MB:
-		case T_MG:
-		case T_MR:
-		case T_NS:
-		case T_PTR:
-		case ns_t_dname:
-			if (!getword_str(buf2, sizeof buf2, &startp, endp))
-				return (-1);
-			n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
-			if (n < 0)
-				return (-1);
-			cp += n;
-			ShrinkBuffer(n);
-			break;
-		case T_MINFO:
-		case T_SOA:
-		case T_RP:
-			for (i = 0; i < 2; i++) {
-				if (!getword_str(buf2, sizeof buf2, &startp,
-						 endp))
-				return (-1);
-				n = dn_comp(buf2, cp, buflen,
-					    dnptrs, lastdnptr);
-				if (n < 0)
-					return (-1);
-				cp += n;
-				ShrinkBuffer(n);
-			}
-			if (rrecp->r_type == T_SOA) {
-				ShrinkBuffer(5 * INT32SZ);
-				while (isspace(*startp) || !*startp)
-					startp++;
-				if (*startp == '(') {
-					multiline = 1;
-					startp++;
-				} else
-					multiline = 0;
-				/* serial, refresh, retry, expire, minimum */
-				for (i = 0; i < 5; i++) {
-					soanum = getnum_str(&startp, endp);
-					if (soanum < 0)
-						return (-1);
-					PUTLONG(soanum, cp);
-				}
-				if (multiline) {
-					while (isspace(*startp) || !*startp)
-						startp++;
-					if (*startp != ')')
-						return (-1);
-				}
-			}
-			break;
-		case T_MX:
-		case T_AFSDB:
-		case T_RT:
-			n = getnum_str(&startp, endp);
-			if (n < 0)
-				return (-1);
-			ShrinkBuffer(INT16SZ);
-			PUTSHORT(n, cp);
-			if (!getword_str(buf2, sizeof buf2, &startp, endp))
-				return (-1);
-			n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
-			if (n < 0)
-				return (-1);
-			cp += n;
-			ShrinkBuffer(n);
-			break;
-		case T_SRV:
-			n = getnum_str(&startp, endp);
-			if (n < 0)
-				return (-1);
-			ShrinkBuffer(INT16SZ);
-			PUTSHORT(n, cp);
-
-			n = getnum_str(&startp, endp);
-			if (n < 0)
-				return (-1);
-			ShrinkBuffer(INT16SZ);
-			PUTSHORT(n, cp);
-
-			n = getnum_str(&startp, endp);
-			if (n < 0)
-				return (-1);
-			ShrinkBuffer(INT16SZ);
-			PUTSHORT(n, cp);
-
-			if (!getword_str(buf2, sizeof buf2, &startp, endp))
-				return (-1);
-			n = dn_comp(buf2, cp, buflen, NULL, NULL);
-			if (n < 0)
-				return (-1);
-			cp += n;
-			ShrinkBuffer(n);
-			break;
-		case T_PX:
-			n = getnum_str(&startp, endp);
-			if (n < 0)
-				return (-1);
-			PUTSHORT(n, cp);
-			ShrinkBuffer(INT16SZ);
-			for (i = 0; i < 2; i++) {
-				if (!getword_str(buf2, sizeof buf2, &startp,
-						 endp))
-					return (-1);
-				n = dn_comp(buf2, cp, buflen, dnptrs,
-					    lastdnptr);
-				if (n < 0)
-					return (-1);
-				cp += n;
-				ShrinkBuffer(n);
-			}
-			break;
-		case T_WKS: {
-			char bm[MAXPORT/8];
-			unsigned int maxbm = 0;
-
-			if (!getword_str(buf2, sizeof buf2, &startp, endp))
-				return (-1);
-			if (!inet_aton(buf2, &ina))
-				return (-1);
-			n1 = ntohl(ina.s_addr);
-			ShrinkBuffer(INT32SZ);
-			PUTLONG(n1, cp);
-
-			if (!getword_str(buf2, sizeof buf2, &startp, endp))
-				return (-1);
-			if ((i = res_protocolnumber(buf2)) < 0)
-				return (-1);
-			ShrinkBuffer(1);
-			*cp++ = i & 0xff;
-			 
-			for (i = 0; i < MAXPORT/8 ; i++)
-				bm[i] = 0;
-
-			while (getword_str(buf2, sizeof buf2, &startp, endp)) {
-				if ((n = res_servicenumber(buf2)) <= 0)
-					return (-1);
-
-				if (n < MAXPORT) {
-					bm[n/8] |= (0x80>>(n%8));
-					if ((unsigned)n > maxbm)
-						maxbm = n;
-				} else
-					return (-1);
-			}
-			maxbm = maxbm/8 + 1;
-			ShrinkBuffer(maxbm);
-			memcpy(cp, bm, maxbm);
-			cp += maxbm;
-			break;
-		}
-		case T_HINFO:
-			for (i = 0; i < 2; i++) {
-				if ((n = getstr_str(buf2, sizeof buf2,
-						&startp, endp)) < 0)
-					return (-1);
-				if (n > 255)
-					return (-1);
-				ShrinkBuffer(n+1);
-				*cp++ = n;
-				memcpy(cp, buf2, n);
-				cp += n;
-			}
-			break;
-		case T_TXT:
-			for (;;) {
-				if ((n = getstr_str(buf2, sizeof buf2,
-						&startp, endp)) < 0) {
-					if (cp != (sp2 + INT16SZ))
-						break;
-					return (-1);
-				}
-				if (n > 255)
-					return (-1);
-				ShrinkBuffer(n+1);
-				*cp++ = n;
-				memcpy(cp, buf2, n);
-				cp += n;
-			}
-			break;
-		case T_X25:
-			/* RFC1183 */
-			if ((n = getstr_str(buf2, sizeof buf2, &startp,
-					 endp)) < 0)
-				return (-1);
-			if (n > 255)
-				return (-1);
-			ShrinkBuffer(n+1);
-			*cp++ = n;
-			memcpy(cp, buf2, n);
-			cp += n;
-			break;
-		case T_ISDN:
-			/* RFC1183 */
-			if ((n = getstr_str(buf2, sizeof buf2, &startp,
-					 endp)) < 0)
-				return (-1);
-			if ((n > 255) || (n == 0))
-				return (-1);
-			ShrinkBuffer(n+1);
-			*cp++ = n;
-			memcpy(cp, buf2, n);
-			cp += n;
-			if ((n = getstr_str(buf2, sizeof buf2, &startp,
-					 endp)) < 0)
-				n = 0;
-			if (n > 255)
-				return (-1);
-			ShrinkBuffer(n+1);
-			*cp++ = n;
-			memcpy(cp, buf2, n);
-			cp += n;
-			break;
-		case T_NSAP:
-			if ((n = inet_nsap_addr((char *)startp, (u_char *)buf2, sizeof(buf2))) != 0) {
-				ShrinkBuffer(n);
-				memcpy(cp, buf2, n);
-				cp += n;
-			} else {
-				return (-1);
-			}
-			break;
-		case T_LOC:
-			if ((n = loc_aton((char *)startp, (u_char *)buf2)) != 0) {
-				ShrinkBuffer(n);
-				memcpy(cp, buf2, n);
-				cp += n;
-			} else
-				return (-1);
-			break;
-		case ns_t_sig:
-		    {
-			int sig_type, success, dateerror;
-			u_int32_t exptime, timesigned;
-
-			/* type */
-			if ((n = getword_str(buf2, sizeof buf2,
-					     &startp, endp)) < 0)
-				return (-1);
-			sig_type = sym_ston(__p_type_syms, buf2, &success);
-			if (!success || sig_type == ns_t_any)
-				return (-1);
-			ShrinkBuffer(INT16SZ);
-			PUTSHORT(sig_type, cp);
-			/* alg */
-			n = getnum_str(&startp, endp);
-			if (n < 0)
-				return (-1);
-			ShrinkBuffer(1);
-			*cp++ = n;
-			/* labels */
-			n = getnum_str(&startp, endp);
-			if (n <= 0 || n > 255)
-				return (-1);
-			ShrinkBuffer(1);
-			*cp++ = n;
-			/* ottl  & expire */
-			if (!getword_str(buf2, sizeof buf2, &startp, endp))
-				return (-1);
-			exptime = ns_datetosecs(buf2, &dateerror);
-			if (!dateerror) {
-				ShrinkBuffer(INT32SZ);
-				PUTLONG(rttl, cp);
-			}
-			else {
-				char *ulendp;
-				u_int32_t ottl;
-
-				errno = 0;
-				ottl = strtoul(buf2, &ulendp, 10);
-				if (errno != 0 ||
-				    (ulendp != NULL && *ulendp != '\0'))
-					return (-1);
-				ShrinkBuffer(INT32SZ);
-				PUTLONG(ottl, cp);
-				if (!getword_str(buf2, sizeof buf2, &startp,
-						 endp))
-					return (-1);
-				exptime = ns_datetosecs(buf2, &dateerror);
-				if (dateerror)
-					return (-1);
-			}
-			/* expire */
-			ShrinkBuffer(INT32SZ);
-			PUTLONG(exptime, cp);
-			/* timesigned */
-			if (!getword_str(buf2, sizeof buf2, &startp, endp))
-				return (-1);
-			timesigned = ns_datetosecs(buf2, &dateerror);
-			if (!dateerror) {
-				ShrinkBuffer(INT32SZ);
-				PUTLONG(timesigned, cp);
-			}
-			else
-				return (-1);
-			/* footprint */
-			n = getnum_str(&startp, endp);
-			if (n < 0)
-				return (-1);
-			ShrinkBuffer(INT16SZ);
-			PUTSHORT(n, cp);
-			/* signer name */
-			if (!getword_str(buf2, sizeof buf2, &startp, endp))
-				return (-1);
-			n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
-			if (n < 0)
-				return (-1);
-			cp += n;
-			ShrinkBuffer(n);
-			/* sig */
-			if ((n = getword_str(buf2, sizeof buf2,
-					     &startp, endp)) < 0)
-				return (-1);
-			siglen = b64_pton(buf2, buf3, sizeof(buf3));
-			if (siglen < 0)
-				return (-1);
-			ShrinkBuffer(siglen);
-			memcpy(cp, buf3, siglen);
-			cp += siglen;
-			break;
-		    }
-		case ns_t_key:
-			/* flags */
-			n = gethexnum_str(&startp, endp);
-			if (n < 0)
-				return (-1);
-			ShrinkBuffer(INT16SZ);
-			PUTSHORT(n, cp);
-			/* proto */
-			n = getnum_str(&startp, endp);
-			if (n < 0)
-				return (-1);
-			ShrinkBuffer(1);
-			*cp++ = n;
-			/* alg */
-			n = getnum_str(&startp, endp);
-			if (n < 0)
-				return (-1);
-			ShrinkBuffer(1);
-			*cp++ = n;
-			/* key */
-			if ((n = getword_str(buf2, sizeof buf2,
-					     &startp, endp)) < 0)
-				return (-1);
-			keylen = b64_pton(buf2, buf3, sizeof(buf3));
-			if (keylen < 0)
-				return (-1);
-			ShrinkBuffer(keylen);
-			memcpy(cp, buf3, keylen);
-			cp += keylen;
-			break;
-		case ns_t_nxt:
-		    {
-			int success, nxt_type;
-			u_char data[32];
-			int maxtype;
-
-			/* next name */
-			if (!getword_str(buf2, sizeof buf2, &startp, endp))
-				return (-1);
-			n = dn_comp(buf2, cp, buflen, NULL, NULL);
-			if (n < 0)
-				return (-1);
-			cp += n;
-			ShrinkBuffer(n);
-			maxtype = 0;
-			memset(data, 0, sizeof data);
-			for (;;) {
-				if (!getword_str(buf2, sizeof buf2, &startp,
-						 endp))
-					break;
-				nxt_type = sym_ston(__p_type_syms, buf2,
-						    &success);
-				if (!success || !ns_t_rr_p(nxt_type))
-					return (-1);
-				NS_NXT_BIT_SET(nxt_type, data);
-				if (nxt_type > maxtype)
-					maxtype = nxt_type;
-			}
-			n = maxtype/NS_NXT_BITS+1;
-			ShrinkBuffer(n);
-			memcpy(cp, data, n);
-			cp += n;
-			break;
-		    }
-		case ns_t_cert:
-			/* type */
-			n = getnum_str(&startp, endp);
-			if (n < 0)
-				return (-1);
-			ShrinkBuffer(INT16SZ);
-			PUTSHORT(n, cp);
-			/* key tag */
-			n = getnum_str(&startp, endp);
-			if (n < 0)
-				return (-1);
-			ShrinkBuffer(INT16SZ);
-			PUTSHORT(n, cp);
-			/* alg */
-			n = getnum_str(&startp, endp);
-			if (n < 0)
-				return (-1);
-			ShrinkBuffer(1);
-			*cp++ = n;
-			/* cert */
-			if ((n = getword_str(buf2, sizeof buf2,
-					     &startp, endp)) < 0)
-				return (-1);
-			certlen = b64_pton(buf2, buf3, sizeof(buf3));
-			if (certlen < 0)
-				return (-1);
-			ShrinkBuffer(certlen);
-			memcpy(cp, buf3, certlen);
-			cp += certlen;
-			break;
-		case ns_t_aaaa:
-			if (!getword_str(buf2, sizeof buf2, &startp, endp))
-				return (-1);
-			if (inet_pton(AF_INET6, buf2, &in6a) <= 0)
-				return (-1);
-			ShrinkBuffer(NS_IN6ADDRSZ);
-			memcpy(cp, &in6a, NS_IN6ADDRSZ);
-			cp += NS_IN6ADDRSZ;
-			break;
-		case ns_t_naptr:
-			/* Order Preference Flags Service Replacement Regexp */
-			/* Order */
-			n = getnum_str(&startp, endp);
-			if (n < 0 || n > 65535)
-				return (-1);
-			ShrinkBuffer(INT16SZ);
-			PUTSHORT(n, cp);
-			/* Preference */
-			n = getnum_str(&startp, endp);
-			if (n < 0 || n > 65535)
-				return (-1);
-			ShrinkBuffer(INT16SZ);
-			PUTSHORT(n, cp);
-			/* Flags */
-			if ((n = getstr_str(buf2, sizeof buf2,
-					&startp, endp)) < 0) {
-				return (-1);
-			}
-			if (n > 255)
-				return (-1);
-			ShrinkBuffer(n+1);
-			*cp++ = n;
-			memcpy(cp, buf2, n);
-			cp += n;
-			/* Service Classes */
-			if ((n = getstr_str(buf2, sizeof buf2,
-					&startp, endp)) < 0) {
-				return (-1);
-			}
-			if (n > 255)
-				return (-1);
-			ShrinkBuffer(n+1);
-			*cp++ = n;
-			memcpy(cp, buf2, n);
-			cp += n;
-			/* Pattern */
-			if ((n = getstr_str(buf2, sizeof buf2,
-					&startp, endp)) < 0) {
-				return (-1);
-			}
-			if (n > 255)
-				return (-1);
-			ShrinkBuffer(n+1);
-			*cp++ = n;
-			memcpy(cp, buf2, n);
-			cp += n;
-			/* Replacement */
-			if (!getword_str(buf2, sizeof buf2, &startp, endp))
-				return (-1);
-			n = dn_comp(buf2, cp, buflen, NULL, NULL);
-			if (n < 0)
-				return (-1);
-			cp += n;
-			ShrinkBuffer(n);
-			break;
-		default:
-			return (-1);
-		} /*switch*/
-		n = (u_int16_t)((cp - sp2) - INT16SZ);
-		PUTSHORT(n, sp2);
-	} /*for*/
-		
-	hp->qdcount = htons(counts[0]);
-	hp->ancount = htons(counts[1]);
-	hp->nscount = htons(counts[2]);
-	hp->arcount = htons(counts[3]);
-	return (cp - buf);
-}
-
-/*%
- * Get a whitespace delimited word from a string (not file)
- * into buf. modify the start pointer to point after the
- * word in the string.
- */
-static int
-getword_str(char *buf, int size, u_char **startpp, u_char *endp) {
-        char *cp;
-        int c;
- 
-        for (cp = buf; *startpp <= endp; ) {
-                c = **startpp;
-                if (isspace(c) || c == '\0') {
-                        if (cp != buf) /*%< trailing whitespace */
-                                break;
-                        else { /*%< leading whitespace */
-                                (*startpp)++;
-                                continue;
-                        }
-                }
-                (*startpp)++;
-                if (cp >= buf+size-1)
-                        break;
-                *cp++ = (u_char)c;
-        }
-        *cp = '\0';
-        return (cp != buf);
-}
-
-/*%
- * get a white spae delimited string from memory.  Process quoted strings
- * and \\DDD escapes.  Return length or -1 on error.  Returned string may
- * contain nulls.
- */
-static char digits[] = "0123456789";
-static int
-getstr_str(char *buf, int size, u_char **startpp, u_char *endp) {
-        char *cp;
-        int c, c1 = 0;
-	int inquote = 0;
-	int seen_quote = 0;
-	int escape = 0;
-	int dig = 0;
- 
-	for (cp = buf; *startpp <= endp; ) {
-                if ((c = **startpp) == '\0')
-			break;
-		/* leading white space */
-		if ((cp == buf) && !seen_quote && isspace(c)) {
-			(*startpp)++;
-			continue;
-		}
-
-		switch (c) {
-		case '\\':
-			if (!escape)  {
-				escape = 1;
-				dig = 0;
-				c1 = 0;
-				(*startpp)++;
-				continue;
-			} 
-			goto do_escape;
-		case '"':
-			if (!escape) {
-				inquote = !inquote;
-				seen_quote = 1;
-				(*startpp)++;
-				continue;
-			}
-			/* fall through */
-		default:
-		do_escape:
-			if (escape) {
-				switch (c) {
-				case '0':
-				case '1':
-				case '2':
-				case '3':
-				case '4':
-				case '5':
-				case '6':
-				case '7':
-				case '8':
-				case '9':
-					c1 = c1 * 10 + 
-						(strchr(digits, c) - digits);
-
-					if (++dig == 3) {
-						c = c1 &0xff;
-						break;
-					}
-					(*startpp)++;
-					continue;
-				}
-				escape = 0;
-			} else if (!inquote && isspace(c))
-				goto done;
-			if (cp >= buf+size-1)
-				goto done;
-			*cp++ = (u_char)c;
-			(*startpp)++;
-		}
-	}
- done:
-	*cp = '\0';
-	return ((cp == buf)?  (seen_quote? 0: -1): (cp - buf));
-}
-
-/*%
- * Get a whitespace delimited base 16 number from a string (not file) into buf
- * update the start pointer to point after the number in the string.
- */
-static int
-gethexnum_str(u_char **startpp, u_char *endp) {
-        int c, n;
-        int seendigit = 0;
-        int m = 0;
-
-	if (*startpp + 2 >= endp || strncasecmp((char *)*startpp, "0x", 2) != 0)
-		return getnum_str(startpp, endp);
-	(*startpp)+=2;
-        for (n = 0; *startpp <= endp; ) {
-                c = **startpp;
-                if (isspace(c) || c == '\0') {
-                        if (seendigit) /*%< trailing whitespace */
-                                break;
-                        else { /*%< leading whitespace */
-                                (*startpp)++;
-                                continue;
-                        }
-                }
-                if (c == ';') {
-                        while ((*startpp <= endp) &&
-			       ((c = **startpp) != '\n'))
-					(*startpp)++;
-                        if (seendigit)
-                                break;
-                        continue;
-                }
-                if (!isxdigit(c)) {
-                        if (c == ')' && seendigit) {
-                                (*startpp)--;
-                                break;
-                        }
-			return (-1);
-                }        
-                (*startpp)++;
-		if (isdigit(c))
-	                n = n * 16 + (c - '0');
-		else
-			n = n * 16 + (tolower(c) - 'a' + 10);
-                seendigit = 1;
-        }
-        return (n + m);
-}
-
-/*%
- * Get a whitespace delimited base 10 number from a string (not file) into buf
- * update the start pointer to point after the number in the string.
- */
-static int
-getnum_str(u_char **startpp, u_char *endp) {
-        int c, n;
-        int seendigit = 0;
-        int m = 0;
-
-        for (n = 0; *startpp <= endp; ) {
-                c = **startpp;
-                if (isspace(c) || c == '\0') {
-                        if (seendigit) /*%< trailing whitespace */
-                                break;
-                        else { /*%< leading whitespace */
-                                (*startpp)++;
-                                continue;
-                        }
-                }
-                if (c == ';') {
-                        while ((*startpp <= endp) &&
-			       ((c = **startpp) != '\n'))
-					(*startpp)++;
-                        if (seendigit)
-                                break;
-                        continue;
-                }
-                if (!isdigit(c)) {
-                        if (c == ')' && seendigit) {
-                                (*startpp)--;
-                                break;
-                        }
-			return (-1);
-                }        
-                (*startpp)++;
-                n = n * 10 + (c - '0');
-                seendigit = 1;
-        }
-        return (n + m);
-}
-
-/*%
- * Allocate a resource record buffer & save rr info.
- */
-ns_updrec *
-res_mkupdrec(int section, const char *dname,
-	     u_int class, u_int type, u_long ttl) {
-	ns_updrec *rrecp = (ns_updrec *)calloc(1, sizeof(ns_updrec));
-
-	if (!rrecp || !(rrecp->r_dname = strdup(dname))) {
-		if (rrecp)
-			free((char *)rrecp);
-		return (NULL);
-	}
-	INIT_LINK(rrecp, r_link);
-	INIT_LINK(rrecp, r_glink);
- 	rrecp->r_class = (ns_class)class;
-	rrecp->r_type = (ns_type)type;
-	rrecp->r_ttl = ttl;
-	rrecp->r_section = (ns_sect)section;
-	return (rrecp);
-}
-
-/*%
- * Free a resource record buffer created by res_mkupdrec.
- */
-void
-res_freeupdrec(ns_updrec *rrecp) {
-	/* Note: freeing r_dp is the caller's responsibility. */
-	if (rrecp->r_dname != NULL)
-		free(rrecp->r_dname);
-	free(rrecp);
-}
-
-struct valuelist {
-	struct valuelist *	next;
-	struct valuelist *	prev;
-	char *			name;
-	char *			proto;
-	int			port;
-};
-static struct valuelist *servicelist, *protolist;
-
-static void
-res_buildservicelist() {
-	struct servent *sp;
-	struct valuelist *slp;
-
-#ifdef MAYBE_HESIOD
-	setservent(0);
-#else
-	setservent(1);
-#endif
-	while ((sp = getservent()) != NULL) {
-		slp = (struct valuelist *)malloc(sizeof(struct valuelist));
-		if (!slp)
-			break;
-		slp->name = strdup(sp->s_name);
-		slp->proto = strdup(sp->s_proto);
-		if ((slp->name == NULL) || (slp->proto == NULL)) {
-			if (slp->name) free(slp->name);
-			if (slp->proto) free(slp->proto);
-			free(slp);
-			break;
-		}
-		slp->port = ntohs((u_int16_t)sp->s_port);  /*%< host byt order */
-		slp->next = servicelist;
-		slp->prev = NULL;
-		if (servicelist)
-			servicelist->prev = slp;
-		servicelist = slp;
-	}
-	endservent();
-}
-
-void
-res_destroyservicelist() {
-	struct valuelist *slp, *slp_next;
-
-	for (slp = servicelist; slp != NULL; slp = slp_next) {
-		slp_next = slp->next;
-		free(slp->name);
-		free(slp->proto);
-		free(slp);
-	}
-	servicelist = (struct valuelist *)0;
-}
-
-void
-res_buildprotolist(void) {
-	struct protoent *pp;
-	struct valuelist *slp;
-
-#ifdef MAYBE_HESIOD
-	setprotoent(0);
-#else
-	setprotoent(1);
-#endif
-	while ((pp = getprotoent()) != NULL) {
-		slp = (struct valuelist *)malloc(sizeof(struct valuelist));
-		if (!slp)
-			break;
-		slp->name = strdup(pp->p_name);
-		if (slp->name == NULL) {
-			free(slp);
-			break;
-		}
-		slp->port = pp->p_proto;	/*%< host byte order */
-		slp->next = protolist;
-		slp->prev = NULL;
-		if (protolist)
-			protolist->prev = slp;
-		protolist = slp;
-	}
-	endprotoent();
-}
-
-void
-res_destroyprotolist(void) {
-	struct valuelist *plp, *plp_next;
-
-	for (plp = protolist; plp != NULL; plp = plp_next) {
-		plp_next = plp->next;
-		free(plp->name);
-		free(plp);
-	}
-	protolist = (struct valuelist *)0;
-}
-
-static int
-findservice(const char *s, struct valuelist **list) {
-	struct valuelist *lp = *list;
-	int n;
-
-	for (; lp != NULL; lp = lp->next)
-		if (strcasecmp(lp->name, s) == 0) {
-			if (lp != *list) {
-				lp->prev->next = lp->next;
-				if (lp->next)
-					lp->next->prev = lp->prev;
-				(*list)->prev = lp;
-				lp->next = *list;
-				*list = lp;
-			}
-			return (lp->port);	/*%< host byte order */
-		}
-	if (sscanf(s, "%d", &n) != 1 || n <= 0)
-		n = -1;
-	return (n);
-}
-
-/*%
- * Convert service name or (ascii) number to int.
- */
-int
-res_servicenumber(const char *p) {
-	if (servicelist == (struct valuelist *)0)
-		res_buildservicelist();
-	return (findservice(p, &servicelist));
-}
-
-/*%
- * Convert protocol name or (ascii) number to int.
- */
-int
-res_protocolnumber(const char *p) {
-	if (protolist == (struct valuelist *)0)
-		res_buildprotolist();
-	return (findservice(p, &protolist));
-}
-
-static struct servent *
-cgetservbyport(u_int16_t port, const char *proto) {	/*%< Host byte order. */
-	struct valuelist **list = &servicelist;
-	struct valuelist *lp = *list;
-	static struct servent serv;
-
-	port = ntohs(port);
-	for (; lp != NULL; lp = lp->next) {
-		if (port != (u_int16_t)lp->port)	/*%< Host byte order. */
-			continue;
-		if (strcasecmp(lp->proto, proto) == 0) {
-			if (lp != *list) {
-				lp->prev->next = lp->next;
-				if (lp->next)
-					lp->next->prev = lp->prev;
-				(*list)->prev = lp;
-				lp->next = *list;
-				*list = lp;
-			}
-			serv.s_name = lp->name;
-			serv.s_port = htons((u_int16_t)lp->port);
-			serv.s_proto = lp->proto;
-			return (&serv);
-		}
-	}
-	return (0);
-}
-
-static struct protoent *
-cgetprotobynumber(int proto) {				/*%< Host byte order. */
-	struct valuelist **list = &protolist;
-	struct valuelist *lp = *list;
-	static struct protoent prot;
-
-	for (; lp != NULL; lp = lp->next)
-		if (lp->port == proto) {		/*%< Host byte order. */
-			if (lp != *list) {
-				lp->prev->next = lp->next;
-				if (lp->next)
-					lp->next->prev = lp->prev;
-				(*list)->prev = lp;
-				lp->next = *list;
-				*list = lp;
-			}
-			prot.p_name = lp->name;
-			prot.p_proto = lp->port;	/*%< Host byte order. */
-			return (&prot);
-		}
-	return (0);
-}
-
-const char *
-res_protocolname(int num) {
-	static char number[8];
-	struct protoent *pp;
-
-	if (protolist == (struct valuelist *)0)
-		res_buildprotolist();
-	pp = cgetprotobynumber(num);
-	if (pp == 0)  {
-		(void) sprintf(number, "%d", num);
-		return (number);
-	}
-	return (pp->p_name);
-}
-
-const char *
-res_servicename(u_int16_t port, const char *proto) {	/*%< Host byte order. */
-	static char number[8];
-	struct servent *ss;
-
-	if (servicelist == (struct valuelist *)0)
-		res_buildservicelist();
-	ss = cgetservbyport(htons(port), proto);
-	if (ss == 0)  {
-		(void) sprintf(number, "%d", port);
-		return (number);
-	}
-	return (ss->s_name);
-}
diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_mkupdate.h /usr/src/lib/libc/resolv/res_mkupdate.h
--- /home/reed/src/isc/libbind/libbind/resolv/res_mkupdate.h	2005-04-26 23:56:42.000000000 -0500
+++ /usr/src/lib/libc/resolv/res_mkupdate.h	1969-12-31 18:00:00.000000000 -0600
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1998,1999 by Internet Software Consortium.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _RES_MKUPDATE_H_
-#define _RES_MKUPDATE_H_
-
-__BEGIN_DECLS
-__END_DECLS
-
-#endif /* _RES_MKUPDATE_H_ */ 
-/*! \file */
diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_private.h /usr/src/lib/libc/resolv/res_private.h
--- /home/reed/src/isc/libbind/libbind/resolv/res_private.h	2005-04-26 23:56:42.000000000 -0500
+++ /usr/src/lib/libc/resolv/res_private.h	2012-10-24 08:34:38.000000000 -0500
@@ -1,3 +1,5 @@
+/*	$NetBSD: res_private.h,v 1.3 2009/10/24 17:24:01 christos Exp $	*/
+
 #ifndef res_private_h
 #define res_private_h
 
@@ -12,10 +14,12 @@ struct __res_state_ext {
 	} sort_list[MAXRESOLVSORT];
 	char nsuffix[64];
 	char nsuffix2[64];
+	struct timespec res_conf_time;
+	int kq, resfd;
 };
 
-extern int
-res_ourserver_p(const res_state statp, const struct sockaddr *sa);
+extern int res_ourserver_p(const res_state, const struct sockaddr *);
+extern int __res_vinit(res_state, int);
 
 #endif
 
diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_query.c /usr/src/lib/libc/resolv/res_query.c
--- /home/reed/src/isc/libbind/libbind/resolv/res_query.c	2013-06-05 09:33:54.000000000 -0500
+++ /usr/src/lib/libc/resolv/res_query.c	2013-06-05 09:26:14.000000000 -0500
@@ -1,3 +1,5 @@
+/*	$NetBSD: res_query.c,v 1.14 2012/03/13 21:13:44 christos Exp $	*/
+
 /*
  * Portions Copyright (C) 2004, 2005, 2008  Internet Systems Consortium, Inc. ("ISC")
  * Portions Copyright (C) 1996-2001, 2003  Internet Software Consortium.
@@ -27,7 +29,11 @@
  * 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 University nor the names of its contributors
+ * 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.
  *
@@ -64,12 +70,36 @@
  * SOFTWARE.
  */
 
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
 #if defined(LIBC_SCCS) && !defined(lint)
+#ifdef notdef
 static const char sccsid[] = "@(#)res_query.c	8.1 (Berkeley) 6/4/93";
-static const char rcsid[] = "$Id: res_query.c,v 1.12 2013-01-06 23:14:54 marka Exp $";
+static const char rcsid[] = "Id: res_query.c,v 1.11 2008/11/14 02:36:51 marka Exp";
+#else
+__RCSID("$NetBSD: res_query.c,v 1.14 2012/03/13 21:13:44 christos Exp $");
+#endif
 #endif /* LIBC_SCCS and not lint */
 
 #include "port_before.h"
+
+#include "namespace.h"
 #include <sys/types.h>
 #include <sys/param.h>
 #include <netinet/in.h>
@@ -81,11 +111,23 @@ static const char rcsid[] = "$Id: res_qu
 #include <resolv.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <unistd.h>
 #include <string.h>
 #include "port_after.h"
 
+#if 0
+#ifdef __weak_alias
+__weak_alias(res_nquery,_res_nquery)
+__weak_alias(res_nsearch,_res_nsearch)
+__weak_alias(res_nquerydomain,__res_nquerydomain)
+__weak_alias(res_hostalias,__res_hostalias)
+#endif
+#endif
+
 /* Options.  Leave them on. */
+#ifndef DEBUG
 #define DEBUG
+#endif
 
 #if PACKETSZ > 1024
 #define MAXPACKET	PACKETSZ
@@ -111,7 +153,7 @@ res_nquery(res_state statp,
 	   int anslen)		/*%< size of answer buffer */
 {
 	u_char buf[MAXPACKET];
-	HEADER *hp = (HEADER *) answer;
+	HEADER *hp = (HEADER *)(void *)answer;
 	u_int oflags;
 	u_char *rdata;
 	int n;
@@ -126,15 +168,15 @@ again:
 #endif
 
 	n = res_nmkquery(statp, QUERY, name, class, type, NULL, 0, NULL,
-			 buf, sizeof(buf));
+			 buf, (int)sizeof(buf));
 #ifdef RES_USE_EDNS0
 	if (n > 0 && (statp->_flags & RES_F_EDNS0ERR) == 0 &&
-	    (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC|RES_NSID))) {
-		n = res_nopt(statp, n, buf, sizeof(buf), anslen);
+	    (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC|RES_NSID)) != 0U) {
+		n = res_nopt(statp, n, buf, (int)sizeof(buf), anslen);
 		rdata = &buf[n];
 		if (n > 0 && (statp->options & RES_NSID) != 0U) {
-			n = res_nopt_rdata(statp, n, buf, sizeof(buf), rdata,
-					   NS_OPT_NSID, 0, NULL);
+			n = res_nopt_rdata(statp, n, buf, (int)sizeof(buf),
+			    rdata, NS_OPT_NSID, 0, NULL);
 		}
 	}
 #endif
@@ -212,7 +254,7 @@ res_nsearch(res_state statp,
 	    int anslen)		/*%< size of answer */
 {
 	const char *cp, * const *domain;
-	HEADER *hp = (HEADER *) answer;
+	HEADER *hp = (HEADER *)(void *)answer;
 	char tmp[NS_MAXDNAME];
 	u_int dots;
 	int trailing_dot, ret, saved_herrno;
@@ -360,7 +402,7 @@ res_nquerydomain(res_state statp,
 {
 	char nbuf[MAXDNAME];
 	const char *longname = nbuf;
-	int n, d;
+	size_t n, d;
 
 #ifdef DEBUG
 	if (statp->options & RES_DEBUG)
@@ -377,8 +419,7 @@ res_nquerydomain(res_state statp,
 			RES_SET_H_ERRNO(statp, NO_RECOVERY);
 			return (-1);
 		}
-		n--;
-		if (n >= 0 && name[n] == '.') {
+		if (n && name[--n] == '.') {
 			strncpy(nbuf, name, n);
 			nbuf[n] = '\0';
 		} else
@@ -403,12 +444,17 @@ res_hostalias(const res_state statp, con
 
 	if (statp->options & RES_NOALIASES)
 		return (NULL);
+	/*
+	 * forbid hostaliases for setuid binary, due to possible security
+	 * breach.
+	 */
+	if (issetugid())
+		return (NULL);
 	file = getenv("HOSTALIASES");
 	if (file == NULL || (fp = fopen(file, "r")) == NULL)
 		return (NULL);
-	setbuf(fp, NULL);
 	buf[sizeof(buf) - 1] = '\0';
-	while (fgets(buf, sizeof(buf), fp)) {
+	while (fgets(buf, (int)sizeof(buf), fp)) {
 		for (cp1 = buf; *cp1 && !isspace((unsigned char)*cp1); ++cp1)
 			;
 		if (!*cp1)
diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_send.c /usr/src/lib/libc/resolv/res_send.c
--- /home/reed/src/isc/libbind/libbind/resolv/res_send.c	2013-04-04 17:43:30.000000000 -0500
+++ /usr/src/lib/libc/resolv/res_send.c	2013-06-05 09:26:14.000000000 -0500
@@ -1,5 +1,7 @@
+/*	$NetBSD: res_send.c,v 1.29 2013/02/16 13:45:45 para Exp $	*/
+
 /*
- * Portions Copyright (C) 2004-2009, 2011  Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2009  Internet Systems Consortium, Inc. ("ISC")
  * Portions Copyright (C) 1996-2003  Internet Software Consortium.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
@@ -27,7 +29,11 @@
  * 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 University nor the names of its contributors
+ * 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.
  *
@@ -64,9 +70,31 @@
  * SOFTWARE.
  */
 
+/*
+ * Copyright (c) 2005 by Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
 #if defined(LIBC_SCCS) && !defined(lint)
+#ifdef notdef
 static const char sccsid[] = "@(#)res_send.c	8.1 (Berkeley) 6/4/93";
-static const char rcsid[] = "$Id: res_send.c,v 1.25 2013-01-06 23:14:54 marka Exp $";
+static const char rcsid[] = "Id: res_send.c,v 1.22 2009/01/22 23:49:23 tbox Exp";
+#else
+__RCSID("$NetBSD: res_send.c,v 1.29 2013/02/16 13:45:45 para Exp $");
+#endif
 #endif /* LIBC_SCCS and not lint */
 
 /*! \file
@@ -74,24 +102,32 @@ static const char rcsid[] = "$Id: res_se
  * Send query to name server and wait for reply.
  */
 
+#include "namespace.h"
 #include "port_before.h"
+#ifndef USE_KQUEUE
 #include "fd_setsize.h"
+#endif /* USE_KQUEUE */
 
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/time.h>
 #include <sys/socket.h>
 #include <sys/uio.h>
+#ifdef USE_KQUEUE
+#include <sys/event.h>
+#endif /* USE_KQUEUE */
 
 #include <netinet/in.h>
 #include <arpa/nameser.h>
 #include <arpa/inet.h>
 
+#include <assert.h>
 #include <errno.h>
 #include <netdb.h>
 #include <resolv.h>
 #include <signal.h>
 #include <stdio.h>
+#include <fcntl.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -100,6 +136,22 @@ static const char rcsid[] = "$Id: res_se
 
 #include "port_after.h"
 
+#if 0
+#ifdef __weak_alias
+__weak_alias(res_ourserver_p,__res_ourserver_p)
+__weak_alias(res_nameinquery,__res_nameinquery)
+__weak_alias(res_queriesmatch,__res_queriesmatch)
+__weak_alias(res_nsend,__res_nsend)
+#endif
+#endif
+
+#ifndef SOCK_NOSIGPIPE
+#define SOCK_NOSIGPIPE 0
+#endif
+#ifndef SOCK_NOCLOEXEC
+#define SOCK_NOCLOEXEC 0
+#endif
+
 #ifdef USE_POLL
 #ifdef HAVE_STROPTS_H
 #include <stropts.h>
@@ -108,32 +160,36 @@ static const char rcsid[] = "$Id: res_se
 #endif /* USE_POLL */
 
 /* Options.  Leave them on. */
+#ifndef DEBUG
 #define DEBUG
+#endif
 #include "res_debug.h"
 #include "res_private.h"
 
 #define EXT(res) ((res)->_u._ext)
 
-#ifndef USE_POLL
+#if !defined(USE_POLL) && !defined(USE_KQUEUE)
 static const int highestFD = FD_SETSIZE - 1;
-#else
-static int highestFD = 0;
 #endif
 
 /* Forward. */
 
-static int		get_salen __P((const struct sockaddr *));
-static struct sockaddr * get_nsaddr __P((res_state, size_t));
-static int		send_vc(res_state, const u_char *, int,
+static socklen_t	get_salen(const struct sockaddr *);
+static struct sockaddr * get_nsaddr(res_state, size_t);
+static int		send_vc(res_state, const void *, size_t,
 				u_char *, int, int *, int);
-static int		send_dg(res_state, const u_char *, int,
+static int		send_dg(res_state,
+#ifdef USE_KQUEUE
+				int,
+#endif
+				const void *, size_t,
 				u_char *, int, int *, int, int,
 				int *, int *);
 static void		Aerror(const res_state, FILE *, const char *, int,
-			       const struct sockaddr *, int);
+			       const struct sockaddr *, socklen_t);
 static void		Perror(const res_state, FILE *, const char *, int);
 static int		sock_eq(struct sockaddr *, struct sockaddr *);
-#if defined(NEED_PSELECT) && !defined(USE_POLL)
+#if defined(NEED_PSELECT) && !defined(USE_POLL) && !defined(USE_KQUEUE)
 static int		pselect(int, void *, void *, void *,
 				struct timespec *,
 				const sigset_t *);
@@ -162,9 +218,9 @@ res_ourserver_p(const res_state statp, c
 
 	switch (sa->sa_family) {
 	case AF_INET:
-		inp = (const struct sockaddr_in *)sa;
+		inp = (const struct sockaddr_in *)(const void *)sa;
 		for (ns = 0;  ns < statp->nscount;  ns++) {
-			srv = (struct sockaddr_in *)get_nsaddr(statp, ns);
+			srv = (struct sockaddr_in *)(void *)get_nsaddr(statp, (size_t)ns);
 			if (srv->sin_family == inp->sin_family &&
 			    srv->sin_port == inp->sin_port &&
 			    (srv->sin_addr.s_addr == INADDR_ANY ||
@@ -175,9 +231,9 @@ res_ourserver_p(const res_state statp, c
 	case AF_INET6:
 		if (EXT(statp).ext == NULL)
 			break;
-		in6p = (const struct sockaddr_in6 *)sa;
+		in6p = (const struct sockaddr_in6 *)(const void *)sa;
 		for (ns = 0;  ns < statp->nscount;  ns++) {
-			srv6 = (struct sockaddr_in6 *)get_nsaddr(statp, ns);
+			srv6 = (struct sockaddr_in6 *)(void *)get_nsaddr(statp, (size_t)ns);
 			if (srv6->sin6_family == in6p->sin6_family &&
 			    srv6->sin6_port == in6p->sin6_port &&
 #ifdef HAVE_SIN6_SCOPE_ID
@@ -214,13 +270,13 @@ res_nameinquery(const char *name, int ty
 		const u_char *buf, const u_char *eom)
 {
 	const u_char *cp = buf + HFIXEDSZ;
-	int qdcount = ntohs(((const HEADER*)buf)->qdcount);
+	int qdcount = ntohs(((const HEADER*)(const void *)buf)->qdcount);
 
 	while (qdcount-- > 0) {
 		char tname[MAXDNAME+1];
 		int n, ttype, tclass;
 
-		n = dn_expand(buf, eom, cp, tname, sizeof tname);
+		n = dn_expand(buf, eom, cp, tname, (int)sizeof tname);
 		if (n < 0)
 			return (-1);
 		cp += n;
@@ -252,7 +308,7 @@ res_queriesmatch(const u_char *buf1, con
 		 const u_char *buf2, const u_char *eom2)
 {
 	const u_char *cp = buf1 + HFIXEDSZ;
-	int qdcount = ntohs(((const HEADER*)buf1)->qdcount);
+	int qdcount = ntohs(((const HEADER*)(const void *)buf1)->qdcount);
 
 	if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2)
 		return (-1);
@@ -261,17 +317,17 @@ res_queriesmatch(const u_char *buf1, con
 	 * Only header section present in replies to
 	 * dynamic update packets.
 	 */
-	if ((((const HEADER *)buf1)->opcode == ns_o_update) &&
-	    (((const HEADER *)buf2)->opcode == ns_o_update))
+	if ((((const HEADER *)(const void *)buf1)->opcode == ns_o_update) &&
+	    (((const HEADER *)(const void *)buf2)->opcode == ns_o_update))
 		return (1);
 
-	if (qdcount != ntohs(((const HEADER*)buf2)->qdcount))
+	if (qdcount != ntohs(((const HEADER*)(const void *)buf2)->qdcount))
 		return (0);
 	while (qdcount-- > 0) {
 		char tname[MAXDNAME+1];
 		int n, ttype, tclass;
 
-		n = dn_expand(buf1, eom1, cp, tname, sizeof tname);
+		n = dn_expand(buf1, eom1, cp, tname, (int)sizeof tname);
 		if (n < 0)
 			return (-1);
 		cp += n;
@@ -290,11 +346,12 @@ res_nsend(res_state statp,
 	  const u_char *buf, int buflen, u_char *ans, int anssiz)
 {
 	int gotsomewhere, terrno, tries, v_circuit, resplen, ns, n;
+#ifdef USE_KQUEUE
+	int kq;
+#endif
 	char abuf[NI_MAXHOST];
 
-#ifdef USE_POLL
-	highestFD = sysconf(_SC_OPEN_MAX) - 1;
-#endif
+	(void)res_check(statp, NULL);
 
 	/* No name servers or res_init() failure */
 	if (statp->nscount == 0 || EXT(statp).ext == NULL) {
@@ -311,6 +368,12 @@ res_nsend(res_state statp,
 	gotsomewhere = 0;
 	terrno = ETIMEDOUT;
 
+#ifdef USE_KQUEUE
+	if ((kq = kqueue1(O_CLOEXEC)) == -1) {
+		return (-1);
+	}
+#endif
+
 	/*
 	 * If the ns_addr_list in the resolver context has changed, then
 	 * invalidate our cached copy and the associated timing data.
@@ -325,8 +388,8 @@ res_nsend(res_state statp,
 		else
 			for (ns = 0; ns < statp->nscount; ns++) {
 				if (statp->nsaddr_list[ns].sin_family &&
-				    !sock_eq((struct sockaddr *)&statp->nsaddr_list[ns],
-					     (struct sockaddr *)&EXT(statp).ext->nsaddrs[ns])) {
+				    !sock_eq((struct sockaddr *)(void *)&statp->nsaddr_list[ns],
+					     (struct sockaddr *)(void *)&EXT(statp).ext->nsaddrs[ns])) {
 					needclose++;
 					break;
 				}
@@ -335,12 +398,12 @@ res_nsend(res_state statp,
 					continue;
 				peerlen = sizeof(peer);
 				if (getpeername(EXT(statp).nssocks[ns],
-				    (struct sockaddr *)&peer, &peerlen) < 0) {
+				    (struct sockaddr *)(void *)&peer, &peerlen) < 0) {
 					needclose++;
 					break;
 				}
-				if (!sock_eq((struct sockaddr *)&peer,
-				    get_nsaddr(statp, ns))) {
+				if (!sock_eq((struct sockaddr *)(void *)&peer,
+				    get_nsaddr(statp, (size_t)ns))) {
 					needclose++;
 					break;
 				}
@@ -404,8 +467,8 @@ res_nsend(res_state statp,
 	for (tries = 0; tries < statp->retry; tries++) {
 	    for (ns = 0; ns < statp->nscount; ns++) {
 		struct sockaddr *nsap;
-		int nsaplen;
-		nsap = get_nsaddr(statp, ns);
+		socklen_t nsaplen;
+		nsap = get_nsaddr(statp, (size_t)ns);
 		nsaplen = get_salen(nsap);
 		statp->_flags &= ~RES_F_LASTMASK;
 		statp->_flags |= (ns << RES_F_LASTSHIFT);
@@ -426,6 +489,9 @@ res_nsend(res_state statp,
 					res_nclose(statp);
 					goto next_ns;
 				case res_done:
+#ifdef USE_KQUEUE
+					close(kq);
+#endif
 					return (resplen);
 				case res_modified:
 					/* give the hook another try */
@@ -441,8 +507,8 @@ res_nsend(res_state statp,
 		}
 
 		Dprint(((statp->options & RES_DEBUG) &&
-			getnameinfo(nsap, nsaplen, abuf, sizeof(abuf),
-				    NULL, 0, niflags) == 0),
+			getnameinfo(nsap, nsaplen, abuf,
+			    (socklen_t)sizeof(abuf), NULL, 0, niflags) == 0),
 		       (stdout, ";; Querying server (# %d) address = %s\n",
 			ns + 1, abuf));
 
@@ -450,7 +516,7 @@ res_nsend(res_state statp,
 		if (v_circuit) {
 			/* Use VC; at most one attempt per server. */
 			tries = statp->retry;
-			n = send_vc(statp, buf, buflen, ans, anssiz, &terrno,
+			n = send_vc(statp, buf, (size_t)buflen, ans, anssiz, &terrno,
 				    ns);
 			if (n < 0)
 				goto fail;
@@ -459,8 +525,12 @@ res_nsend(res_state statp,
 			resplen = n;
 		} else {
 			/* Use datagrams. */
-			n = send_dg(statp, buf, buflen, ans, anssiz, &terrno,
-				    ns, tries, &v_circuit, &gotsomewhere);
+			n = send_dg(statp,
+#ifdef USE_KQUEUE
+			    kq,
+#endif
+			    buf, (size_t)buflen, ans, anssiz, &terrno,
+			    ns, tries, &v_circuit, &gotsomewhere);
 			if (n < 0)
 				goto fail;
 			if (n == 0)
@@ -518,11 +588,17 @@ res_nsend(res_state statp,
 			} while (!done);
 
 		}
+#ifdef USE_KQUEUE
+		close(kq);
+#endif
 		return (resplen);
  next_ns: ;
 	   } /*foreach ns*/
 	} /*foreach retry*/
 	res_nclose(statp);
+#ifdef USE_KQUEUE
+	close(kq);
+#endif
 	if (!v_circuit) {
 		if (!gotsomewhere)
 			errno = ECONNREFUSED;	/*%< no nameservers found */
@@ -533,37 +609,37 @@ res_nsend(res_state statp,
 	return (-1);
  fail:
 	res_nclose(statp);
+#ifdef USE_KQUEUE
+	close(kq);
+#endif
 	return (-1);
 }
 
 /* Private */
 
-static int
-get_salen(sa)
-	const struct sockaddr *sa;
+static socklen_t
+get_salen(const struct sockaddr *sa)
 {
 
 #ifdef HAVE_SA_LEN
 	/* There are people do not set sa_len.  Be forgiving to them. */
 	if (sa->sa_len)
-		return (sa->sa_len);
+		return (socklen_t)sa->sa_len;
 #endif
 
 	if (sa->sa_family == AF_INET)
-		return (sizeof(struct sockaddr_in));
+		return (socklen_t)sizeof(struct sockaddr_in);
 	else if (sa->sa_family == AF_INET6)
-		return (sizeof(struct sockaddr_in6));
+		return (socklen_t)sizeof(struct sockaddr_in6);
 	else
-		return (0);	/*%< unknown, die on connect */
+		return 0;	/*%< unknown, die on connect */
 }
 
 /*%
  * pick appropriate nsaddr_list for use.  see res_init() for initialization.
  */
 static struct sockaddr *
-get_nsaddr(statp, n)
-	res_state statp;
-	size_t n;
+get_nsaddr(res_state statp, size_t n)
 {
 
 	if (!statp->nsaddr_list[n].sin_family && EXT(statp).ext) {
@@ -585,23 +661,24 @@ get_nsaddr(statp, n)
 
 static int
 send_vc(res_state statp,
-	const u_char *buf, int buflen, u_char *ans, int anssiz,
+	const void *buf, size_t buflen, u_char *ans, int anssiz,
 	int *terrno, int ns)
 {
-	const HEADER *hp = (const HEADER *) buf;
-	HEADER *anhp = (HEADER *) ans;
+	const HEADER *hp = (const HEADER *)(const void *)buf;
+	HEADER *anhp = (HEADER *)(void *)ans;
 	struct sockaddr *nsap;
-	int nsaplen;
-	int truncating, connreset, resplen, n;
+	socklen_t nsaplen;
+	int truncating, connreset, resplen;
+	ssize_t n;
 	struct iovec iov[2];
 	u_short len;
 	u_char *cp;
 	void *tmp;
-#ifdef SO_NOSIGPIPE
+#if defined(SO_NOSIGPIPE) && SOCK_NOSIGPIPE == 0
 	int on = 1;
 #endif
 
-	nsap = get_nsaddr(statp, ns);
+	nsap = get_nsaddr(statp, (size_t)ns);
 	nsaplen = get_salen(nsap);
 
 	connreset = 0;
@@ -614,8 +691,8 @@ send_vc(res_state statp,
 		ISC_SOCKLEN_T size = sizeof peer;
 
 		if (getpeername(statp->_vcsock,
-				(struct sockaddr *)&peer, &size) < 0 ||
-		    !sock_eq((struct sockaddr *)&peer, nsap)) {
+				(struct sockaddr *)(void *)&peer, &size) < 0 ||
+		    !sock_eq((struct sockaddr *)(void *)&peer, nsap)) {
 			res_nclose(statp);
 			statp->_flags &= ~RES_F_VC;
 		}
@@ -625,11 +702,17 @@ send_vc(res_state statp,
 		if (statp->_vcsock >= 0)
 			res_nclose(statp);
 
-		statp->_vcsock = socket(nsap->sa_family, SOCK_STREAM, 0);
+		statp->_vcsock = socket(nsap->sa_family, SOCK_STREAM
+			| SOCK_NOSIGPIPE | SOCK_CLOEXEC, 0);
+#if SOCK_CLOEXEC == 0
+		fcntl(statp->_vcsock, F_SETFD, FD_CLOEXEC);
+#endif
+#if !defined(USE_POLL) && !defined(USE_KQUEUE)
 		if (statp->_vcsock > highestFD) {
 			res_nclose(statp);
 			errno = ENOTSOCK;
 		}
+#endif
 		if (statp->_vcsock < 0) {
 			switch (errno) {
 			case EPROTONOSUPPORT:
@@ -645,7 +728,7 @@ send_vc(res_state statp,
 				return (-1);
 			}
 		}
-#ifdef SO_NOSIGPIPE
+#if defined(SO_NOSIGPIPE) && SOCK_NOSIGPIPE == 0
 		/*
 		 * Disable generation of SIGPIPE when writing to a closed
 		 * socket.  Write should return -1 and set errno to EPIPE
@@ -654,7 +737,7 @@ send_vc(res_state statp,
 		 * Push on even if setsockopt(SO_NOSIGPIPE) fails.
 		 */
 		(void)setsockopt(statp->_vcsock, SOL_SOCKET, SO_NOSIGPIPE, &on,
-				 sizeof(on));
+				 (socklen_t)sizeof(on));
 #endif
 		errno = 0;
 		if (connect(statp->_vcsock, nsap, nsaplen) < 0) {
@@ -670,11 +753,11 @@ send_vc(res_state statp,
 	/*
 	 * Send length & message
 	 */
-	ns_put16((u_short)buflen, (u_char*)&len);
+	ns_put16((u_short)buflen, (u_char*)(void *)&len);
 	iov[0] = evConsIovec(&len, INT16SZ);
 	DE_CONST(buf, tmp);
-	iov[1] = evConsIovec(tmp, buflen);
-	if (writev(statp->_vcsock, iov, 2) != (INT16SZ + buflen)) {
+	iov[1] = evConsIovec(tmp, (size_t)buflen);
+	if (writev(statp->_vcsock, iov, 2) != (ssize_t)(INT16SZ + buflen)) {
 		*terrno = errno;
 		Perror(statp, stderr, "write failed", errno);
 		res_nclose(statp);
@@ -686,9 +769,9 @@ send_vc(res_state statp,
  read_len:
 	cp = ans;
 	len = INT16SZ;
-	while ((n = read(statp->_vcsock, (char *)cp, (int)len)) > 0) {
+	while ((n = read(statp->_vcsock, (char *)cp, (size_t)len)) > 0) {
 		cp += n;
-		if ((len -= n) == 0)
+		if ((len -= (u_short)n) == 0)
 			break;
 	}
 	if (n <= 0) {
@@ -732,9 +815,9 @@ send_vc(res_state statp,
 		return (0);
 	}
 	cp = ans;
-	while (len != 0 && (n = read(statp->_vcsock, (char *)cp, (int)len)) > 0){
+	while (len != 0 && (n = read(statp->_vcsock, (char *)cp, (size_t)len)) > 0){
 		cp += n;
-		len -= n;
+		len -= (u_short)n;
 	}
 	if (n <= 0) {
 		*terrno = errno;
@@ -754,7 +837,7 @@ send_vc(res_state statp,
 			n = read(statp->_vcsock, junk,
 				 (len > sizeof junk) ? sizeof junk : len);
 			if (n > 0)
-				len -= n;
+				len -= (u_short)n;
 			else
 				break;
 		}
@@ -782,33 +865,48 @@ send_vc(res_state statp,
 }
 
 static int
-send_dg(res_state statp, const u_char *buf, int buflen, u_char *ans,
+send_dg(res_state statp,
+#ifdef USE_KQUEUE
+	int kq,
+#endif
+	const void *buf, size_t buflen, u_char *ans,
 	int anssiz, int *terrno, int ns, int tries, int *v_circuit,
 	int *gotsomewhere)
 {
-	const HEADER *hp = (const HEADER *) buf;
-	HEADER *anhp = (HEADER *) ans;
+	const HEADER *hp = (const HEADER *)(const void *)buf;
+	HEADER *anhp = (HEADER *)(void *)ans;
 	const struct sockaddr *nsap;
-	int nsaplen;
+	socklen_t nsaplen;
 	struct timespec now, timeout, finish;
 	struct sockaddr_storage from;
 	ISC_SOCKLEN_T fromlen;
-	int resplen, seconds, n, s;
+	ssize_t resplen;
+	int seconds, n, s;
+#ifdef USE_KQUEUE
+	struct kevent kv;
+#else
 #ifdef USE_POLL
 	int     polltimeout;
 	struct pollfd   pollfd;
 #else
 	fd_set dsmask;
 #endif
+#endif
 
-	nsap = get_nsaddr(statp, ns);
+	nsap = get_nsaddr(statp, (size_t)ns);
 	nsaplen = get_salen(nsap);
 	if (EXT(statp).nssocks[ns] == -1) {
-		EXT(statp).nssocks[ns] = socket(nsap->sa_family, SOCK_DGRAM, 0);
+		EXT(statp).nssocks[ns] = socket(nsap->sa_family, SOCK_DGRAM
+			| SOCK_CLOEXEC, 0);
+#if SOCK_CLOEXEC == 0
+		fcntl(EXT(statp)nssocks[ns], F_SETFD, FD_CLOEXEC);
+#endif
+#if !defined(USE_POLL) && !defined(USE_KQUEUE)
 		if (EXT(statp).nssocks[ns] > highestFD) {
 			res_nclose(statp);
 			errno = ENOTSOCK;
 		}
+#endif
 		if (EXT(statp).nssocks[ns] < 0) {
 			switch (errno) {
 			case EPROTONOSUPPORT:
@@ -835,8 +933,16 @@ send_dg(res_state statp, const u_char *b
 		 * socket operation, and select returns if the
 		 * error message is received.  We can thus detect
 		 * the absence of a nameserver without timing out.
-		 */
-		if (connect(EXT(statp).nssocks[ns], nsap, nsaplen) < 0) {
+		 *
+		 * When the option "insecure1" is specified, we'd
+		 * rather expect to see responses from an "unknown"
+		 * address.  In order to let the kernel accept such
+		 * responses, do not connect the socket here.
+		 * XXX: or do we need an explicit option to disable
+		 * connecting?
+ 		 */
+		if (!(statp->options & RES_INSECURE1) &&
+		    connect(EXT(statp).nssocks[ns], nsap, nsaplen) < 0) {
 			Aerror(statp, stderr, "connect(dg)", errno, nsap,
 			    nsaplen);
 			res_nclose(statp);
@@ -848,13 +954,20 @@ send_dg(res_state statp, const u_char *b
 	}
 	s = EXT(statp).nssocks[ns];
 #ifndef CANNOT_CONNECT_DGRAM
-	if (send(s, (const char*)buf, buflen, 0) != buflen) {
+	if (statp->options & RES_INSECURE1) {
+		if (sendto(s, buf, buflen, 0, nsap, nsaplen) !=
+		    (ssize_t)buflen) {
+			Aerror(statp, stderr, "sendto", errno, nsap, nsaplen);
+			res_nclose(statp);
+			return (0);
+		}
+	} else if (send(s, buf, buflen, 0) != (ssize_t)buflen) {
 		Perror(statp, stderr, "send", errno);
 		res_nclose(statp);
 		return (0);
 	}
 #else /* !CANNOT_CONNECT_DGRAM */
-	if (sendto(s, (const char*)buf, buflen, 0, nsap, nsaplen) != buflen)
+	if (sendto(s, buf, buflen, 0, nsap, nsaplen) != (ssize_t)buflen)
 	{
 		Aerror(statp, stderr, "sendto", errno, nsap, nsaplen);
 		res_nclose(statp);
@@ -871,26 +984,31 @@ send_dg(res_state statp, const u_char *b
 	if (seconds <= 0)
 		seconds = 1;
 	now = evNowTime();
-	timeout = evConsTime(seconds, 0);
+	timeout = evConsTime((time_t)seconds, 0L);
 	finish = evAddTime(now, timeout);
 	goto nonow;
  wait:
 	now = evNowTime();
  nonow:
 #ifndef USE_POLL
-	FD_ZERO(&dsmask);
-	FD_SET(s, &dsmask);
 	if (evCmpTime(finish, now) > 0)
 		timeout = evSubTime(finish, now);
 	else
-		timeout = evConsTime(0, 0);
+		timeout = evConsTime(0L, 0L);
+#ifdef USE_KQUEUE
+	EV_SET(&kv, s, EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, 0);
+	n = kevent(kq, &kv, 1, &kv, 1, &timeout);
+#else
+	FD_ZERO(&dsmask);
+	FD_SET(s, &dsmask);
 	n = pselect(s + 1, &dsmask, NULL, NULL, &timeout, NULL);
+#endif
 #else
 	timeout = evSubTime(finish, now);
 	if (timeout.tv_sec < 0)
-		timeout = evConsTime(0, 0);
-	polltimeout = 1000*timeout.tv_sec +
-		timeout.tv_nsec/1000000;
+		timeout = evConsTime((time_t)0, 0L);
+	polltimeout = 1000*(int)timeout.tv_sec +
+		(int)timeout.tv_nsec/1000000;
 	pollfd.fd = s;
 	pollfd.events = POLLRDNORM;
 	n = poll(&pollfd, 1, polltimeout);
@@ -902,20 +1020,27 @@ send_dg(res_state statp, const u_char *b
 		return (0);
 	}
 	if (n < 0) {
+#if defined(USE_POLL)
+		static const char *fun = "poll";
+#elif defined(USE_SELECT)
+		static const char *fun = "select";
+#elif defined(USE_KQUEUE)
+		static const char *fun = "kevent";
+#endif
 		if (errno == EINTR)
 			goto wait;
-#ifndef USE_POLL
-		Perror(statp, stderr, "select", errno);
-#else
-		Perror(statp, stderr, "poll", errno);
-#endif /* USE_POLL */
+		Perror(statp, stderr, fun, errno);
 		res_nclose(statp);
 		return (0);
 	}
+#ifdef USE_KQUEUE
+	if ((int)kv.ident != s)
+		goto wait;
+#endif
 	errno = 0;
 	fromlen = sizeof(from);
-	resplen = recvfrom(s, (char*)ans, anssiz,0,
-			   (struct sockaddr *)&from, &fromlen);
+	resplen = recvfrom(s, (char*)ans, (size_t)anssiz,0,
+			   (struct sockaddr *)(void *)&from, &fromlen);
 	if (resplen <= 0) {
 		Perror(statp, stderr, "recvfrom", errno);
 		res_nclose(statp);
@@ -927,7 +1052,7 @@ send_dg(res_state statp, const u_char *b
 		 * Undersized message.
 		 */
 		Dprint(statp->options & RES_DEBUG,
-		       (stdout, ";; undersized: %d\n",
+		       (stdout, ";; undersized: %zd\n",
 			resplen));
 		*terrno = EMSGSIZE;
 		res_nclose(statp);
@@ -946,7 +1071,7 @@ send_dg(res_state statp, const u_char *b
 		goto wait;
 	}
 	if (!(statp->options & RES_INSECURE1) &&
-	    !res_ourserver_p(statp, (struct sockaddr *)&from)) {
+	    !res_ourserver_p(statp, (struct sockaddr *)(void *)&from)) {
 		/*
 		 * response from wrong server? ignore it.
 		 * XXX - potential security hazard could
@@ -975,7 +1100,7 @@ send_dg(res_state statp, const u_char *b
 	}
 #endif
 	if (!(statp->options & RES_INSECURE2) &&
-	    !res_queriesmatch(buf, buf + buflen,
+	    !res_queriesmatch(buf, (const u_char *)buf + buflen,
 			      ans, ans + anssiz)) {
 		/*
 		 * response contains wrong query? ignore it.
@@ -985,7 +1110,7 @@ send_dg(res_state statp, const u_char *b
 		DprintQ((statp->options & RES_DEBUG) ||
 			(statp->pfcode & RES_PRF_REPLY),
 			(stdout, ";; wrong query name:\n"),
-			ans, (resplen > anssiz) ? anssiz : resplen);
+			ans, (int)(resplen > anssiz) ? anssiz : resplen);
 		goto wait;
 	}
 	if (anhp->rcode == SERVFAIL ||
@@ -993,7 +1118,7 @@ send_dg(res_state statp, const u_char *b
 	    anhp->rcode == REFUSED) {
 		DprintQ(statp->options & RES_DEBUG,
 			(stdout, "server rejected query:\n"),
-			ans, (resplen > anssiz) ? anssiz : resplen);
+			ans, (int)(resplen > anssiz) ? anssiz : resplen);
 		res_nclose(statp);
 		/* don't retry if called from dig */
 		if (!statp->pfcode)
@@ -1014,20 +1139,22 @@ send_dg(res_state statp, const u_char *b
 	 * All is well, or the error is fatal.  Signal that the
 	 * next nameserver ought not be tried.
 	 */
-	return (resplen);
+	_DIAGASSERT(__type_fit(int, resplen));
+	return (int)resplen;
 }
 
 static void
 Aerror(const res_state statp, FILE *file, const char *string, int error,
-       const struct sockaddr *address, int alen)
+       const struct sockaddr *address, socklen_t alen)
 {
 	int save = errno;
 	char hbuf[NI_MAXHOST];
 	char sbuf[NI_MAXSERV];
 
 	if ((statp->options & RES_DEBUG) != 0U) {
-		if (getnameinfo(address, alen, hbuf, sizeof(hbuf),
-		    sbuf, sizeof(sbuf), niflags)) {
+		if (getnameinfo(address, alen, hbuf,
+		    (socklen_t)sizeof(hbuf), sbuf, (socklen_t)sizeof(sbuf),
+		    niflags)) {
 			strncpy(hbuf, "?", sizeof(hbuf) - 1);
 			hbuf[sizeof(hbuf) - 1] = '\0';
 			strncpy(sbuf, "?", sizeof(sbuf) - 1);
@@ -1058,13 +1185,13 @@ sock_eq(struct sockaddr *a, struct socka
 		return 0;
 	switch (a->sa_family) {
 	case AF_INET:
-		a4 = (struct sockaddr_in *)a;
-		b4 = (struct sockaddr_in *)b;
+		a4 = (struct sockaddr_in *)(void *)a;
+		b4 = (struct sockaddr_in *)(void *)b;
 		return a4->sin_port == b4->sin_port &&
 		    a4->sin_addr.s_addr == b4->sin_addr.s_addr;
 	case AF_INET6:
-		a6 = (struct sockaddr_in6 *)a;
-		b6 = (struct sockaddr_in6 *)b;
+		a6 = (struct sockaddr_in6 *)(void *)a;
+		b6 = (struct sockaddr_in6 *)(void *)b;
 		return a6->sin6_port == b6->sin6_port &&
 #ifdef HAVE_SIN6_SCOPE_ID
 		    a6->sin6_scope_id == b6->sin6_scope_id &&
@@ -1075,7 +1202,7 @@ sock_eq(struct sockaddr *a, struct socka
 	}
 }
 
-#if defined(NEED_PSELECT) && !defined(USE_POLL)
+#if defined(NEED_PSELECT) && !defined(USE_POLL) && !defined(USE_KQUEUE)
 /* XXX needs to move to the porting library. */
 static int
 pselect(int nfds, void *rfds, void *wfds, void *efds,
diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_sendsigned.c /usr/src/lib/libc/resolv/res_sendsigned.c
--- /home/reed/src/isc/libbind/libbind/resolv/res_sendsigned.c	2006-03-09 17:57:56.000000000 -0600
+++ /usr/src/lib/libc/resolv/res_sendsigned.c	1969-12-31 18:00:00.000000000 -0600
@@ -1,170 +0,0 @@
-#include "port_before.h"
-#include "fd_setsize.h"
-
-#include <sys/types.h>
-#include <sys/param.h>
-
-#include <netinet/in.h>
-#include <arpa/nameser.h>
-#include <arpa/inet.h>
-
-#include <isc/dst.h>
-
-#include <errno.h>
-#include <netdb.h>
-#include <resolv.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "port_after.h"
-
-#define DEBUG
-#include "res_debug.h"
-
-
-/*% res_nsendsigned */
-int
-res_nsendsigned(res_state statp, const u_char *msg, int msglen,
-		ns_tsig_key *key, u_char *answer, int anslen)
-{
-	res_state nstatp;
-	DST_KEY *dstkey;
-	int usingTCP = 0;
-	u_char *newmsg;
-	int newmsglen, bufsize, siglen;
-	u_char sig[64];
-	HEADER *hp;
-	time_t tsig_time;
-	int ret;
-	int len;
-
-	dst_init();
-
-	nstatp = (res_state) malloc(sizeof(*statp));
-	if (nstatp == NULL) {
-		errno = ENOMEM;
-		return (-1);
-	}
-	memcpy(nstatp, statp, sizeof(*statp));
-
-	bufsize = msglen + 1024;
-	newmsg = (u_char *) malloc(bufsize);
-	if (newmsg == NULL) {
-		free(nstatp);
-		errno = ENOMEM;
-		return (-1);
-	}
-	memcpy(newmsg, msg, msglen);
-	newmsglen = msglen;
-
-	if (ns_samename(key->alg, NS_TSIG_ALG_HMAC_MD5) != 1)
-		dstkey = NULL;
-	else
-		dstkey = dst_buffer_to_key(key->name, KEY_HMAC_MD5,
-					   NS_KEY_TYPE_AUTH_ONLY,
-					   NS_KEY_PROT_ANY,
-					   key->data, key->len);
-	if (dstkey == NULL) {
-		errno = EINVAL;
-		free(nstatp);
-		free(newmsg);
-		return (-1);
-	}
-
-	nstatp->nscount = 1;
-	siglen = sizeof(sig);
-	ret = ns_sign(newmsg, &newmsglen, bufsize, NOERROR, dstkey, NULL, 0,
-		      sig, &siglen, 0);
-	if (ret < 0) {
-		free (nstatp);
-		free (newmsg);
-		dst_free_key(dstkey);
-		if (ret == NS_TSIG_ERROR_NO_SPACE)
-			errno  = EMSGSIZE;
-		else if (ret == -1)
-			errno  = EINVAL;
-		return (ret);
-	}
-
-	if (newmsglen > PACKETSZ || nstatp->options & RES_USEVC)
-		usingTCP = 1;
-	if (usingTCP == 0)
-		nstatp->options |= RES_IGNTC;
-	else
-		nstatp->options |= RES_USEVC;
-	/*
-	 * Stop res_send printing the answer.
-	 */
-	nstatp->options &= ~RES_DEBUG;
-	nstatp->pfcode &= ~RES_PRF_REPLY;
-
-retry:
-
-	len = res_nsend(nstatp, newmsg, newmsglen, answer, anslen);
-	if (len < 0) {
-		free (nstatp);
-		free (newmsg);
-		dst_free_key(dstkey);
-		return (len);
-	}
-
-	ret = ns_verify(answer, &len, dstkey, sig, siglen,
-			NULL, NULL, &tsig_time, nstatp->options & RES_KEEPTSIG);
-	if (ret != 0) {
-		Dprint((statp->options & RES_DEBUG) ||
-		       ((statp->pfcode & RES_PRF_REPLY) &&
-			(statp->pfcode & RES_PRF_HEAD1)),
-		       (stdout, ";; got answer:\n"));
-
-		DprintQ((statp->options & RES_DEBUG) ||
-			(statp->pfcode & RES_PRF_REPLY),
-			(stdout, "%s", ""),
-			answer, (anslen > len) ? len : anslen);
-
-		if (ret > 0) {
-			Dprint(statp->pfcode & RES_PRF_REPLY,
-			       (stdout, ";; server rejected TSIG (%s)\n",
-				p_rcode(ret)));
-		} else {
-			Dprint(statp->pfcode & RES_PRF_REPLY,
-			       (stdout, ";; TSIG invalid (%s)\n",
-				p_rcode(-ret)));
-		}
-
-		free (nstatp);
-		free (newmsg);
-		dst_free_key(dstkey);
-		if (ret == -1)
-			errno = EINVAL;
-		else
-			errno = ENOTTY;
-		return (-1);
-	}
-
-	hp = (HEADER *) answer;
-	if (hp->tc && !usingTCP && (statp->options & RES_IGNTC) == 0U) {
-		nstatp->options &= ~RES_IGNTC;
-		usingTCP = 1;
-		goto retry;
-	}
-	Dprint((statp->options & RES_DEBUG) ||
-	       ((statp->pfcode & RES_PRF_REPLY) &&
-		(statp->pfcode & RES_PRF_HEAD1)),
-	       (stdout, ";; got answer:\n"));
-
-	DprintQ((statp->options & RES_DEBUG) ||
-		(statp->pfcode & RES_PRF_REPLY),
-		(stdout, "%s", ""),
-		answer, (anslen > len) ? len : anslen);
-
-	Dprint(statp->pfcode & RES_PRF_REPLY, (stdout, ";; TSIG ok\n"));
-
-	free (nstatp);
-	free (newmsg);
-	dst_free_key(dstkey);
-	return (len);
-}
-
-/*! \file */
diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_state.c /usr/src/lib/libc/resolv/res_state.c
--- /home/reed/src/isc/libbind/libbind/resolv/res_state.c	1969-12-31 18:00:00.000000000 -0600
+++ /usr/src/lib/libc/resolv/res_state.c	2012-10-24 08:34:38.000000000 -0500
@@ -0,0 +1,73 @@
+/*	$NetBSD: res_state.c,v 1.8 2009/01/11 02:46:29 christos Exp $	*/
+
+/*-
+ * Copyright (c) 2004 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: res_state.c,v 1.8 2009/01/11 02:46:29 christos Exp $");
+#endif
+
+#include <sys/types.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <resolv.h>
+
+struct __res_state _nres
+# if defined(__BIND_RES_TEXT)
+	= { .retrans = RES_TIMEOUT, }	/*%< Motorola, et al. */
+# endif
+	;
+
+res_state __res_get_state_nothread(void);
+void __res_put_state_nothread(res_state);
+
+#ifdef __weak_alias
+__weak_alias(__res_get_state, __res_get_state_nothread)
+__weak_alias(__res_put_state, __res_put_state_nothread)
+/* Source compatibility; only for single threaded programs */
+__weak_alias(__res_state, __res_get_state_nothread)
+#endif
+
+res_state
+__res_get_state_nothread(void)
+{
+	if ((_nres.options & RES_INIT) == 0 && res_ninit(&_nres) == -1) {
+		h_errno = NETDB_INTERNAL;
+		return NULL;
+	}
+	return &_nres;
+}
+
+void
+/*ARGSUSED*/
+__res_put_state_nothread(res_state res)
+{
+}
diff -pruN /home/reed/src/isc/libbind/libbind/resolv/res_update.c /usr/src/lib/libc/resolv/res_update.c
--- /home/reed/src/isc/libbind/libbind/resolv/res_update.c	2005-04-26 23:56:43.000000000 -0500
+++ /usr/src/lib/libc/resolv/res_update.c	1969-12-31 18:00:00.000000000 -0600
@@ -1,213 +0,0 @@
-#if !defined(lint) && !defined(SABER)
-static const char rcsid[] = "$Id: res_update.c,v 1.13 2005/04/27 04:56:43 sra Exp $";
-#endif /* not lint */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1996-1999 by Internet Software Consortium.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*! \file
- * \brief
- * Based on the Dynamic DNS reference implementation by Viraj Bais
- * &lt;viraj_bais@ccm.fm.intel.com>
- */
-
-#include "port_before.h"
-
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <arpa/nameser.h>
-
-#include <errno.h>
-#include <limits.h>
-#include <netdb.h>
-#include <res_update.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <isc/list.h>
-#include <resolv.h>
-
-#include "port_after.h"
-#include "res_private.h"
-
-/*%
- * Separate a linked list of records into groups so that all records
- * in a group will belong to a single zone on the nameserver.
- * Create a dynamic update packet for each zone and send it to the
- * nameservers for that zone, and await answer.
- * Abort if error occurs in updating any zone.
- * Return the number of zones updated on success, < 0 on error.
- *
- * On error, caller must deal with the unsynchronized zones
- * eg. an A record might have been successfully added to the forward
- * zone but the corresponding PTR record would be missing if error
- * was encountered while updating the reverse zone.
- */
-
-struct zonegrp {
-	char			z_origin[MAXDNAME];
-	ns_class		z_class;
-	union res_sockaddr_union z_nsaddrs[MAXNS];
-	int			z_nscount;
-	int			z_flags;
-	LIST(ns_updrec)		z_rrlist;
-	LINK(struct zonegrp)	z_link;
-};
-
-#define ZG_F_ZONESECTADDED	0x0001
-
-/* Forward. */
-
-static void	res_dprintf(const char *, ...) ISC_FORMAT_PRINTF(1, 2);
-
-/* Macros. */
-
-#define DPRINTF(x) do {\
-		int save_errno = errno; \
-		if ((statp->options & RES_DEBUG) != 0U) res_dprintf x; \
-		errno = save_errno; \
-	} while (0)
-
-/* Public. */
-
-int
-res_nupdate(res_state statp, ns_updrec *rrecp_in, ns_tsig_key *key) {
-	ns_updrec *rrecp;
-	u_char answer[PACKETSZ];
-	u_char *packet;
-	struct zonegrp *zptr, tgrp;
-	LIST(struct zonegrp) zgrps;
-	int nzones = 0, nscount = 0, n;
-	union res_sockaddr_union nsaddrs[MAXNS];
-
-	packet = malloc(NS_MAXMSG);
-	if (packet == NULL) {
-		DPRINTF(("malloc failed"));
-		return (0);
-	}
-	/* Thread all of the updates onto a list of groups. */
-	INIT_LIST(zgrps);
-	memset(&tgrp, 0, sizeof (tgrp));
-	for (rrecp = rrecp_in; rrecp;
-	     rrecp = LINKED(rrecp, r_link) ? NEXT(rrecp, r_link) : NULL) {
-		int nscnt;
-		/* Find the origin for it if there is one. */
-		tgrp.z_class = rrecp->r_class;
-		nscnt = res_findzonecut2(statp, rrecp->r_dname, tgrp.z_class,
-					 RES_EXHAUSTIVE, tgrp.z_origin,
-					 sizeof tgrp.z_origin, 
-					 tgrp.z_nsaddrs, MAXNS);
-		if (nscnt <= 0) {
-			DPRINTF(("res_findzonecut failed (%d)", nscnt));
-			goto done;
-		}
-		tgrp.z_nscount = nscnt;
-		/* Find the group for it if there is one. */
-		for (zptr = HEAD(zgrps); zptr != NULL; zptr = NEXT(zptr, z_link))
-			if (ns_samename(tgrp.z_origin, zptr->z_origin) == 1 &&
-			    tgrp.z_class == zptr->z_class)
-				break;
-		/* Make a group for it if there isn't one. */
-		if (zptr == NULL) {
-			zptr = malloc(sizeof *zptr);
-			if (zptr == NULL) {
-				DPRINTF(("malloc failed"));
-				goto done;
-			}
-			*zptr = tgrp;
-			zptr->z_flags = 0;
-			INIT_LINK(zptr, z_link);
-			INIT_LIST(zptr->z_rrlist);
-			APPEND(zgrps, zptr, z_link);
-		}
-		/* Thread this rrecp onto the right group. */
-		APPEND(zptr->z_rrlist, rrecp, r_glink);
-	}
-
-	for (zptr = HEAD(zgrps); zptr != NULL; zptr = NEXT(zptr, z_link)) {
-		/* Construct zone section and prepend it. */
-		rrecp = res_mkupdrec(ns_s_zn, zptr->z_origin,
-				     zptr->z_class, ns_t_soa, 0);
-		if (rrecp == NULL) {
-			DPRINTF(("res_mkupdrec failed"));
-			goto done;
-		}
-		PREPEND(zptr->z_rrlist, rrecp, r_glink);
-		zptr->z_flags |= ZG_F_ZONESECTADDED;
-
-		/* Marshall the update message. */
-		n = res_nmkupdate(statp, HEAD(zptr->z_rrlist),
-				  packet, NS_MAXMSG);
-		DPRINTF(("res_mkupdate -> %d", n));
-		if (n < 0)
-			goto done;
-
-		/* Temporarily replace the resolver's nameserver set. */
-		nscount = res_getservers(statp, nsaddrs, MAXNS);
-		res_setservers(statp, zptr->z_nsaddrs, zptr->z_nscount);
-
-		/* Send the update and remember the result. */
-		if (key != NULL)
-			n = res_nsendsigned(statp, packet, n, key,
-					    answer, sizeof answer);
-		else
-			n = res_nsend(statp, packet, n, answer, sizeof answer);
-		if (n < 0) {
-			DPRINTF(("res_nsend: send error, n=%d (%s)\n",
-				 n, strerror(errno)));
-			goto done;
-		}
-		if (((HEADER *)answer)->rcode == NOERROR)
-			nzones++;
-
-		/* Restore resolver's nameserver set. */
-		res_setservers(statp, nsaddrs, nscount);
-		nscount = 0;
-	}
- done:
-	while (!EMPTY(zgrps)) {
-		zptr = HEAD(zgrps);
-		if ((zptr->z_flags & ZG_F_ZONESECTADDED) != 0)
-			res_freeupdrec(HEAD(zptr->z_rrlist));
-		UNLINK(zgrps, zptr, z_link);
-		free(zptr);
-	}
-	if (nscount != 0)
-		res_setservers(statp, nsaddrs, nscount);
-
-	free(packet);
-	return (nzones);
-}
-
-/* Private. */
-
-static void
-res_dprintf(const char *fmt, ...) {
-	va_list ap;
-
-	va_start(ap, fmt);
-	fputs(";; res_nupdate: ", stderr);
-	vfprintf(stderr, fmt, ap);
-	fputc('\n', stderr);
-	va_end(ap);
-}