aboutsummaryrefslogtreecommitdiffstats
path: root/lib/liblwres
diff options
context:
space:
mode:
Diffstat (limited to 'lib/liblwres')
-rw-r--r--lib/liblwres/Makefile73
-rw-r--r--lib/liblwres/api3
-rw-r--r--lib/liblwres/assert_p.h33
-rw-r--r--lib/liblwres/async.c361
-rw-r--r--lib/liblwres/config.h0
-rw-r--r--lib/liblwres/context.c380
-rw-r--r--lib/liblwres/context_p.h68
-rw-r--r--lib/liblwres/gai_strerror.c52
-rw-r--r--lib/liblwres/getaddrinfo.c692
-rw-r--r--lib/liblwres/gethost.c219
-rw-r--r--lib/liblwres/getipnode.c839
-rw-r--r--lib/liblwres/getnameinfo.c289
-rw-r--r--lib/liblwres/getrrset.c211
-rw-r--r--lib/liblwres/getrrset2.c97
-rw-r--r--lib/liblwres/herror.c101
-rw-r--r--lib/liblwres/include/lwres/async.h78
-rw-r--r--lib/liblwres/include/lwres/context.h133
-rw-r--r--lib/liblwres/include/lwres/int.h32
-rw-r--r--lib/liblwres/include/lwres/ipv6.h118
-rw-r--r--lib/liblwres/include/lwres/lang.h31
-rw-r--r--lib/liblwres/include/lwres/list.h119
-rw-r--r--lib/liblwres/include/lwres/lwbuffer.h402
-rw-r--r--lib/liblwres/include/lwres/lwpacket.h124
-rw-r--r--lib/liblwres/include/lwres/lwres.h584
-rw-r--r--lib/liblwres/include/lwres/netdb.h522
-rw-r--r--lib/liblwres/include/lwres/netdb.h.in518
-rw-r--r--lib/liblwres/include/lwres/platform.h91
-rw-r--r--lib/liblwres/include/lwres/platform.h.in91
-rw-r--r--lib/liblwres/include/lwres/result.h40
-rw-r--r--lib/liblwres/lwbuffer.c287
-rw-r--r--lib/liblwres/lwconfig.c703
-rw-r--r--lib/liblwres/lwinetaton.c203
-rw-r--r--lib/liblwres/lwinetntop.c191
-rw-r--r--lib/liblwres/lwinetpton.c206
-rw-r--r--lib/liblwres/lwpacket.c85
-rw-r--r--lib/liblwres/lwres_gabn.c415
-rw-r--r--lib/liblwres/lwres_gnba.c328
-rw-r--r--lib/liblwres/lwres_grbn.c416
-rw-r--r--lib/liblwres/lwres_noop.c255
-rw-r--r--lib/liblwres/lwresutil.c491
-rw-r--r--lib/liblwres/man/Makefile.in232
-rw-r--r--lib/liblwres/man/lwres.3158
-rw-r--r--lib/liblwres/man/lwres.docbook244
-rw-r--r--lib/liblwres/man/lwres.html444
-rw-r--r--lib/liblwres/man/lwres_buffer.3277
-rw-r--r--lib/liblwres/man/lwres_buffer.docbook378
-rw-r--r--lib/liblwres/man/lwres_buffer.html608
-rw-r--r--lib/liblwres/man/lwres_config.3105
-rw-r--r--lib/liblwres/man/lwres_config.docbook159
-rw-r--r--lib/liblwres/man/lwres_config.html295
-rw-r--r--lib/liblwres/man/lwres_context.3194
-rw-r--r--lib/liblwres/man/lwres_context.docbook283
-rw-r--r--lib/liblwres/man/lwres_context.html519
-rw-r--r--lib/liblwres/man/lwres_gabn.3193
-rw-r--r--lib/liblwres/man/lwres_gabn.docbook255
-rw-r--r--lib/liblwres/man/lwres_gabn.html442
-rw-r--r--lib/liblwres/man/lwres_gai_strerror.386
-rw-r--r--lib/liblwres/man/lwres_gai_strerror.docbook161
-rw-r--r--lib/liblwres/man/lwres_gai_strerror.html294
-rw-r--r--lib/liblwres/man/lwres_getaddrinfo.3247
-rw-r--r--lib/liblwres/man/lwres_getaddrinfo.docbook372
-rw-r--r--lib/liblwres/man/lwres_getaddrinfo.html722
-rw-r--r--lib/liblwres/man/lwres_gethostent.3270
-rw-r--r--lib/liblwres/man/lwres_gethostent.docbook407
-rw-r--r--lib/liblwres/man/lwres_gethostent.html827
-rw-r--r--lib/liblwres/man/lwres_getipnode.3187
-rw-r--r--lib/liblwres/man/lwres_getipnode.docbook307
-rw-r--r--lib/liblwres/man/lwres_getipnode.html529
-rw-r--r--lib/liblwres/man/lwres_getnameinfo.384
-rw-r--r--lib/liblwres/man/lwres_getnameinfo.docbook154
-rw-r--r--lib/liblwres/man/lwres_getnameinfo.html303
-rw-r--r--lib/liblwres/man/lwres_getrrsetbyname.3142
-rw-r--r--lib/liblwres/man/lwres_getrrsetbyname.docbook208
-rw-r--r--lib/liblwres/man/lwres_getrrsetbyname.html371
-rw-r--r--lib/liblwres/man/lwres_gnba.3186
-rw-r--r--lib/liblwres/man/lwres_gnba.docbook259
-rw-r--r--lib/liblwres/man/lwres_gnba.html408
-rw-r--r--lib/liblwres/man/lwres_hstrerror.367
-rw-r--r--lib/liblwres/man/lwres_hstrerror.docbook124
-rw-r--r--lib/liblwres/man/lwres_hstrerror.html242
-rw-r--r--lib/liblwres/man/lwres_inetntop.352
-rw-r--r--lib/liblwres/man/lwres_inetntop.docbook99
-rw-r--r--lib/liblwres/man/lwres_inetntop.html186
-rw-r--r--lib/liblwres/man/lwres_noop.3160
-rw-r--r--lib/liblwres/man/lwres_noop.docbook229
-rw-r--r--lib/liblwres/man/lwres_noop.html409
-rw-r--r--lib/liblwres/man/lwres_packet.3149
-rw-r--r--lib/liblwres/man/lwres_packet.docbook218
-rw-r--r--lib/liblwres/man/lwres_packet.html373
-rw-r--r--lib/liblwres/man/lwres_resutil.3151
-rw-r--r--lib/liblwres/man/lwres_resutil.docbook221
-rw-r--r--lib/liblwres/man/lwres_resutil.html412
-rw-r--r--lib/liblwres/unix/include/lwres/net.h127
-rw-r--r--lib/liblwres/version.c24
94 files changed, 24434 insertions, 0 deletions
diff --git a/lib/liblwres/Makefile b/lib/liblwres/Makefile
new file mode 100644
index 000000000..84a7713ab
--- /dev/null
+++ b/lib/liblwres/Makefile
@@ -0,0 +1,73 @@
+# Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SOFTWARE CONSORTIUM 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.
+
+# $Id: Makefile,v 1.1 2004/03/15 20:35:25 as Exp $
+
+srcdir = .
+VPATH = .
+top_srcdir = .
+
+CINCLUDES = -I${srcdir}/unix/include \
+ -I. -I./include -I${srcdir}/include
+CDEFINES = -g
+CWARNINGS = -Werror
+
+CFLAGS=${CINCLUDES} ${CDEFINES} ${CWARNINGS}
+
+VERSION="@(\#) freeswan-hacking-9.2.1-for-fs2"
+LIBINTERFACE=2
+LIBREVISION=0
+LIBAGE=1
+RANLIB=ranlib
+
+# Alphabetically
+OBJS = async.o context.o gai_strerror.o getaddrinfo.o gethost.o \
+ getipnode.o getnameinfo.o getrrset.o getrrset2.o herror.o \
+ lwbuffer.o lwconfig.o lwpacket.o lwresutil.o \
+ lwres_gabn.o lwres_gnba.o lwres_grbn.o lwres_noop.o \
+ lwinetaton.o lwinetpton.o lwinetntop.o
+
+# Alphabetically
+SRCS = async.c context.c gai_strerror.c getaddrinfo.c gethost.c \
+ getipnode.c getnameinfo.c getrrset.c getrrset2.c herror.c \
+ lwbuffer.c lwconfig.c lwpacket.c lwresutil.c \
+ lwres_gabn.c lwres_gnba.c lwres_grbn.c lwres_noop.c \
+ lwinetaton.c lwinetpton.c lwinetntop.c
+
+programs all: liblwres.a
+
+version.o: version.c
+ ${LIBTOOL} ${CC} ${ALL_CFLAGS} \
+ -DVERSION=\"${VERSION}\" \
+ -DLIBINTERFACE=${LIBINTERFACE} \
+ -DLIBREVISION=${LIBREVISION} \
+ -DLIBAGE=${LIBAGE} \
+ -c ${srcdir}/version.c
+
+liblwres.a: ${OBJS} version.o
+ ${AR} ${ARFLAGS} $@ ${OBJS} version.o
+ ${RANLIB} $@
+
+timestamp: liblwres.a
+ touch timestamp
+
+clean distclean mostlyclean realclean cleanall spotless::
+ rm -f liblwres.a liblwres.la timestamp $(OBJS)
+
+install checkprograms check install_file_list:
+ @true
+
+TAGS: ${SRCS}
+ etags ${SRCS}
diff --git a/lib/liblwres/api b/lib/liblwres/api
new file mode 100644
index 000000000..f86947031
--- /dev/null
+++ b/lib/liblwres/api
@@ -0,0 +1,3 @@
+LIBINTERFACE = 2
+LIBREVISION = 0
+LIBAGE = 1
diff --git a/lib/liblwres/assert_p.h b/lib/liblwres/assert_p.h
new file mode 100644
index 000000000..0c5718290
--- /dev/null
+++ b/lib/liblwres/assert_p.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: assert_p.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_ASSERT_P_H
+#define LWRES_ASSERT_P_H 1
+
+#include <assert.h> /* Required for assert() prototype. */
+
+#define REQUIRE(x) assert(x)
+#define INSIST(x) assert(x)
+
+#define UNUSED(x) ((void)(x))
+
+#define SPACE_OK(b, s) (LWRES_BUFFER_AVAILABLECOUNT(b) >= (s))
+#define SPACE_REMAINING(b, s) (LWRES_BUFFER_REMAINING(b) >= (s))
+
+#endif /* LWRES_ASSERT_P_H */
diff --git a/lib/liblwres/async.c b/lib/liblwres/async.c
new file mode 100644
index 000000000..b23596a70
--- /dev/null
+++ b/lib/liblwres/async.c
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2003, Michael Richardson <mcr@freeswawn.org>
+ * Derived from code: Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: async.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <lwres/lwres.h>
+#include <lwres/net.h>
+#include <lwres/netdb.h> /* XXX #include <netdb.h> */
+#include <lwres/async.h>
+
+#include "assert_p.h"
+#include "context_p.h"
+
+/*
+ * malloc / calloc functions that guarantee to only
+ * return NULL if there is an error, like they used
+ * to before the ANSI C committee broke them.
+ */
+
+static void *
+sane_malloc(size_t size) {
+ if (size == 0)
+ size = 1;
+ return (malloc(size));
+}
+
+static void *
+sane_calloc(size_t number, size_t size) {
+ size_t len = number * size;
+ void *mem = sane_malloc(len);
+ if (mem != NULL)
+ memset(mem, 0, len);
+ return (mem);
+}
+
+int
+lwres_async_init(lwres_context_t **pctx)
+{
+ lwres_result_t lwresult;
+ lwres_context_t *ctx = NULL;
+ int result;
+
+ lwresult = lwres_context_create(&ctx, NULL, NULL, NULL, 0);
+ if (lwresult != LWRES_R_SUCCESS) {
+ result = lwresult_to_result(lwresult);
+ return(result);
+ }
+ (void) lwres_conf_parse(ctx, lwres_resolv_conf);
+
+ *pctx = ctx;
+ return (ERRSET_SUCCESS);
+}
+
+int
+lwres_getrrsetbyname_init(const char *hostname, unsigned int rdclass,
+ unsigned int rdtype, unsigned int flags,
+ lwres_context_t *ctx,
+ struct lwres_async_state *las)
+{
+ lwres_result_t lwresult;
+ unsigned int i;
+ unsigned int lwflags;
+ unsigned int result;
+
+ int ret;
+ lwres_lwpacket_t pkt;
+ lwres_grbnrequest_t request;
+ char target_name[1024];
+ unsigned int target_length;
+
+ int ret2;
+
+ if (rdclass > 0xffff || rdtype > 0xffff) {
+ result = ERRSET_INVAL;
+ return result;
+ }
+
+ /*
+ * Don't allow queries of class or type ANY
+ */
+ if (rdclass == 0xff || rdtype == 0xff) {
+ result = ERRSET_INVAL;
+ return result;
+ }
+
+ /*
+ * If any input flags were defined, lwflags would be set here
+ * based on them
+ */
+ UNUSED(flags);
+ lwflags = 0;
+
+ las->b_in.base = NULL;
+ las->b_out.base = NULL;
+ las->serial = lwres_context_nextserial(ctx);
+ las->opcode = LWRES_OPCODE_GETRDATABYNAME;
+
+ target_length = strlen(hostname);
+ if (target_length >= sizeof(target_name))
+ return (LWRES_R_FAILURE);
+ strcpy(target_name, hostname); /* strcpy is safe */
+
+ /*
+ * Set up our request and render it to a buffer.
+ */
+ request.rdclass = rdclass;
+ request.rdtype = rdtype;
+ request.flags = lwflags;
+ request.name = target_name;
+ request.namelen = target_length;
+ pkt.pktflags = 0;
+ pkt.serial = las->serial;
+ pkt.result = 0;
+ pkt.recvlength = LWRES_RECVLENGTH;
+
+ /* set up async system */
+ las->next = ctx->pending;
+ ctx->pending = las;
+
+ ret = lwres_grbnrequest_render(ctx, &request, &pkt, &las->b_out);
+
+ return ret;
+}
+
+int
+lwres_getrrsetbyname_xmit(lwres_context_t *ctx,
+ struct lwres_async_state *las)
+{
+ lwres_result_t lwresult;
+ int ret;
+
+ lwresult = lwres_context_send(ctx, las->b_out.base, las->b_out.length);
+
+ return(lwresult_to_result(lwresult));
+}
+
+
+
+unsigned long
+lwres_async_timeout(lwres_context_t *ctx)
+{
+ unsigned long tv_sec;
+
+ /*
+ * Type of tv_sec is long, so make sure the unsigned long timeout
+ * does not overflow it.
+ */
+ if (ctx->timeout <= LONG_MAX)
+ tv_sec = (long)ctx->timeout;
+ else
+ tv_sec = LONG_MAX;
+
+ return tv_sec;
+}
+
+int
+lwres_async_fd(lwres_context_t *ctx)
+{
+ return (ctx->sock);
+}
+
+
+/*
+const char *hostname, unsigned int rdclass,
+ unsigned int rdtype, unsigned int flags,
+*/
+
+int
+lwres_getrrsetbyname_read(struct lwres_async_state **plas,
+ lwres_context_t *ctx,
+ struct rrsetinfo **res)
+{
+ lwres_result_t lwresult;
+ lwres_grbnresponse_t *response = NULL;
+ char *buffer;
+ struct rrsetinfo *rrset = NULL;
+ int recvlen;
+ int ret, result, i;
+ lwres_buffer_t b_in;
+ struct lwres_async_state *las;
+ struct lwres_async_state **las_prev;
+ lwres_lwpacket_t pkt;
+
+ buffer = NULL;
+ buffer = CTXMALLOC(LWRES_RECVLENGTH);
+ if (buffer == NULL) {
+ return ERRSET_NOMEMORY;
+ }
+
+ ret = LWRES_R_SUCCESS;
+ lwresult = lwres_context_recv(ctx, buffer, LWRES_RECVLENGTH, &recvlen);
+ if (lwresult == LWRES_R_RETRY) {
+ ret = LWRES_R_RETRY;
+ goto out;
+ }
+
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ lwres_buffer_init(&b_in, buffer, recvlen);
+ b_in.used = recvlen;
+
+ /*
+ * Parse the packet header.
+ */
+ ret = lwres_lwpacket_parseheader(&b_in, &pkt);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ /*
+ * find an appropriate waiting las entry. This is a linear search.
+ * we can do MUCH better, since we control the serial number!
+ * do that later.
+ */
+ las_prev = &ctx->pending;
+ las = ctx->pending;
+ while(las && las->serial != pkt.serial) {
+ las_prev=&las->next;
+ las=las->next;
+ }
+
+ if(las == NULL) {
+ /* no matching serial number! */
+ return(LWRES_R_RETRY);
+ }
+
+ /* okay, remove it from the receive queue */
+ *las_prev = las->next;
+ las->next = NULL;
+
+ *plas = las;
+
+ /*
+ * Free what we've transmitted, long ago.
+ */
+ CTXFREE(las->b_out.base, las->b_out.length);
+ las->b_out.base = NULL;
+ las->b_out.length = 0;
+
+ if (pkt.result != LWRES_R_SUCCESS) {
+ ret = pkt.result;
+ goto out;
+ }
+
+ /*
+ * Parse the response.
+ */
+ ret = lwres_grbnresponse_parse(ctx, &b_in, &pkt, &response);
+ if (ret != LWRES_R_SUCCESS) {
+ out:
+ if (buffer != NULL)
+ CTXFREE(buffer, LWRES_RECVLENGTH);
+ if (response != NULL)
+ lwres_grbnresponse_free(ctx, &response);
+ result = lwresult_to_result(ret);
+ goto fail;
+ }
+
+ response->base = buffer;
+ response->baselen = LWRES_RECVLENGTH;
+ buffer = NULL; /* don't free this below */
+
+ lwresult = LWRES_R_SUCCESS;
+
+ rrset = sane_malloc(sizeof(struct rrsetinfo));
+ if (rrset == NULL) {
+ result = ERRSET_NOMEMORY;
+ goto fail;
+ }
+ rrset->rri_name = NULL;
+ rrset->rri_rdclass = response->rdclass;
+ rrset->rri_rdtype = response->rdtype;
+ rrset->rri_ttl = response->ttl;
+ rrset->rri_flags = 0;
+ rrset->rri_nrdatas = 0;
+ rrset->rri_rdatas = NULL;
+ rrset->rri_nsigs = 0;
+ rrset->rri_sigs = NULL;
+
+ rrset->rri_name = sane_malloc(response->realnamelen + 1);
+ if (rrset->rri_name == NULL) {
+ result = ERRSET_NOMEMORY;
+ goto fail;
+ }
+ strncpy(rrset->rri_name, response->realname, response->realnamelen);
+ rrset->rri_name[response->realnamelen] = 0;
+
+ if ((response->flags & LWRDATA_VALIDATED) != 0)
+ rrset->rri_flags |= RRSET_VALIDATED;
+
+ rrset->rri_nrdatas = response->nrdatas;
+ rrset->rri_rdatas = sane_calloc(rrset->rri_nrdatas,
+ sizeof(struct rdatainfo));
+ if (rrset->rri_rdatas == NULL) {
+ result = ERRSET_NOMEMORY;
+ goto fail;
+ }
+ for (i = 0; i < rrset->rri_nrdatas; i++) {
+ rrset->rri_rdatas[i].rdi_length = response->rdatalen[i];
+ rrset->rri_rdatas[i].rdi_data =
+ sane_malloc(rrset->rri_rdatas[i].rdi_length);
+ if (rrset->rri_rdatas[i].rdi_data == NULL) {
+ result = ERRSET_NOMEMORY;
+ goto fail;
+ }
+ memcpy(rrset->rri_rdatas[i].rdi_data, response->rdatas[i],
+ rrset->rri_rdatas[i].rdi_length);
+ }
+ rrset->rri_nsigs = response->nsigs;
+ rrset->rri_sigs = sane_calloc(rrset->rri_nsigs,
+ sizeof(struct rdatainfo));
+ if (rrset->rri_sigs == NULL) {
+ result = ERRSET_NOMEMORY;
+ goto fail;
+ }
+ for (i = 0; i < rrset->rri_nsigs; i++) {
+ rrset->rri_sigs[i].rdi_length = response->siglen[i];
+ rrset->rri_sigs[i].rdi_data =
+ sane_malloc(rrset->rri_sigs[i].rdi_length);
+ if (rrset->rri_sigs[i].rdi_data == NULL) {
+ result = ERRSET_NOMEMORY;
+ goto fail;
+ }
+ memcpy(rrset->rri_sigs[i].rdi_data, response->sigs[i],
+ rrset->rri_sigs[i].rdi_length);
+ }
+
+ lwres_grbnresponse_free(ctx, &response);
+
+ *res = rrset;
+ return (ERRSET_SUCCESS);
+ fail:
+ if (rrset != NULL)
+ lwres_freerrset(rrset);
+ if (response != NULL)
+ lwres_grbnresponse_free(ctx, &response);
+ return (result);
+
+}
+
diff --git a/lib/liblwres/config.h b/lib/liblwres/config.h
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/lib/liblwres/config.h
diff --git a/lib/liblwres/context.c b/lib/liblwres/context.c
new file mode 100644
index 000000000..40f8f3e3d
--- /dev/null
+++ b/lib/liblwres/context.c
@@ -0,0 +1,380 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: context.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <fcntl.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <lwres/lwres.h>
+#include <lwres/net.h>
+#include <lwres/platform.h>
+
+#ifdef LWRES_PLATFORM_NEEDSYSSELECTH
+#include <sys/select.h>
+#endif
+
+#include "context_p.h"
+#include "assert_p.h"
+
+/*
+ * Some systems define the socket length argument as an int, some as size_t,
+ * some as socklen_t. The last is what the current POSIX standard mandates.
+ * This definition is here so it can be portable but easily changed if needed.
+ */
+#ifndef LWRES_SOCKADDR_LEN_T
+#define LWRES_SOCKADDR_LEN_T unsigned int
+#endif
+
+/*
+ * Make a socket nonblocking.
+ */
+#ifndef MAKE_NONBLOCKING
+#define MAKE_NONBLOCKING(sd, retval) \
+do { \
+ retval = fcntl(sd, F_GETFL, 0); \
+ if (retval != -1) { \
+ retval |= O_NONBLOCK; \
+ retval = fcntl(sd, F_SETFL, retval); \
+ } \
+} while (0)
+#endif
+
+lwres_uint16_t lwres_udp_port = LWRES_UDP_PORT;
+const char *lwres_resolv_conf = LWRES_RESOLV_CONF;
+
+static void *
+lwres_malloc(void *, size_t);
+
+static void
+lwres_free(void *, void *, size_t);
+
+static lwres_result_t
+context_connect(lwres_context_t *);
+
+lwres_result_t
+lwres_context_create(lwres_context_t **contextp, void *arg,
+ lwres_malloc_t malloc_function,
+ lwres_free_t free_function,
+ unsigned int flags)
+{
+ lwres_context_t *ctx;
+
+ REQUIRE(contextp != NULL && *contextp == NULL);
+ UNUSED(flags);
+
+ /*
+ * If we were not given anything special to use, use our own
+ * functions. These are just wrappers around malloc() and free().
+ */
+ if (malloc_function == NULL || free_function == NULL) {
+ REQUIRE(malloc_function == NULL);
+ REQUIRE(free_function == NULL);
+ malloc_function = lwres_malloc;
+ free_function = lwres_free;
+ }
+
+ ctx = malloc_function(arg, sizeof(lwres_context_t));
+ if (ctx == NULL)
+ return (LWRES_R_NOMEMORY);
+
+ /*
+ * Set up the context.
+ */
+ ctx->malloc = malloc_function;
+ ctx->free = free_function;
+ ctx->arg = arg;
+ ctx->sock = -1;
+
+ ctx->timeout = LWRES_DEFAULT_TIMEOUT;
+ ctx->serial = time(NULL); /* XXXMLG or BEW */
+
+ /*
+ * Init resolv.conf bits.
+ */
+ lwres_conf_init(ctx);
+
+ *contextp = ctx;
+ return (LWRES_R_SUCCESS);
+}
+
+void
+lwres_context_destroy(lwres_context_t **contextp) {
+ lwres_context_t *ctx;
+
+ REQUIRE(contextp != NULL && *contextp != NULL);
+
+ ctx = *contextp;
+ *contextp = NULL;
+
+ if (ctx->sock != -1) {
+ close(ctx->sock);
+ ctx->sock = -1;
+ }
+
+ CTXFREE(ctx, sizeof(lwres_context_t));
+}
+
+lwres_uint32_t
+lwres_context_nextserial(lwres_context_t *ctx) {
+ REQUIRE(ctx != NULL);
+
+ return (ctx->serial++);
+}
+
+void
+lwres_context_initserial(lwres_context_t *ctx, lwres_uint32_t serial) {
+ REQUIRE(ctx != NULL);
+
+ ctx->serial = serial;
+}
+
+void
+lwres_context_freemem(lwres_context_t *ctx, void *mem, size_t len) {
+ REQUIRE(mem != NULL);
+ REQUIRE(len != 0);
+
+ CTXFREE(mem, len);
+}
+
+void *
+lwres_context_allocmem(lwres_context_t *ctx, size_t len) {
+ REQUIRE(len != 0);
+
+ return (CTXMALLOC(len));
+}
+
+static void *
+lwres_malloc(void *arg, size_t len) {
+ void *mem;
+
+ UNUSED(arg);
+
+ mem = malloc(len);
+ if (mem == NULL)
+ return (NULL);
+
+ memset(mem, 0xe5, len);
+
+ return (mem);
+}
+
+static void
+lwres_free(void *arg, void *mem, size_t len) {
+ UNUSED(arg);
+
+ memset(mem, 0xa9, len);
+ free(mem);
+}
+
+static lwres_result_t
+context_connect(lwres_context_t *ctx) {
+ int s;
+ int ret;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+ struct sockaddr *sa;
+ LWRES_SOCKADDR_LEN_T salen;
+ int domain;
+
+ if (ctx->confdata.lwnext != 0) {
+ memcpy(&ctx->address, &ctx->confdata.lwservers[0],
+ sizeof(lwres_addr_t));
+ LWRES_LINK_INIT(&ctx->address, link);
+ } else {
+ /* The default is the IPv4 loopback address 127.0.0.1. */
+ memset(&ctx->address, 0, sizeof(ctx->address));
+ ctx->address.family = LWRES_ADDRTYPE_V4;
+ ctx->address.length = 4;
+ ctx->address.address[0] = 127;
+ ctx->address.address[1] = 0;
+ ctx->address.address[2] = 0;
+ ctx->address.address[3] = 1;
+ }
+
+ if (ctx->address.family == LWRES_ADDRTYPE_V4) {
+ memcpy(&sin.sin_addr, ctx->address.address,
+ sizeof(sin.sin_addr));
+ sin.sin_port = htons(lwres_udp_port);
+ sin.sin_family = AF_INET;
+ sa = (struct sockaddr *)&sin;
+ salen = sizeof(sin);
+ domain = PF_INET;
+ } else if (ctx->address.family == LWRES_ADDRTYPE_V6) {
+ memcpy(&sin6.sin6_addr, ctx->address.address,
+ sizeof(sin6.sin6_addr));
+ sin6.sin6_port = htons(lwres_udp_port);
+ sin6.sin6_family = AF_INET6;
+ sa = (struct sockaddr *)&sin6;
+ salen = sizeof(sin6);
+ domain = PF_INET6;
+ } else
+ return (LWRES_R_IOERROR);
+
+ s = socket(domain, SOCK_DGRAM, IPPROTO_UDP);
+ if (s < 0)
+ return (LWRES_R_IOERROR);
+
+ ret = connect(s, sa, salen);
+ if (ret != 0) {
+ close(s);
+ return (LWRES_R_IOERROR);
+ }
+
+ MAKE_NONBLOCKING(s, ret);
+ if (ret < 0)
+ return (LWRES_R_IOERROR);
+
+ ctx->sock = s;
+
+ return (LWRES_R_SUCCESS);
+}
+
+int
+lwres_context_getsocket(lwres_context_t *ctx) {
+ return (ctx->sock);
+}
+
+lwres_result_t
+lwres_context_send(lwres_context_t *ctx,
+ void *sendbase, int sendlen) {
+ int ret;
+ lwres_result_t lwresult;
+
+ if (ctx->sock == -1) {
+ lwresult = context_connect(ctx);
+ if (lwresult != LWRES_R_SUCCESS)
+ return (lwresult);
+ }
+
+ ret = sendto(ctx->sock, sendbase, sendlen, 0, NULL, 0);
+ if (ret < 0)
+ return (LWRES_R_IOERROR);
+ if (ret != sendlen)
+ return (LWRES_R_IOERROR);
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_context_recv(lwres_context_t *ctx,
+ void *recvbase, int recvlen,
+ int *recvd_len)
+{
+ LWRES_SOCKADDR_LEN_T fromlen;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+ struct sockaddr *sa;
+ int ret;
+
+ if (ctx->address.family == LWRES_ADDRTYPE_V4) {
+ sa = (struct sockaddr *)&sin;
+ fromlen = sizeof(sin);
+ } else {
+ sa = (struct sockaddr *)&sin6;
+ fromlen = sizeof(sin6);
+ }
+
+ /*
+ * The address of fromlen is cast to void * to shut up compiler
+ * warnings, namely on systems that have the sixth parameter
+ * prototyped as a signed int when LWRES_SOCKADDR_LEN_T is
+ * defined as unsigned.
+ */
+ ret = recvfrom(ctx->sock, recvbase, recvlen, 0, sa, (void *)&fromlen);
+
+ if (ret < 0)
+ return (LWRES_R_IOERROR);
+
+ if (ret == recvlen)
+ return (LWRES_R_TOOLARGE);
+
+ /*
+ * If we got something other than what we expect, have the caller
+ * wait for another packet. This can happen if an old result
+ * comes in, or if someone is sending us random stuff.
+ */
+ if (ctx->address.family == LWRES_ADDRTYPE_V4) {
+ if (fromlen != sizeof(sin)
+ || memcmp(&sin.sin_addr, ctx->address.address,
+ sizeof(sin.sin_addr)) != 0
+ || sin.sin_port != htons(lwres_udp_port))
+ return (LWRES_R_RETRY);
+ } else {
+ if (fromlen != sizeof(sin6)
+ || memcmp(&sin6.sin6_addr, ctx->address.address,
+ sizeof(sin6.sin6_addr)) != 0
+ || sin6.sin6_port != htons(lwres_udp_port))
+ return (LWRES_R_RETRY);
+ }
+
+ if (recvd_len != NULL)
+ *recvd_len = ret;
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_context_sendrecv(lwres_context_t *ctx,
+ void *sendbase, int sendlen,
+ void *recvbase, int recvlen,
+ int *recvd_len)
+{
+ lwres_result_t result;
+ int ret2;
+ fd_set readfds;
+ struct timeval timeout;
+
+ /*
+ * Type of tv_sec is long, so make sure the unsigned long timeout
+ * does not overflow it.
+ */
+ if (ctx->timeout <= LONG_MAX)
+ timeout.tv_sec = (long)ctx->timeout;
+ else
+ timeout.tv_sec = LONG_MAX;
+
+ timeout.tv_usec = 0;
+
+ result = lwres_context_send(ctx, sendbase, sendlen);
+ if (result != LWRES_R_SUCCESS)
+ return (result);
+ again:
+ FD_ZERO(&readfds);
+ FD_SET(ctx->sock, &readfds);
+ ret2 = select(ctx->sock + 1, &readfds, NULL, NULL, &timeout);
+
+ /*
+ * What happened with select?
+ */
+ if (ret2 < 0)
+ return (LWRES_R_IOERROR);
+ if (ret2 == 0)
+ return (LWRES_R_TIMEOUT);
+
+ result = lwres_context_recv(ctx, recvbase, recvlen, recvd_len);
+ if (result == LWRES_R_RETRY)
+ goto again;
+
+ return (result);
+}
diff --git a/lib/liblwres/context_p.h b/lib/liblwres/context_p.h
new file mode 100644
index 000000000..52dd870e1
--- /dev/null
+++ b/lib/liblwres/context_p.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: context_p.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_CONTEXT_P_H
+#define LWRES_CONTEXT_P_H 1
+
+/*
+ * Helper functions, assuming the context is always called "ctx" in
+ * the scope these functions are called from.
+ */
+#define CTXMALLOC(len) ctx->malloc(ctx->arg, (len))
+#define CTXFREE(addr, len) ctx->free(ctx->arg, (addr), (len))
+
+#define LWRES_DEFAULT_TIMEOUT 120 /* 120 seconds for a reply */
+
+/*
+ * Not all the attributes here are actually settable by the application at
+ * this time.
+ */
+struct lwres_context {
+ unsigned int timeout; /* time to wait for reply */
+ lwres_uint32_t serial; /* serial number state */
+
+ /*
+ * For network I/O.
+ */
+ int sock; /* socket to send on */
+ lwres_addr_t address; /* address to send to */
+
+ /*
+ * Function pointers for allocating memory.
+ */
+ lwres_malloc_t malloc;
+ lwres_free_t free;
+ void *arg;
+
+ /*
+ * resolv.conf-like data
+ */
+ lwres_conf_t confdata;
+
+ /* linked list of outstanding DNS requests */
+ struct lwres_async_state *pending;
+};
+
+#endif /* LWRES_CONTEXT_P_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 8
+ * End Variables:
+ */
diff --git a/lib/liblwres/gai_strerror.c b/lib/liblwres/gai_strerror.c
new file mode 100644
index 000000000..913b5139f
--- /dev/null
+++ b/lib/liblwres/gai_strerror.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: gai_strerror.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <lwres/netdb.h>
+
+static const char *gai_messages[] = {
+ "no error",
+ "address family for hostname not supported",
+ "temporary failure in name resolution",
+ "invalid value for ai_flags",
+ "non-recoverable failure in name resolution",
+ "ai_family not supported",
+ "memory allocation failure",
+ "no address associated with hostname",
+ "hostname nor servname provided, or not known",
+ "servname not supported for ai_socktype",
+ "ai_socktype not supported",
+ "system error returned in errno",
+ "bad hints",
+ "bad protocol"
+};
+
+char *
+lwres_gai_strerror(int ecode) {
+ union {
+ const char *const_ptr;
+ char *deconst_ptr;
+ } ptr;
+
+ if ((ecode < 0) ||
+ (ecode >= (int)(sizeof(gai_messages)/sizeof(*gai_messages))))
+ ptr.const_ptr = "invalid error code";
+ else
+ ptr.const_ptr = gai_messages[ecode];
+ return (ptr.deconst_ptr);
+}
diff --git a/lib/liblwres/getaddrinfo.c b/lib/liblwres/getaddrinfo.c
new file mode 100644
index 000000000..06cb39ffc
--- /dev/null
+++ b/lib/liblwres/getaddrinfo.c
@@ -0,0 +1,692 @@
+/*
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * This code is derived from software contributed to Internet Software
+ * Consortium by Berkeley Software Design, Inc.
+ *
+ * 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 INTERNET SOFTWARE CONSORTIUM AND
+ * BERKELEY SOFTWARE DESIGN, INC DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE CONSORTIUM OR BERKELEY
+ * SOFTWARE DESIGN, INC 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.
+ */
+
+/* $Id: getaddrinfo.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <lwres/lwres.h>
+#include <lwres/net.h>
+#include <lwres/netdb.h>
+
+#define SA(addr) ((struct sockaddr *)(addr))
+#define SIN(addr) ((struct sockaddr_in *)(addr))
+#define SIN6(addr) ((struct sockaddr_in6 *)(addr))
+#define SUN(addr) ((struct sockaddr_un *)(addr))
+
+static struct addrinfo
+ *ai_reverse(struct addrinfo *oai),
+ *ai_clone(struct addrinfo *oai, int family),
+ *ai_alloc(int family, int addrlen);
+#ifdef AF_LOCAL
+static int get_local(const char *name, int socktype, struct addrinfo **res);
+#endif
+
+static int add_ipv4(const char *hostname, int flags, struct addrinfo **aip,
+ int socktype, int port);
+static int add_ipv6(const char *hostname, int flags, struct addrinfo **aip,
+ int socktype, int port);
+static void set_order(int, int (**)(const char *, int, struct addrinfo **,
+ int, int));
+
+#define FOUND_IPV4 0x1
+#define FOUND_IPV6 0x2
+#define FOUND_MAX 2
+
+#define ISC_AI_MASK (AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST)
+
+int
+lwres_getaddrinfo(const char *hostname, const char *servname,
+ const struct addrinfo *hints, struct addrinfo **res)
+{
+ struct servent *sp;
+ const char *proto;
+ int family, socktype, flags, protocol;
+ struct addrinfo *ai, *ai_list;
+ int port, err, i;
+ int (*net_order[FOUND_MAX+1])(const char *, int, struct addrinfo **,
+ int, int);
+
+ if (hostname == NULL && servname == NULL)
+ return (EAI_NONAME);
+
+ proto = NULL;
+ if (hints != NULL) {
+ if ((hints->ai_flags & ~(ISC_AI_MASK)) != 0)
+ return (EAI_BADFLAGS);
+ if (hints->ai_addrlen || hints->ai_canonname ||
+ hints->ai_addr || hints->ai_next) {
+ errno = EINVAL;
+ return (EAI_SYSTEM);
+ }
+ family = hints->ai_family;
+ socktype = hints->ai_socktype;
+ protocol = hints->ai_protocol;
+ flags = hints->ai_flags;
+ switch (family) {
+ case AF_UNSPEC:
+ switch (hints->ai_socktype) {
+ case SOCK_STREAM:
+ proto = "tcp";
+ break;
+ case SOCK_DGRAM:
+ proto = "udp";
+ break;
+ }
+ break;
+ case AF_INET:
+ case AF_INET6:
+ switch (hints->ai_socktype) {
+ case 0:
+ break;
+ case SOCK_STREAM:
+ proto = "tcp";
+ break;
+ case SOCK_DGRAM:
+ proto = "udp";
+ break;
+ case SOCK_RAW:
+ break;
+ default:
+ return (EAI_SOCKTYPE);
+ }
+ break;
+#ifdef AF_LOCAL
+ case AF_LOCAL:
+ switch (hints->ai_socktype) {
+ case 0:
+ break;
+ case SOCK_STREAM:
+ break;
+ case SOCK_DGRAM:
+ break;
+ default:
+ return (EAI_SOCKTYPE);
+ }
+ break;
+#endif
+ default:
+ return (EAI_FAMILY);
+ }
+ } else {
+ protocol = 0;
+ family = 0;
+ socktype = 0;
+ flags = 0;
+ }
+
+#ifdef AF_LOCAL
+ /*
+ * First, deal with AF_LOCAL. If the family was not set,
+ * then assume AF_LOCAL if the first character of the
+ * hostname/servname is '/'.
+ */
+
+ if (hostname != NULL &&
+ (family == AF_LOCAL || (family == 0 && *hostname == '/')))
+ return (get_local(hostname, socktype, res));
+
+ if (servname != NULL &&
+ (family == AF_LOCAL || (family == 0 && *servname == '/')))
+ return (get_local(servname, socktype, res));
+#endif
+
+ /*
+ * Ok, only AF_INET and AF_INET6 left.
+ */
+ ai_list = NULL;
+
+ /*
+ * First, look up the service name (port) if it was
+ * requested. If the socket type wasn't specified, then
+ * try and figure it out.
+ */
+ if (servname != NULL) {
+ char *e;
+
+ port = strtol(servname, &e, 10);
+ if (*e == '\0') {
+ if (socktype == 0)
+ return (EAI_SOCKTYPE);
+ if (port < 0 || port > 65535)
+ return (EAI_SERVICE);
+ port = htons((unsigned short) port);
+ } else {
+ sp = getservbyname(servname, proto);
+ if (sp == NULL)
+ return (EAI_SERVICE);
+ port = sp->s_port;
+ if (socktype == 0) {
+ if (strcmp(sp->s_proto, "tcp") == 0)
+ socktype = SOCK_STREAM;
+ else if (strcmp(sp->s_proto, "udp") == 0)
+ socktype = SOCK_DGRAM;
+ }
+ }
+ } else
+ port = 0;
+
+ /*
+ * Next, deal with just a service name, and no hostname.
+ * (we verified that one of them was non-null up above).
+ */
+ if (hostname == NULL && (flags & AI_PASSIVE) != 0) {
+ if (family == AF_INET || family == 0) {
+ ai = ai_alloc(AF_INET, sizeof(struct sockaddr_in));
+ if (ai == NULL)
+ return (EAI_MEMORY);
+ ai->ai_socktype = socktype;
+ ai->ai_protocol = protocol;
+ SIN(ai->ai_addr)->sin_port = port;
+ ai->ai_next = ai_list;
+ ai_list = ai;
+ }
+
+ if (family == AF_INET6 || family == 0) {
+ ai = ai_alloc(AF_INET6, sizeof(struct sockaddr_in6));
+ if (ai == NULL) {
+ lwres_freeaddrinfo(ai_list);
+ return (EAI_MEMORY);
+ }
+ ai->ai_socktype = socktype;
+ ai->ai_protocol = protocol;
+ SIN6(ai->ai_addr)->sin6_port = port;
+ ai->ai_next = ai_list;
+ ai_list = ai;
+ }
+
+ *res = ai_list;
+ return (0);
+ }
+
+ /*
+ * If the family isn't specified or AI_NUMERICHOST specified,
+ * check first to see if it is a numeric address.
+ * Though the gethostbyname2() routine
+ * will recognize numeric addresses, it will only recognize
+ * the format that it is being called for. Thus, a numeric
+ * AF_INET address will be treated by the AF_INET6 call as
+ * a domain name, and vice versa. Checking for both numerics
+ * here avoids that.
+ */
+ if (hostname != NULL &&
+ (family == 0 || (flags & AI_NUMERICHOST) != 0)) {
+ char abuf[sizeof(struct in6_addr)];
+ char nbuf[NI_MAXHOST];
+ int addrsize, addroff;
+#ifdef LWRES_HAVE_SIN6_SCOPE_ID
+ char *p, *ep;
+ char ntmp[NI_MAXHOST];
+ lwres_uint32_t scopeid;
+#endif
+
+#ifdef LWRES_HAVE_SIN6_SCOPE_ID
+ /*
+ * Scope identifier portion.
+ */
+ ntmp[0] = '\0';
+ if (strchr(hostname, '%') != NULL) {
+ strncpy(ntmp, hostname, sizeof(ntmp) - 1);
+ ntmp[sizeof(ntmp) - 1] = '\0';
+ p = strchr(ntmp, '%');
+ ep = NULL;
+
+ /*
+ * Vendors may want to support non-numeric
+ * scopeid around here.
+ */
+
+ if (p != NULL)
+ scopeid = (lwres_uint32_t)strtoul(p + 1,
+ &ep, 10);
+ if (p != NULL && ep != NULL && ep[0] == '\0')
+ *p = '\0';
+ else {
+ ntmp[0] = '\0';
+ scopeid = 0;
+ }
+ } else
+ scopeid = 0;
+#endif
+
+ if (lwres_net_pton(AF_INET, hostname, (struct in_addr *)abuf)
+ == 1)
+ {
+ if (family == AF_INET6) {
+ /*
+ * Convert to a V4 mapped address.
+ */
+ struct in6_addr *a6 = (struct in6_addr *)abuf;
+ memcpy(&a6->s6_addr[12], &a6->s6_addr[0], 4);
+ memset(&a6->s6_addr[10], 0xff, 2);
+ memset(&a6->s6_addr[0], 0, 10);
+ goto inet6_addr;
+ }
+ addrsize = sizeof(struct in_addr);
+ addroff = (char *)(&SIN(0)->sin_addr) - (char *)0;
+ family = AF_INET;
+ goto common;
+#ifdef LWRES_HAVE_SIN6_SCOPE_ID
+ } else if (ntmp[0] != '\0' &&
+ lwres_net_pton(AF_INET6, ntmp, abuf) == 1)
+ {
+ if (family && family != AF_INET6)
+ return (EAI_NONAME);
+ addrsize = sizeof(struct in6_addr);
+ addroff = (char *)(&SIN6(0)->sin6_addr) - (char *)0;
+ family = AF_INET6;
+ goto common;
+#endif
+ } else if (lwres_net_pton(AF_INET6, hostname, abuf) == 1) {
+ if (family != 0 && family != AF_INET6)
+ return (EAI_NONAME);
+ inet6_addr:
+ addrsize = sizeof(struct in6_addr);
+ addroff = (char *)(&SIN6(0)->sin6_addr) - (char *)0;
+ family = AF_INET6;
+
+ common:
+ ai = ai_clone(ai_list, family);
+ if (ai == NULL)
+ return (EAI_MEMORY);
+ ai_list = ai;
+ ai->ai_socktype = socktype;
+ SIN(ai->ai_addr)->sin_port = port;
+ memcpy((char *)ai->ai_addr + addroff, abuf, addrsize);
+ if (flags & AI_CANONNAME) {
+#if defined(LWRES_HAVE_SIN6_SCOPE_ID)
+ if (ai->ai_family == AF_INET6)
+ SIN6(ai->ai_addr)->sin6_scope_id =
+ scopeid;
+#endif
+ if (lwres_getnameinfo(ai->ai_addr,
+ ai->ai_addrlen, nbuf, sizeof(nbuf),
+ NULL, 0,
+ NI_NUMERICHOST) == 0) {
+ ai->ai_canonname = strdup(nbuf);
+ if (ai->ai_canonname == NULL)
+ return (EAI_MEMORY);
+ } else {
+ /* XXX raise error? */
+ ai->ai_canonname = NULL;
+ }
+ }
+ goto done;
+ } else if ((flags & AI_NUMERICHOST) != 0) {
+ return (EAI_NONAME);
+ }
+ }
+
+ set_order(family, net_order);
+ for (i = 0; i < FOUND_MAX; i++) {
+ if (net_order[i] == NULL)
+ break;
+ err = (net_order[i])(hostname, flags, &ai_list,
+ socktype, port);
+ if (err != 0)
+ return (err);
+ }
+
+ if (ai_list == NULL)
+ return (EAI_NODATA);
+
+done:
+ ai_list = ai_reverse(ai_list);
+
+ *res = ai_list;
+ return (0);
+}
+
+static char *
+lwres_strsep(char **stringp, const char *delim) {
+ char *string = *stringp;
+ char *s;
+ const char *d;
+ char sc, dc;
+
+ if (string == NULL)
+ return (NULL);
+
+ for (s = string; *s != '\0'; s++) {
+ sc = *s;
+ for (d = delim; (dc = *d) != '\0'; d++)
+ if (sc == dc) {
+ *s++ = '\0';
+ *stringp = s;
+ return (string);
+ }
+ }
+ *stringp = NULL;
+ return (string);
+}
+
+static void
+set_order(int family, int (**net_order)(const char *, int, struct addrinfo **,
+ int, int))
+{
+ char *order, *tok;
+ int found;
+
+ if (family) {
+ switch (family) {
+ case AF_INET:
+ *net_order++ = add_ipv4;
+ break;
+ case AF_INET6:
+ *net_order++ = add_ipv6;
+ break;
+ }
+ } else {
+ order = getenv("NET_ORDER");
+ found = 0;
+ while (order != NULL) {
+ /*
+ * We ignore any unknown names.
+ */
+ tok = lwres_strsep(&order, ":");
+ if (strcasecmp(tok, "inet6") == 0) {
+ if ((found & FOUND_IPV6) == 0)
+ *net_order++ = add_ipv6;
+ found |= FOUND_IPV6;
+ } else if (strcasecmp(tok, "inet") == 0 ||
+ strcasecmp(tok, "inet4") == 0) {
+ if ((found & FOUND_IPV4) == 0)
+ *net_order++ = add_ipv4;
+ found |= FOUND_IPV4;
+ }
+ }
+
+ /*
+ * Add in anything that we didn't find.
+ */
+ if ((found & FOUND_IPV4) == 0)
+ *net_order++ = add_ipv4;
+ if ((found & FOUND_IPV6) == 0)
+ *net_order++ = add_ipv6;
+ }
+ *net_order = NULL;
+ return;
+}
+
+static char v4_loop[4] = { 127, 0, 0, 1 };
+
+/*
+ * The test against 0 is there to keep the Solaris compiler
+ * from complaining about "end-of-loop code not reached".
+ */
+#define ERR(code) \
+ do { result = (code); \
+ if (result != 0) goto cleanup; \
+ } while (0)
+
+static int
+add_ipv4(const char *hostname, int flags, struct addrinfo **aip,
+ int socktype, int port)
+{
+ struct addrinfo *ai;
+ lwres_context_t *lwrctx = NULL;
+ lwres_gabnresponse_t *by = NULL;
+ lwres_addr_t *addr;
+ lwres_result_t lwres;
+ int result = 0;
+
+ lwres = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
+ if (lwres != LWRES_R_SUCCESS)
+ ERR(EAI_FAIL);
+ (void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
+ if (hostname == NULL && (flags & AI_PASSIVE) == 0) {
+ ai = ai_clone(*aip, AF_INET);
+ if (ai == NULL) {
+ lwres_freeaddrinfo(*aip);
+ ERR(EAI_MEMORY);
+ }
+
+ *aip = ai;
+ ai->ai_socktype = socktype;
+ SIN(ai->ai_addr)->sin_port = port;
+ memcpy(&SIN(ai->ai_addr)->sin_addr, v4_loop, 4);
+ } else {
+ lwres = lwres_getaddrsbyname(lwrctx, hostname,
+ LWRES_ADDRTYPE_V4, &by);
+ if (lwres != LWRES_R_SUCCESS) {
+ if (lwres == LWRES_R_NOTFOUND)
+ goto cleanup;
+ else
+ ERR(EAI_FAIL);
+ }
+ addr = LWRES_LIST_HEAD(by->addrs);
+ while (addr != NULL) {
+ ai = ai_clone(*aip, AF_INET);
+ if (ai == NULL) {
+ lwres_freeaddrinfo(*aip);
+ ERR(EAI_MEMORY);
+ }
+ *aip = ai;
+ ai->ai_socktype = socktype;
+ SIN(ai->ai_addr)->sin_port = port;
+ memcpy(&SIN(ai->ai_addr)->sin_addr,
+ addr->address, 4);
+ if (flags & AI_CANONNAME) {
+ ai->ai_canonname = strdup(by->realname);
+ if (ai->ai_canonname == NULL)
+ ERR(EAI_MEMORY);
+ }
+ addr = LWRES_LIST_NEXT(addr, link);
+ }
+ }
+ cleanup:
+ if (by != NULL)
+ lwres_gabnresponse_free(lwrctx, &by);
+ if (lwrctx != NULL) {
+ lwres_conf_clear(lwrctx);
+ lwres_context_destroy(&lwrctx);
+ }
+ return (result);
+}
+
+static char v6_loop[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
+
+static int
+add_ipv6(const char *hostname, int flags, struct addrinfo **aip,
+ int socktype, int port)
+{
+ struct addrinfo *ai;
+ lwres_context_t *lwrctx = NULL;
+ lwres_gabnresponse_t *by = NULL;
+ lwres_addr_t *addr;
+ lwres_result_t lwres;
+ int result = 0;
+
+ lwres = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
+ if (lwres != LWRES_R_SUCCESS)
+ ERR(EAI_FAIL);
+ (void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
+
+ if (hostname == NULL && (flags & AI_PASSIVE) == 0) {
+ ai = ai_clone(*aip, AF_INET6);
+ if (ai == NULL) {
+ lwres_freeaddrinfo(*aip);
+ ERR(EAI_MEMORY);
+ }
+
+ *aip = ai;
+ ai->ai_socktype = socktype;
+ SIN6(ai->ai_addr)->sin6_port = port;
+ memcpy(&SIN6(ai->ai_addr)->sin6_addr, v6_loop, 16);
+ } else {
+ lwres = lwres_getaddrsbyname(lwrctx, hostname,
+ LWRES_ADDRTYPE_V6, &by);
+ if (lwres != LWRES_R_SUCCESS) {
+ if (lwres == LWRES_R_NOTFOUND)
+ goto cleanup;
+ else
+ ERR(EAI_FAIL);
+ }
+ addr = LWRES_LIST_HEAD(by->addrs);
+ while (addr != NULL) {
+ ai = ai_clone(*aip, AF_INET6);
+ if (ai == NULL) {
+ lwres_freeaddrinfo(*aip);
+ ERR(EAI_MEMORY);
+ }
+ *aip = ai;
+ ai->ai_socktype = socktype;
+ SIN6(ai->ai_addr)->sin6_port = port;
+ memcpy(&SIN6(ai->ai_addr)->sin6_addr,
+ addr->address, 16);
+ if (flags & AI_CANONNAME) {
+ ai->ai_canonname = strdup(by->realname);
+ if (ai->ai_canonname == NULL)
+ ERR(EAI_MEMORY);
+ }
+ addr = LWRES_LIST_NEXT(addr, link);
+ }
+ }
+ cleanup:
+ if (by != NULL)
+ lwres_gabnresponse_free(lwrctx, &by);
+ if (lwrctx != NULL) {
+ lwres_conf_clear(lwrctx);
+ lwres_context_destroy(&lwrctx);
+ }
+ return (result);
+}
+
+void
+lwres_freeaddrinfo(struct addrinfo *ai) {
+ struct addrinfo *ai_next;
+
+ while (ai != NULL) {
+ ai_next = ai->ai_next;
+ if (ai->ai_addr != NULL)
+ free(ai->ai_addr);
+ if (ai->ai_canonname)
+ free(ai->ai_canonname);
+ free(ai);
+ ai = ai_next;
+ }
+}
+
+#ifdef AF_LOCAL
+static int
+get_local(const char *name, int socktype, struct addrinfo **res) {
+ struct addrinfo *ai;
+ struct sockaddr_un *sun;
+
+ if (socktype == 0)
+ return (EAI_SOCKTYPE);
+
+ ai = ai_alloc(AF_LOCAL, sizeof(*sun));
+ if (ai == NULL)
+ return (EAI_MEMORY);
+
+ sun = SUN(ai->ai_addr);
+ strncpy(sun->sun_path, name, sizeof(sun->sun_path));
+
+ ai->ai_socktype = socktype;
+ /*
+ * ai->ai_flags, ai->ai_protocol, ai->ai_canonname,
+ * and ai->ai_next were initialized to zero.
+ */
+
+ *res = ai;
+ return (0);
+}
+#endif
+
+/*
+ * Allocate an addrinfo structure, and a sockaddr structure
+ * of the specificed length. We initialize:
+ * ai_addrlen
+ * ai_family
+ * ai_addr
+ * ai_addr->sa_family
+ * ai_addr->sa_len (LWRES_PLATFORM_HAVESALEN)
+ * and everything else is initialized to zero.
+ */
+static struct addrinfo *
+ai_alloc(int family, int addrlen) {
+ struct addrinfo *ai;
+
+ ai = (struct addrinfo *)calloc(1, sizeof(*ai));
+ if (ai == NULL)
+ return (NULL);
+
+ ai->ai_addr = SA(calloc(1, addrlen));
+ if (ai->ai_addr == NULL) {
+ free(ai);
+ return (NULL);
+ }
+ ai->ai_addrlen = addrlen;
+ ai->ai_family = family;
+ ai->ai_addr->sa_family = family;
+#ifdef LWRES_PLATFORM_HAVESALEN
+ ai->ai_addr->sa_len = addrlen;
+#endif
+ return (ai);
+}
+
+static struct addrinfo *
+ai_clone(struct addrinfo *oai, int family) {
+ struct addrinfo *ai;
+
+ ai = ai_alloc(family, ((family == AF_INET6) ?
+ sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)));
+
+ if (ai == NULL) {
+ lwres_freeaddrinfo(oai);
+ return (NULL);
+ }
+ if (oai == NULL)
+ return (ai);
+
+ ai->ai_flags = oai->ai_flags;
+ ai->ai_socktype = oai->ai_socktype;
+ ai->ai_protocol = oai->ai_protocol;
+ ai->ai_canonname = NULL;
+ ai->ai_next = oai;
+ return (ai);
+}
+
+static struct addrinfo *
+ai_reverse(struct addrinfo *oai) {
+ struct addrinfo *nai, *tai;
+
+ nai = NULL;
+
+ while (oai != NULL) {
+ /*
+ * Grab one off the old list.
+ */
+ tai = oai;
+ oai = oai->ai_next;
+ /*
+ * Put it on the front of the new list.
+ */
+ tai->ai_next = nai;
+ nai = tai;
+ }
+ return (nai);
+}
diff --git a/lib/liblwres/gethost.c b/lib/liblwres/gethost.c
new file mode 100644
index 000000000..32c8359b4
--- /dev/null
+++ b/lib/liblwres/gethost.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: gethost.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <errno.h>
+#include <string.h>
+
+#include <lwres/net.h>
+#include <lwres/netdb.h>
+
+#include "assert_p.h"
+
+#define LWRES_ALIGNBYTES (sizeof(char *) - 1)
+#define LWRES_ALIGN(p) \
+ (((unsigned long)(p) + LWRES_ALIGNBYTES) &~ LWRES_ALIGNBYTES)
+
+static struct hostent *he = NULL;
+static int copytobuf(struct hostent *, struct hostent *, char *, int);
+
+struct hostent *
+lwres_gethostbyname(const char *name) {
+
+ if (he != NULL)
+ lwres_freehostent(he);
+
+ he = lwres_getipnodebyname(name, AF_INET, 0, &lwres_h_errno);
+ return (he);
+}
+
+struct hostent *
+lwres_gethostbyname2(const char *name, int af) {
+ if (he != NULL)
+ lwres_freehostent(he);
+
+ he = lwres_getipnodebyname(name, af, 0, &lwres_h_errno);
+ return (he);
+}
+
+struct hostent *
+lwres_gethostbyaddr(const char *addr, int len, int type) {
+
+ if (he != NULL)
+ lwres_freehostent(he);
+
+ he = lwres_getipnodebyaddr(addr, len, type, &lwres_h_errno);
+ return (he);
+}
+
+struct hostent *
+lwres_gethostent(void) {
+ if (he != NULL)
+ lwres_freehostent(he);
+
+ return (NULL);
+}
+
+void
+lwres_sethostent(int stayopen) {
+ /*
+ * Empty.
+ */
+ UNUSED(stayopen);
+}
+
+void
+lwres_endhostent(void) {
+ /*
+ * Empty.
+ */
+}
+
+struct hostent *
+lwres_gethostbyname_r(const char *name, struct hostent *resbuf,
+ char *buf, int buflen, int *error)
+{
+ struct hostent *he;
+ int res;
+
+ he = lwres_getipnodebyname(name, AF_INET, 0, error);
+ if (he == NULL)
+ return (NULL);
+ res = copytobuf(he, resbuf, buf, buflen);
+ lwres_freehostent(he);
+ if (res != 0) {
+ errno = ERANGE;
+ return (NULL);
+ }
+ return (resbuf);
+}
+
+struct hostent *
+lwres_gethostbyaddr_r(const char *addr, int len, int type,
+ struct hostent *resbuf, char *buf, int buflen,
+ int *error)
+{
+ struct hostent *he;
+ int res;
+
+ he = lwres_getipnodebyaddr(addr, len, type, error);
+ if (he == NULL)
+ return (NULL);
+ res = copytobuf(he, resbuf, buf, buflen);
+ lwres_freehostent(he);
+ if (res != 0) {
+ errno = ERANGE;
+ return (NULL);
+ }
+ return (resbuf);
+}
+
+struct hostent *
+lwres_gethostent_r(struct hostent *resbuf, char *buf, int buflen, int *error) {
+ UNUSED(resbuf);
+ UNUSED(buf);
+ UNUSED(buflen);
+ *error = 0;
+ return (NULL);
+}
+
+void
+lwres_sethostent_r(int stayopen) {
+ /*
+ * Empty.
+ */
+ UNUSED(stayopen);
+}
+
+void
+lwres_endhostent_r(void) {
+ /*
+ * Empty.
+ */
+}
+
+static int
+copytobuf(struct hostent *he, struct hostent *hptr, char *buf, int buflen) {
+ char *cp;
+ char **ptr;
+ int i, n;
+ int nptr, len;
+
+ /*
+ * Find out the amount of space required to store the answer.
+ */
+ nptr = 2; /* NULL ptrs */
+ len = (char *)LWRES_ALIGN(buf) - buf;
+ for (i = 0; he->h_addr_list[i]; i++, nptr++) {
+ len += he->h_length;
+ }
+ for (i = 0; he->h_aliases[i]; i++, nptr++) {
+ len += strlen(he->h_aliases[i]) + 1;
+ }
+ len += strlen(he->h_name) + 1;
+ len += nptr * sizeof(char*);
+
+ if (len > buflen) {
+ return (-1);
+ }
+
+ /*
+ * Copy address size and type.
+ */
+ hptr->h_addrtype = he->h_addrtype;
+ n = hptr->h_length = he->h_length;
+
+ ptr = (char **)LWRES_ALIGN(buf);
+ cp = (char *)LWRES_ALIGN(buf) + nptr * sizeof(char *);
+
+ /*
+ * Copy address list.
+ */
+ hptr->h_addr_list = ptr;
+ for (i = 0; he->h_addr_list[i]; i++, ptr++) {
+ memcpy(cp, he->h_addr_list[i], n);
+ hptr->h_addr_list[i] = cp;
+ cp += n;
+ }
+ hptr->h_addr_list[i] = NULL;
+ ptr++;
+
+ /*
+ * Copy official name.
+ */
+ n = strlen(he->h_name) + 1;
+ strcpy(cp, he->h_name);
+ hptr->h_name = cp;
+ cp += n;
+
+ /*
+ * Copy aliases.
+ */
+ hptr->h_aliases = ptr;
+ for (i = 0; he->h_aliases[i]; i++) {
+ n = strlen(he->h_aliases[i]) + 1;
+ strcpy(cp, he->h_aliases[i]);
+ hptr->h_aliases[i] = cp;
+ cp += n;
+ }
+ hptr->h_aliases[i] = NULL;
+
+ return (0);
+}
diff --git a/lib/liblwres/getipnode.c b/lib/liblwres/getipnode.c
new file mode 100644
index 000000000..94882cbe4
--- /dev/null
+++ b/lib/liblwres/getipnode.c
@@ -0,0 +1,839 @@
+/*
+ * Copyright (C) 1999-2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: getipnode.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <lwres/lwres.h>
+#include <lwres/net.h>
+#include <lwres/netdb.h> /* XXX #include <netdb.h> */
+
+#include "assert_p.h"
+
+#ifndef INADDRSZ
+#define INADDRSZ 4
+#endif
+#ifndef IN6ADDRSZ
+#define IN6ADDRSZ 16
+#endif
+
+#ifdef LWRES_PLATFORM_NEEDIN6ADDRANY
+LIBLWRES_EXTERNAL_DATA const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
+#endif
+
+#ifndef IN6_IS_ADDR_V4COMPAT
+static const unsigned char in6addr_compat[12] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+#define IN6_IS_ADDR_V4COMPAT(x) (!memcmp((x)->s6_addr, in6addr_compat, 12) && \
+ ((x)->s6_addr[12] != 0 || \
+ (x)->s6_addr[13] != 0 || \
+ (x)->s6_addr[14] != 0 || \
+ ((x)->s6_addr[15] != 0 && \
+ (x)->s6_addr[15] != 1)))
+#endif
+#ifndef IN6_IS_ADDR_V4MAPPED
+#define IN6_IS_ADDR_V4MAPPED(x) (!memcmp((x)->s6_addr, in6addr_mapped, 12))
+#endif
+
+static const unsigned char in6addr_mapped[12] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff
+};
+
+/***
+ *** Forward declarations.
+ ***/
+
+static int
+scan_interfaces(int *, int *);
+
+static struct hostent *
+copyandmerge(struct hostent *, struct hostent *, int, int *);
+
+static struct hostent *
+hostfromaddr(lwres_gnbaresponse_t *addr, int af, const void *src);
+
+static struct hostent *
+hostfromname(lwres_gabnresponse_t *name, int af);
+
+/***
+ *** Public functions.
+ ***/
+
+/*
+ * AI_V4MAPPED + AF_INET6
+ * If no IPv6 address then a query for IPv4 and map returned values.
+ *
+ * AI_ALL + AI_V4MAPPED + AF_INET6
+ * Return IPv6 and IPv4 mapped.
+ *
+ * AI_ADDRCONFIG
+ * Only return IPv6 / IPv4 address if there is an interface of that
+ * type active.
+ */
+
+struct hostent *
+lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) {
+ int have_v4 = 1, have_v6 = 1;
+ struct in_addr in4;
+ struct in6_addr in6;
+ struct hostent he, *he1 = NULL, *he2 = NULL, *he3 = NULL;
+ int v4 = 0, v6 = 0;
+ int tmp_err;
+ lwres_context_t *lwrctx = NULL;
+ lwres_gabnresponse_t *by = NULL;
+ int n;
+
+ /*
+ * If we care about active interfaces then check.
+ */
+ if ((flags & AI_ADDRCONFIG) != 0)
+ if (scan_interfaces(&have_v4, &have_v6) == -1) {
+ *error_num = NO_RECOVERY;
+ return (NULL);
+ }
+
+ /* Check for literal address. */
+ if ((v4 = lwres_net_pton(AF_INET, name, &in4)) != 1)
+ v6 = lwres_net_pton(AF_INET6, name, &in6);
+
+ /*
+ * Impossible combination?
+ */
+ if ((af == AF_INET6 && (flags & AI_V4MAPPED) == 0 && v4 == 1) ||
+ (af == AF_INET && v6 == 1) ||
+ (have_v4 == 0 && v4 == 1) ||
+ (have_v6 == 0 && v6 == 1) ||
+ (have_v4 == 0 && af == AF_INET) ||
+ (have_v6 == 0 && af == AF_INET6 &&
+ (((flags & AI_V4MAPPED) != 0 && have_v4) ||
+ (flags & AI_V4MAPPED) == 0))) {
+ *error_num = HOST_NOT_FOUND;
+ return (NULL);
+ }
+
+ /*
+ * Literal address?
+ */
+ if (v4 == 1 || v6 == 1) {
+ char *addr_list[2];
+ char *aliases[1];
+ union {
+ const char *const_name;
+ char *deconst_name;
+ } u;
+
+ u.const_name = name;
+ he.h_name = u.deconst_name;
+ he.h_addr_list = addr_list;
+ he.h_addr_list[0] = (v4 == 1) ? (char *)&in4 : (char *)&in6;
+ he.h_addr_list[1] = NULL;
+ he.h_aliases = aliases;
+ he.h_aliases[0] = NULL;
+ he.h_length = (v4 == 1) ? INADDRSZ : IN6ADDRSZ;
+ he.h_addrtype = (v4 == 1) ? AF_INET : AF_INET6;
+ return (copyandmerge(&he, NULL, af, error_num));
+ }
+
+ n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
+ if (n != 0) {
+ *error_num = NO_RECOVERY;
+ goto cleanup;
+ }
+ (void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
+ tmp_err = NO_RECOVERY;
+ if (have_v6 && af == AF_INET6) {
+
+ n = lwres_getaddrsbyname(lwrctx, name, LWRES_ADDRTYPE_V6, &by);
+ if (n == 0) {
+ he1 = hostfromname(by, AF_INET6);
+ lwres_gabnresponse_free(lwrctx, &by);
+ if (he1 == NULL) {
+ *error_num = NO_RECOVERY;
+ goto cleanup;
+ }
+ } else {
+ tmp_err = HOST_NOT_FOUND;
+ }
+ }
+
+ if (have_v4 &&
+ ((af == AF_INET) ||
+ (af == AF_INET6 && (flags & AI_V4MAPPED) != 0 &&
+ (he1 == NULL || (flags & AI_ALL) != 0)))) {
+ n = lwres_getaddrsbyname(lwrctx, name, LWRES_ADDRTYPE_V4, &by);
+ if (n == 0) {
+ he2 = hostfromname(by, AF_INET);
+ lwres_gabnresponse_free(lwrctx, &by);
+ if (he2 == NULL) {
+ *error_num = NO_RECOVERY;
+ goto cleanup;
+ }
+ } else if (he1 == NULL) {
+ if (n == LWRES_R_NOTFOUND)
+ *error_num = HOST_NOT_FOUND;
+ else
+ *error_num = NO_RECOVERY;
+ goto cleanup;
+ }
+ } else
+ *error_num = tmp_err;
+
+ he3 = copyandmerge(he1, he2, af, error_num);
+
+ cleanup:
+ if (he1 != NULL)
+ lwres_freehostent(he1);
+ if (he2 != NULL)
+ lwres_freehostent(he2);
+ if (lwrctx != NULL) {
+ lwres_conf_clear(lwrctx);
+ lwres_context_destroy(&lwrctx);
+ }
+ return (he3);
+}
+
+struct hostent *
+lwres_getipnodebyaddr(const void *src, size_t len, int af, int *error_num) {
+ struct hostent *he1, *he2;
+ lwres_context_t *lwrctx = NULL;
+ lwres_gnbaresponse_t *by = NULL;
+ lwres_result_t n;
+ union {
+ const void *konst;
+ struct in6_addr *in6;
+ } u;
+
+ /*
+ * Sanity checks.
+ */
+ if (src == NULL) {
+ *error_num = NO_RECOVERY;
+ return (NULL);
+ }
+
+ switch (af) {
+ case AF_INET:
+ if (len != INADDRSZ) {
+ *error_num = NO_RECOVERY;
+ return (NULL);
+ }
+ break;
+ case AF_INET6:
+ if (len != IN6ADDRSZ) {
+ *error_num = NO_RECOVERY;
+ return (NULL);
+ }
+ break;
+ default:
+ *error_num = NO_RECOVERY;
+ return (NULL);
+ }
+
+ /*
+ * The de-"const"-ing game is done because at least one
+ * vendor's system (RedHat 6.0) defines the IN6_IS_ADDR_*
+ * macros in such a way that they discard the const with
+ * internal casting, and gcc ends up complaining. Rather
+ * than replacing their own (possibly optimized) definitions
+ * with our own, cleanly discarding the const is the easiest
+ * thing to do.
+ */
+ u.konst = src;
+
+ /*
+ * Look up IPv4 and IPv4 mapped/compatible addresses.
+ */
+ if ((af == AF_INET6 && IN6_IS_ADDR_V4COMPAT(u.in6)) ||
+ (af == AF_INET6 && IN6_IS_ADDR_V4MAPPED(u.in6)) ||
+ (af == AF_INET)) {
+ const unsigned char *cp = src;
+
+ if (af == AF_INET6)
+ cp += 12;
+ n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
+ if (n == LWRES_R_SUCCESS)
+ (void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
+ if (n == LWRES_R_SUCCESS)
+ n = lwres_getnamebyaddr(lwrctx, LWRES_ADDRTYPE_V4,
+ INADDRSZ, cp, &by);
+ if (n != LWRES_R_SUCCESS) {
+ lwres_conf_clear(lwrctx);
+ lwres_context_destroy(&lwrctx);
+ if (n == LWRES_R_NOTFOUND)
+ *error_num = HOST_NOT_FOUND;
+ else
+ *error_num = NO_RECOVERY;
+ return (NULL);
+ }
+ he1 = hostfromaddr(by, AF_INET, cp);
+ lwres_gnbaresponse_free(lwrctx, &by);
+ lwres_conf_clear(lwrctx);
+ lwres_context_destroy(&lwrctx);
+ if (af != AF_INET6)
+ return (he1);
+
+ /*
+ * Convert from AF_INET to AF_INET6.
+ */
+ he2 = copyandmerge(he1, NULL, af, error_num);
+ lwres_freehostent(he1);
+ if (he2 == NULL)
+ return (NULL);
+ /*
+ * Restore original address.
+ */
+ memcpy(he2->h_addr, src, len);
+ return (he2);
+ }
+
+ /*
+ * Lookup IPv6 address.
+ */
+ if (memcmp(src, &in6addr_any, IN6ADDRSZ) == 0) {
+ *error_num = HOST_NOT_FOUND;
+ return (NULL);
+ }
+
+ n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
+ if (n == LWRES_R_SUCCESS)
+ (void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
+ if (n == LWRES_R_SUCCESS)
+ n = lwres_getnamebyaddr(lwrctx, LWRES_ADDRTYPE_V6, IN6ADDRSZ,
+ src, &by);
+ if (n != 0) {
+ *error_num = HOST_NOT_FOUND;
+ return (NULL);
+ }
+ he1 = hostfromaddr(by, AF_INET6, src);
+ lwres_gnbaresponse_free(lwrctx, &by);
+ if (he1 == NULL)
+ *error_num = NO_RECOVERY;
+ lwres_context_destroy(&lwrctx);
+ return (he1);
+}
+
+void
+lwres_freehostent(struct hostent *he) {
+ char **cpp;
+ int names = 1;
+ int addresses = 1;
+
+ free(he->h_name);
+
+ cpp = he->h_addr_list;
+ while (*cpp != NULL) {
+ free(*cpp);
+ *cpp = NULL;
+ cpp++;
+ addresses++;
+ }
+
+ cpp = he->h_aliases;
+ while (*cpp != NULL) {
+ free(*cpp);
+ cpp++;
+ names++;
+ }
+
+ free(he->h_aliases);
+ free(he->h_addr_list);
+ free(he);
+}
+
+/*
+ * Private
+ */
+
+/*
+ * Scan the interface table and set have_v4 and have_v6 depending
+ * upon whether there are IPv4 and IPv6 interface addresses.
+ *
+ * Returns:
+ * 0 on success
+ * -1 on failure.
+ */
+
+static int
+scan_interfaces(int *have_v4, int *have_v6) {
+#if 1
+ *have_v4 = *have_v6 = 1;
+ return (0);
+#else
+ struct ifconf ifc;
+ struct ifreq ifreq;
+ struct in_addr in4;
+ struct in6_addr in6;
+ char *buf = NULL, *cp, *cplim;
+ static int bufsiz = 4095;
+ int s, cpsize, n;
+
+ /*
+ * Set to zero. Used as loop terminators below.
+ */
+ *have_v4 = *have_v6 = 0;
+
+ /*
+ * Get interface list from system.
+ */
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+ goto err_ret;
+
+ /*
+ * Grow buffer until large enough to contain all interface
+ * descriptions.
+ */
+ for (;;) {
+ buf = malloc(bufsiz);
+ if (buf == NULL)
+ goto err_ret;
+ ifc.ifc_len = bufsiz;
+ ifc.ifc_buf = buf;
+#ifdef IRIX_EMUL_IOCTL_SIOCGIFCONF
+ /*
+ * This is a fix for IRIX OS in which the call to ioctl with
+ * the flag SIOCGIFCONF may not return an entry for all the
+ * interfaces like most flavors of Unix.
+ */
+ if (emul_ioctl(&ifc) >= 0)
+ break;
+#else
+ if ((n = ioctl(s, SIOCGIFCONF, (char *)&ifc)) != -1) {
+ /*
+ * Some OS's just return what will fit rather
+ * than set EINVAL if the buffer is too small
+ * to fit all the interfaces in. If
+ * ifc.ifc_len is too near to the end of the
+ * buffer we will grow it just in case and
+ * retry.
+ */
+ if (ifc.ifc_len + 2 * sizeof(ifreq) < bufsiz)
+ break;
+ }
+#endif
+ if ((n == -1) && errno != EINVAL)
+ goto err_ret;
+
+ if (bufsiz > 1000000)
+ goto err_ret;
+
+ free(buf);
+ bufsiz += 4096;
+ }
+
+ /*
+ * Parse system's interface list.
+ */
+ cplim = buf + ifc.ifc_len; /* skip over if's with big ifr_addr's */
+ for (cp = buf;
+ (*have_v4 == 0 || *have_v6 == 0) && cp < cplim;
+ cp += cpsize) {
+ memcpy(&ifreq, cp, sizeof ifreq);
+#ifdef LWRES_PLATFORM_HAVESALEN
+#ifdef FIX_ZERO_SA_LEN
+ if (ifreq.ifr_addr.sa_len == 0)
+ ifreq.ifr_addr.sa_len = IN6ADDRSZ;
+#endif
+#ifdef HAVE_MINIMUM_IFREQ
+ cpsize = sizeof ifreq;
+ if (ifreq.ifr_addr.sa_len > sizeof (struct sockaddr))
+ cpsize += (int)ifreq.ifr_addr.sa_len -
+ (int)(sizeof(struct sockaddr));
+#else
+ cpsize = sizeof ifreq.ifr_name + ifreq.ifr_addr.sa_len;
+#endif /* HAVE_MINIMUM_IFREQ */
+#elif defined SIOCGIFCONF_ADDR
+ cpsize = sizeof ifreq;
+#else
+ cpsize = sizeof ifreq.ifr_name;
+ /* XXX maybe this should be a hard error? */
+ if (ioctl(s, SIOCGIFADDR, (char *)&ifreq) < 0)
+ continue;
+#endif /* LWRES_PLATFORM_HAVESALEN */
+ switch (ifreq.ifr_addr.sa_family) {
+ case AF_INET:
+ if (*have_v4 == 0) {
+ memcpy(&in4,
+ &((struct sockaddr_in *)
+ &ifreq.ifr_addr)->sin_addr,
+ sizeof(in4));
+ if (in4.s_addr == INADDR_ANY)
+ break;
+ n = ioctl(s, SIOCGIFFLAGS, (char *)&ifreq);
+ if (n < 0)
+ break;
+ if ((ifreq.ifr_flags & IFF_UP) == 0)
+ break;
+ *have_v4 = 1;
+ }
+ break;
+ case AF_INET6:
+ if (*have_v6 == 0) {
+ memcpy(&in6,
+ &((struct sockaddr_in6 *)
+ &ifreq.ifr_addr)->sin6_addr,
+ sizeof(in6));
+ if (memcmp(&in6, &in6addr_any,
+ sizeof(in6)) == 0)
+ break;
+ n = ioctl(s, SIOCGIFFLAGS, (char *)&ifreq);
+ if (n < 0)
+ break;
+ if ((ifreq.ifr_flags & IFF_UP) == 0)
+ break;
+ *have_v6 = 1;
+ }
+ break;
+ }
+ }
+ if (buf != NULL)
+ free(buf);
+ close(s);
+ return (0);
+ err_ret:
+ if (buf != NULL)
+ free(buf);
+ if (s != -1)
+ close(s);
+ return (-1);
+#endif
+}
+
+static struct hostent *
+copyandmerge(struct hostent *he1, struct hostent *he2, int af, int *error_num)
+{
+ struct hostent *he = NULL;
+ int addresses = 1; /* NULL terminator */
+ int names = 1; /* NULL terminator */
+ int len = 0;
+ char **cpp, **npp;
+
+ /*
+ * Work out array sizes.
+ */
+ if (he1 != NULL) {
+ cpp = he1->h_addr_list;
+ while (*cpp != NULL) {
+ addresses++;
+ cpp++;
+ }
+ cpp = he1->h_aliases;
+ while (*cpp != NULL) {
+ names++;
+ cpp++;
+ }
+ }
+
+ if (he2 != NULL) {
+ cpp = he2->h_addr_list;
+ while (*cpp != NULL) {
+ addresses++;
+ cpp++;
+ }
+ if (he1 == NULL) {
+ cpp = he2->h_aliases;
+ while (*cpp != NULL) {
+ names++;
+ cpp++;
+ }
+ }
+ }
+
+ if (addresses == 1) {
+ *error_num = NO_ADDRESS;
+ return (NULL);
+ }
+
+ he = malloc(sizeof *he);
+ if (he == NULL)
+ goto no_recovery;
+
+ he->h_addr_list = malloc(sizeof(char *) * (addresses));
+ if (he->h_addr_list == NULL)
+ goto cleanup0;
+ memset(he->h_addr_list, 0, sizeof(char *) * (addresses));
+
+ /*
+ * Copy addresses.
+ */
+ npp = he->h_addr_list;
+ if (he1 != NULL) {
+ cpp = he1->h_addr_list;
+ while (*cpp != NULL) {
+ *npp = malloc((af == AF_INET) ? INADDRSZ : IN6ADDRSZ);
+ if (*npp == NULL)
+ goto cleanup1;
+ /*
+ * Convert to mapped if required.
+ */
+ if (af == AF_INET6 && he1->h_addrtype == AF_INET) {
+ memcpy(*npp, in6addr_mapped,
+ sizeof in6addr_mapped);
+ memcpy(*npp + sizeof in6addr_mapped, *cpp,
+ INADDRSZ);
+ } else {
+ memcpy(*npp, *cpp,
+ (af == AF_INET) ? INADDRSZ : IN6ADDRSZ);
+ }
+ cpp++;
+ npp++;
+ }
+ }
+
+ if (he2 != NULL) {
+ cpp = he2->h_addr_list;
+ while (*cpp != NULL) {
+ *npp = malloc((af == AF_INET) ? INADDRSZ : IN6ADDRSZ);
+ if (*npp == NULL)
+ goto cleanup1;
+ /*
+ * Convert to mapped if required.
+ */
+ if (af == AF_INET6 && he2->h_addrtype == AF_INET) {
+ memcpy(*npp, in6addr_mapped,
+ sizeof in6addr_mapped);
+ memcpy(*npp + sizeof in6addr_mapped, *cpp,
+ INADDRSZ);
+ } else {
+ memcpy(*npp, *cpp,
+ (af == AF_INET) ? INADDRSZ : IN6ADDRSZ);
+ }
+ cpp++;
+ npp++;
+ }
+ }
+
+ he->h_aliases = malloc(sizeof(char *) * (names));
+ if (he->h_aliases == NULL)
+ goto cleanup1;
+ memset(he->h_aliases, 0, sizeof(char *) * (names));
+
+ /*
+ * Copy aliases.
+ */
+ npp = he->h_aliases;
+ cpp = (he1 != NULL) ? he1->h_aliases : he2->h_aliases;
+ while (*cpp != NULL) {
+ len = strlen (*cpp) + 1;
+ *npp = malloc(len);
+ if (*npp == NULL)
+ goto cleanup2;
+ strcpy(*npp, *cpp);
+ npp++;
+ cpp++;
+ }
+
+ /*
+ * Copy hostname.
+ */
+ he->h_name = malloc(strlen((he1 != NULL) ?
+ he1->h_name : he2->h_name) + 1);
+ if (he->h_name == NULL)
+ goto cleanup2;
+ strcpy(he->h_name, (he1 != NULL) ? he1->h_name : he2->h_name);
+
+ /*
+ * Set address type and length.
+ */
+ he->h_addrtype = af;
+ he->h_length = (af == AF_INET) ? INADDRSZ : IN6ADDRSZ;
+ return (he);
+
+ cleanup2:
+ cpp = he->h_aliases;
+ while (*cpp != NULL) {
+ free(*cpp);
+ cpp++;
+ }
+ free(he->h_aliases);
+
+ cleanup1:
+ cpp = he->h_addr_list;
+ while (*cpp != NULL) {
+ free(*cpp);
+ *cpp = NULL;
+ cpp++;
+ }
+ free(he->h_addr_list);
+
+ cleanup0:
+ free(he);
+
+ no_recovery:
+ *error_num = NO_RECOVERY;
+ return (NULL);
+}
+
+static struct hostent *
+hostfromaddr(lwres_gnbaresponse_t *addr, int af, const void *src) {
+ struct hostent *he;
+ int i;
+
+ he = malloc(sizeof *he);
+ if (he == NULL)
+ goto cleanup;
+ memset(he, 0, sizeof(*he));
+
+ /*
+ * Set family and length.
+ */
+ he->h_addrtype = af;
+ switch (af) {
+ case AF_INET:
+ he->h_length = INADDRSZ;
+ break;
+ case AF_INET6:
+ he->h_length = IN6ADDRSZ;
+ break;
+ default:
+ INSIST(0);
+ }
+
+ /*
+ * Copy name.
+ */
+ he->h_name = strdup(addr->realname);
+ if (he->h_name == NULL)
+ goto cleanup;
+
+ /*
+ * Copy aliases.
+ */
+ he->h_aliases = malloc(sizeof(char *) * (addr->naliases + 1));
+ if (he->h_aliases == NULL)
+ goto cleanup;
+ for (i = 0 ; i < addr->naliases; i++) {
+ he->h_aliases[i] = strdup(addr->aliases[i]);
+ if (he->h_aliases[i] == NULL)
+ goto cleanup;
+ }
+ he->h_aliases[i] = NULL;
+
+ /*
+ * Copy address.
+ */
+ he->h_addr_list = malloc(sizeof(char *) * 2);
+ if (he->h_addr_list == NULL)
+ goto cleanup;
+ he->h_addr_list[0] = malloc(he->h_length);
+ if (he->h_addr_list[0] == NULL)
+ goto cleanup;
+ memcpy(he->h_addr_list[0], src, he->h_length);
+ he->h_addr_list[1] = NULL;
+ return (he);
+
+ cleanup:
+ if (he != NULL && he->h_addr_list != NULL) {
+ for (i = 0; he->h_addr_list[i] != NULL; i++)
+ free(he->h_addr_list[i]);
+ free(he->h_addr_list);
+ }
+ if (he != NULL && he->h_aliases != NULL) {
+ for (i = 0; he->h_aliases[i] != NULL; i++)
+ free(he->h_aliases[i]);
+ free(he->h_aliases);
+ }
+ if (he != NULL && he->h_name != NULL)
+ free(he->h_name);
+ if (he != NULL)
+ free(he);
+ return (NULL);
+}
+
+static struct hostent *
+hostfromname(lwres_gabnresponse_t *name, int af) {
+ struct hostent *he;
+ int i;
+ lwres_addr_t *addr;
+
+ he = malloc(sizeof *he);
+ if (he == NULL)
+ goto cleanup;
+ memset(he, 0, sizeof(*he));
+
+ /*
+ * Set family and length.
+ */
+ he->h_addrtype = af;
+ switch (af) {
+ case AF_INET:
+ he->h_length = INADDRSZ;
+ break;
+ case AF_INET6:
+ he->h_length = IN6ADDRSZ;
+ break;
+ default:
+ INSIST(0);
+ }
+
+ /*
+ * Copy name.
+ */
+ he->h_name = strdup(name->realname);
+ if (he->h_name == NULL)
+ goto cleanup;
+
+ /*
+ * Copy aliases.
+ */
+ he->h_aliases = malloc(sizeof(char *) * (name->naliases + 1));
+ for (i = 0 ; i < name->naliases; i++) {
+ he->h_aliases[i] = strdup(name->aliases[i]);
+ if (he->h_aliases[i] == NULL)
+ goto cleanup;
+ }
+ he->h_aliases[i] = NULL;
+
+ /*
+ * Copy addresses.
+ */
+ he->h_addr_list = malloc(sizeof(char *) * (name->naddrs + 1));
+ addr = LWRES_LIST_HEAD(name->addrs);
+ i = 0;
+ while (addr != NULL) {
+ he->h_addr_list[i] = malloc(he->h_length);
+ if (he->h_addr_list[i] == NULL)
+ goto cleanup;
+ memcpy(he->h_addr_list[i], addr->address, he->h_length);
+ addr = LWRES_LIST_NEXT(addr, link);
+ i++;
+ }
+ he->h_addr_list[i] = NULL;
+ return (he);
+
+ cleanup:
+ if (he != NULL && he->h_addr_list != NULL) {
+ for (i = 0; he->h_addr_list[i] != NULL; i++)
+ free(he->h_addr_list[i]);
+ free(he->h_addr_list);
+ }
+ if (he != NULL && he->h_aliases != NULL) {
+ for (i = 0; he->h_aliases[i] != NULL; i++)
+ free(he->h_aliases[i]);
+ free(he->h_aliases);
+ }
+ if (he != NULL && he->h_name != NULL)
+ free(he->h_name);
+ if (he != NULL)
+ free(he);
+ return (NULL);
+}
diff --git a/lib/liblwres/getnameinfo.c b/lib/liblwres/getnameinfo.c
new file mode 100644
index 000000000..36eea3180
--- /dev/null
+++ b/lib/liblwres/getnameinfo.c
@@ -0,0 +1,289 @@
+/*
+ * Portions Copyright (C) 1999-2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: getnameinfo.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by WIDE Project and
+ * its contributors.
+ * 4. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * XXX
+ * Issues to be discussed:
+ * - Return values. There seems to be no standard for return value (RFC2553)
+ * but INRIA implementation returns EAI_xxx defined for getaddrinfo().
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include <lwres/lwres.h>
+#include <lwres/net.h>
+#include <lwres/netdb.h>
+
+#include "assert_p.h"
+
+#define SUCCESS 0
+
+static struct afd {
+ int a_af;
+ size_t a_addrlen;
+ size_t a_socklen;
+} afdl [] = {
+ /*
+ * First entry is linked last...
+ */
+ { AF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in) },
+ { AF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6) },
+ {0, 0, 0},
+};
+
+#define ENI_NOSERVNAME 1
+#define ENI_NOHOSTNAME 2
+#define ENI_MEMORY 3
+#define ENI_SYSTEM 4
+#define ENI_FAMILY 5
+#define ENI_SALEN 6
+#define ENI_NOSOCKET 7
+
+/*
+ * The test against 0 is there to keep the Solaris compiler
+ * from complaining about "end-of-loop code not reached".
+ */
+#define ERR(code) \
+ do { result = (code); \
+ if (result != 0) goto cleanup; \
+ } while (0)
+
+int
+lwres_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
+ size_t hostlen, char *serv, size_t servlen, int flags)
+{
+ struct afd *afd;
+ struct servent *sp;
+ unsigned short port;
+#ifdef LWRES_PLATFORM_HAVESALEN
+ size_t len;
+#endif
+ int family, i;
+ const void *addr;
+ char *p;
+#if 0
+ unsigned long v4a;
+ unsigned char pfx;
+#endif
+ char numserv[sizeof("65000")];
+ char numaddr[sizeof("abcd:abcd:abcd:abcd:abcd:abcd:255.255.255.255")
+ + 1 + sizeof("4294967295")];
+ const char *proto;
+ lwres_uint32_t lwf = 0;
+ lwres_context_t *lwrctx = NULL;
+ lwres_gnbaresponse_t *by = NULL;
+ int result = SUCCESS;
+ int n;
+
+ if (sa == NULL)
+ ERR(ENI_NOSOCKET);
+
+#ifdef LWRES_PLATFORM_HAVESALEN
+ len = sa->sa_len;
+ if (len != salen)
+ ERR(ENI_SALEN);
+#endif
+
+ family = sa->sa_family;
+ for (i = 0; afdl[i].a_af; i++)
+ if (afdl[i].a_af == family) {
+ afd = &afdl[i];
+ goto found;
+ }
+ ERR(ENI_FAMILY);
+
+ found:
+ if (salen != afd->a_socklen)
+ ERR(ENI_SALEN);
+
+ switch (family) {
+ case AF_INET:
+ port = ((const struct sockaddr_in *)sa)->sin_port;
+ addr = &((const struct sockaddr_in *)sa)->sin_addr.s_addr;
+ break;
+
+ case AF_INET6:
+ port = ((const struct sockaddr_in6 *)sa)->sin6_port;
+ addr = ((const struct sockaddr_in6 *)sa)->sin6_addr.s6_addr;
+ break;
+
+ default:
+ port = 0;
+ addr = NULL;
+ INSIST(0);
+ }
+ proto = (flags & NI_DGRAM) ? "udp" : "tcp";
+
+ if (serv == NULL || servlen == 0) {
+ /*
+ * Caller does not want service.
+ */
+ } else if ((flags & NI_NUMERICSERV) != 0 ||
+ (sp = getservbyport(port, proto)) == NULL) {
+ sprintf(numserv, "%d", ntohs(port));
+ if ((strlen(numserv) + 1) > servlen)
+ ERR(ENI_MEMORY);
+ strcpy(serv, numserv);
+ } else {
+ if ((strlen(sp->s_name) + 1) > servlen)
+ ERR(ENI_MEMORY);
+ strcpy(serv, sp->s_name);
+ }
+
+#if 0
+ switch (sa->sa_family) {
+ case AF_INET:
+ v4a = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
+ if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
+ flags |= NI_NUMERICHOST;
+ v4a >>= IN_CLASSA_NSHIFT;
+ if (v4a == 0 || v4a == IN_LOOPBACKNET)
+ flags |= NI_NUMERICHOST;
+ break;
+
+ case AF_INET6:
+ pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[0];
+ if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
+ flags |= NI_NUMERICHOST;
+ break;
+ }
+#endif
+
+ if (host == NULL || hostlen == 0) {
+ /*
+ * What should we do?
+ */
+ } else if (flags & NI_NUMERICHOST) {
+ if (lwres_net_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
+ == NULL)
+ ERR(ENI_SYSTEM);
+#if defined(LWRES_HAVE_SIN6_SCOPE_ID)
+ if (afd->a_af == AF_INET6 &&
+ ((const struct sockaddr_in6 *)sa)->sin6_scope_id) {
+ char *p = numaddr + strlen(numaddr);
+ const char *stringscope = NULL;
+#if 0
+ if ((flags & NI_NUMERICSCOPE) == 0) {
+ /*
+ * Vendors may want to add support for
+ * non-numeric scope identifier.
+ */
+ stringscope = foo;
+ }
+#endif
+ if (stringscope == NULL) {
+ snprintf(p, sizeof(numaddr) - (p - numaddr),
+ "%%%u",
+ ((const struct sockaddr_in6 *)sa)->sin6_scope_id);
+ } else {
+ snprintf(p, sizeof(numaddr) - (p - numaddr),
+ "%%%s", stringscope);
+ }
+ }
+#endif
+ if (strlen(numaddr) + 1 > hostlen)
+ ERR(ENI_MEMORY);
+ strcpy(host, numaddr);
+ } else {
+ switch (family) {
+ case AF_INET:
+ lwf = LWRES_ADDRTYPE_V4;
+ break;
+ case AF_INET6:
+ lwf = LWRES_ADDRTYPE_V6;
+ break;
+ default:
+ INSIST(0);
+ }
+
+ n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
+ if (n == 0)
+ (void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
+
+ if (n == 0)
+ n = lwres_getnamebyaddr(lwrctx, lwf,
+ (lwres_uint16_t)afd->a_addrlen,
+ addr, &by);
+ if (n == 0) {
+ if (flags & NI_NOFQDN) {
+ p = strchr(by->realname, '.');
+ if (p)
+ *p = '\0';
+ }
+ if ((strlen(by->realname) + 1) > hostlen)
+ ERR(ENI_MEMORY);
+ strcpy(host, by->realname);
+ } else {
+ if (flags & NI_NAMEREQD)
+ ERR(ENI_NOHOSTNAME);
+ if (lwres_net_ntop(afd->a_af, addr, numaddr,
+ sizeof(numaddr))
+ == NULL)
+ ERR(ENI_NOHOSTNAME);
+ if ((strlen(numaddr) + 1) > hostlen)
+ ERR(ENI_MEMORY);
+ strcpy(host, numaddr);
+ }
+ }
+ result = SUCCESS;
+ cleanup:
+ if (by != NULL)
+ lwres_gnbaresponse_free(lwrctx, &by);
+ if (lwrctx != NULL) {
+ lwres_conf_clear(lwrctx);
+ lwres_context_destroy(&lwrctx);
+ }
+ return (result);
+}
diff --git a/lib/liblwres/getrrset.c b/lib/liblwres/getrrset.c
new file mode 100644
index 000000000..cf8359268
--- /dev/null
+++ b/lib/liblwres/getrrset.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: getrrset.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <lwres/lwres.h>
+#include <lwres/net.h>
+#include <lwres/netdb.h> /* XXX #include <netdb.h> */
+
+#include "assert_p.h"
+
+unsigned int
+lwresult_to_result(lwres_result_t lwresult) {
+ switch (lwresult) {
+ case LWRES_R_SUCCESS: return (ERRSET_SUCCESS);
+ case LWRES_R_NOMEMORY: return (ERRSET_NOMEMORY);
+ case LWRES_R_NOTFOUND: return (ERRSET_NONAME);
+ case LWRES_R_TYPENOTFOUND: return (ERRSET_NODATA);
+ case LWRES_R_RETRY: return (ERRSET_RETRY);
+ default: return (ERRSET_FAIL);
+ }
+}
+
+/*
+ * malloc / calloc functions that guarantee to only
+ * return NULL if there is an error, like they used
+ * to before the ANSI C committee broke them.
+ */
+
+static void *
+sane_malloc(size_t size) {
+ if (size == 0)
+ size = 1;
+ return (malloc(size));
+}
+
+static void *
+sane_calloc(size_t number, size_t size) {
+ size_t len = number * size;
+ void *mem = sane_malloc(len);
+ if (mem != NULL)
+ memset(mem, 0, len);
+ return (mem);
+}
+
+int
+lwres_getrrsetbyname(const char *hostname, unsigned int rdclass,
+ unsigned int rdtype, unsigned int flags,
+ struct rrsetinfo **res)
+{
+ lwres_context_t *lwrctx = NULL;
+ lwres_result_t lwresult;
+ lwres_grbnresponse_t *response = NULL;
+ struct rrsetinfo *rrset = NULL;
+ unsigned int i;
+ unsigned int lwflags;
+ unsigned int result;
+
+ if (rdclass > 0xffff || rdtype > 0xffff) {
+ result = ERRSET_INVAL;
+ goto fail;
+ }
+
+ /*
+ * Don't allow queries of class or type ANY
+ */
+ if (rdclass == 0xff || rdtype == 0xff) {
+ result = ERRSET_INVAL;
+ goto fail;
+ }
+
+ lwresult = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
+ if (lwresult != LWRES_R_SUCCESS) {
+ result = lwresult_to_result(lwresult);
+ goto fail;
+ }
+ (void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
+
+ /*
+ * If any input flags were defined, lwflags would be set here
+ * based on them
+ */
+ UNUSED(flags);
+ lwflags = 0;
+
+ lwresult = lwres_getrdatabyname(lwrctx, hostname,
+ (lwres_uint16_t)rdclass,
+ (lwres_uint16_t)rdtype,
+ lwflags, &response);
+ if (lwresult != LWRES_R_SUCCESS) {
+ result = lwresult_to_result(lwresult);
+ goto fail;
+ }
+
+ rrset = sane_malloc(sizeof(struct rrsetinfo));
+ if (rrset == NULL) {
+ result = ERRSET_NOMEMORY;
+ goto fail;
+ }
+ rrset->rri_name = NULL;
+ rrset->rri_rdclass = response->rdclass;
+ rrset->rri_rdtype = response->rdtype;
+ rrset->rri_ttl = response->ttl;
+ rrset->rri_flags = 0;
+ rrset->rri_nrdatas = 0;
+ rrset->rri_rdatas = NULL;
+ rrset->rri_nsigs = 0;
+ rrset->rri_sigs = NULL;
+
+ rrset->rri_name = sane_malloc(response->realnamelen + 1);
+ if (rrset->rri_name == NULL) {
+ result = ERRSET_NOMEMORY;
+ goto fail;
+ }
+ strncpy(rrset->rri_name, response->realname, response->realnamelen);
+ rrset->rri_name[response->realnamelen] = 0;
+
+ if ((response->flags & LWRDATA_VALIDATED) != 0)
+ rrset->rri_flags |= RRSET_VALIDATED;
+
+ rrset->rri_nrdatas = response->nrdatas;
+ rrset->rri_rdatas = sane_calloc(rrset->rri_nrdatas,
+ sizeof(struct rdatainfo));
+ if (rrset->rri_rdatas == NULL) {
+ result = ERRSET_NOMEMORY;
+ goto fail;
+ }
+ for (i = 0; i < rrset->rri_nrdatas; i++) {
+ rrset->rri_rdatas[i].rdi_length = response->rdatalen[i];
+ rrset->rri_rdatas[i].rdi_data =
+ sane_malloc(rrset->rri_rdatas[i].rdi_length);
+ if (rrset->rri_rdatas[i].rdi_data == NULL) {
+ result = ERRSET_NOMEMORY;
+ goto fail;
+ }
+ memcpy(rrset->rri_rdatas[i].rdi_data, response->rdatas[i],
+ rrset->rri_rdatas[i].rdi_length);
+ }
+ rrset->rri_nsigs = response->nsigs;
+ rrset->rri_sigs = sane_calloc(rrset->rri_nsigs,
+ sizeof(struct rdatainfo));
+ if (rrset->rri_sigs == NULL) {
+ result = ERRSET_NOMEMORY;
+ goto fail;
+ }
+ for (i = 0; i < rrset->rri_nsigs; i++) {
+ rrset->rri_sigs[i].rdi_length = response->siglen[i];
+ rrset->rri_sigs[i].rdi_data =
+ sane_malloc(rrset->rri_sigs[i].rdi_length);
+ if (rrset->rri_sigs[i].rdi_data == NULL) {
+ result = ERRSET_NOMEMORY;
+ goto fail;
+ }
+ memcpy(rrset->rri_sigs[i].rdi_data, response->sigs[i],
+ rrset->rri_sigs[i].rdi_length);
+ }
+
+ lwres_grbnresponse_free(lwrctx, &response);
+ lwres_context_destroy(&lwrctx);
+ *res = rrset;
+ return (ERRSET_SUCCESS);
+ fail:
+ if (rrset != NULL)
+ lwres_freerrset(rrset);
+ if (response != NULL)
+ lwres_grbnresponse_free(lwrctx, &response);
+ if (lwrctx != NULL)
+ lwres_context_destroy(&lwrctx);
+ return (result);
+
+}
+
+void
+lwres_freerrset(struct rrsetinfo *rrset) {
+ unsigned int i;
+ for (i = 0; i < rrset->rri_nrdatas; i++) {
+ if (rrset->rri_rdatas[i].rdi_data == NULL)
+ break;
+ free(rrset->rri_rdatas[i].rdi_data);
+ }
+ free(rrset->rri_rdatas);
+ for (i = 0; i < rrset->rri_nsigs; i++) {
+ if (rrset->rri_sigs[i].rdi_data == NULL)
+ break;
+ free(rrset->rri_sigs[i].rdi_data);
+ }
+ free(rrset->rri_sigs);
+ free(rrset->rri_name);
+ free(rrset);
+}
+
diff --git a/lib/liblwres/getrrset2.c b/lib/liblwres/getrrset2.c
new file mode 100644
index 000000000..031021e06
--- /dev/null
+++ b/lib/liblwres/getrrset2.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: getrrset2.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <lwres/lwres.h>
+#include <lwres/net.h>
+#include <lwres/netdb.h> /* XXX #include <netdb.h> */
+
+#include <lwres/async.h>
+
+#include "assert_p.h"
+
+int
+lwres_getrrsetbyname_async(const char *hostname, unsigned int rdclass,
+ unsigned int rdtype, unsigned int flags,
+ struct rrsetinfo **res)
+{
+ int ret, ret2;
+ lwres_context_t *ctx = NULL;
+ struct lwres_async_state las;
+ struct lwres_async_state *plas;
+ struct timeval timeout;
+ fd_set readfds;
+ int sock;
+
+ ret = lwres_async_init(&ctx);
+ if(ret != ERRSET_SUCCESS) {
+ return(ret);
+ }
+
+ ret = lwres_getrrsetbyname_init(hostname, rdclass,
+ rdtype, flags,
+ ctx, &las);
+
+ if(ret != ERRSET_SUCCESS) {
+ return ret;
+ }
+
+ again:
+
+ lwres_getrrsetbyname_xmit(ctx, &las);
+ timeout.tv_sec = lwres_async_timeout(ctx);
+ sock = lwres_async_fd(ctx);
+
+ FD_ZERO(&readfds);
+ FD_SET(sock, &readfds);
+ ret2 = select(sock + 1, &readfds, NULL, NULL, &timeout);
+
+ /*
+ * What happened with select?
+ */
+ if (ret2 < 0) {
+ ret = LWRES_R_IOERROR;
+ goto out3;
+ }
+ if (ret2 == 0) {
+ ret = LWRES_R_TIMEOUT;
+ goto out3;
+ }
+
+ ret = lwres_getrrsetbyname_read(&plas, ctx, res);
+ if(ret == LWRES_R_RETRY) {
+ /* XXX retransmit */
+ goto again;
+ }
+
+ out3:
+ /* clean stuff up */
+
+ out:
+ if (ctx != NULL)
+ lwres_context_destroy(&ctx);
+
+ return ret;
+}
+
diff --git a/lib/liblwres/herror.c b/lib/liblwres/herror.c
new file mode 100644
index 000000000..7a8bcb2bd
--- /dev/null
+++ b/lib/liblwres/herror.c
@@ -0,0 +1,101 @@
+/*
+ * Portions Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93";
+static const char rcsid[] =
+ "$Id: herror.c,v 1.1 2004/03/15 20:35:25 as Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <lwres/netdb.h>
+#include <lwres/platform.h>
+
+LIBLWRES_EXTERNAL_DATA int lwres_h_errno;
+
+/*
+ * these have never been declared in any header file so make them static
+ */
+
+static const char *h_errlist[] = {
+ "Resolver Error 0 (no error)",
+ "Unknown host", /* 1 HOST_NOT_FOUND */
+ "Host name lookup failure", /* 2 TRY_AGAIN */
+ "Unknown server error", /* 3 NO_RECOVERY */
+ "No address associated with name", /* 4 NO_ADDRESS */
+};
+
+static int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] };
+
+
+/*
+ * herror --
+ * print the error indicated by the h_errno value.
+ */
+void
+lwres_herror(const char *s) {
+ fprintf(stderr, "%s: %s\n", s, lwres_hstrerror(lwres_h_errno));
+}
+
+/*
+ * hstrerror --
+ * return the string associated with a given "host" errno value.
+ */
+const char *
+lwres_hstrerror(int err) {
+ if (err < 0)
+ return ("Resolver internal error");
+ else if (err < h_nerr)
+ return (h_errlist[err]);
+ return ("Unknown resolver error");
+}
diff --git a/lib/liblwres/include/lwres/async.h b/lib/liblwres/include/lwres/async.h
new file mode 100644
index 000000000..6715afaed
--- /dev/null
+++ b/lib/liblwres/include/lwres/async.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2003 Michael Richardson
+ * Contributed by Michael Richardson <mcr@freeswan.org> while working
+ * on the Linux FreeS/WAN project in 2003.
+ *
+ * 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: async.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_ASYNC_H
+#define LWRES_ASYNC_H 1
+
+#include <lwres/lwres.h>
+
+/*
+ * support for asynchronous requests to lwres port
+ */
+struct lwres_async_state {
+ struct lwres_async_state *next;
+
+ lwres_buffer_t b_in, b_out;
+ lwres_uint32_t serial;
+ int opcode;
+
+ int (*callback)(void *uctx, struct rrsetinfo *res);
+ void *uctx;
+};
+
+
+
+/*
+ * The calls for asynchronous requests.
+ */
+
+int lwres_async_init(lwres_context_t **pctx);
+
+int lwres_getrrsetbyname_init(const char *hostname, unsigned int rdclass,
+ unsigned int rdtype, unsigned int flags,
+ lwres_context_t *ctx,
+ struct lwres_async_state *las);
+
+int lwres_getrrsetbyname_xmit(lwres_context_t *ctx,
+ struct lwres_async_state *las);
+
+unsigned long lwres_async_timeout(lwres_context_t *ctx);
+
+int lwres_async_fd(lwres_context_t *ctx);
+
+int lwres_getrrsetbyname_read(struct lwres_async_state **plas,
+ lwres_context_t *ctx,
+ struct rrsetinfo **res);
+
+int lwres_getrrsetbyname_async(const char *hostname, unsigned int rdclass,
+ unsigned int rdtype, unsigned int flags,
+ struct rrsetinfo **res);
+
+#endif /* LWRES_ASYNC_H */
+
+
+
+
+
+
+
+
+
diff --git a/lib/liblwres/include/lwres/context.h b/lib/liblwres/include/lwres/context.h
new file mode 100644
index 000000000..55ca3c7fb
--- /dev/null
+++ b/lib/liblwres/include/lwres/context.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: context.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_CONTEXT_H
+#define LWRES_CONTEXT_H 1
+
+#include <stddef.h>
+
+#include <lwres/lang.h>
+#include <lwres/int.h>
+#include <lwres/result.h>
+
+/*
+ * Used to set various options such as timeout, authentication, etc
+ */
+typedef struct lwres_context lwres_context_t;
+
+LWRES_LANG_BEGINDECLS
+
+typedef void *(*lwres_malloc_t)(void *arg, size_t length);
+typedef void (*lwres_free_t)(void *arg, void *mem, size_t length);
+
+/*
+ * XXXMLG
+ *
+ * Make the server reload /etc/resolv.conf periodically.
+ *
+ * Make the server do sortlist/searchlist.
+ *
+ * Client side can disable the search/sortlist processing.
+ *
+ * Use an array of addresses/masks and searchlist for client-side, and
+ * if added to the client disable the processing on the server.
+ *
+ * Share /etc/resolv.conf data between contexts.
+ */
+
+/*
+ * _SERVERMODE
+ * Don't allocate and connect a socket to the server, since the
+ * caller _is_ a server.
+ */
+#define LWRES_CONTEXT_SERVERMODE 0x00000001U
+
+lwres_result_t
+lwres_context_create(lwres_context_t **contextp, void *arg,
+ lwres_malloc_t malloc_function,
+ lwres_free_t free_function,
+ unsigned int flags);
+/*
+ * Allocate a lwres context. This is used in all lwres calls.
+ *
+ * Memory management can be replaced here by passing in two functions.
+ * If one is non-NULL, they must both be non-NULL. "arg" is passed to
+ * these functions.
+ *
+ * Contexts are not thread safe. Document at the top of the file.
+ * XXXMLG
+ *
+ * If they are NULL, the standard malloc() and free() will be used.
+ *
+ * Requires:
+ *
+ * contextp != NULL && contextp == NULL.
+ *
+ * Returns:
+ *
+ * Returns 0 on success, non-zero on failure.
+ */
+
+void
+lwres_context_destroy(lwres_context_t **contextp);
+/*
+ * Frees all memory associated with a lwres context.
+ *
+ * Requires:
+ *
+ * contextp != NULL && contextp == NULL.
+ */
+
+lwres_uint32_t
+lwres_context_nextserial(lwres_context_t *ctx);
+/*
+ * XXXMLG Document
+ */
+
+void
+lwres_context_initserial(lwres_context_t *ctx, lwres_uint32_t serial);
+
+void
+lwres_context_freemem(lwres_context_t *ctx, void *mem, size_t len);
+
+void *
+lwres_context_allocmem(lwres_context_t *ctx, size_t len);
+
+int
+lwres_context_getsocket(lwres_context_t *ctx);
+
+lwres_result_t
+lwres_context_send(lwres_context_t *ctx,
+ void *sendbase, int sendlen);
+
+lwres_result_t
+lwres_context_recv(lwres_context_t *ctx,
+ void *recvbase, int recvlen,
+ int *recvd_len);
+
+lwres_result_t
+lwres_context_sendrecv(lwres_context_t *ctx,
+ void *sendbase, int sendlen,
+ void *recvbase, int recvlen,
+ int *recvd_len);
+
+LWRES_LANG_ENDDECLS
+
+#endif /* LWRES_CONTEXT_H */
+
diff --git a/lib/liblwres/include/lwres/int.h b/lib/liblwres/include/lwres/int.h
new file mode 100644
index 000000000..470372e77
--- /dev/null
+++ b/lib/liblwres/include/lwres/int.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: int.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_INT_H
+#define LWRES_INT_H 1
+
+typedef char lwres_int8_t;
+typedef unsigned char lwres_uint8_t;
+typedef short lwres_int16_t;
+typedef unsigned short lwres_uint16_t;
+typedef int lwres_int32_t;
+typedef unsigned int lwres_uint32_t;
+typedef long long lwres_int64_t;
+typedef unsigned long long lwres_uint64_t;
+
+#endif /* LWRES_INT_H */
diff --git a/lib/liblwres/include/lwres/ipv6.h b/lib/liblwres/include/lwres/ipv6.h
new file mode 100644
index 000000000..ee7bc0743
--- /dev/null
+++ b/lib/liblwres/include/lwres/ipv6.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: ipv6.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_IPV6_H
+#define LWRES_IPV6_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*
+ * IPv6 definitions for systems which do not support IPv6.
+ */
+
+/***
+ *** Imports.
+ ***/
+
+#include <lwres/int.h>
+#include <lwres/platform.h>
+
+/***
+ *** Types.
+ ***/
+
+struct in6_addr {
+ union {
+ lwres_uint8_t _S6_u8[16];
+ lwres_uint16_t _S6_u16[8];
+ lwres_uint32_t _S6_u32[4];
+ } _S6_un;
+};
+#define s6_addr _S6_un._S6_u8
+#define s6_addr8 _S6_un._S6_u8
+#define s6_addr16 _S6_un._S6_u16
+#define s6_addr32 _S6_un._S6_u32
+
+#define IN6ADDR_ANY_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}}
+#define IN6ADDR_LOOPBACK_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}}
+
+LIBLWRES_EXTERNAL_DATA extern const struct in6_addr in6addr_any;
+LIBLWRES_EXTERNAL_DATA extern const struct in6_addr in6addr_loopback;
+
+struct sockaddr_in6 {
+#ifdef LWRES_PLATFORM_HAVESALEN
+ lwres_uint8_t sin6_len;
+ lwres_uint8_t sin6_family;
+#else
+ lwres_uint16_t sin6_family;
+#endif
+ lwres_uint16_t sin6_port;
+ lwres_uint32_t sin6_flowinfo;
+ struct in6_addr sin6_addr;
+ lwres_uint32_t sin6_scope_id;
+};
+
+#ifdef LWRES_PLATFORM_HAVESALEN
+#define SIN6_LEN 1
+#endif
+
+struct in6_pktinfo {
+ struct in6_addr ipi6_addr; /* src/dst IPv6 address */
+ unsigned int ipi6_ifindex; /* send/recv interface index */
+};
+
+/*
+ * Unspecified
+ */
+#define IN6_IS_ADDR_UNSPECIFIED(a) \
+ (((a)->s6_addr32[0] == 0) && \
+ ((a)->s6_addr32[1] == 0) && \
+ ((a)->s6_addr32[2] == 0) && \
+ ((a)->s6_addr32[3] == 0))
+
+/*
+ * Loopback
+ */
+#define IN6_IS_ADDR_LOOPBACK(a) \
+ (((a)->s6_addr32[0] == 0) && \
+ ((a)->s6_addr32[1] == 0) && \
+ ((a)->s6_addr32[2] == 0) && \
+ ((a)->s6_addr32[3] == htonl(1)))
+
+/*
+ * IPv4 compatible
+ */
+#define IN6_IS_ADDR_V4COMPAT(a) \
+ (((a)->s6_addr32[0] == 0) && \
+ ((a)->s6_addr32[1] == 0) && \
+ ((a)->s6_addr32[2] == 0) && \
+ ((a)->s6_addr32[3] != 0) && \
+ ((a)->s6_addr32[3] != htonl(1)))
+
+/*
+ * Mapped
+ */
+#define IN6_IS_ADDR_V4MAPPED(a) \
+ (((a)->s6_addr32[0] == 0) && \
+ ((a)->s6_addr32[1] == 0) && \
+ ((a)->s6_addr32[2] == htonl(0x0000ffff)))
+
+#endif /* LWRES_IPV6_H */
diff --git a/lib/liblwres/include/lwres/lang.h b/lib/liblwres/include/lwres/lang.h
new file mode 100644
index 000000000..1de35fd91
--- /dev/null
+++ b/lib/liblwres/include/lwres/lang.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: lang.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_LANG_H
+#define LWRES_LANG_H 1
+
+#ifdef __cplusplus
+#define LWRES_LANG_BEGINDECLS extern "C" {
+#define LWRES_LANG_ENDDECLS }
+#else
+#define LWRES_LANG_BEGINDECLS
+#define LWRES_LANG_ENDDECLS
+#endif
+
+#endif /* LWRES_LANG_H */
diff --git a/lib/liblwres/include/lwres/list.h b/lib/liblwres/include/lwres/list.h
new file mode 100644
index 000000000..e90a1b55a
--- /dev/null
+++ b/lib/liblwres/include/lwres/list.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 1997-2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: list.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_LIST_H
+#define LWRES_LIST_H 1
+
+#define LWRES_LIST(type) struct { type *head, *tail; }
+#define LWRES_LIST_INIT(list) \
+ do { (list).head = NULL; (list).tail = NULL; } while (0)
+
+#define LWRES_LINK(type) struct { type *prev, *next; }
+#define LWRES_LINK_INIT(elt, link) \
+ do { \
+ (elt)->link.prev = (void *)(-1); \
+ (elt)->link.next = (void *)(-1); \
+ } while (0)
+#define LWRES_LINK_LINKED(elt, link) \
+ ((void *)((elt)->link.prev) != (void *)(-1))
+
+#define LWRES_LIST_HEAD(list) ((list).head)
+#define LWRES_LIST_TAIL(list) ((list).tail)
+#define LWRES_LIST_EMPTY(list) LWRES_TF((list).head == NULL)
+
+#define LWRES_LIST_PREPEND(list, elt, link) \
+ do { \
+ if ((list).head != NULL) \
+ (list).head->link.prev = (elt); \
+ else \
+ (list).tail = (elt); \
+ (elt)->link.prev = NULL; \
+ (elt)->link.next = (list).head; \
+ (list).head = (elt); \
+ } while (0)
+
+#define LWRES_LIST_APPEND(list, elt, link) \
+ do { \
+ if ((list).tail != NULL) \
+ (list).tail->link.next = (elt); \
+ else \
+ (list).head = (elt); \
+ (elt)->link.prev = (list).tail; \
+ (elt)->link.next = NULL; \
+ (list).tail = (elt); \
+ } while (0)
+
+#define LWRES_LIST_UNLINK(list, elt, link) \
+ do { \
+ if ((elt)->link.next != NULL) \
+ (elt)->link.next->link.prev = (elt)->link.prev; \
+ else \
+ (list).tail = (elt)->link.prev; \
+ if ((elt)->link.prev != NULL) \
+ (elt)->link.prev->link.next = (elt)->link.next; \
+ else \
+ (list).head = (elt)->link.next; \
+ (elt)->link.prev = (void *)(-1); \
+ (elt)->link.next = (void *)(-1); \
+ } while (0)
+
+#define LWRES_LIST_PREV(elt, link) ((elt)->link.prev)
+#define LWRES_LIST_NEXT(elt, link) ((elt)->link.next)
+
+#define LWRES_LIST_INSERTBEFORE(list, before, elt, link) \
+ do { \
+ if ((before)->link.prev == NULL) \
+ LWRES_LIST_PREPEND(list, elt, link); \
+ else { \
+ (elt)->link.prev = (before)->link.prev; \
+ (before)->link.prev = (elt); \
+ (elt)->link.prev->link.next = (elt); \
+ (elt)->link.next = (before); \
+ } \
+ } while (0)
+
+#define LWRES_LIST_INSERTAFTER(list, after, elt, link) \
+ do { \
+ if ((after)->link.next == NULL) \
+ LWRES_LIST_APPEND(list, elt, link); \
+ else { \
+ (elt)->link.next = (after)->link.next; \
+ (after)->link.next = (elt); \
+ (elt)->link.next->link.prev = (elt); \
+ (elt)->link.prev = (after); \
+ } \
+ } while (0)
+
+#define LWRES_LIST_APPENDLIST(list1, list2, link) \
+ do { \
+ if (LWRES_LIST_EMPTY(list1)) \
+ (list1) = (list2); \
+ else if (!LWRES_LIST_EMPTY(list2)) { \
+ (list1).tail->link.next = (list2).head; \
+ (list2).head->link.prev = (list1).tail; \
+ (list1).tail = (list2).tail; \
+ } \
+ (list2).head = NULL; \
+ (list2).tail = NULL; \
+ } while (0)
+
+#define LWRES_LIST_ENQUEUE(list, elt, link) LWRES_LIST_APPEND(list, elt, link)
+#define LWRES_LIST_DEQUEUE(list, elt, link) LWRES_LIST_UNLINK(list, elt, link)
+
+#endif /* LWRES_LIST_H */
diff --git a/lib/liblwres/include/lwres/lwbuffer.h b/lib/liblwres/include/lwres/lwbuffer.h
new file mode 100644
index 000000000..7486e8bc3
--- /dev/null
+++ b/lib/liblwres/include/lwres/lwbuffer.h
@@ -0,0 +1,402 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: lwbuffer.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_LWBUFFER_H
+#define LWRES_LWBUFFER_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*
+ * Buffers
+ *
+ * A buffer is a region of memory, together with a set of related subregions.
+ * Buffers are used for parsing and I/O operations.
+ *
+ * The 'used region' and the 'available' region are disjoint, and their
+ * union is the buffer's region. The used region extends from the beginning
+ * of the buffer region to the last used byte. The available region
+ * extends from one byte greater than the last used byte to the end of the
+ * buffer's region. The size of the used region can be changed using various
+ * buffer commands. Initially, the used region is empty.
+ *
+ * The used region is further subdivided into two disjoint regions: the
+ * 'consumed region' and the 'remaining region'. The union of these two
+ * regions is the used region. The consumed region extends from the beginning
+ * of the used region to the byte before the 'current' offset (if any). The
+ * 'remaining' region the current pointer to the end of the used
+ * region. The size of the consumed region can be changed using various
+ * buffer commands. Initially, the consumed region is empty.
+ *
+ * The 'active region' is an (optional) subregion of the remaining region.
+ * It extends from the current offset to an offset in the remaining region
+ * that is selected with lwres_buffer_setactive(). Initially, the active
+ * region is empty. If the current offset advances beyond the chosen offset,
+ * the active region will also be empty.
+ *
+ * /----- used region -----\/-- available --\
+ * +----------------------------------------+
+ * | consumed | remaining | |
+ * +----------------------------------------+
+ * a b c d e
+ *
+ * a == base of buffer.
+ * b == current pointer. Can be anywhere between a and d.
+ * c == active pointer. Meaningful between b and d.
+ * d == used pointer.
+ * e == length of buffer.
+ *
+ * a-e == entire (length) of buffer.
+ * a-d == used region.
+ * a-b == consumed region.
+ * b-d == remaining region.
+ * b-c == optional active region.
+ *
+ * The following invariants are maintained by all routines:
+ *
+ * length > 0
+ *
+ * base is a valid pointer to length bytes of memory
+ *
+ * 0 <= used <= length
+ *
+ * 0 <= current <= used
+ *
+ * 0 <= active <= used
+ * (although active < current implies empty active region)
+ *
+ * MP:
+ * Buffers have no synchronization. Clients must ensure exclusive
+ * access.
+ *
+ * Reliability:
+ * No anticipated impact.
+ *
+ * Resources:
+ * Memory: 1 pointer + 6 unsigned integers per buffer.
+ *
+ * Security:
+ * No anticipated impact.
+ *
+ * Standards:
+ * None.
+ */
+
+/***
+ *** Imports
+ ***/
+
+#include <lwres/lang.h>
+#include <lwres/int.h>
+
+LWRES_LANG_BEGINDECLS
+
+/***
+ *** Magic numbers
+ ***/
+#define LWRES_BUFFER_MAGIC 0x4275663fU /* Buf?. */
+
+#define LWRES_BUFFER_VALID(b) ((b) != NULL && \
+ (b)->magic == LWRES_BUFFER_MAGIC)
+
+/*
+ * The following macros MUST be used only on valid buffers. It is the
+ * caller's responsibility to ensure this by using the LWRES_BUFFER_VALID
+ * check above, or by calling another lwres_buffer_*() function (rather than
+ * another macro.)
+ */
+
+/*
+ * Get the length of the used region of buffer "b"
+ */
+#define LWRES_BUFFER_USEDCOUNT(b) ((b)->used)
+
+/*
+ * Get the length of the available region of buffer "b"
+ */
+#define LWRES_BUFFER_AVAILABLECOUNT(b) ((b)->length - (b)->used)
+
+#define LWRES_BUFFER_REMAINING(b) ((b)->used - (b)->current)
+
+/*
+ * Note that the buffer structure is public. This is principally so buffer
+ * operations can be implemented using macros. Applications are strongly
+ * discouraged from directly manipulating the structure.
+ */
+
+typedef struct lwres_buffer lwres_buffer_t;
+struct lwres_buffer {
+ unsigned int magic;
+ unsigned char *base;
+ /* The following integers are byte offsets from 'base'. */
+ unsigned int length;
+ unsigned int used;
+ unsigned int current;
+ unsigned int active;
+};
+
+/***
+ *** Functions
+ ***/
+
+void
+lwres_buffer_init(lwres_buffer_t *b, void *base, unsigned int length);
+/*
+ * Make 'b' refer to the 'length'-byte region starting at base.
+ *
+ * Requires:
+ *
+ * 'length' > 0
+ *
+ * 'base' is a pointer to a sequence of 'length' bytes.
+ *
+ */
+
+void
+lwres_buffer_invalidate(lwres_buffer_t *b);
+/*
+ * Make 'b' an invalid buffer.
+ *
+ * Requires:
+ * 'b' is a valid buffer.
+ *
+ * Ensures:
+ * If assertion checking is enabled, future attempts to use 'b' without
+ * calling lwres_buffer_init() on it will cause an assertion failure.
+ */
+
+void
+lwres_buffer_add(lwres_buffer_t *b, unsigned int n);
+/*
+ * Increase the 'used' region of 'b' by 'n' bytes.
+ *
+ * Requires:
+ *
+ * 'b' is a valid buffer
+ *
+ * used + n <= length
+ *
+ */
+
+void
+lwres_buffer_subtract(lwres_buffer_t *b, unsigned int n);
+/*
+ * Decrease the 'used' region of 'b' by 'n' bytes.
+ *
+ * Requires:
+ *
+ * 'b' is a valid buffer
+ *
+ * used >= n
+ *
+ */
+
+void
+lwres_buffer_clear(lwres_buffer_t *b);
+/*
+ * Make the used region empty.
+ *
+ * Requires:
+ *
+ * 'b' is a valid buffer
+ *
+ * Ensures:
+ *
+ * used = 0
+ *
+ */
+
+void
+lwres_buffer_first(lwres_buffer_t *b);
+/*
+ * Make the consumed region empty.
+ *
+ * Requires:
+ *
+ * 'b' is a valid buffer
+ *
+ * Ensures:
+ *
+ * current == 0
+ *
+ */
+
+void
+lwres_buffer_forward(lwres_buffer_t *b, unsigned int n);
+/*
+ * Increase the 'consumed' region of 'b' by 'n' bytes.
+ *
+ * Requires:
+ *
+ * 'b' is a valid buffer
+ *
+ * current + n <= used
+ *
+ */
+
+void
+lwres_buffer_back(lwres_buffer_t *b, unsigned int n);
+/*
+ * Decrease the 'consumed' region of 'b' by 'n' bytes.
+ *
+ * Requires:
+ *
+ * 'b' is a valid buffer
+ *
+ * n <= current
+ *
+ */
+
+lwres_uint8_t
+lwres_buffer_getuint8(lwres_buffer_t *b);
+/*
+ * Read an unsigned 8-bit integer from 'b' and return it.
+ *
+ * Requires:
+ *
+ * 'b' is a valid buffer.
+ *
+ * The length of the available region of 'b' is at least 1.
+ *
+ * Ensures:
+ *
+ * The current pointer in 'b' is advanced by 1.
+ *
+ * Returns:
+ *
+ * A 8-bit unsigned integer.
+ */
+
+void
+lwres_buffer_putuint8(lwres_buffer_t *b, lwres_uint8_t val);
+/*
+ * Store an unsigned 8-bit integer from 'val' into 'b'.
+ *
+ * Requires:
+ * 'b' is a valid buffer.
+ *
+ * The length of the unused region of 'b' is at least 1.
+ *
+ * Ensures:
+ * The used pointer in 'b' is advanced by 1.
+ */
+
+lwres_uint16_t
+lwres_buffer_getuint16(lwres_buffer_t *b);
+/*
+ * Read an unsigned 16-bit integer in network byte order from 'b', convert
+ * it to host byte order, and return it.
+ *
+ * Requires:
+ *
+ * 'b' is a valid buffer.
+ *
+ * The length of the available region of 'b' is at least 2.
+ *
+ * Ensures:
+ *
+ * The current pointer in 'b' is advanced by 2.
+ *
+ * Returns:
+ *
+ * A 16-bit unsigned integer.
+ */
+
+void
+lwres_buffer_putuint16(lwres_buffer_t *b, lwres_uint16_t val);
+/*
+ * Store an unsigned 16-bit integer in host byte order from 'val'
+ * into 'b' in network byte order.
+ *
+ * Requires:
+ * 'b' is a valid buffer.
+ *
+ * The length of the unused region of 'b' is at least 2.
+ *
+ * Ensures:
+ * The used pointer in 'b' is advanced by 2.
+ */
+
+lwres_uint32_t
+lwres_buffer_getuint32(lwres_buffer_t *b);
+/*
+ * Read an unsigned 32-bit integer in network byte order from 'b', convert
+ * it to host byte order, and return it.
+ *
+ * Requires:
+ *
+ * 'b' is a valid buffer.
+ *
+ * The length of the available region of 'b' is at least 2.
+ *
+ * Ensures:
+ *
+ * The current pointer in 'b' is advanced by 2.
+ *
+ * Returns:
+ *
+ * A 32-bit unsigned integer.
+ */
+
+void
+lwres_buffer_putuint32(lwres_buffer_t *b, lwres_uint32_t val);
+/*
+ * Store an unsigned 32-bit integer in host byte order from 'val'
+ * into 'b' in network byte order.
+ *
+ * Requires:
+ * 'b' is a valid buffer.
+ *
+ * The length of the unused region of 'b' is at least 4.
+ *
+ * Ensures:
+ * The used pointer in 'b' is advanced by 4.
+ */
+
+void
+lwres_buffer_putmem(lwres_buffer_t *b, const unsigned char *base,
+ unsigned int length);
+/*
+ * Copy 'length' bytes of memory at 'base' into 'b'.
+ *
+ * Requires:
+ * 'b' is a valid buffer.
+ *
+ * 'base' points to 'length' bytes of valid memory.
+ *
+ */
+
+void
+lwres_buffer_getmem(lwres_buffer_t *b, unsigned char *base,
+ unsigned int length);
+/*
+ * Copy 'length' bytes of memory from 'b' into 'base'.
+ *
+ * Requires:
+ * 'b' is a valid buffer.
+ *
+ * 'base' points to at least 'length' bytes of valid memory.
+ *
+ * 'b' have at least 'length' bytes remaining.
+ */
+
+LWRES_LANG_ENDDECLS
+
+#endif /* LWRES_LWBUFFER_H */
diff --git a/lib/liblwres/include/lwres/lwpacket.h b/lib/liblwres/include/lwres/lwpacket.h
new file mode 100644
index 000000000..a0d216e57
--- /dev/null
+++ b/lib/liblwres/include/lwres/lwpacket.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 1999-2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: lwpacket.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_LWPACKET_H
+#define LWRES_LWPACKET_H 1
+
+#include <lwres/lang.h>
+#include <lwres/lwbuffer.h>
+#include <lwres/result.h>
+
+typedef struct lwres_lwpacket lwres_lwpacket_t;
+
+struct lwres_lwpacket {
+ lwres_uint32_t length;
+ lwres_uint16_t version;
+ lwres_uint16_t pktflags;
+ lwres_uint32_t serial;
+ lwres_uint32_t opcode;
+ lwres_uint32_t result;
+ lwres_uint32_t recvlength;
+ lwres_uint16_t authtype;
+ lwres_uint16_t authlength;
+};
+
+#define LWRES_LWPACKET_LENGTH (4 * 5 + 2 * 4)
+
+#define LWRES_LWPACKETFLAG_RESPONSE 0x0001U /* if set, pkt is a response */
+
+
+#define LWRES_LWPACKETVERSION_0 0
+
+/*
+ * "length" is the overall packet length, including the entire packet header.
+ *
+ * "version" specifies the header format. Currently, there is only one
+ * format, LWRES_LWPACKETVERSION_0.
+ *
+ * "flags" specifies library-defined flags for this packet. None of these
+ * are definable by the caller, but library-defined values can be set by
+ * the caller. For example, one bit in this field indicates if the packet
+ * is a request or a response.
+ *
+ * "serial" is set by the requestor and is returned in all replies. If two
+ * packets from the same source have the same serial number and are from
+ * the same source, they are assumed to be duplicates and the latter ones
+ * may be dropped. (The library does not do this by default on replies, but
+ * does so on requests.)
+ *
+ * "opcode" is application defined. Opcodes between 0x04000000 and 0xffffffff
+ * are application defined. Opcodes between 0x00000000 and 0x03ffffff are
+ * reserved for library use.
+ *
+ * "result" is application defined, and valid only on replies.
+ * Results between 0x04000000 and 0xffffffff are application defined.
+ * Results between 0x00000000 and 0x03ffffff are reserved for library use.
+ * (This is the same reserved range defined in <isc/resultclass.h>, so it
+ * would be trivial to map ISC_R_* result codes into packet result codes
+ * when appropriate.)
+ *
+ * "recvlength" is set to the maximum buffer size that the receiver can
+ * handle on requests, and the size of the buffer needed to satisfy a request
+ * when the buffer is too large for replies.
+ *
+ * "authtype" is the packet level auth type used.
+ * Authtypes between 0x1000 and 0xffff are application defined. Authtypes
+ * between 0x0000 and 0x0fff are reserved for library use. This is currently
+ * unused and MUST be set to zero.
+ *
+ * "authlen" is the length of the authentication data. See the specific
+ * authtypes for more information on what is contained in this field. This
+ * is currently unused, and MUST be set to zero.
+ *
+ * The remainder of the packet consists of two regions, one described by
+ * "authlen" and one of "length - authlen - sizeof(lwres_lwpacket_t)".
+ *
+ * That is:
+ *
+ * pkt header
+ * authlen bytes of auth information
+ * data bytes
+ */
+
+/*
+ * Currently defined opcodes:
+ *
+ * NOOP. Success is always returned, with the packet contents echoed.
+ *
+ * GETADDRSBYNAME. Return all known addresses for a given name.
+ * This may return NIS or /etc/hosts info as well as DNS
+ * information. Flags will be provided to indicate ip4/ip6
+ * addresses are desired.
+ *
+ * GETNAMEBYADDR. Return the hostname for the given address. Once
+ * again, it will return data from multiple sources.
+ */
+
+LWRES_LANG_BEGINDECLS
+
+/* XXXMLG document */
+lwres_result_t
+lwres_lwpacket_renderheader(lwres_buffer_t *b, lwres_lwpacket_t *pkt);
+
+lwres_result_t
+lwres_lwpacket_parseheader(lwres_buffer_t *b, lwres_lwpacket_t *pkt);
+
+LWRES_LANG_ENDDECLS
+
+#endif /* LWRES_LWPACKET_H */
diff --git a/lib/liblwres/include/lwres/lwres.h b/lib/liblwres/include/lwres/lwres.h
new file mode 100644
index 000000000..e819c8b68
--- /dev/null
+++ b/lib/liblwres/include/lwres/lwres.h
@@ -0,0 +1,584 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: lwres.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_LWRES_H
+#define LWRES_LWRES_H 1
+
+#include <stdio.h>
+
+#include <lwres/context.h>
+#include <lwres/lang.h>
+#include <lwres/list.h>
+#include <lwres/lwpacket.h>
+
+/*
+ * Design notes:
+ *
+ * Each opcode has two structures and three functions which operate on each
+ * structure. For example, using the "no operation/ping" opcode as an
+ * example:
+ *
+ * lwres_nooprequest_t:
+ *
+ * lwres_nooprequest_render() takes a lwres_nooprequest_t and
+ * and renders it into wire format, storing the allocated
+ * buffer information in a passed-in buffer. When this buffer
+ * is no longer needed, it must be freed by
+ * lwres_context_freemem(). All other memory used by the
+ * caller must be freed manually, including the
+ * lwres_nooprequest_t passed in.
+ *
+ * lwres_nooprequest_parse() takes a wire format message and
+ * breaks it out into a lwres_nooprequest_t. The structure
+ * must be freed via lwres_nooprequest_free() when it is no longer
+ * needed.
+ *
+ * lwres_nooprequest_free() releases into the lwres_context_t
+ * any space allocated during parsing.
+ *
+ * lwres_noopresponse_t:
+ *
+ * The functions used are similar to the three used for
+ * requests, just with different names.
+ *
+ * Typically, the client will use request_render, response_parse, and
+ * response_free, while the daemon will use request_parse, response_render,
+ * and request_free.
+ *
+ * The basic flow of a typical client is:
+ *
+ * fill in a request_t, and call the render function.
+ *
+ * Transmit the buffer returned to the daemon.
+ *
+ * Wait for a response.
+ *
+ * When a response is received, parse it into a response_t.
+ *
+ * free the request buffer using lwres_context_freemem().
+ *
+ * free the response structure and its associated buffer using
+ * response_free().
+ */
+
+#define LWRES_UDP_PORT 921
+#define LWRES_RECVLENGTH 16384
+#define LWRES_ADDR_MAXLEN 16 /* changing this breaks ABI */
+#define LWRES_RESOLV_CONF "/etc/resolv.conf"
+
+/*
+ * Flags.
+ *
+ * These flags are only relevant to rrset queries.
+ *
+ * TRUSTNOTREQUIRED: DNSSEC is not required (input)
+ * SECUREDATA: The data was crypto-verified with DNSSEC (output)
+ *
+ */
+#define LWRES_FLAG_TRUSTNOTREQUIRED 0x00000001U
+#define LWRES_FLAG_SECUREDATA 0x00000002U
+
+/*
+ * no-op
+ */
+#define LWRES_OPCODE_NOOP 0x00000000U
+
+typedef struct {
+ /* public */
+ lwres_uint16_t datalength;
+ unsigned char *data;
+} lwres_nooprequest_t;
+
+typedef struct {
+ /* public */
+ lwres_uint16_t datalength;
+ unsigned char *data;
+} lwres_noopresponse_t;
+
+/*
+ * get addresses by name
+ */
+#define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U
+
+typedef struct lwres_addr lwres_addr_t;
+typedef LWRES_LIST(lwres_addr_t) lwres_addrlist_t;
+
+struct lwres_addr {
+ lwres_uint32_t family;
+ lwres_uint16_t length;
+ unsigned char address[LWRES_ADDR_MAXLEN];
+ LWRES_LINK(lwres_addr_t) link;
+};
+
+typedef struct {
+ /* public */
+ lwres_uint32_t flags;
+ lwres_uint32_t addrtypes;
+ lwres_uint16_t namelen;
+ char *name;
+} lwres_gabnrequest_t;
+
+typedef struct {
+ /* public */
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ lwres_uint16_t naddrs;
+ char *realname;
+ char **aliases;
+ lwres_uint16_t realnamelen;
+ lwres_uint16_t *aliaslen;
+ lwres_addrlist_t addrs;
+ /* if base != NULL, it will be freed when this structure is freed. */
+ void *base;
+ size_t baselen;
+} lwres_gabnresponse_t;
+
+/*
+ * get name by address
+ */
+#define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U
+typedef struct {
+ /* public */
+ lwres_uint32_t flags;
+ lwres_addr_t addr;
+} lwres_gnbarequest_t;
+
+typedef struct {
+ /* public */
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ char *realname;
+ char **aliases;
+ lwres_uint16_t realnamelen;
+ lwres_uint16_t *aliaslen;
+ /* if base != NULL, it will be freed when this structure is freed. */
+ void *base;
+ size_t baselen;
+} lwres_gnbaresponse_t;
+
+/*
+ * get rdata by name
+ */
+#define LWRES_OPCODE_GETRDATABYNAME 0x00010003U
+
+typedef struct {
+ /* public */
+ lwres_uint32_t flags;
+ lwres_uint16_t rdclass;
+ lwres_uint16_t rdtype;
+ lwres_uint16_t namelen;
+ char *name;
+} lwres_grbnrequest_t;
+
+typedef struct {
+ /* public */
+ lwres_uint32_t flags;
+ lwres_uint16_t rdclass;
+ lwres_uint16_t rdtype;
+ lwres_uint32_t ttl;
+ lwres_uint16_t nrdatas;
+ lwres_uint16_t nsigs;
+ char *realname;
+ lwres_uint16_t realnamelen;
+ unsigned char **rdatas;
+ lwres_uint16_t *rdatalen;
+ unsigned char **sigs;
+ lwres_uint16_t *siglen;
+ /* if base != NULL, it will be freed when this structure is freed. */
+ void *base;
+ size_t baselen;
+} lwres_grbnresponse_t;
+
+#define LWRDATA_VALIDATED 0x00000001
+
+/*
+ * resolv.conf data
+ */
+
+#define LWRES_CONFMAXNAMESERVERS 3 /* max 3 "nameserver" entries */
+#define LWRES_CONFMAXLWSERVERS 1 /* max 1 "lwserver" entry */
+#define LWRES_CONFMAXSEARCH 8 /* max 8 domains in "search" entry */
+#define LWRES_CONFMAXLINELEN 256 /* max size of a line */
+#define LWRES_CONFMAXSORTLIST 10
+typedef struct {
+ lwres_context_t *lwctx;
+ lwres_addr_t nameservers[LWRES_CONFMAXNAMESERVERS];
+ lwres_uint8_t nsnext; /* index for next free slot */
+
+ lwres_addr_t lwservers[LWRES_CONFMAXLWSERVERS];
+ lwres_uint8_t lwnext; /* index for next free slot */
+
+ char *domainname;
+
+ char *search[LWRES_CONFMAXSEARCH];
+ lwres_uint8_t searchnxt; /* index for next free slot */
+
+ struct {
+ lwres_addr_t addr;
+ /* mask has a non-zero 'family' and 'length' if set */
+ lwres_addr_t mask;
+ } sortlist[LWRES_CONFMAXSORTLIST];
+ lwres_uint8_t sortlistnxt;
+
+ lwres_uint8_t resdebug; /* non-zero if 'options debug' set */
+ lwres_uint8_t ndots; /* set to n in 'options ndots:n' */
+ lwres_uint8_t no_tld_query; /* non-zero if 'options no_tld_query' */
+} lwres_conf_t;
+
+#define LWRES_ADDRTYPE_V4 0x00000001U /* ipv4 */
+#define LWRES_ADDRTYPE_V6 0x00000002U /* ipv6 */
+
+#define LWRES_MAX_ALIASES 16 /* max # of aliases */
+#define LWRES_MAX_ADDRS 64 /* max # of addrs */
+
+LWRES_LANG_BEGINDECLS
+
+/*
+ * This is in host byte order.
+ */
+extern lwres_uint16_t lwres_udp_port;
+
+extern const char *lwres_resolv_conf;
+
+lwres_result_t
+lwres_gabnrequest_render(lwres_context_t *ctx, lwres_gabnrequest_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+
+lwres_result_t
+lwres_gabnresponse_render(lwres_context_t *ctx, lwres_gabnresponse_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+
+lwres_result_t
+lwres_gabnrequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt, lwres_gabnrequest_t **structp);
+
+lwres_result_t
+lwres_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt,
+ lwres_gabnresponse_t **structp);
+
+void
+lwres_gabnrequest_free(lwres_context_t *ctx, lwres_gabnrequest_t **structp);
+/*
+ * Frees any dynamically allocated memory for this structure.
+ *
+ * Requires:
+ *
+ * ctx != NULL, and be a context returned via lwres_contextcreate().
+ *
+ * structp != NULL && *structp != NULL.
+ *
+ * Ensures:
+ *
+ * *structp == NULL.
+ *
+ * All memory allocated by this structure will be returned to the
+ * system via the context's free function.
+ */
+
+void
+lwres_gabnresponse_free(lwres_context_t *ctx, lwres_gabnresponse_t **structp);
+/*
+ * Frees any dynamically allocated memory for this structure.
+ *
+ * Requires:
+ *
+ * ctx != NULL, and be a context returned via lwres_contextcreate().
+ *
+ * structp != NULL && *structp != NULL.
+ *
+ * Ensures:
+ *
+ * *structp == NULL.
+ *
+ * All memory allocated by this structure will be returned to the
+ * system via the context's free function.
+ */
+
+
+lwres_result_t
+lwres_gnbarequest_render(lwres_context_t *ctx, lwres_gnbarequest_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+
+lwres_result_t
+lwres_gnbaresponse_render(lwres_context_t *ctx, lwres_gnbaresponse_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+
+lwres_result_t
+lwres_gnbarequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt, lwres_gnbarequest_t **structp);
+
+lwres_result_t
+lwres_gnbaresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt,
+ lwres_gnbaresponse_t **structp);
+
+void
+lwres_gnbarequest_free(lwres_context_t *ctx, lwres_gnbarequest_t **structp);
+/*
+ * Frees any dynamically allocated memory for this structure.
+ *
+ * Requires:
+ *
+ * ctx != NULL, and be a context returned via lwres_contextcreate().
+ *
+ * structp != NULL && *structp != NULL.
+ *
+ * Ensures:
+ *
+ * *structp == NULL.
+ *
+ * All memory allocated by this structure will be returned to the
+ * system via the context's free function.
+ */
+
+void
+lwres_gnbaresponse_free(lwres_context_t *ctx, lwres_gnbaresponse_t **structp);
+/*
+ * Frees any dynamically allocated memory for this structure.
+ *
+ * Requires:
+ *
+ * ctx != NULL, and be a context returned via lwres_contextcreate().
+ *
+ * structp != NULL && *structp != NULL.
+ *
+ * Ensures:
+ *
+ * *structp == NULL.
+ *
+ * All memory allocated by this structure will be returned to the
+ * system via the context's free function.
+ */
+
+lwres_result_t
+lwres_grbnrequest_render(lwres_context_t *ctx, lwres_grbnrequest_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+
+lwres_result_t
+lwres_grbnresponse_render(lwres_context_t *ctx, lwres_grbnresponse_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+
+lwres_result_t
+lwres_grbnrequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt, lwres_grbnrequest_t **structp);
+
+lwres_result_t
+lwres_grbnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt,
+ lwres_grbnresponse_t **structp);
+
+void
+lwres_grbnrequest_free(lwres_context_t *ctx, lwres_grbnrequest_t **structp);
+/*
+ * Frees any dynamically allocated memory for this structure.
+ *
+ * Requires:
+ *
+ * ctx != NULL, and be a context returned via lwres_contextcreate().
+ *
+ * structp != NULL && *structp != NULL.
+ *
+ * Ensures:
+ *
+ * *structp == NULL.
+ *
+ * All memory allocated by this structure will be returned to the
+ * system via the context's free function.
+ */
+
+void
+lwres_grbnresponse_free(lwres_context_t *ctx, lwres_grbnresponse_t **structp);
+/*
+ * Frees any dynamically allocated memory for this structure.
+ *
+ * Requires:
+ *
+ * ctx != NULL, and be a context returned via lwres_contextcreate().
+ *
+ * structp != NULL && *structp != NULL.
+ *
+ * Ensures:
+ *
+ * *structp == NULL.
+ *
+ * All memory allocated by this structure will be returned to the
+ * system via the context's free function.
+ */
+
+lwres_result_t
+lwres_nooprequest_render(lwres_context_t *ctx, lwres_nooprequest_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+/*
+ * Allocate space and render into wire format a noop request packet.
+ *
+ * Requires:
+ *
+ * ctx != NULL, and be a context returned via lwres_contextcreate().
+ *
+ * b != NULL, and points to a lwres_buffer_t. The contents of the
+ * buffer structure will be initialized to contain the wire-format
+ * noop request packet.
+ *
+ * Caller needs to fill in parts of "pkt" before calling:
+ * serial, maxrecv, result.
+ *
+ * Returns:
+ *
+ * Returns 0 on success, non-zero on failure.
+ *
+ * On successful return, *b will contain data about the wire-format
+ * packet. It can be transmitted in any way, including lwres_sendblock().
+ */
+
+lwres_result_t
+lwres_noopresponse_render(lwres_context_t *ctx, lwres_noopresponse_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+
+lwres_result_t
+lwres_nooprequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt, lwres_nooprequest_t **structp);
+/*
+ * Parse a noop request. Note that to get here, the lwpacket must have
+ * already been parsed and removed by the caller, otherwise it would be
+ * pretty hard for it to know this is the right function to call.
+ *
+ * The function verifies bits of the header, but does not modify it.
+ */
+
+lwres_result_t
+lwres_noopresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt,
+ lwres_noopresponse_t **structp);
+
+void
+lwres_nooprequest_free(lwres_context_t *ctx, lwres_nooprequest_t **structp);
+
+void
+lwres_noopresponse_free(lwres_context_t *ctx, lwres_noopresponse_t **structp);
+
+/*
+ * Frees any dynamically allocated memory for this structure.
+ *
+ * Requires:
+ *
+ * ctx != NULL, and be a context returned via lwres_contextcreate().
+ *
+ * structp != NULL && *structp != NULL.
+ *
+ * Ensures:
+ *
+ * *structp == NULL.
+ *
+ * All memory allocated by this structure will be returned to the
+ * system via the context's free function.
+ */
+
+lwres_result_t
+lwres_conf_parse(lwres_context_t *ctx, const char *filename);
+/*
+ * parses a resolv.conf-format file and stores the results in the structure
+ * pointed to by *ctx.
+ *
+ * Requires:
+ * ctx != NULL
+ * filename != NULL && strlen(filename) > 0
+ *
+ * Returns:
+ * LWRES_R_SUCCESS on a successful parse.
+ * Anything else on error, although the structure may be partially filled
+ * in.
+ */
+
+lwres_result_t
+lwres_conf_print(lwres_context_t *ctx, FILE *fp);
+/*
+ * Prints a resolv.conf-format of confdata output to fp.
+ *
+ * Requires:
+ * ctx != NULL
+ */
+
+void
+lwres_conf_init(lwres_context_t *ctx);
+/*
+ * sets all internal fields to a default state. Used to initialize a new
+ * lwres_conf_t structure (not reset a used on).
+ *
+ * Requires:
+ * ctx != NULL
+ */
+
+void
+lwres_conf_clear(lwres_context_t *ctx);
+/*
+ * frees all internally allocated memory in confdata. Uses the memory
+ * routines supplied by ctx.
+ *
+ * Requires:
+ * ctx != NULL
+ */
+
+lwres_conf_t *
+lwres_conf_get(lwres_context_t *ctx);
+/*
+ * returns a pointer to the current config structure.
+ * Be extremely cautions in modifying the contents of this structure; it
+ * needs an API to return the various bits of data, walk lists, etc.
+ *
+ * Requires:
+ * ctx != NULL
+ */
+
+/*
+ * Helper functions
+ */
+
+lwres_result_t
+lwres_data_parse(lwres_buffer_t *b, unsigned char **p, lwres_uint16_t *len);
+
+lwres_result_t
+lwres_string_parse(lwres_buffer_t *b, char **c, lwres_uint16_t *len);
+
+lwres_result_t
+lwres_addr_parse(lwres_buffer_t *b, lwres_addr_t *addr);
+
+lwres_result_t
+lwres_getaddrsbyname(lwres_context_t *ctx, const char *name,
+ lwres_uint32_t addrtypes, lwres_gabnresponse_t **structp);
+
+lwres_result_t
+lwres_getnamebyaddr(lwres_context_t *ctx, lwres_uint32_t addrtype,
+ lwres_uint16_t addrlen, const unsigned char *addr,
+ lwres_gnbaresponse_t **structp);
+
+lwres_result_t
+lwres_getrdatabyname(lwres_context_t *ctx, const char *name,
+ lwres_uint16_t rdclass, lwres_uint16_t rdtype,
+ lwres_uint32_t flags, lwres_grbnresponse_t **structp);
+
+lwres_result_t
+lwres_getaddrsbyname_setup(lwres_context_t *ctx, const char *name,
+ lwres_uint32_t addrtypes, lwres_gabnresponse_t **structp);
+
+
+
+LWRES_LANG_ENDDECLS
+
+#endif /* LWRES_LWRES_H */
diff --git a/lib/liblwres/include/lwres/netdb.h b/lib/liblwres/include/lwres/netdb.h
new file mode 100644
index 000000000..2391d31fb
--- /dev/null
+++ b/lib/liblwres/include/lwres/netdb.h
@@ -0,0 +1,522 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: netdb.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_NETDB_H
+#define LWRES_NETDB_H 1
+
+#include <stddef.h> /* Required on FreeBSD (and others?) for size_t. */
+#include <netdb.h> /* Contractual provision. */
+
+#include <lwres/lang.h>
+
+/*
+ * Define if <netdb.h> does not declare struct addrinfo.
+ */
+#undef ISC_LWRES_NEEDADDRINFO
+
+#ifdef ISC_LWRES_NEEDADDRINFO
+struct addrinfo {
+ int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
+ int ai_family; /* PF_xxx */
+ int ai_socktype; /* SOCK_xxx */
+ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+ size_t ai_addrlen; /* Length of ai_addr */
+ char *ai_canonname; /* Canonical name for hostname */
+ struct sockaddr *ai_addr; /* Binary address */
+ struct addrinfo *ai_next; /* Next structure in linked list */
+};
+#endif
+
+/*
+ * Undefine all #defines we are interested in as <netdb.h> may or may not have
+ * defined them.
+ */
+
+/*
+ * Error return codes from gethostbyname() and gethostbyaddr()
+ * (left in extern int h_errno).
+ */
+
+#undef NETDB_INTERNAL
+#undef NETDB_SUCCESS
+#undef HOST_NOT_FOUND
+#undef TRY_AGAIN
+#undef NO_RECOVERY
+#undef NO_DATA
+#undef NO_ADDRESS
+
+#define NETDB_INTERNAL -1 /* see errno */
+#define NETDB_SUCCESS 0 /* no problem */
+#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */
+#define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */
+#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
+#define NO_DATA 4 /* Valid name, no data record of requested type */
+#define NO_ADDRESS NO_DATA /* no address, look for MX record */
+
+/*
+ * Error return codes from getaddrinfo()
+ */
+
+#undef EAI_ADDRFAMILY
+#undef EAI_AGAIN
+#undef EAI_BADFLAGS
+#undef EAI_FAIL
+#undef EAI_FAMILY
+#undef EAI_MEMORY
+#undef EAI_NODATA
+#undef EAI_NONAME
+#undef EAI_SERVICE
+#undef EAI_SOCKTYPE
+#undef EAI_SYSTEM
+#undef EAI_BADHINTS
+#undef EAI_PROTOCOL
+#undef EAI_MAX
+
+#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */
+#define EAI_AGAIN 2 /* temporary failure in name resolution */
+#define EAI_BADFLAGS 3 /* invalid value for ai_flags */
+#define EAI_FAIL 4 /* non-recoverable failure in name resolution */
+#define EAI_FAMILY 5 /* ai_family not supported */
+#define EAI_MEMORY 6 /* memory allocation failure */
+#define EAI_NODATA 7 /* no address associated with hostname */
+#define EAI_NONAME 8 /* hostname nor servname provided, or not known */
+#define EAI_SERVICE 9 /* servname not supported for ai_socktype */
+#define EAI_SOCKTYPE 10 /* ai_socktype not supported */
+#define EAI_SYSTEM 11 /* system error returned in errno */
+#define EAI_BADHINTS 12
+#define EAI_PROTOCOL 13
+#define EAI_MAX 14
+
+/*
+ * Flag values for getaddrinfo()
+ */
+#undef AI_PASSIVE
+#undef AI_CANONNAME
+#undef AI_NUMERICHOST
+
+#define AI_PASSIVE 0x00000001
+#define AI_CANONNAME 0x00000002
+#define AI_NUMERICHOST 0x00000004
+
+/*
+ * Flag values for getipnodebyname()
+ */
+#undef AI_V4MAPPED
+#undef AI_ALL
+#undef AI_ADDRCONFIG
+#undef AI_DEFAULT
+
+#define AI_V4MAPPED 0x00000008
+#define AI_ALL 0x00000010
+#define AI_ADDRCONFIG 0x00000020
+#define AI_DEFAULT (AI_V4MAPPED|AI_ADDRCONFIG)
+
+/*
+ * Constants for lwres_getnameinfo()
+ */
+#undef NI_MAXHOST
+#undef NI_MAXSERV
+
+#define NI_MAXHOST 1025
+#define NI_MAXSERV 32
+
+/*
+ * Flag values for lwres_getnameinfo()
+ */
+#undef NI_NOFQDN
+#undef NI_NUMERICHOST
+#undef NI_NAMEREQD
+#undef NI_NUMERICSERV
+#undef NI_DGRAM
+#undef NI_NUMERICSCOPE
+
+#define NI_NOFQDN 0x00000001
+#define NI_NUMERICHOST 0x00000002
+#define NI_NAMEREQD 0x00000004
+#define NI_NUMERICSERV 0x00000008
+#define NI_DGRAM 0x00000010
+#define NI_NUMERICSCOPE 0x00000020 /*2553bis-00*/
+
+/*
+ * Define if <netdb.h> does not declare struct rrsetinfo.
+ */
+#define ISC_LWRES_NEEDRRSETINFO 1
+
+#ifdef ISC_LWRES_NEEDRRSETINFO
+/*
+ * Structures for getrrsetbyname()
+ */
+struct rdatainfo {
+ unsigned int rdi_length;
+ unsigned char *rdi_data;
+};
+
+struct rrsetinfo {
+ unsigned int rri_flags;
+ int rri_rdclass;
+ int rri_rdtype;
+ unsigned int rri_ttl;
+ unsigned int rri_nrdatas;
+ unsigned int rri_nsigs;
+ char *rri_name;
+ struct rdatainfo *rri_rdatas;
+ struct rdatainfo *rri_sigs;
+};
+
+/*
+ * Flags for getrrsetbyname()
+ */
+#define RRSET_VALIDATED 0x00000001
+ /* Set was dnssec validated */
+
+/*
+ * Return codes for getrrsetbyname()
+ */
+#define ERRSET_SUCCESS 0
+#define ERRSET_NOMEMORY 1
+#define ERRSET_FAIL 2
+#define ERRSET_INVAL 3
+#define ERRSET_NONAME 4
+#define ERRSET_NODATA 5
+#define ERRSET_RETRY 6
+#endif
+
+/*
+ * Define to map into lwres_ namespace.
+ */
+
+#define LWRES_NAMESPACE
+
+#ifdef LWRES_NAMESPACE
+
+/*
+ * Use our versions not the ones from the C library.
+ */
+
+#ifdef getnameinfo
+#undef getnameinfo
+#endif
+#define getnameinfo lwres_getnameinfo
+
+#ifdef getaddrinfo
+#undef getaddrinfo
+#endif
+#define getaddrinfo lwres_getaddrinfo
+
+#ifdef freeaddrinfo
+#undef freeaddrinfo
+#endif
+#define freeaddrinfo lwres_freeaddrinfo
+
+#ifdef gai_strerror
+#undef gai_strerror
+#endif
+#define gai_strerror lwres_gai_strerror
+
+#ifdef herror
+#undef herror
+#endif
+#define herror lwres_herror
+
+#ifdef hstrerror
+#undef hstrerror
+#endif
+#define hstrerror lwres_hstrerror
+
+#ifdef getipnodebyname
+#undef getipnodebyname
+#endif
+#define getipnodebyname lwres_getipnodebyname
+
+#ifdef getipnodebyaddr
+#undef getipnodebyaddr
+#endif
+#define getipnodebyaddr lwres_getipnodebyaddr
+
+#ifdef freehostent
+#undef freehostent
+#endif
+#define freehostent lwres_freehostent
+
+#ifdef gethostbyname
+#undef gethostbyname
+#endif
+#define gethostbyname lwres_gethostbyname
+
+#ifdef gethostbyname2
+#undef gethostbyname2
+#endif
+#define gethostbyname2 lwres_gethostbyname2
+
+#ifdef gethostbyaddr
+#undef gethostbyaddr
+#endif
+#define gethostbyaddr lwres_gethostbyaddr
+
+#ifdef gethostent
+#undef gethostent
+#endif
+#define gethostent lwres_gethostent
+
+#ifdef sethostent
+#undef sethostent
+#endif
+#define sethostent lwres_sethostent
+
+#ifdef endhostent
+#undef endhostent
+#endif
+#define endhostent lwres_endhostent
+
+/* #define sethostfile lwres_sethostfile */
+
+#ifdef gethostbyname_r
+#undef gethostbyname_r
+#endif
+#define gethostbyname_r lwres_gethostbyname_r
+
+#ifdef gethostbyaddr_r
+#undef gethostbyaddr_r
+#endif
+#define gethostbyaddr_r lwres_gethostbyaddr_r
+
+#ifdef gethostent_r
+#undef gethostent_r
+#endif
+#define gethostent_r lwres_gethostent_r
+
+#ifdef sethostent_r
+#undef sethostent_r
+#endif
+#define sethostent_r lwres_sethostent_r
+
+#ifdef endhostent_r
+#undef endhostent_r
+#endif
+#define endhostent_r lwres_endhostent_r
+
+#ifdef getrrsetbyname
+#undef getrrsetbyname
+#endif
+#define getrrsetbyname lwres_getrrsetbyname
+
+#ifdef freerrset
+#undef freerrset
+#endif
+#define freerrset lwres_freerrset
+
+#ifdef notyet
+#define getservbyname lwres_getservbyname
+#define getservbyport lwres_getservbyport
+#define getservent lwres_getservent
+#define setservent lwres_setservent
+#define endservent lwres_endservent
+
+#define getservbyname_r lwres_getservbyname_r
+#define getservbyport_r lwres_getservbyport_r
+#define getservent_r lwres_getservent_r
+#define setservent_r lwres_setservent_r
+#define endservent_r lwres_endservent_r
+
+#define getprotobyname lwres_getprotobyname
+#define getprotobynumber lwres_getprotobynumber
+#define getprotoent lwres_getprotoent
+#define setprotoent lwres_setprotoent
+#define endprotoent lwres_endprotoent
+
+#define getprotobyname_r lwres_getprotobyname_r
+#define getprotobynumber_r lwres_getprotobynumber_r
+#define getprotoent_r lwres_getprotoent_r
+#define setprotoent_r lwres_setprotoent_r
+#define endprotoent_r lwres_endprotoent_r
+
+#ifdef getnetbyname
+#undef getnetbyname
+#endif
+#define getnetbyname lwres_getnetbyname
+
+#ifdef getnetbyaddr
+#undef getnetbyaddr
+#endif
+#define getnetbyaddr lwres_getnetbyaddr
+
+#ifdef getnetent
+#undef getnetent
+#endif
+#define getnetent lwres_getnetent
+
+#ifdef setnetent
+#undef setnetent
+#endif
+#define setnetent lwres_setnetent
+
+#ifdef endnetent
+#undef endnetent
+#endif
+#define endnetent lwres_endnetent
+
+
+#ifdef getnetbyname_r
+#undef getnetbyname_r
+#endif
+#define getnetbyname_r lwres_getnetbyname_r
+
+#ifdef getnetbyaddr_r
+#undef getnetbyaddr_r
+#endif
+#define getnetbyaddr_r lwres_getnetbyaddr_r
+
+#ifdef getnetent_r
+#undef getnetent_r
+#endif
+#define getnetent_r lwres_getnetent_r
+
+#ifdef setnetent_r
+#undef setnetent_r
+#endif
+#define setnetent_r lwres_setnetent_r
+
+#ifdef endnetent_r
+#undef endnetent_r
+#endif
+#define endnetent_r lwres_endnetent_r
+#endif /* notyet */
+
+#ifdef h_errno
+#undef h_errno
+#endif
+#define h_errno lwres_h_errno
+
+#endif /* LWRES_NAMESPACE */
+
+LWRES_LANG_BEGINDECLS
+
+extern int lwres_h_errno;
+
+int lwres_getaddrinfo(const char *, const char *,
+ const struct addrinfo *, struct addrinfo **);
+int lwres_getnameinfo(const struct sockaddr *, size_t, char *,
+ size_t, char *, size_t, int);
+void lwres_freeaddrinfo(struct addrinfo *);
+char *lwres_gai_strerror(int);
+
+struct hostent *lwres_gethostbyaddr(const char *, int, int);
+struct hostent *lwres_gethostbyname(const char *);
+struct hostent *lwres_gethostbyname2(const char *, int);
+struct hostent *lwres_gethostent(void);
+struct hostent *lwres_getipnodebyname(const char *, int, int, int *);
+struct hostent *lwres_getipnodebyaddr(const void *, size_t, int, int *);
+void lwres_endhostent(void);
+void lwres_sethostent(int);
+/* void lwres_sethostfile(const char *); */
+void lwres_freehostent(struct hostent *);
+
+int lwres_getrrsetbyname(const char *, unsigned int, unsigned int,
+ unsigned int, struct rrsetinfo **);
+int lwres_getrrsetbyname_all(const char *, unsigned int,
+ unsigned int,
+ unsigned int, struct rrsetinfo **);
+void lwres_freerrset(struct rrsetinfo *);
+
+#ifdef notyet
+struct netent *lwres_getnetbyaddr(unsigned long, int);
+struct netent *lwres_getnetbyname(const char *);
+struct netent *lwres_getnetent(void);
+void lwres_endnetent(void);
+void lwres_setnetent(int);
+
+struct protoent *lwres_getprotobyname(const char *);
+struct protoent *lwres_getprotobynumber(int);
+struct protoent *lwres_getprotoent(void);
+void lwres_endprotoent(void);
+void lwres_setprotoent(int);
+
+struct servent *lwres_getservbyname(const char *, const char *);
+struct servent *lwres_getservbyport(int, const char *);
+struct servent *lwres_getservent(void);
+void lwres_endservent(void);
+void lwres_setservent(int);
+#endif /* notyet */
+
+void lwres_herror(const char *);
+const char *lwres_hstrerror(int);
+
+
+struct hostent *lwres_gethostbyaddr_r(const char *, int, int, struct hostent *,
+ char *, int, int *);
+struct hostent *lwres_gethostbyname_r(const char *, struct hostent *,
+ char *, int, int *);
+struct hostent *lwres_gethostent_r(struct hostent *, char *, int, int *);
+void lwres_sethostent_r(int);
+void lwres_endhostent_r(void);
+
+#ifdef notyet
+struct netent *lwres_getnetbyname_r(const char *, struct netent *,
+ char *, int);
+struct netent *lwres_getnetbyaddr_r(long, int, struct netent *,
+ char *, int);
+struct netent *lwres_getnetent_r(struct netent *, char *, int);
+void lwres_setnetent_r(int);
+void lwres_endnetent_r(void);
+
+struct protoent *lwres_getprotobyname_r(const char *,
+ struct protoent *, char *, int);
+struct protoent *lwres_getprotobynumber_r(int,
+ struct protoent *, char *, int);
+struct protoent *lwres_getprotoent_r(struct protoent *, char *, int);
+void lwres_setprotoent_r(int);
+void lwres_endprotoent_r(void);
+
+struct servent *lwres_getservbyname_r(const char *name, const char *,
+ struct servent *, char *, int);
+struct servent *lwres_getservbyport_r(int port, const char *,
+ struct servent *, char *, int);
+struct servent *lwres_getservent_r(struct servent *, char *, int);
+void lwres_setservent_r(int);
+void lwres_endservent_r(void);
+#endif /* notyet */
+
+LWRES_LANG_ENDDECLS
+
+#ifdef notyet
+/* This is nec'y to make this include file properly replace the sun version. */
+#ifdef sun
+#ifdef __GNU_LIBRARY__
+#include <rpc/netdb.h> /* Required. */
+#else /* !__GNU_LIBRARY__ */
+struct rpcent {
+ char *r_name; /* name of server for this rpc program */
+ char **r_aliases; /* alias list */
+ int r_number; /* rpc program number */
+};
+struct rpcent *lwres_getrpcbyname();
+struct rpcent *lwres_getrpcbynumber(),
+struct rpcent *lwres_getrpcent();
+#endif /* __GNU_LIBRARY__ */
+#endif /* sun */
+#endif /* notyet */
+
+/*
+ * Tell Emacs to use C mode on this file.
+ * Local variables:
+ * mode: c
+ * End:
+ */
+
+#endif /* LWRES_NETDB_H */
diff --git a/lib/liblwres/include/lwres/netdb.h.in b/lib/liblwres/include/lwres/netdb.h.in
new file mode 100644
index 000000000..75446e8f8
--- /dev/null
+++ b/lib/liblwres/include/lwres/netdb.h.in
@@ -0,0 +1,518 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: netdb.h.in,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_NETDB_H
+#define LWRES_NETDB_H 1
+
+#include <stddef.h> /* Required on FreeBSD (and others?) for size_t. */
+#include <netdb.h> /* Contractual provision. */
+
+#include <lwres/lang.h>
+
+/*
+ * Define if <netdb.h> does not declare struct addrinfo.
+ */
+@ISC_LWRES_NEEDADDRINFO@
+
+#ifdef ISC_LWRES_NEEDADDRINFO
+struct addrinfo {
+ int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
+ int ai_family; /* PF_xxx */
+ int ai_socktype; /* SOCK_xxx */
+ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+ size_t ai_addrlen; /* Length of ai_addr */
+ char *ai_canonname; /* Canonical name for hostname */
+ struct sockaddr *ai_addr; /* Binary address */
+ struct addrinfo *ai_next; /* Next structure in linked list */
+};
+#endif
+
+/*
+ * Undefine all #defines we are interested in as <netdb.h> may or may not have
+ * defined them.
+ */
+
+/*
+ * Error return codes from gethostbyname() and gethostbyaddr()
+ * (left in extern int h_errno).
+ */
+
+#undef NETDB_INTERNAL
+#undef NETDB_SUCCESS
+#undef HOST_NOT_FOUND
+#undef TRY_AGAIN
+#undef NO_RECOVERY
+#undef NO_DATA
+#undef NO_ADDRESS
+
+#define NETDB_INTERNAL -1 /* see errno */
+#define NETDB_SUCCESS 0 /* no problem */
+#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */
+#define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */
+#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
+#define NO_DATA 4 /* Valid name, no data record of requested type */
+#define NO_ADDRESS NO_DATA /* no address, look for MX record */
+
+/*
+ * Error return codes from getaddrinfo()
+ */
+
+#undef EAI_ADDRFAMILY
+#undef EAI_AGAIN
+#undef EAI_BADFLAGS
+#undef EAI_FAIL
+#undef EAI_FAMILY
+#undef EAI_MEMORY
+#undef EAI_NODATA
+#undef EAI_NONAME
+#undef EAI_SERVICE
+#undef EAI_SOCKTYPE
+#undef EAI_SYSTEM
+#undef EAI_BADHINTS
+#undef EAI_PROTOCOL
+#undef EAI_MAX
+
+#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */
+#define EAI_AGAIN 2 /* temporary failure in name resolution */
+#define EAI_BADFLAGS 3 /* invalid value for ai_flags */
+#define EAI_FAIL 4 /* non-recoverable failure in name resolution */
+#define EAI_FAMILY 5 /* ai_family not supported */
+#define EAI_MEMORY 6 /* memory allocation failure */
+#define EAI_NODATA 7 /* no address associated with hostname */
+#define EAI_NONAME 8 /* hostname nor servname provided, or not known */
+#define EAI_SERVICE 9 /* servname not supported for ai_socktype */
+#define EAI_SOCKTYPE 10 /* ai_socktype not supported */
+#define EAI_SYSTEM 11 /* system error returned in errno */
+#define EAI_BADHINTS 12
+#define EAI_PROTOCOL 13
+#define EAI_MAX 14
+
+/*
+ * Flag values for getaddrinfo()
+ */
+#undef AI_PASSIVE
+#undef AI_CANONNAME
+#undef AI_NUMERICHOST
+
+#define AI_PASSIVE 0x00000001
+#define AI_CANONNAME 0x00000002
+#define AI_NUMERICHOST 0x00000004
+
+/*
+ * Flag values for getipnodebyname()
+ */
+#undef AI_V4MAPPED
+#undef AI_ALL
+#undef AI_ADDRCONFIG
+#undef AI_DEFAULT
+
+#define AI_V4MAPPED 0x00000008
+#define AI_ALL 0x00000010
+#define AI_ADDRCONFIG 0x00000020
+#define AI_DEFAULT (AI_V4MAPPED|AI_ADDRCONFIG)
+
+/*
+ * Constants for lwres_getnameinfo()
+ */
+#undef NI_MAXHOST
+#undef NI_MAXSERV
+
+#define NI_MAXHOST 1025
+#define NI_MAXSERV 32
+
+/*
+ * Flag values for lwres_getnameinfo()
+ */
+#undef NI_NOFQDN
+#undef NI_NUMERICHOST
+#undef NI_NAMEREQD
+#undef NI_NUMERICSERV
+#undef NI_DGRAM
+#undef NI_NUMERICSCOPE
+
+#define NI_NOFQDN 0x00000001
+#define NI_NUMERICHOST 0x00000002
+#define NI_NAMEREQD 0x00000004
+#define NI_NUMERICSERV 0x00000008
+#define NI_DGRAM 0x00000010
+#define NI_NUMERICSCOPE 0x00000020 /*2553bis-00*/
+
+/*
+ * Define if <netdb.h> does not declare struct rrsetinfo.
+ */
+@ISC_LWRES_NEEDRRSETINFO@
+
+#ifdef ISC_LWRES_NEEDRRSETINFO
+/*
+ * Structures for getrrsetbyname()
+ */
+struct rdatainfo {
+ unsigned int rdi_length;
+ unsigned char *rdi_data;
+};
+
+struct rrsetinfo {
+ unsigned int rri_flags;
+ int rri_rdclass;
+ int rri_rdtype;
+ unsigned int rri_ttl;
+ unsigned int rri_nrdatas;
+ unsigned int rri_nsigs;
+ char *rri_name;
+ struct rdatainfo *rri_rdatas;
+ struct rdatainfo *rri_sigs;
+};
+
+/*
+ * Flags for getrrsetbyname()
+ */
+#define RRSET_VALIDATED 0x00000001
+ /* Set was dnssec validated */
+
+/*
+ * Return codes for getrrsetbyname()
+ */
+#define ERRSET_SUCCESS 0
+#define ERRSET_NOMEMORY 1
+#define ERRSET_FAIL 2
+#define ERRSET_INVAL 3
+#define ERRSET_NONAME 4
+#define ERRSET_NODATA 5
+#endif
+
+/*
+ * Define to map into lwres_ namespace.
+ */
+
+#define LWRES_NAMESPACE
+
+#ifdef LWRES_NAMESPACE
+
+/*
+ * Use our versions not the ones from the C library.
+ */
+
+#ifdef getnameinfo
+#undef getnameinfo
+#endif
+#define getnameinfo lwres_getnameinfo
+
+#ifdef getaddrinfo
+#undef getaddrinfo
+#endif
+#define getaddrinfo lwres_getaddrinfo
+
+#ifdef freeaddrinfo
+#undef freeaddrinfo
+#endif
+#define freeaddrinfo lwres_freeaddrinfo
+
+#ifdef gai_strerror
+#undef gai_strerror
+#endif
+#define gai_strerror lwres_gai_strerror
+
+#ifdef herror
+#undef herror
+#endif
+#define herror lwres_herror
+
+#ifdef hstrerror
+#undef hstrerror
+#endif
+#define hstrerror lwres_hstrerror
+
+#ifdef getipnodebyname
+#undef getipnodebyname
+#endif
+#define getipnodebyname lwres_getipnodebyname
+
+#ifdef getipnodebyaddr
+#undef getipnodebyaddr
+#endif
+#define getipnodebyaddr lwres_getipnodebyaddr
+
+#ifdef freehostent
+#undef freehostent
+#endif
+#define freehostent lwres_freehostent
+
+#ifdef gethostbyname
+#undef gethostbyname
+#endif
+#define gethostbyname lwres_gethostbyname
+
+#ifdef gethostbyname2
+#undef gethostbyname2
+#endif
+#define gethostbyname2 lwres_gethostbyname2
+
+#ifdef gethostbyaddr
+#undef gethostbyaddr
+#endif
+#define gethostbyaddr lwres_gethostbyaddr
+
+#ifdef gethostent
+#undef gethostent
+#endif
+#define gethostent lwres_gethostent
+
+#ifdef sethostent
+#undef sethostent
+#endif
+#define sethostent lwres_sethostent
+
+#ifdef endhostent
+#undef endhostent
+#endif
+#define endhostent lwres_endhostent
+
+/* #define sethostfile lwres_sethostfile */
+
+#ifdef gethostbyname_r
+#undef gethostbyname_r
+#endif
+#define gethostbyname_r lwres_gethostbyname_r
+
+#ifdef gethostbyaddr_r
+#undef gethostbyaddr_r
+#endif
+#define gethostbyaddr_r lwres_gethostbyaddr_r
+
+#ifdef gethostent_r
+#undef gethostent_r
+#endif
+#define gethostent_r lwres_gethostent_r
+
+#ifdef sethostent_r
+#undef sethostent_r
+#endif
+#define sethostent_r lwres_sethostent_r
+
+#ifdef endhostent_r
+#undef endhostent_r
+#endif
+#define endhostent_r lwres_endhostent_r
+
+#ifdef getrrsetbyname
+#undef getrrsetbyname
+#endif
+#define getrrsetbyname lwres_getrrsetbyname
+
+#ifdef freerrset
+#undef freerrset
+#endif
+#define freerrset lwres_freerrset
+
+#ifdef notyet
+#define getservbyname lwres_getservbyname
+#define getservbyport lwres_getservbyport
+#define getservent lwres_getservent
+#define setservent lwres_setservent
+#define endservent lwres_endservent
+
+#define getservbyname_r lwres_getservbyname_r
+#define getservbyport_r lwres_getservbyport_r
+#define getservent_r lwres_getservent_r
+#define setservent_r lwres_setservent_r
+#define endservent_r lwres_endservent_r
+
+#define getprotobyname lwres_getprotobyname
+#define getprotobynumber lwres_getprotobynumber
+#define getprotoent lwres_getprotoent
+#define setprotoent lwres_setprotoent
+#define endprotoent lwres_endprotoent
+
+#define getprotobyname_r lwres_getprotobyname_r
+#define getprotobynumber_r lwres_getprotobynumber_r
+#define getprotoent_r lwres_getprotoent_r
+#define setprotoent_r lwres_setprotoent_r
+#define endprotoent_r lwres_endprotoent_r
+
+#ifdef getnetbyname
+#undef getnetbyname
+#endif
+#define getnetbyname lwres_getnetbyname
+
+#ifdef getnetbyaddr
+#undef getnetbyaddr
+#endif
+#define getnetbyaddr lwres_getnetbyaddr
+
+#ifdef getnetent
+#undef getnetent
+#endif
+#define getnetent lwres_getnetent
+
+#ifdef setnetent
+#undef setnetent
+#endif
+#define setnetent lwres_setnetent
+
+#ifdef endnetent
+#undef endnetent
+#endif
+#define endnetent lwres_endnetent
+
+
+#ifdef getnetbyname_r
+#undef getnetbyname_r
+#endif
+#define getnetbyname_r lwres_getnetbyname_r
+
+#ifdef getnetbyaddr_r
+#undef getnetbyaddr_r
+#endif
+#define getnetbyaddr_r lwres_getnetbyaddr_r
+
+#ifdef getnetent_r
+#undef getnetent_r
+#endif
+#define getnetent_r lwres_getnetent_r
+
+#ifdef setnetent_r
+#undef setnetent_r
+#endif
+#define setnetent_r lwres_setnetent_r
+
+#ifdef endnetent_r
+#undef endnetent_r
+#endif
+#define endnetent_r lwres_endnetent_r
+#endif /* notyet */
+
+#ifdef h_errno
+#undef h_errno
+#endif
+#define h_errno lwres_h_errno
+
+#endif /* LWRES_NAMESPACE */
+
+LWRES_LANG_BEGINDECLS
+
+extern int lwres_h_errno;
+
+int lwres_getaddrinfo(const char *, const char *,
+ const struct addrinfo *, struct addrinfo **);
+int lwres_getnameinfo(const struct sockaddr *, size_t, char *,
+ size_t, char *, size_t, int);
+void lwres_freeaddrinfo(struct addrinfo *);
+char *lwres_gai_strerror(int);
+
+struct hostent *lwres_gethostbyaddr(const char *, int, int);
+struct hostent *lwres_gethostbyname(const char *);
+struct hostent *lwres_gethostbyname2(const char *, int);
+struct hostent *lwres_gethostent(void);
+struct hostent *lwres_getipnodebyname(const char *, int, int, int *);
+struct hostent *lwres_getipnodebyaddr(const void *, size_t, int, int *);
+void lwres_endhostent(void);
+void lwres_sethostent(int);
+/* void lwres_sethostfile(const char *); */
+void lwres_freehostent(struct hostent *);
+
+int lwres_getrrsetbyname(const char *, unsigned int, unsigned int,
+ unsigned int, struct rrsetinfo **);
+void lwres_freerrset(struct rrsetinfo *);
+
+#ifdef notyet
+struct netent *lwres_getnetbyaddr(unsigned long, int);
+struct netent *lwres_getnetbyname(const char *);
+struct netent *lwres_getnetent(void);
+void lwres_endnetent(void);
+void lwres_setnetent(int);
+
+struct protoent *lwres_getprotobyname(const char *);
+struct protoent *lwres_getprotobynumber(int);
+struct protoent *lwres_getprotoent(void);
+void lwres_endprotoent(void);
+void lwres_setprotoent(int);
+
+struct servent *lwres_getservbyname(const char *, const char *);
+struct servent *lwres_getservbyport(int, const char *);
+struct servent *lwres_getservent(void);
+void lwres_endservent(void);
+void lwres_setservent(int);
+#endif /* notyet */
+
+void lwres_herror(const char *);
+const char *lwres_hstrerror(int);
+
+
+struct hostent *lwres_gethostbyaddr_r(const char *, int, int, struct hostent *,
+ char *, int, int *);
+struct hostent *lwres_gethostbyname_r(const char *, struct hostent *,
+ char *, int, int *);
+struct hostent *lwres_gethostent_r(struct hostent *, char *, int, int *);
+void lwres_sethostent_r(int);
+void lwres_endhostent_r(void);
+
+#ifdef notyet
+struct netent *lwres_getnetbyname_r(const char *, struct netent *,
+ char *, int);
+struct netent *lwres_getnetbyaddr_r(long, int, struct netent *,
+ char *, int);
+struct netent *lwres_getnetent_r(struct netent *, char *, int);
+void lwres_setnetent_r(int);
+void lwres_endnetent_r(void);
+
+struct protoent *lwres_getprotobyname_r(const char *,
+ struct protoent *, char *, int);
+struct protoent *lwres_getprotobynumber_r(int,
+ struct protoent *, char *, int);
+struct protoent *lwres_getprotoent_r(struct protoent *, char *, int);
+void lwres_setprotoent_r(int);
+void lwres_endprotoent_r(void);
+
+struct servent *lwres_getservbyname_r(const char *name, const char *,
+ struct servent *, char *, int);
+struct servent *lwres_getservbyport_r(int port, const char *,
+ struct servent *, char *, int);
+struct servent *lwres_getservent_r(struct servent *, char *, int);
+void lwres_setservent_r(int);
+void lwres_endservent_r(void);
+#endif /* notyet */
+
+LWRES_LANG_ENDDECLS
+
+#ifdef notyet
+/* This is nec'y to make this include file properly replace the sun version. */
+#ifdef sun
+#ifdef __GNU_LIBRARY__
+#include <rpc/netdb.h> /* Required. */
+#else /* !__GNU_LIBRARY__ */
+struct rpcent {
+ char *r_name; /* name of server for this rpc program */
+ char **r_aliases; /* alias list */
+ int r_number; /* rpc program number */
+};
+struct rpcent *lwres_getrpcbyname();
+struct rpcent *lwres_getrpcbynumber(),
+struct rpcent *lwres_getrpcent();
+#endif /* __GNU_LIBRARY__ */
+#endif /* sun */
+#endif /* notyet */
+
+/*
+ * Tell Emacs to use C mode on this file.
+ * Local variables:
+ * mode: c
+ * End:
+ */
+
+#endif /* LWRES_NETDB_H */
diff --git a/lib/liblwres/include/lwres/platform.h b/lib/liblwres/include/lwres/platform.h
new file mode 100644
index 000000000..af4c615d9
--- /dev/null
+++ b/lib/liblwres/include/lwres/platform.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: platform.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_PLATFORM_H
+#define LWRES_PLATFORM_H 1
+
+/*****
+ ***** Platform-dependent defines.
+ *****/
+
+/***
+ *** Network.
+ ***/
+
+/*
+ * Define if this system needs the <netinet/in6.h> header file for IPv6.
+ */
+#undef LWRES_PLATFORM_NEEDNETINETIN6H
+
+/*
+ * Define if this system needs the <netinet6/in6.h> header file for IPv6.
+ */
+#undef LWRES_PLATFORM_NEEDNETINET6IN6H
+
+/*
+ * If sockaddrs on this system have an sa_len field, LWRES_PLATFORM_HAVESALEN
+ * will be defined.
+ */
+#undef LWRES_PLATFORM_HAVESALEN
+
+/*
+ * If this system has the IPv6 structure definitions, LWRES_PLATFORM_HAVEIPV6
+ * will be defined.
+ */
+#define LWRES_PLATFORM_HAVEIPV6 1
+
+/*
+ * If this system is missing in6addr_any, LWRES_PLATFORM_NEEDIN6ADDRANY will
+ * be defined.
+ */
+#undef LWRES_PLATFORM_NEEDIN6ADDRANY
+
+/*
+ * If this system is missing in6addr_loopback,
+ * LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK will be defined.
+ */
+#undef LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK
+
+/*
+ * If this system has in_addr6, rather than in6_addr,
+ * LWRES_PLATFORM_HAVEINADDR6 will be defined.
+ */
+#undef LWRES_PLATFORM_HAVEINADDR6
+
+/*
+ * Defined if unistd.h does not cause fd_set to be delared.
+ */
+#define LWRES_PLATFORM_NEEDSYSSELECTH 1
+
+/*
+ * Used to control how extern data is linked; needed for Win32 platforms.
+ */
+#undef LWRES_PLATFORM_USEDECLSPEC
+
+#ifndef LWRES_PLATFORM_USEDECLSPEC
+#define LIBLWRES_EXTERNAL_DATA
+#else
+#ifdef LIBLWRES_EXPORTS
+#define LIBLWRES_EXTERNAL_DATA __declspec(dllexport)
+#else
+#define LIBLWRES_EXTERNAL_DATA __declspec(dllimport)
+#endif
+#endif
+
+#endif /* LWRES_PLATFORM_H */
diff --git a/lib/liblwres/include/lwres/platform.h.in b/lib/liblwres/include/lwres/platform.h.in
new file mode 100644
index 000000000..c679d8fae
--- /dev/null
+++ b/lib/liblwres/include/lwres/platform.h.in
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: platform.h.in,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_PLATFORM_H
+#define LWRES_PLATFORM_H 1
+
+/*****
+ ***** Platform-dependent defines.
+ *****/
+
+/***
+ *** Network.
+ ***/
+
+/*
+ * Define if this system needs the <netinet/in6.h> header file for IPv6.
+ */
+@LWRES_PLATFORM_NEEDNETINETIN6H@
+
+/*
+ * Define if this system needs the <netinet6/in6.h> header file for IPv6.
+ */
+@LWRES_PLATFORM_NEEDNETINET6IN6H@
+
+/*
+ * If sockaddrs on this system have an sa_len field, LWRES_PLATFORM_HAVESALEN
+ * will be defined.
+ */
+@LWRES_PLATFORM_HAVESALEN@
+
+/*
+ * If this system has the IPv6 structure definitions, LWRES_PLATFORM_HAVEIPV6
+ * will be defined.
+ */
+@LWRES_PLATFORM_HAVEIPV6@
+
+/*
+ * If this system is missing in6addr_any, LWRES_PLATFORM_NEEDIN6ADDRANY will
+ * be defined.
+ */
+@LWRES_PLATFORM_NEEDIN6ADDRANY@
+
+/*
+ * If this system is missing in6addr_loopback,
+ * LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK will be defined.
+ */
+@LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK@
+
+/*
+ * If this system has in_addr6, rather than in6_addr,
+ * LWRES_PLATFORM_HAVEINADDR6 will be defined.
+ */
+@LWRES_PLATFORM_HAVEINADDR6@
+
+/*
+ * Defined if unistd.h does not cause fd_set to be delared.
+ */
+@LWRES_PLATFORM_NEEDSYSSELECTH@
+
+/*
+ * Used to control how extern data is linked; needed for Win32 platforms.
+ */
+@LWRES_PLATFORM_USEDECLSPEC@
+
+#ifndef LWRES_PLATFORM_USEDECLSPEC
+#define LIBLWRES_EXTERNAL_DATA
+#else
+#ifdef LIBLWRES_EXPORTS
+#define LIBLWRES_EXTERNAL_DATA __declspec(dllexport)
+#else
+#define LIBLWRES_EXTERNAL_DATA __declspec(dllimport)
+#endif
+#endif
+
+#endif /* LWRES_PLATFORM_H */
diff --git a/lib/liblwres/include/lwres/result.h b/lib/liblwres/include/lwres/result.h
new file mode 100644
index 000000000..42e1bccea
--- /dev/null
+++ b/lib/liblwres/include/lwres/result.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: result.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_RESULT_H
+#define LWRES_RESULT_H 1
+
+typedef unsigned int lwres_result_t;
+
+#define LWRES_R_SUCCESS 0
+#define LWRES_R_NOMEMORY 1
+#define LWRES_R_TIMEOUT 2
+#define LWRES_R_NOTFOUND 3
+#define LWRES_R_UNEXPECTEDEND 4 /* unexpected end of input */
+#define LWRES_R_FAILURE 5 /* generic failure */
+#define LWRES_R_IOERROR 6
+#define LWRES_R_NOTIMPLEMENTED 7
+#define LWRES_R_UNEXPECTED 8
+#define LWRES_R_TRAILINGDATA 9
+#define LWRES_R_INCOMPLETE 10
+#define LWRES_R_RETRY 11
+#define LWRES_R_TYPENOTFOUND 12
+#define LWRES_R_TOOLARGE 13
+
+#endif /* LWRES_RESULT_H */
diff --git a/lib/liblwres/lwbuffer.c b/lib/liblwres/lwbuffer.c
new file mode 100644
index 000000000..465ad2569
--- /dev/null
+++ b/lib/liblwres/lwbuffer.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: lwbuffer.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <lwres/lwbuffer.h>
+
+#include "assert_p.h"
+
+void
+lwres_buffer_init(lwres_buffer_t *b, void *base, unsigned int length)
+{
+ /*
+ * Make 'b' refer to the 'length'-byte region starting at base.
+ */
+
+ REQUIRE(b != NULL);
+
+ b->magic = LWRES_BUFFER_MAGIC;
+ b->base = base;
+ b->length = length;
+ b->used = 0;
+ b->current = 0;
+ b->active = 0;
+}
+
+void
+lwres_buffer_invalidate(lwres_buffer_t *b)
+{
+ /*
+ * Make 'b' an invalid buffer.
+ */
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+
+ b->magic = 0;
+ b->base = NULL;
+ b->length = 0;
+ b->used = 0;
+ b->current = 0;
+ b->active = 0;
+}
+
+void
+lwres_buffer_add(lwres_buffer_t *b, unsigned int n)
+{
+ /*
+ * Increase the 'used' region of 'b' by 'n' bytes.
+ */
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+ REQUIRE(b->used + n <= b->length);
+
+ b->used += n;
+}
+
+void
+lwres_buffer_subtract(lwres_buffer_t *b, unsigned int n)
+{
+ /*
+ * Decrease the 'used' region of 'b' by 'n' bytes.
+ */
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+ REQUIRE(b->used >= n);
+
+ b->used -= n;
+ if (b->current > b->used)
+ b->current = b->used;
+ if (b->active > b->used)
+ b->active = b->used;
+}
+
+void
+lwres_buffer_clear(lwres_buffer_t *b)
+{
+ /*
+ * Make the used region empty.
+ */
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+
+ b->used = 0;
+ b->current = 0;
+ b->active = 0;
+}
+
+void
+lwres_buffer_first(lwres_buffer_t *b)
+{
+ /*
+ * Make the consumed region empty.
+ */
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+
+ b->current = 0;
+}
+
+void
+lwres_buffer_forward(lwres_buffer_t *b, unsigned int n)
+{
+ /*
+ * Increase the 'consumed' region of 'b' by 'n' bytes.
+ */
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+ REQUIRE(b->current + n <= b->used);
+
+ b->current += n;
+}
+
+void
+lwres_buffer_back(lwres_buffer_t *b, unsigned int n)
+{
+ /*
+ * Decrease the 'consumed' region of 'b' by 'n' bytes.
+ */
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+ REQUIRE(n <= b->current);
+
+ b->current -= n;
+}
+
+lwres_uint8_t
+lwres_buffer_getuint8(lwres_buffer_t *b)
+{
+ unsigned char *cp;
+ lwres_uint8_t result;
+
+ /*
+ * Read an unsigned 8-bit integer from 'b' and return it.
+ */
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+ REQUIRE(b->used - b->current >= 1);
+
+ cp = b->base;
+ cp += b->current;
+ b->current += 1;
+ result = ((unsigned int)(cp[0]));
+
+ return (result);
+}
+
+void
+lwres_buffer_putuint8(lwres_buffer_t *b, lwres_uint8_t val)
+{
+ unsigned char *cp;
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+ REQUIRE(b->used + 1 <= b->length);
+
+ cp = b->base;
+ cp += b->used;
+ b->used += 1;
+ cp[0] = (val & 0x00ff);
+}
+
+lwres_uint16_t
+lwres_buffer_getuint16(lwres_buffer_t *b)
+{
+ unsigned char *cp;
+ lwres_uint16_t result;
+
+ /*
+ * Read an unsigned 16-bit integer in network byte order from 'b',
+ * convert it to host byte order, and return it.
+ */
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+ REQUIRE(b->used - b->current >= 2);
+
+ cp = b->base;
+ cp += b->current;
+ b->current += 2;
+ result = ((unsigned int)(cp[0])) << 8;
+ result |= ((unsigned int)(cp[1]));
+
+ return (result);
+}
+
+void
+lwres_buffer_putuint16(lwres_buffer_t *b, lwres_uint16_t val)
+{
+ unsigned char *cp;
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+ REQUIRE(b->used + 2 <= b->length);
+
+ cp = b->base;
+ cp += b->used;
+ b->used += 2;
+ cp[0] = (val & 0xff00) >> 8;
+ cp[1] = (val & 0x00ff);
+}
+
+lwres_uint32_t
+lwres_buffer_getuint32(lwres_buffer_t *b)
+{
+ unsigned char *cp;
+ lwres_uint32_t result;
+
+ /*
+ * Read an unsigned 32-bit integer in network byte order from 'b',
+ * convert it to host byte order, and return it.
+ */
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+ REQUIRE(b->used - b->current >= 4);
+
+ cp = b->base;
+ cp += b->current;
+ b->current += 4;
+ result = ((unsigned int)(cp[0])) << 24;
+ result |= ((unsigned int)(cp[1])) << 16;
+ result |= ((unsigned int)(cp[2])) << 8;
+ result |= ((unsigned int)(cp[3]));
+
+ return (result);
+}
+
+void
+lwres_buffer_putuint32(lwres_buffer_t *b, lwres_uint32_t val)
+{
+ unsigned char *cp;
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+ REQUIRE(b->used + 4 <= b->length);
+
+ cp = b->base;
+ cp += b->used;
+ b->used += 4;
+ cp[0] = (unsigned char)((val & 0xff000000) >> 24);
+ cp[1] = (unsigned char)((val & 0x00ff0000) >> 16);
+ cp[2] = (unsigned char)((val & 0x0000ff00) >> 8);
+ cp[3] = (unsigned char)(val & 0x000000ff);
+}
+
+void
+lwres_buffer_putmem(lwres_buffer_t *b, const unsigned char *base,
+ unsigned int length)
+{
+ unsigned char *cp;
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+ REQUIRE(b->used + length <= b->length);
+
+ cp = (unsigned char *)b->base + b->used;
+ memcpy(cp, base, length);
+ b->used += length;
+}
+
+void
+lwres_buffer_getmem(lwres_buffer_t *b, unsigned char *base,
+ unsigned int length)
+{
+ unsigned char *cp;
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+ REQUIRE(b->used - b->current >= length);
+
+ cp = b->base;
+ cp += b->current;
+ b->current += length;
+
+ memcpy(base, cp, length);
+}
diff --git a/lib/liblwres/lwconfig.c b/lib/liblwres/lwconfig.c
new file mode 100644
index 000000000..f1c19b697
--- /dev/null
+++ b/lib/liblwres/lwconfig.c
@@ -0,0 +1,703 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: lwconfig.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+/***
+ *** Module for parsing resolv.conf files.
+ ***
+ *** entry points are:
+ *** lwres_conf_init(lwres_context_t *ctx)
+ *** intializes data structure for subsequent config parsing.
+ ***
+ *** lwres_conf_parse(lwres_context_t *ctx, const char *filename)
+ *** parses a file and fills in the data structure.
+ ***
+ *** lwres_conf_print(lwres_context_t *ctx, FILE *fp)
+ *** prints the config data structure to the FILE.
+ ***
+ *** lwres_conf_clear(lwres_context_t *ctx)
+ *** frees up all the internal memory used by the config data
+ *** structure, returning it to the lwres_context_t.
+ ***
+ ***/
+
+#include <config.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <lwres/lwbuffer.h>
+#include <lwres/lwres.h>
+#include <lwres/net.h>
+#include <lwres/result.h>
+
+#include "assert_p.h"
+#include "context_p.h"
+
+
+#if ! defined(NS_INADDRSZ)
+#define NS_INADDRSZ 4
+#endif
+
+#if ! defined(NS_IN6ADDRSZ)
+#define NS_IN6ADDRSZ 16
+#endif
+
+static lwres_result_t
+lwres_conf_parsenameserver(lwres_context_t *ctx, FILE *fp);
+
+static lwres_result_t
+lwres_conf_parselwserver(lwres_context_t *ctx, FILE *fp);
+
+static lwres_result_t
+lwres_conf_parsedomain(lwres_context_t *ctx, FILE *fp);
+
+static lwres_result_t
+lwres_conf_parsesearch(lwres_context_t *ctx, FILE *fp);
+
+static lwres_result_t
+lwres_conf_parsesortlist(lwres_context_t *ctx, FILE *fp);
+
+static lwres_result_t
+lwres_conf_parseoption(lwres_context_t *ctx, FILE *fp);
+
+static void
+lwres_resetaddr(lwres_addr_t *addr);
+
+static lwres_result_t
+lwres_create_addr(const char *buff, lwres_addr_t *addr, int convert_zero);
+
+static int lwresaddr2af(int lwresaddrtype);
+
+
+static int
+lwresaddr2af(int lwresaddrtype)
+{
+ int af = 0;
+
+ switch (lwresaddrtype) {
+ case LWRES_ADDRTYPE_V4:
+ af = AF_INET;
+ break;
+
+ case LWRES_ADDRTYPE_V6:
+ af = AF_INET6;
+ break;
+ }
+
+ return (af);
+}
+
+
+/*
+ * Eat characters from FP until EOL or EOF. Returns EOF or '\n'
+ */
+static int
+eatline(FILE *fp) {
+ int ch;
+
+ ch = fgetc(fp);
+ while (ch != '\n' && ch != EOF)
+ ch = fgetc(fp);
+
+ return (ch);
+}
+
+
+/*
+ * Eats white space up to next newline or non-whitespace character (of
+ * EOF). Returns the last character read. Comments are considered white
+ * space.
+ */
+static int
+eatwhite(FILE *fp) {
+ int ch;
+
+ ch = fgetc(fp);
+ while (ch != '\n' && ch != EOF && isspace((unsigned char)ch))
+ ch = fgetc(fp);
+
+ if (ch == ';' || ch == '#')
+ ch = eatline(fp);
+
+ return (ch);
+}
+
+
+/*
+ * Skip over any leading whitespace and then read in the next sequence of
+ * non-whitespace characters. In this context newline is not considered
+ * whitespace. Returns EOF on end-of-file, or the character
+ * that caused the reading to stop.
+ */
+static int
+getword(FILE *fp, char *buffer, size_t size) {
+ int ch;
+ char *p = buffer;
+
+ REQUIRE(buffer != NULL);
+ REQUIRE(size > 0);
+
+ *p = '\0';
+
+ ch = eatwhite(fp);
+
+ if (ch == EOF)
+ return (EOF);
+
+ do {
+ *p = '\0';
+
+ if (ch == EOF || isspace((unsigned char)ch))
+ break;
+ else if ((size_t) (p - buffer) == size - 1)
+ return (EOF); /* Not enough space. */
+
+ *p++ = (char)ch;
+ ch = fgetc(fp);
+ } while (1);
+
+ return (ch);
+}
+
+static void
+lwres_resetaddr(lwres_addr_t *addr) {
+ REQUIRE(addr != NULL);
+
+ memset(addr->address, 0, LWRES_ADDR_MAXLEN);
+ addr->family = 0;
+ addr->length = 0;
+}
+
+static char *
+lwres_strdup(lwres_context_t *ctx, const char *str) {
+ char *p;
+
+ REQUIRE(str != NULL);
+ REQUIRE(strlen(str) > 0);
+
+ p = CTXMALLOC(strlen(str) + 1);
+ if (p != NULL)
+ strcpy(p, str);
+
+ return (p);
+}
+
+void
+lwres_conf_init(lwres_context_t *ctx) {
+ int i;
+ lwres_conf_t *confdata;
+
+ REQUIRE(ctx != NULL);
+ confdata = &ctx->confdata;
+
+ confdata->nsnext = 0;
+ confdata->lwnext = 0;
+ confdata->domainname = NULL;
+ confdata->searchnxt = 0;
+ confdata->sortlistnxt = 0;
+ confdata->resdebug = 0;
+ confdata->ndots = 1;
+ confdata->no_tld_query = 0;
+
+ for (i = 0 ; i < LWRES_CONFMAXNAMESERVERS ; i++)
+ lwres_resetaddr(&confdata->nameservers[i]);
+
+ for (i = 0 ; i < LWRES_CONFMAXSEARCH ; i++)
+ confdata->search[i] = NULL;
+
+ for (i = 0 ; i < LWRES_CONFMAXSORTLIST ; i++) {
+ lwres_resetaddr(&confdata->sortlist[i].addr);
+ lwres_resetaddr(&confdata->sortlist[i].mask);
+ }
+}
+
+void
+lwres_conf_clear(lwres_context_t *ctx) {
+ int i;
+ lwres_conf_t *confdata;
+
+ REQUIRE(ctx != NULL);
+ confdata = &ctx->confdata;
+
+ for (i = 0 ; i < confdata->nsnext ; i++)
+ lwres_resetaddr(&confdata->nameservers[i]);
+
+ if (confdata->domainname != NULL) {
+ CTXFREE(confdata->domainname,
+ strlen(confdata->domainname) + 1);
+ confdata->domainname = NULL;
+ }
+
+ for (i = 0 ; i < confdata->searchnxt ; i++) {
+ if (confdata->search[i] != NULL) {
+ CTXFREE(confdata->search[i],
+ strlen(confdata->search[i]) + 1);
+ confdata->search[i] = NULL;
+ }
+ }
+
+ for (i = 0 ; i < LWRES_CONFMAXSORTLIST ; i++) {
+ lwres_resetaddr(&confdata->sortlist[i].addr);
+ lwres_resetaddr(&confdata->sortlist[i].mask);
+ }
+
+ confdata->nsnext = 0;
+ confdata->lwnext = 0;
+ confdata->domainname = NULL;
+ confdata->searchnxt = 0;
+ confdata->sortlistnxt = 0;
+ confdata->resdebug = 0;
+ confdata->ndots = 1;
+ confdata->no_tld_query = 0;
+}
+
+static lwres_result_t
+lwres_conf_parsenameserver(lwres_context_t *ctx, FILE *fp) {
+ char word[LWRES_CONFMAXLINELEN];
+ int res;
+ lwres_conf_t *confdata;
+
+ confdata = &ctx->confdata;
+
+ if (confdata->nsnext == LWRES_CONFMAXNAMESERVERS)
+ return (LWRES_R_SUCCESS);
+
+ res = getword(fp, word, sizeof(word));
+ if (strlen(word) == 0)
+ return (LWRES_R_FAILURE); /* Nothing on line. */
+ else if (res == ' ' || res == '\t')
+ res = eatwhite(fp);
+
+ if (res != EOF && res != '\n')
+ return (LWRES_R_FAILURE); /* Extra junk on line. */
+
+ res = lwres_create_addr(word,
+ &confdata->nameservers[confdata->nsnext++], 1);
+ if (res != LWRES_R_SUCCESS)
+ return (res);
+
+ return (LWRES_R_SUCCESS);
+}
+
+static lwres_result_t
+lwres_conf_parselwserver(lwres_context_t *ctx, FILE *fp) {
+ char word[LWRES_CONFMAXLINELEN];
+ int res;
+ lwres_conf_t *confdata;
+
+ confdata = &ctx->confdata;
+
+ if (confdata->lwnext == LWRES_CONFMAXLWSERVERS)
+ return (LWRES_R_SUCCESS);
+
+ res = getword(fp, word, sizeof(word));
+ if (strlen(word) == 0)
+ return (LWRES_R_FAILURE); /* Nothing on line. */
+ else if (res == ' ' || res == '\t')
+ res = eatwhite(fp);
+
+ if (res != EOF && res != '\n')
+ return (LWRES_R_FAILURE); /* Extra junk on line. */
+
+ res = lwres_create_addr(word,
+ &confdata->lwservers[confdata->lwnext++], 1);
+ if (res != LWRES_R_SUCCESS)
+ return (res);
+
+ return (LWRES_R_SUCCESS);
+}
+
+static lwres_result_t
+lwres_conf_parsedomain(lwres_context_t *ctx, FILE *fp) {
+ char word[LWRES_CONFMAXLINELEN];
+ int res, i;
+ lwres_conf_t *confdata;
+
+ confdata = &ctx->confdata;
+
+ res = getword(fp, word, sizeof(word));
+ if (strlen(word) == 0)
+ return (LWRES_R_FAILURE); /* Nothing else on line. */
+ else if (res == ' ' || res == '\t')
+ res = eatwhite(fp);
+
+ if (res != EOF && res != '\n')
+ return (LWRES_R_FAILURE); /* Extra junk on line. */
+
+ if (confdata->domainname != NULL)
+ CTXFREE(confdata->domainname,
+ strlen(confdata->domainname) + 1); /* */
+
+ /*
+ * Search and domain are mutually exclusive.
+ */
+ for (i = 0 ; i < LWRES_CONFMAXSEARCH ; i++) {
+ if (confdata->search[i] != NULL) {
+ CTXFREE(confdata->search[i],
+ strlen(confdata->search[i])+1);
+ confdata->search[i] = NULL;
+ }
+ }
+ confdata->searchnxt = 0;
+
+ confdata->domainname = lwres_strdup(ctx, word);
+
+ if (confdata->domainname == NULL)
+ return (LWRES_R_FAILURE);
+
+ return (LWRES_R_SUCCESS);
+}
+
+static lwres_result_t
+lwres_conf_parsesearch(lwres_context_t *ctx, FILE *fp) {
+ int idx, delim;
+ char word[LWRES_CONFMAXLINELEN];
+ lwres_conf_t *confdata;
+
+ confdata = &ctx->confdata;
+
+ if (confdata->domainname != NULL) {
+ /*
+ * Search and domain are mutually exclusive.
+ */
+ CTXFREE(confdata->domainname,
+ strlen(confdata->domainname) + 1);
+ confdata->domainname = NULL;
+ }
+
+ /*
+ * Remove any previous search definitions.
+ */
+ for (idx = 0 ; idx < LWRES_CONFMAXSEARCH ; idx++) {
+ if (confdata->search[idx] != NULL) {
+ CTXFREE(confdata->search[idx],
+ strlen(confdata->search[idx])+1);
+ confdata->search[idx] = NULL;
+ }
+ }
+ confdata->searchnxt = 0;
+
+ delim = getword(fp, word, sizeof(word));
+ if (strlen(word) == 0)
+ return (LWRES_R_FAILURE); /* Nothing else on line. */
+
+ idx = 0;
+ while (strlen(word) > 0) {
+ if (confdata->searchnxt == LWRES_CONFMAXSEARCH)
+ goto ignore; /* Too many domains. */
+
+ confdata->search[idx] = lwres_strdup(ctx, word);
+ if (confdata->search[idx] == NULL)
+ return (LWRES_R_FAILURE);
+ idx++;
+ confdata->searchnxt++;
+
+ ignore:
+ if (delim == EOF || delim == '\n')
+ break;
+ else
+ delim = getword(fp, word, sizeof(word));
+ }
+
+ return (LWRES_R_SUCCESS);
+}
+
+static lwres_result_t
+lwres_create_addr(const char *buffer, lwres_addr_t *addr, int convert_zero) {
+ struct in_addr v4;
+ struct in6_addr v6;
+
+ if (lwres_net_aton(buffer, &v4) == 1) {
+ if (convert_zero) {
+ unsigned char zeroaddress[] = {0, 0, 0, 0};
+ unsigned char loopaddress[] = {127, 0, 0, 1};
+ if (memcmp(&v4, zeroaddress, 4) == 0)
+ memcpy(&v4, loopaddress, 4);
+ }
+ addr->family = LWRES_ADDRTYPE_V4;
+ addr->length = NS_INADDRSZ;
+ memcpy((void *)addr->address, &v4, NS_INADDRSZ);
+
+ } else if (lwres_net_pton(AF_INET6, buffer, &v6) == 1) {
+ addr->family = LWRES_ADDRTYPE_V6;
+ addr->length = NS_IN6ADDRSZ;
+ memcpy((void *)addr->address, &v6, NS_IN6ADDRSZ);
+ } else {
+ return (LWRES_R_FAILURE); /* Unrecognised format. */
+ }
+
+ return (LWRES_R_SUCCESS);
+}
+
+static lwres_result_t
+lwres_conf_parsesortlist(lwres_context_t *ctx, FILE *fp) {
+ int delim, res, idx;
+ char word[LWRES_CONFMAXLINELEN];
+ char *p;
+ lwres_conf_t *confdata;
+
+ confdata = &ctx->confdata;
+
+ delim = getword(fp, word, sizeof(word));
+ if (strlen(word) == 0)
+ return (LWRES_R_FAILURE); /* Empty line after keyword. */
+
+ while (strlen(word) > 0) {
+ if (confdata->sortlistnxt == LWRES_CONFMAXSORTLIST)
+ return (LWRES_R_FAILURE); /* Too many values. */
+
+ p = strchr(word, '/');
+ if (p != NULL)
+ *p++ = '\0';
+
+ idx = confdata->sortlistnxt;
+ res = lwres_create_addr(word, &confdata->sortlist[idx].addr, 1);
+ if (res != LWRES_R_SUCCESS)
+ return (res);
+
+ if (p != NULL) {
+ res = lwres_create_addr(p,
+ &confdata->sortlist[idx].mask,
+ 0);
+ if (res != LWRES_R_SUCCESS)
+ return (res);
+ } else {
+ /*
+ * Make up a mask.
+ */
+ confdata->sortlist[idx].mask =
+ confdata->sortlist[idx].addr;
+
+ memset(&confdata->sortlist[idx].mask.address, 0xff,
+ confdata->sortlist[idx].addr.length);
+ }
+
+ confdata->sortlistnxt++;
+
+ if (delim == EOF || delim == '\n')
+ break;
+ else
+ delim = getword(fp, word, sizeof(word));
+ }
+
+ return (LWRES_R_SUCCESS);
+}
+
+static lwres_result_t
+lwres_conf_parseoption(lwres_context_t *ctx, FILE *fp) {
+ int delim;
+ long ndots;
+ char *p;
+ char word[LWRES_CONFMAXLINELEN];
+ lwres_conf_t *confdata;
+
+ REQUIRE(ctx != NULL);
+ confdata = &ctx->confdata;
+
+ delim = getword(fp, word, sizeof(word));
+ if (strlen(word) == 0)
+ return (LWRES_R_FAILURE); /* Empty line after keyword. */
+
+ while (strlen(word) > 0) {
+ if (strcmp("debug", word) == 0) {
+ confdata->resdebug = 1;
+ } else if (strcmp("no_tld_query", word) == 0) {
+ confdata->no_tld_query = 1;
+ } else if (strncmp("ndots:", word, 6) == 0) {
+ ndots = strtol(word + 6, &p, 10);
+ if (*p != '\0') /* Bad string. */
+ return (LWRES_R_FAILURE);
+ if (ndots < 0 || ndots > 0xff) /* Out of range. */
+ return (LWRES_R_FAILURE);
+ confdata->ndots = (lwres_uint8_t)ndots;
+ }
+
+ if (delim == EOF || delim == '\n')
+ break;
+ else
+ delim = getword(fp, word, sizeof(word));
+ }
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_conf_parse(lwres_context_t *ctx, const char *filename) {
+ FILE *fp = NULL;
+ char word[256];
+ lwres_result_t rval, ret;
+ lwres_conf_t *confdata;
+ int stopchar;
+
+ REQUIRE(ctx != NULL);
+ confdata = &ctx->confdata;
+
+ REQUIRE(filename != NULL);
+ REQUIRE(strlen(filename) > 0);
+ REQUIRE(confdata != NULL);
+
+ errno = 0;
+ if ((fp = fopen(filename, "r")) == NULL)
+ return (LWRES_R_FAILURE);
+
+ ret = LWRES_R_SUCCESS;
+ do {
+ stopchar = getword(fp, word, sizeof(word));
+ if (stopchar == EOF) {
+ rval = LWRES_R_SUCCESS;
+ break;
+ }
+
+ if (strlen(word) == 0)
+ rval = LWRES_R_SUCCESS;
+ else if (strcmp(word, "nameserver") == 0)
+ rval = lwres_conf_parsenameserver(ctx, fp);
+ else if (strcmp(word, "lwserver") == 0)
+ rval = lwres_conf_parselwserver(ctx, fp);
+ else if (strcmp(word, "domain") == 0)
+ rval = lwres_conf_parsedomain(ctx, fp);
+ else if (strcmp(word, "search") == 0)
+ rval = lwres_conf_parsesearch(ctx, fp);
+ else if (strcmp(word, "sortlist") == 0)
+ rval = lwres_conf_parsesortlist(ctx, fp);
+ else if (strcmp(word, "option") == 0)
+ rval = lwres_conf_parseoption(ctx, fp);
+ else {
+ /* unrecognised word. Ignore entire line */
+ rval = LWRES_R_SUCCESS;
+ stopchar = eatline(fp);
+ if (stopchar == EOF) {
+ break;
+ }
+ }
+ if (ret == LWRES_R_SUCCESS && rval != LWRES_R_SUCCESS)
+ ret = rval;
+ } while (1);
+
+ fclose(fp);
+
+ return (ret);
+}
+
+lwres_result_t
+lwres_conf_print(lwres_context_t *ctx, FILE *fp) {
+ int i;
+ int af;
+ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
+ const char *p;
+ lwres_conf_t *confdata;
+ lwres_addr_t tmpaddr;
+
+ REQUIRE(ctx != NULL);
+ confdata = &ctx->confdata;
+
+ REQUIRE(confdata->nsnext <= LWRES_CONFMAXNAMESERVERS);
+
+ for (i = 0 ; i < confdata->nsnext ; i++) {
+ af = lwresaddr2af(confdata->nameservers[i].family);
+
+ p = lwres_net_ntop(af, confdata->nameservers[i].address,
+ tmp, sizeof(tmp));
+ if (p != tmp)
+ return (LWRES_R_FAILURE);
+
+ fprintf(fp, "nameserver %s\n", tmp);
+ }
+
+ for (i = 0 ; i < confdata->lwnext ; i++) {
+ af = lwresaddr2af(confdata->lwservers[i].family);
+
+ p = lwres_net_ntop(af, confdata->lwservers[i].address,
+ tmp, sizeof(tmp));
+ if (p != tmp)
+ return (LWRES_R_FAILURE);
+
+ fprintf(fp, "lwserver %s\n", tmp);
+ }
+
+ if (confdata->domainname != NULL) {
+ fprintf(fp, "domain %s\n", confdata->domainname);
+ } else if (confdata->searchnxt > 0) {
+ REQUIRE(confdata->searchnxt <= LWRES_CONFMAXSEARCH);
+
+ fprintf(fp, "search");
+ for (i = 0 ; i < confdata->searchnxt ; i++)
+ fprintf(fp, " %s", confdata->search[i]);
+ fputc('\n', fp);
+ }
+
+ REQUIRE(confdata->sortlistnxt <= LWRES_CONFMAXSORTLIST);
+
+ if (confdata->sortlistnxt > 0) {
+ fputs("sortlist", fp);
+ for (i = 0 ; i < confdata->sortlistnxt ; i++) {
+ af = lwresaddr2af(confdata->sortlist[i].addr.family);
+
+ p = lwres_net_ntop(af,
+ confdata->sortlist[i].addr.address,
+ tmp, sizeof(tmp));
+ if (p != tmp)
+ return (LWRES_R_FAILURE);
+
+ fprintf(fp, " %s", tmp);
+
+ tmpaddr = confdata->sortlist[i].mask;
+ memset(&tmpaddr.address, 0xff, tmpaddr.length);
+
+ if (memcmp(&tmpaddr.address,
+ confdata->sortlist[i].mask.address,
+ confdata->sortlist[i].mask.length) != 0) {
+ af = lwresaddr2af(
+ confdata->sortlist[i].mask.family);
+ p = lwres_net_ntop
+ (af,
+ confdata->sortlist[i].mask.address,
+ tmp, sizeof(tmp));
+ if (p != tmp)
+ return (LWRES_R_FAILURE);
+
+ fprintf(fp, "/%s", tmp);
+ }
+ }
+ fputc('\n', fp);
+ }
+
+ if (confdata->resdebug)
+ fprintf(fp, "options debug\n");
+
+ if (confdata->ndots > 0)
+ fprintf(fp, "options ndots:%d\n", confdata->ndots);
+
+ if (confdata->no_tld_query)
+ fprintf(fp, "options no_tld_query\n");
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_conf_t *
+lwres_conf_get(lwres_context_t *ctx) {
+ REQUIRE(ctx != NULL);
+
+ return (&ctx->confdata);
+}
diff --git a/lib/liblwres/lwinetaton.c b/lib/liblwres/lwinetaton.c
new file mode 100644
index 000000000..42a2cfa69
--- /dev/null
+++ b/lib/liblwres/lwinetaton.c
@@ -0,0 +1,203 @@
+/*
+ * Portions Copyright (C) 1996-2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/*
+ * Copyright (c) 1983, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * 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, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
+static char rcsid[] = "$Id: lwinetaton.c,v 1.1 2004/03/15 20:35:25 as Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <config.h>
+
+#include <ctype.h>
+
+#include <stddef.h>
+
+#include <lwres/int.h>
+#include <lwres/net.h>
+
+#include "assert_p.h"
+
+/*
+ * Check whether "cp" is a valid ascii representation
+ * of an Internet address and convert to a binary address.
+ * Returns 1 if the address is valid, 0 if not.
+ * This replaces inet_addr, the return value from which
+ * cannot distinguish between failure and a local broadcast address.
+ */
+int
+lwres_net_aton(const char *cp, struct in_addr *addr) {
+ unsigned long val;
+ int base, n;
+ unsigned char c;
+ lwres_uint8_t parts[4];
+ lwres_uint8_t *pp = parts;
+ int digit;
+
+ REQUIRE(cp != NULL);
+
+ c = *cp;
+ for (;;) {
+ /*
+ * Collect number up to ``.''.
+ * Values are specified as for C:
+ * 0x=hex, 0=octal, isdigit=decimal.
+ */
+ if (!isdigit(c & 0xff))
+ return (0);
+ val = 0;
+ base = 10;
+ digit = 0;
+ if (c == '0') {
+ c = *++cp;
+ if (c == 'x' || c == 'X') {
+ base = 16;
+ c = *++cp;
+ } else {
+ base = 8;
+ digit = 1;
+ }
+ }
+ for (;;) {
+ /*
+ * isascii() is valid for all integer values, and
+ * when it is true, c is known to be in scope
+ * for isdigit(). No cast necessary. Similar
+ * comment applies for later ctype uses.
+ */
+ if (isascii(c) && isdigit(c)) {
+ if (base == 8 && (c == '8' || c == '9'))
+ return (0);
+ val = (val * base) + (c - '0');
+ c = *++cp;
+ digit = 1;
+ } else if (base == 16 && isascii(c) && isxdigit(c)) {
+ val = (val << 4) |
+ (c + 10 - (islower(c) ? 'a' : 'A'));
+ c = *++cp;
+ digit = 1;
+ } else
+ break;
+ }
+ if (c == '.') {
+ /*
+ * Internet format:
+ * a.b.c.d
+ * a.b.c (with c treated as 16 bits)
+ * a.b (with b treated as 24 bits)
+ */
+ if (pp >= parts + 3 || val > 0xff)
+ return (0);
+ *pp++ = (lwres_uint8_t)val;
+ c = *++cp;
+ } else
+ break;
+ }
+ /*
+ * Check for trailing characters.
+ */
+ if (c != '\0' && (!isascii(c) || !isspace(c)))
+ return (0);
+ /*
+ * Did we get a valid digit?
+ */
+ if (!digit)
+ return (0);
+ /*
+ * Concoct the address according to
+ * the number of parts specified.
+ */
+ n = pp - parts + 1;
+ switch (n) {
+ case 1: /* a -- 32 bits */
+ break;
+
+ case 2: /* a.b -- 8.24 bits */
+ if (val > 0xffffff)
+ return (0);
+ val |= parts[0] << 24;
+ break;
+
+ case 3: /* a.b.c -- 8.8.16 bits */
+ if (val > 0xffff)
+ return (0);
+ val |= (parts[0] << 24) | (parts[1] << 16);
+ break;
+
+ case 4: /* a.b.c.d -- 8.8.8.8 bits */
+ if (val > 0xff)
+ return (0);
+ val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+ break;
+ }
+ if (addr != NULL)
+ addr->s_addr = htonl(val);
+
+ return (1);
+}
diff --git a/lib/liblwres/lwinetntop.c b/lib/liblwres/lwinetntop.c
new file mode 100644
index 000000000..dfc55a97c
--- /dev/null
+++ b/lib/liblwres/lwinetntop.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 1996-2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] =
+ "$Id: lwinetntop.c,v 1.1 2004/03/15 20:35:25 as Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <config.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <lwres/net.h>
+
+#define NS_INT16SZ 2
+#define NS_IN6ADDRSZ 16
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static const char *inet_ntop4(const unsigned char *src, char *dst,
+ size_t size);
+
+#ifdef AF_INET6
+static const char *inet_ntop6(const unsigned char *src, char *dst,
+ size_t size);
+#endif
+
+/* char *
+ * lwres_net_ntop(af, src, dst, size)
+ * convert a network format address to presentation format.
+ * return:
+ * pointer to presentation format address (`dst'), or NULL (see errno).
+ * author:
+ * Paul Vixie, 1996.
+ */
+const char *
+lwres_net_ntop(int af, const void *src, char *dst, size_t size) {
+ switch (af) {
+ case AF_INET:
+ return (inet_ntop4(src, dst, size));
+#ifdef AF_INET6
+ case AF_INET6:
+ return (inet_ntop6(src, dst, size));
+#endif
+ default:
+ errno = EAFNOSUPPORT;
+ return (NULL);
+ }
+ /* NOTREACHED */
+}
+
+/* const char *
+ * inet_ntop4(src, dst, size)
+ * format an IPv4 address
+ * return:
+ * `dst' (as a const)
+ * notes:
+ * (1) uses no statics
+ * (2) takes a unsigned char* not an in_addr as input
+ * author:
+ * Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop4(const unsigned char *src, char *dst, size_t size) {
+ static const char fmt[] = "%u.%u.%u.%u";
+ char tmp[sizeof "255.255.255.255"];
+
+ if ((size_t)sprintf(tmp, fmt, src[0], src[1], src[2], src[3]) >= size)
+ {
+ errno = ENOSPC;
+ return (NULL);
+ }
+ strcpy(dst, tmp);
+
+ return (dst);
+}
+
+/* const char *
+ * inet_ntop6(src, dst, size)
+ * convert IPv6 binary address into presentation (printable) format
+ * author:
+ * Paul Vixie, 1996.
+ */
+#ifdef AF_INET6
+static const char *
+inet_ntop6(const unsigned char *src, char *dst, size_t size) {
+ /*
+ * Note that int32_t and int16_t need only be "at least" large enough
+ * to contain a value of the specified size. On some systems, like
+ * Crays, there is no such thing as an integer variable with 16 bits.
+ * Keep this in mind if you think this function should have been coded
+ * to use pointer overlays. All the world's not a VAX.
+ */
+ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
+ struct { int base, len; } best, cur;
+ unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ];
+ int i;
+
+ /*
+ * Preprocess:
+ * Copy the input (bytewise) array into a wordwise array.
+ * Find the longest run of 0x00's in src[] for :: shorthanding.
+ */
+ memset(words, '\0', sizeof words);
+ for (i = 0; i < NS_IN6ADDRSZ; i++)
+ words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
+ best.base = -1;
+ cur.base = -1;
+ for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
+ if (words[i] == 0) {
+ if (cur.base == -1)
+ cur.base = i, cur.len = 1;
+ else
+ cur.len++;
+ } else {
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
+ cur.base = -1;
+ }
+ }
+ }
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
+ }
+ if (best.base != -1 && best.len < 2)
+ best.base = -1;
+
+ /*
+ * Format the result.
+ */
+ tp = tmp;
+ for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
+ /* Are we inside the best run of 0x00's? */
+ if (best.base != -1 && i >= best.base &&
+ i < (best.base + best.len)) {
+ if (i == best.base)
+ *tp++ = ':';
+ continue;
+ }
+ /* Are we following an initial run of 0x00s or any real hex? */
+ if (i != 0)
+ *tp++ = ':';
+ /* Is this address an encapsulated IPv4? */
+ if (i == 6 && best.base == 0 &&
+ (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
+ if (!inet_ntop4(src+12, tp,
+ sizeof tmp - (tp - tmp)))
+ return (NULL);
+ tp += strlen(tp);
+ break;
+ }
+ tp += sprintf(tp, "%x", words[i]);
+ }
+ /* Was it a trailing run of 0x00's? */
+ if (best.base != -1 && (best.base + best.len) ==
+ (NS_IN6ADDRSZ / NS_INT16SZ))
+ *tp++ = ':';
+ *tp++ = '\0';
+
+ /*
+ * Check for overflow, copy, and we're done.
+ */
+ if ((size_t)(tp - tmp) > size) {
+ errno = ENOSPC;
+ return (NULL);
+ }
+ strcpy(dst, tmp);
+ return (dst);
+}
+#endif /* AF_INET6 */
diff --git a/lib/liblwres/lwinetpton.c b/lib/liblwres/lwinetpton.c
new file mode 100644
index 000000000..792a74775
--- /dev/null
+++ b/lib/liblwres/lwinetpton.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 1996-2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$Id: lwinetpton.c,v 1.1 2004/03/15 20:35:25 as Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <config.h>
+
+#include <errno.h>
+#include <string.h>
+
+#include <lwres/net.h>
+
+#define NS_INT16SZ 2
+#define NS_INADDRSZ 4
+#define NS_IN6ADDRSZ 16
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static int inet_pton4(const char *src, unsigned char *dst);
+static int inet_pton6(const char *src, unsigned char *dst);
+
+/* int
+ * lwres_net_pton(af, src, dst)
+ * convert from presentation format (which usually means ASCII printable)
+ * to network format (which is usually some kind of binary format).
+ * return:
+ * 1 if the address was valid for the specified address family
+ * 0 if the address wasn't valid (`dst' is untouched in this case)
+ * -1 if some other error occurred (`dst' is untouched in this case, too)
+ * author:
+ * Paul Vixie, 1996.
+ */
+int
+lwres_net_pton(int af, const char *src, void *dst) {
+ switch (af) {
+ case AF_INET:
+ return (inet_pton4(src, dst));
+ case AF_INET6:
+ return (inet_pton6(src, dst));
+ default:
+ errno = EAFNOSUPPORT;
+ return (-1);
+ }
+ /* NOTREACHED */
+}
+
+/* int
+ * inet_pton4(src, dst)
+ * like inet_aton() but without all the hexadecimal and shorthand.
+ * return:
+ * 1 if `src' is a valid dotted quad, else 0.
+ * notice:
+ * does not touch `dst' unless it's returning 1.
+ * author:
+ * Paul Vixie, 1996.
+ */
+static int
+inet_pton4(const char *src, unsigned char *dst) {
+ static const char digits[] = "0123456789";
+ int saw_digit, octets, ch;
+ unsigned char tmp[NS_INADDRSZ], *tp;
+
+ saw_digit = 0;
+ octets = 0;
+ *(tp = tmp) = 0;
+ while ((ch = *src++) != '\0') {
+ const char *pch;
+
+ if ((pch = strchr(digits, ch)) != NULL) {
+ unsigned int new = *tp * 10 + (pch - digits);
+
+ if (new > 255)
+ return (0);
+ *tp = new;
+ if (! saw_digit) {
+ if (++octets > 4)
+ return (0);
+ saw_digit = 1;
+ }
+ } else if (ch == '.' && saw_digit) {
+ if (octets == 4)
+ return (0);
+ *++tp = 0;
+ saw_digit = 0;
+ } else
+ return (0);
+ }
+ if (octets < 4)
+ return (0);
+ memcpy(dst, tmp, NS_INADDRSZ);
+ return (1);
+}
+
+/* int
+ * inet_pton6(src, dst)
+ * convert presentation level address to network order binary form.
+ * return:
+ * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * notice:
+ * (1) does not touch `dst' unless it's returning 1.
+ * (2) :: in a full address is silently ignored.
+ * credit:
+ * inspired by Mark Andrews.
+ * author:
+ * Paul Vixie, 1996.
+ */
+static int
+inet_pton6(const char *src, unsigned char *dst) {
+ static const char xdigits_l[] = "0123456789abcdef",
+ xdigits_u[] = "0123456789ABCDEF";
+ unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
+ const char *xdigits, *curtok;
+ int ch, saw_xdigit;
+ unsigned int val;
+
+ memset((tp = tmp), '\0', NS_IN6ADDRSZ);
+ endp = tp + NS_IN6ADDRSZ;
+ colonp = NULL;
+ /* Leading :: requires some special handling. */
+ if (*src == ':')
+ if (*++src != ':')
+ return (0);
+ curtok = src;
+ saw_xdigit = 0;
+ val = 0;
+ while ((ch = *src++) != '\0') {
+ const char *pch;
+
+ if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+ pch = strchr((xdigits = xdigits_u), ch);
+ if (pch != NULL) {
+ val <<= 4;
+ val |= (pch - xdigits);
+ if (val > 0xffff)
+ return (0);
+ saw_xdigit = 1;
+ continue;
+ }
+ if (ch == ':') {
+ curtok = src;
+ if (!saw_xdigit) {
+ if (colonp)
+ return (0);
+ colonp = tp;
+ continue;
+ }
+ if (tp + NS_INT16SZ > endp)
+ return (0);
+ *tp++ = (unsigned char) (val >> 8) & 0xff;
+ *tp++ = (unsigned char) val & 0xff;
+ saw_xdigit = 0;
+ val = 0;
+ continue;
+ }
+ if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
+ inet_pton4(curtok, tp) > 0) {
+ tp += NS_INADDRSZ;
+ saw_xdigit = 0;
+ break; /* '\0' was seen by inet_pton4(). */
+ }
+ return (0);
+ }
+ if (saw_xdigit) {
+ if (tp + NS_INT16SZ > endp)
+ return (0);
+ *tp++ = (unsigned char) (val >> 8) & 0xff;
+ *tp++ = (unsigned char) val & 0xff;
+ }
+ if (colonp != NULL) {
+ /*
+ * Since some memmove()'s erroneously fail to handle
+ * overlapping regions, we'll do the shift by hand.
+ */
+ const int n = tp - colonp;
+ int i;
+
+ for (i = 1; i <= n; i++) {
+ endp[- i] = colonp[n - i];
+ colonp[n - i] = 0;
+ }
+ tp = endp;
+ }
+ if (tp != endp)
+ return (0);
+ memcpy(dst, tmp, NS_IN6ADDRSZ);
+ return (1);
+}
diff --git a/lib/liblwres/lwpacket.c b/lib/liblwres/lwpacket.c
new file mode 100644
index 000000000..7bcdbbd4a
--- /dev/null
+++ b/lib/liblwres/lwpacket.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: lwpacket.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <lwres/lwbuffer.h>
+#include <lwres/lwpacket.h>
+#include <lwres/result.h>
+
+#include "assert_p.h"
+
+#define LWPACKET_LENGTH \
+ (sizeof(lwres_uint16_t) * 4 + sizeof(lwres_uint32_t) * 5)
+
+lwres_result_t
+lwres_lwpacket_renderheader(lwres_buffer_t *b, lwres_lwpacket_t *pkt) {
+ REQUIRE(b != NULL);
+ REQUIRE(pkt != NULL);
+
+ if (!SPACE_OK(b, LWPACKET_LENGTH))
+ return (LWRES_R_UNEXPECTEDEND);
+
+ lwres_buffer_putuint32(b, pkt->length);
+ lwres_buffer_putuint16(b, pkt->version);
+ lwres_buffer_putuint16(b, pkt->pktflags);
+ lwres_buffer_putuint32(b, pkt->serial);
+ lwres_buffer_putuint32(b, pkt->opcode);
+ lwres_buffer_putuint32(b, pkt->result);
+ lwres_buffer_putuint32(b, pkt->recvlength);
+ lwres_buffer_putuint16(b, pkt->authtype);
+ lwres_buffer_putuint16(b, pkt->authlength);
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_lwpacket_parseheader(lwres_buffer_t *b, lwres_lwpacket_t *pkt) {
+ lwres_uint32_t space;
+
+ REQUIRE(b != NULL);
+ REQUIRE(pkt != NULL);
+
+ space = LWRES_BUFFER_REMAINING(b);
+ if (space < LWPACKET_LENGTH)
+ return (LWRES_R_UNEXPECTEDEND);
+
+ pkt->length = lwres_buffer_getuint32(b);
+ /*
+ * XXXBEW/MLG Checking that the buffer is long enough probably
+ * shouldn't be done here, since this function is supposed to just
+ * parse the header.
+ */
+ if (pkt->length > space)
+ return (LWRES_R_UNEXPECTEDEND);
+ pkt->version = lwres_buffer_getuint16(b);
+ pkt->pktflags = lwres_buffer_getuint16(b);
+ pkt->serial = lwres_buffer_getuint32(b);
+ pkt->opcode = lwres_buffer_getuint32(b);
+ pkt->result = lwres_buffer_getuint32(b);
+ pkt->recvlength = lwres_buffer_getuint32(b);
+ pkt->authtype = lwres_buffer_getuint16(b);
+ pkt->authlength = lwres_buffer_getuint16(b);
+
+ return (LWRES_R_SUCCESS);
+}
diff --git a/lib/liblwres/lwres_gabn.c b/lib/liblwres/lwres_gabn.c
new file mode 100644
index 000000000..5e809ba8e
--- /dev/null
+++ b/lib/liblwres/lwres_gabn.c
@@ -0,0 +1,415 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: lwres_gabn.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <lwres/lwbuffer.h>
+#include <lwres/lwpacket.h>
+#include <lwres/lwres.h>
+#include <lwres/result.h>
+
+#include "context_p.h"
+#include "assert_p.h"
+
+lwres_result_t
+lwres_gabnrequest_render(lwres_context_t *ctx, lwres_gabnrequest_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b)
+{
+ unsigned char *buf;
+ size_t buflen;
+ int ret;
+ size_t payload_length;
+ lwres_uint16_t datalen;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(req != NULL);
+ REQUIRE(req->name != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+
+ datalen = strlen(req->name);
+
+ payload_length = 4 + 4 + 2 + req->namelen + 1;
+
+ buflen = LWRES_LWPACKET_LENGTH + payload_length;
+ buf = CTXMALLOC(buflen);
+ if (buf == NULL)
+ return (LWRES_R_NOMEMORY);
+
+ lwres_buffer_init(b, buf, buflen);
+
+ pkt->length = buflen;
+ pkt->version = LWRES_LWPACKETVERSION_0;
+ pkt->pktflags &= ~LWRES_LWPACKETFLAG_RESPONSE;
+ pkt->opcode = LWRES_OPCODE_GETADDRSBYNAME;
+ pkt->result = 0;
+ pkt->authtype = 0;
+ pkt->authlength = 0;
+
+ ret = lwres_lwpacket_renderheader(b, pkt);
+ if (ret != LWRES_R_SUCCESS) {
+ lwres_buffer_invalidate(b);
+ CTXFREE(buf, buflen);
+ return (ret);
+ }
+
+ INSIST(SPACE_OK(b, payload_length));
+
+ /*
+ * Flags.
+ */
+ lwres_buffer_putuint32(b, req->flags);
+
+ /*
+ * Address types we'll accept.
+ */
+ lwres_buffer_putuint32(b, req->addrtypes);
+
+ /*
+ * Put the length and the data. We know this will fit because we
+ * just checked for it.
+ */
+ lwres_buffer_putuint16(b, datalen);
+ lwres_buffer_putmem(b, (unsigned char *)req->name, datalen);
+ lwres_buffer_putuint8(b, 0); /* trailing NUL */
+
+ INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_gabnresponse_render(lwres_context_t *ctx, lwres_gabnresponse_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b)
+{
+ unsigned char *buf;
+ size_t buflen;
+ int ret;
+ size_t payload_length;
+ lwres_uint16_t datalen;
+ lwres_addr_t *addr;
+ int x;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(req != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+
+ /* naliases, naddrs */
+ payload_length = 4 + 2 + 2;
+ /* real name encoding */
+ payload_length += 2 + req->realnamelen + 1;
+ /* each alias */
+ for (x = 0 ; x < req->naliases ; x++)
+ payload_length += 2 + req->aliaslen[x] + 1;
+ /* each address */
+ x = 0;
+ addr = LWRES_LIST_HEAD(req->addrs);
+ while (addr != NULL) {
+ payload_length += 4 + 2;
+ payload_length += addr->length;
+ addr = LWRES_LIST_NEXT(addr, link);
+ x++;
+ }
+ INSIST(x == req->naddrs);
+
+ buflen = LWRES_LWPACKET_LENGTH + payload_length;
+ buf = CTXMALLOC(buflen);
+ if (buf == NULL)
+ return (LWRES_R_NOMEMORY);
+ lwres_buffer_init(b, buf, buflen);
+
+ pkt->length = buflen;
+ pkt->version = LWRES_LWPACKETVERSION_0;
+ pkt->pktflags |= LWRES_LWPACKETFLAG_RESPONSE;
+ pkt->opcode = LWRES_OPCODE_GETADDRSBYNAME;
+ pkt->authtype = 0;
+ pkt->authlength = 0;
+
+ ret = lwres_lwpacket_renderheader(b, pkt);
+ if (ret != LWRES_R_SUCCESS) {
+ lwres_buffer_invalidate(b);
+ CTXFREE(buf, buflen);
+ return (ret);
+ }
+
+ /*
+ * Check space needed here.
+ */
+ INSIST(SPACE_OK(b, payload_length));
+
+ /* Flags. */
+ lwres_buffer_putuint32(b, req->flags);
+
+ /* encode naliases and naddrs */
+ lwres_buffer_putuint16(b, req->naliases);
+ lwres_buffer_putuint16(b, req->naddrs);
+
+ /* encode the real name */
+ datalen = req->realnamelen;
+ lwres_buffer_putuint16(b, datalen);
+ lwres_buffer_putmem(b, (unsigned char *)req->realname, datalen);
+ lwres_buffer_putuint8(b, 0);
+
+ /* encode the aliases */
+ for (x = 0 ; x < req->naliases ; x++) {
+ datalen = req->aliaslen[x];
+ lwres_buffer_putuint16(b, datalen);
+ lwres_buffer_putmem(b, (unsigned char *)req->aliases[x],
+ datalen);
+ lwres_buffer_putuint8(b, 0);
+ }
+
+ /* encode the addresses */
+ addr = LWRES_LIST_HEAD(req->addrs);
+ while (addr != NULL) {
+ lwres_buffer_putuint32(b, addr->family);
+ lwres_buffer_putuint16(b, addr->length);
+ lwres_buffer_putmem(b, addr->address, addr->length);
+ addr = LWRES_LIST_NEXT(addr, link);
+ }
+
+ INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
+ INSIST(LWRES_BUFFER_USEDCOUNT(b) == pkt->length);
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_gabnrequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt, lwres_gabnrequest_t **structp)
+{
+ int ret;
+ char *name;
+ lwres_gabnrequest_t *gabn;
+ lwres_uint32_t addrtypes;
+ lwres_uint32_t flags;
+ lwres_uint16_t namelen;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+ REQUIRE(structp != NULL && *structp == NULL);
+
+ if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0)
+ return (LWRES_R_FAILURE);
+
+ if (!SPACE_REMAINING(b, 4 + 4))
+ return (LWRES_R_UNEXPECTEDEND);
+
+ flags = lwres_buffer_getuint32(b);
+ addrtypes = lwres_buffer_getuint32(b);
+
+ /*
+ * Pull off the name itself
+ */
+ ret = lwres_string_parse(b, &name, &namelen);
+ if (ret != LWRES_R_SUCCESS)
+ return (ret);
+
+ if (LWRES_BUFFER_REMAINING(b) != 0)
+ return (LWRES_R_TRAILINGDATA);
+
+ gabn = CTXMALLOC(sizeof(lwres_gabnrequest_t));
+ if (gabn == NULL)
+ return (LWRES_R_NOMEMORY);
+
+ gabn->flags = flags;
+ gabn->addrtypes = addrtypes;
+ gabn->name = name;
+ gabn->namelen = namelen;
+
+ *structp = gabn;
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt, lwres_gabnresponse_t **structp)
+{
+ lwres_result_t ret;
+ unsigned int x;
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ lwres_uint16_t naddrs;
+ lwres_gabnresponse_t *gabn;
+ lwres_addrlist_t addrlist;
+ lwres_addr_t *addr;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+ REQUIRE(structp != NULL && *structp == NULL);
+
+ gabn = NULL;
+
+ if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0)
+ return (LWRES_R_FAILURE);
+
+ /*
+ * Pull off the name itself
+ */
+ if (!SPACE_REMAINING(b, 4 + 2 + 2))
+ return (LWRES_R_UNEXPECTEDEND);
+ flags = lwres_buffer_getuint32(b);
+ naliases = lwres_buffer_getuint16(b);
+ naddrs = lwres_buffer_getuint16(b);
+
+ gabn = CTXMALLOC(sizeof(lwres_gabnresponse_t));
+ if (gabn == NULL)
+ return (LWRES_R_NOMEMORY);
+ gabn->aliases = NULL;
+ gabn->aliaslen = NULL;
+ LWRES_LIST_INIT(gabn->addrs);
+ gabn->base = NULL;
+
+ gabn->flags = flags;
+ gabn->naliases = naliases;
+ gabn->naddrs = naddrs;
+
+ LWRES_LIST_INIT(addrlist);
+
+ if (naliases > 0) {
+ gabn->aliases = CTXMALLOC(sizeof(char *) * naliases);
+ if (gabn->aliases == NULL) {
+ ret = LWRES_R_NOMEMORY;
+ goto out;
+ }
+
+ gabn->aliaslen = CTXMALLOC(sizeof(lwres_uint16_t) * naliases);
+ if (gabn->aliaslen == NULL) {
+ ret = LWRES_R_NOMEMORY;
+ goto out;
+ }
+ }
+
+ for (x = 0 ; x < naddrs ; x++) {
+ addr = CTXMALLOC(sizeof(lwres_addr_t));
+ if (addr == NULL) {
+ ret = LWRES_R_NOMEMORY;
+ goto out;
+ }
+ LWRES_LINK_INIT(addr, link);
+ LWRES_LIST_APPEND(addrlist, addr, link);
+ }
+
+ /*
+ * Now, pull off the real name.
+ */
+ ret = lwres_string_parse(b, &gabn->realname, &gabn->realnamelen);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ /*
+ * Parse off the aliases.
+ */
+ for (x = 0 ; x < gabn->naliases ; x++) {
+ ret = lwres_string_parse(b, &gabn->aliases[x],
+ &gabn->aliaslen[x]);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+ }
+
+ /*
+ * Pull off the addresses. We already strung the linked list
+ * up above.
+ */
+ addr = LWRES_LIST_HEAD(addrlist);
+ for (x = 0 ; x < gabn->naddrs ; x++) {
+ INSIST(addr != NULL);
+ ret = lwres_addr_parse(b, addr);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+ addr = LWRES_LIST_NEXT(addr, link);
+ }
+
+ if (LWRES_BUFFER_REMAINING(b) != 0) {
+ ret = LWRES_R_TRAILINGDATA;
+ goto out;
+ }
+
+ gabn->addrs = addrlist;
+
+ *structp = gabn;
+ return (LWRES_R_SUCCESS);
+
+ out:
+ if (gabn != NULL) {
+ if (gabn->aliases != NULL)
+ CTXFREE(gabn->aliases, sizeof(char *) * naliases);
+ if (gabn->aliaslen != NULL)
+ CTXFREE(gabn->aliaslen,
+ sizeof(lwres_uint16_t) * naliases);
+ addr = LWRES_LIST_HEAD(addrlist);
+ while (addr != NULL) {
+ LWRES_LIST_UNLINK(addrlist, addr, link);
+ CTXFREE(addr, sizeof(lwres_addr_t));
+ addr = LWRES_LIST_HEAD(addrlist);
+ }
+ CTXFREE(gabn, sizeof(lwres_gabnresponse_t));
+ }
+
+ return (ret);
+}
+
+void
+lwres_gabnrequest_free(lwres_context_t *ctx, lwres_gabnrequest_t **structp)
+{
+ lwres_gabnrequest_t *gabn;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(structp != NULL && *structp != NULL);
+
+ gabn = *structp;
+ *structp = NULL;
+
+ CTXFREE(gabn, sizeof(lwres_gabnrequest_t));
+}
+
+void
+lwres_gabnresponse_free(lwres_context_t *ctx, lwres_gabnresponse_t **structp)
+{
+ lwres_gabnresponse_t *gabn;
+ lwres_addr_t *addr;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(structp != NULL && *structp != NULL);
+
+ gabn = *structp;
+ *structp = NULL;
+
+ if (gabn->naliases > 0) {
+ CTXFREE(gabn->aliases, sizeof(char *) * gabn->naliases);
+ CTXFREE(gabn->aliaslen,
+ sizeof(lwres_uint16_t) * gabn->naliases);
+ }
+ addr = LWRES_LIST_HEAD(gabn->addrs);
+ while (addr != NULL) {
+ LWRES_LIST_UNLINK(gabn->addrs, addr, link);
+ CTXFREE(addr, sizeof(lwres_addr_t));
+ addr = LWRES_LIST_HEAD(gabn->addrs);
+ }
+ if (gabn->base != NULL)
+ CTXFREE(gabn->base, gabn->baselen);
+ CTXFREE(gabn, sizeof(lwres_gabnresponse_t));
+}
diff --git a/lib/liblwres/lwres_gnba.c b/lib/liblwres/lwres_gnba.c
new file mode 100644
index 000000000..293eb05ac
--- /dev/null
+++ b/lib/liblwres/lwres_gnba.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: lwres_gnba.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <lwres/lwbuffer.h>
+#include <lwres/lwpacket.h>
+#include <lwres/lwres.h>
+#include <lwres/result.h>
+
+#include "context_p.h"
+#include "assert_p.h"
+
+lwres_result_t
+lwres_gnbarequest_render(lwres_context_t *ctx, lwres_gnbarequest_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b)
+{
+ unsigned char *buf;
+ size_t buflen;
+ int ret;
+ size_t payload_length;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(req != NULL);
+ REQUIRE(req->addr.family != 0);
+ REQUIRE(req->addr.length != 0);
+ REQUIRE(req->addr.address != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+
+ payload_length = 4 + 4 + 2 + + req->addr.length;
+
+ buflen = LWRES_LWPACKET_LENGTH + payload_length;
+ buf = CTXMALLOC(buflen);
+ if (buf == NULL)
+ return (LWRES_R_NOMEMORY);
+ lwres_buffer_init(b, buf, buflen);
+
+ pkt->length = buflen;
+ pkt->version = LWRES_LWPACKETVERSION_0;
+ pkt->pktflags &= ~LWRES_LWPACKETFLAG_RESPONSE;
+ pkt->opcode = LWRES_OPCODE_GETNAMEBYADDR;
+ pkt->result = 0;
+ pkt->authtype = 0;
+ pkt->authlength = 0;
+
+ ret = lwres_lwpacket_renderheader(b, pkt);
+ if (ret != LWRES_R_SUCCESS) {
+ lwres_buffer_invalidate(b);
+ CTXFREE(buf, buflen);
+ return (ret);
+ }
+
+ INSIST(SPACE_OK(b, payload_length));
+
+ /*
+ * Put the length and the data. We know this will fit because we
+ * just checked for it.
+ */
+ lwres_buffer_putuint32(b, req->flags);
+ lwres_buffer_putuint32(b, req->addr.family);
+ lwres_buffer_putuint16(b, req->addr.length);
+ lwres_buffer_putmem(b, (unsigned char *)req->addr.address,
+ req->addr.length);
+
+ INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_gnbaresponse_render(lwres_context_t *ctx, lwres_gnbaresponse_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b)
+{
+ unsigned char *buf;
+ size_t buflen;
+ int ret;
+ size_t payload_length;
+ lwres_uint16_t datalen;
+ int x;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(req != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+
+ /*
+ * Calculate packet size.
+ */
+ payload_length = 4; /* flags */
+ payload_length += 2; /* naliases */
+ payload_length += 2 + req->realnamelen + 1; /* real name encoding */
+ for (x = 0 ; x < req->naliases ; x++) /* each alias */
+ payload_length += 2 + req->aliaslen[x] + 1;
+
+ buflen = LWRES_LWPACKET_LENGTH + payload_length;
+ buf = CTXMALLOC(buflen);
+ if (buf == NULL)
+ return (LWRES_R_NOMEMORY);
+ lwres_buffer_init(b, buf, buflen);
+
+ pkt->length = buflen;
+ pkt->version = LWRES_LWPACKETVERSION_0;
+ pkt->pktflags |= LWRES_LWPACKETFLAG_RESPONSE;
+ pkt->opcode = LWRES_OPCODE_GETNAMEBYADDR;
+ pkt->authtype = 0;
+ pkt->authlength = 0;
+
+ ret = lwres_lwpacket_renderheader(b, pkt);
+ if (ret != LWRES_R_SUCCESS) {
+ lwres_buffer_invalidate(b);
+ CTXFREE(buf, buflen);
+ return (ret);
+ }
+
+ INSIST(SPACE_OK(b, payload_length));
+ lwres_buffer_putuint32(b, req->flags);
+
+ /* encode naliases */
+ lwres_buffer_putuint16(b, req->naliases);
+
+ /* encode the real name */
+ datalen = req->realnamelen;
+ lwres_buffer_putuint16(b, datalen);
+ lwres_buffer_putmem(b, (unsigned char *)req->realname, datalen);
+ lwres_buffer_putuint8(b, 0);
+
+ /* encode the aliases */
+ for (x = 0 ; x < req->naliases ; x++) {
+ datalen = req->aliaslen[x];
+ lwres_buffer_putuint16(b, datalen);
+ lwres_buffer_putmem(b, (unsigned char *)req->aliases[x],
+ datalen);
+ lwres_buffer_putuint8(b, 0);
+ }
+
+ INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_gnbarequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt, lwres_gnbarequest_t **structp)
+{
+ int ret;
+ lwres_gnbarequest_t *gnba;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+ REQUIRE(structp != NULL && *structp == NULL);
+
+ if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0)
+ return (LWRES_R_FAILURE);
+
+ gnba = CTXMALLOC(sizeof(lwres_gnbarequest_t));
+ if (gnba == NULL)
+ return (LWRES_R_NOMEMORY);
+
+ if (!SPACE_REMAINING(b, 4))
+ return (LWRES_R_UNEXPECTEDEND);
+
+ gnba->flags = lwres_buffer_getuint32(b);
+
+ ret = lwres_addr_parse(b, &gnba->addr);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ if (LWRES_BUFFER_REMAINING(b) != 0) {
+ ret = LWRES_R_TRAILINGDATA;
+ goto out;
+ }
+
+ *structp = gnba;
+ return (LWRES_R_SUCCESS);
+
+ out:
+ if (gnba != NULL)
+ lwres_gnbarequest_free(ctx, &gnba);
+
+ return (ret);
+}
+
+lwres_result_t
+lwres_gnbaresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt, lwres_gnbaresponse_t **structp)
+{
+ int ret;
+ unsigned int x;
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ lwres_gnbaresponse_t *gnba;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+ REQUIRE(structp != NULL && *structp == NULL);
+
+ gnba = NULL;
+
+ if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0)
+ return (LWRES_R_FAILURE);
+
+ /*
+ * Pull off flags & naliases
+ */
+ if (!SPACE_REMAINING(b, 4 + 2))
+ return (LWRES_R_UNEXPECTEDEND);
+ flags = lwres_buffer_getuint32(b);
+ naliases = lwres_buffer_getuint16(b);
+
+ gnba = CTXMALLOC(sizeof(lwres_gnbaresponse_t));
+ if (gnba == NULL)
+ return (LWRES_R_NOMEMORY);
+ gnba->base = NULL;
+ gnba->aliases = NULL;
+ gnba->aliaslen = NULL;
+
+ gnba->flags = flags;
+ gnba->naliases = naliases;
+
+ if (naliases > 0) {
+ gnba->aliases = CTXMALLOC(sizeof(char *) * naliases);
+ if (gnba->aliases == NULL) {
+ ret = LWRES_R_NOMEMORY;
+ goto out;
+ }
+
+ gnba->aliaslen = CTXMALLOC(sizeof(lwres_uint16_t) * naliases);
+ if (gnba->aliaslen == NULL) {
+ ret = LWRES_R_NOMEMORY;
+ goto out;
+ }
+ }
+
+ /*
+ * Now, pull off the real name.
+ */
+ ret = lwres_string_parse(b, &gnba->realname, &gnba->realnamelen);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ /*
+ * Parse off the aliases.
+ */
+ for (x = 0 ; x < gnba->naliases ; x++) {
+ ret = lwres_string_parse(b, &gnba->aliases[x],
+ &gnba->aliaslen[x]);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+ }
+
+ if (LWRES_BUFFER_REMAINING(b) != 0) {
+ ret = LWRES_R_TRAILINGDATA;
+ goto out;
+ }
+
+ *structp = gnba;
+ return (LWRES_R_SUCCESS);
+
+ out:
+ if (gnba != NULL) {
+ if (gnba->aliases != NULL)
+ CTXFREE(gnba->aliases, sizeof(char *) * naliases);
+ if (gnba->aliaslen != NULL)
+ CTXFREE(gnba->aliaslen,
+ sizeof(lwres_uint16_t) * naliases);
+ CTXFREE(gnba, sizeof(lwres_gnbaresponse_t));
+ }
+
+ return (ret);
+}
+
+void
+lwres_gnbarequest_free(lwres_context_t *ctx, lwres_gnbarequest_t **structp)
+{
+ lwres_gnbarequest_t *gnba;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(structp != NULL && *structp != NULL);
+
+ gnba = *structp;
+ *structp = NULL;
+
+ CTXFREE(gnba, sizeof(lwres_gnbarequest_t));
+}
+
+void
+lwres_gnbaresponse_free(lwres_context_t *ctx, lwres_gnbaresponse_t **structp)
+{
+ lwres_gnbaresponse_t *gnba;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(structp != NULL && *structp != NULL);
+
+ gnba = *structp;
+ *structp = NULL;
+
+ if (gnba->naliases > 0) {
+ CTXFREE(gnba->aliases, sizeof(char *) * gnba->naliases);
+ CTXFREE(gnba->aliaslen,
+ sizeof(lwres_uint16_t) * gnba->naliases);
+ }
+ if (gnba->base != NULL)
+ CTXFREE(gnba->base, gnba->baselen);
+ CTXFREE(gnba, sizeof(lwres_gnbaresponse_t));
+}
diff --git a/lib/liblwres/lwres_grbn.c b/lib/liblwres/lwres_grbn.c
new file mode 100644
index 000000000..fd8de50a2
--- /dev/null
+++ b/lib/liblwres/lwres_grbn.c
@@ -0,0 +1,416 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: lwres_grbn.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <lwres/lwbuffer.h>
+#include <lwres/lwpacket.h>
+#include <lwres/lwres.h>
+#include <lwres/result.h>
+
+#include "context_p.h"
+#include "assert_p.h"
+
+lwres_result_t
+lwres_grbnrequest_render(lwres_context_t *ctx, lwres_grbnrequest_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b)
+{
+ unsigned char *buf;
+ size_t buflen;
+ int ret;
+ size_t payload_length;
+ lwres_uint16_t datalen;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(req != NULL);
+ REQUIRE(req->name != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+
+ datalen = strlen(req->name);
+
+ payload_length = 4 + 2 + 2 + 2 + req->namelen + 1;
+
+ buflen = LWRES_LWPACKET_LENGTH + payload_length;
+ buf = CTXMALLOC(buflen);
+ if (buf == NULL)
+ return (LWRES_R_NOMEMORY);
+
+ lwres_buffer_init(b, buf, buflen);
+
+ pkt->length = buflen;
+ pkt->version = LWRES_LWPACKETVERSION_0;
+ pkt->pktflags &= ~LWRES_LWPACKETFLAG_RESPONSE;
+ pkt->opcode = LWRES_OPCODE_GETRDATABYNAME;
+ pkt->result = 0;
+ pkt->authtype = 0;
+ pkt->authlength = 0;
+
+ ret = lwres_lwpacket_renderheader(b, pkt);
+ if (ret != LWRES_R_SUCCESS) {
+ lwres_buffer_invalidate(b);
+ CTXFREE(buf, buflen);
+ return (ret);
+ }
+
+ INSIST(SPACE_OK(b, payload_length));
+
+ /*
+ * Flags.
+ */
+ lwres_buffer_putuint32(b, req->flags);
+
+ /*
+ * Class.
+ */
+ lwres_buffer_putuint16(b, req->rdclass);
+
+ /*
+ * Type.
+ */
+ lwres_buffer_putuint16(b, req->rdtype);
+
+ /*
+ * Put the length and the data. We know this will fit because we
+ * just checked for it.
+ */
+ lwres_buffer_putuint16(b, datalen);
+ lwres_buffer_putmem(b, (unsigned char *)req->name, datalen);
+ lwres_buffer_putuint8(b, 0); /* trailing NUL */
+
+ INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_grbnresponse_render(lwres_context_t *ctx, lwres_grbnresponse_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b)
+{
+ unsigned char *buf;
+ size_t buflen;
+ int ret;
+ size_t payload_length;
+ lwres_uint16_t datalen;
+ int x;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(req != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+
+ /* flags, class, type, ttl, nrdatas, nsigs */
+ payload_length = 4 + 2 + 2 + 4 + 2 + 2;
+ /* real name encoding */
+ payload_length += 2 + req->realnamelen + 1;
+ /* each rr */
+ for (x = 0 ; x < req->nrdatas ; x++)
+ payload_length += 2 + req->rdatalen[x];
+ for (x = 0 ; x < req->nsigs ; x++)
+ payload_length += 2 + req->siglen[x];
+
+ buflen = LWRES_LWPACKET_LENGTH + payload_length;
+ buf = CTXMALLOC(buflen);
+ if (buf == NULL)
+ return (LWRES_R_NOMEMORY);
+ lwres_buffer_init(b, buf, buflen);
+
+ pkt->length = buflen;
+ pkt->version = LWRES_LWPACKETVERSION_0;
+ pkt->pktflags |= LWRES_LWPACKETFLAG_RESPONSE;
+ pkt->opcode = LWRES_OPCODE_GETRDATABYNAME;
+ pkt->authtype = 0;
+ pkt->authlength = 0;
+
+ ret = lwres_lwpacket_renderheader(b, pkt);
+ if (ret != LWRES_R_SUCCESS) {
+ lwres_buffer_invalidate(b);
+ CTXFREE(buf, buflen);
+ return (ret);
+ }
+
+ /*
+ * Check space needed here.
+ */
+ INSIST(SPACE_OK(b, payload_length));
+
+ /* Flags. */
+ lwres_buffer_putuint32(b, req->flags);
+
+ /* encode class, type, ttl, and nrdatas */
+ lwres_buffer_putuint16(b, req->rdclass);
+ lwres_buffer_putuint16(b, req->rdtype);
+ lwres_buffer_putuint32(b, req->ttl);
+ lwres_buffer_putuint16(b, req->nrdatas);
+ lwres_buffer_putuint16(b, req->nsigs);
+
+ /* encode the real name */
+ datalen = req->realnamelen;
+ lwres_buffer_putuint16(b, datalen);
+ lwres_buffer_putmem(b, (unsigned char *)req->realname, datalen);
+ lwres_buffer_putuint8(b, 0);
+
+ /* encode the rdatas */
+ for (x = 0 ; x < req->nrdatas ; x++) {
+ datalen = req->rdatalen[x];
+ lwres_buffer_putuint16(b, datalen);
+ lwres_buffer_putmem(b, req->rdatas[x], datalen);
+ }
+
+ /* encode the signatures */
+ for (x = 0 ; x < req->nsigs ; x++) {
+ datalen = req->siglen[x];
+ lwres_buffer_putuint16(b, datalen);
+ lwres_buffer_putmem(b, req->sigs[x], datalen);
+ }
+
+ INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
+ INSIST(LWRES_BUFFER_USEDCOUNT(b) == pkt->length);
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_grbnrequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt, lwres_grbnrequest_t **structp)
+{
+ int ret;
+ char *name;
+ lwres_grbnrequest_t *grbn;
+ lwres_uint32_t flags;
+ lwres_uint16_t rdclass, rdtype;
+ lwres_uint16_t namelen;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+ REQUIRE(structp != NULL && *structp == NULL);
+
+ if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0)
+ return (LWRES_R_FAILURE);
+
+ if (!SPACE_REMAINING(b, 4 + 2 + 2))
+ return (LWRES_R_UNEXPECTEDEND);
+
+ /*
+ * Pull off the flags, class, and type.
+ */
+ flags = lwres_buffer_getuint32(b);
+ rdclass = lwres_buffer_getuint16(b);
+ rdtype = lwres_buffer_getuint16(b);
+
+ /*
+ * Pull off the name itself
+ */
+ ret = lwres_string_parse(b, &name, &namelen);
+ if (ret != LWRES_R_SUCCESS)
+ return (ret);
+
+ if (LWRES_BUFFER_REMAINING(b) != 0)
+ return (LWRES_R_TRAILINGDATA);
+
+ grbn = CTXMALLOC(sizeof(lwres_grbnrequest_t));
+ if (grbn == NULL)
+ return (LWRES_R_NOMEMORY);
+
+ grbn->flags = flags;
+ grbn->rdclass = rdclass;
+ grbn->rdtype = rdtype;
+ grbn->name = name;
+ grbn->namelen = namelen;
+
+ *structp = grbn;
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_grbnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt, lwres_grbnresponse_t **structp)
+{
+ lwres_result_t ret;
+ unsigned int x;
+ lwres_uint32_t flags;
+ lwres_uint16_t rdclass, rdtype;
+ lwres_uint32_t ttl;
+ lwres_uint16_t nrdatas, nsigs;
+ lwres_grbnresponse_t *grbn;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+ REQUIRE(structp != NULL && *structp == NULL);
+
+ grbn = NULL;
+
+ if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0)
+ return (LWRES_R_FAILURE);
+
+ /*
+ * Pull off the flags, class, type, ttl, nrdatas, and nsigs
+ */
+ if (!SPACE_REMAINING(b, 4 + 2 + 2 + 4 + 2 + 2))
+ return (LWRES_R_UNEXPECTEDEND);
+ flags = lwres_buffer_getuint32(b);
+ rdclass = lwres_buffer_getuint16(b);
+ rdtype = lwres_buffer_getuint16(b);
+ ttl = lwres_buffer_getuint32(b);
+ nrdatas = lwres_buffer_getuint16(b);
+ nsigs = lwres_buffer_getuint16(b);
+
+ /*
+ * Pull off the name itself
+ */
+
+ grbn = CTXMALLOC(sizeof(lwres_grbnresponse_t));
+ if (grbn == NULL)
+ return (LWRES_R_NOMEMORY);
+ grbn->rdatas = NULL;
+ grbn->rdatalen = NULL;
+ grbn->sigs = NULL;
+ grbn->siglen = NULL;
+ grbn->base = NULL;
+
+ grbn->flags = flags;
+ grbn->rdclass = rdclass;
+ grbn->rdtype = rdtype;
+ grbn->ttl = ttl;
+ grbn->nrdatas = nrdatas;
+ grbn->nsigs = nsigs;
+
+ if (nrdatas > 0) {
+ grbn->rdatas = CTXMALLOC(sizeof(char *) * nrdatas);
+ if (grbn->rdatas == NULL) {
+ ret = LWRES_R_NOMEMORY;
+ goto out;
+ }
+
+ grbn->rdatalen = CTXMALLOC(sizeof(lwres_uint16_t) * nrdatas);
+ if (grbn->rdatalen == NULL) {
+ ret = LWRES_R_NOMEMORY;
+ goto out;
+ }
+ }
+
+ if (nsigs > 0) {
+ grbn->sigs = CTXMALLOC(sizeof(char *) * nsigs);
+ if (grbn->sigs == NULL) {
+ ret = LWRES_R_NOMEMORY;
+ goto out;
+ }
+
+ grbn->siglen = CTXMALLOC(sizeof(lwres_uint16_t) * nsigs);
+ if (grbn->siglen == NULL) {
+ ret = LWRES_R_NOMEMORY;
+ goto out;
+ }
+ }
+
+ /*
+ * Now, pull off the real name.
+ */
+ ret = lwres_string_parse(b, &grbn->realname, &grbn->realnamelen);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ /*
+ * Parse off the rdatas.
+ */
+ for (x = 0 ; x < grbn->nrdatas ; x++) {
+ ret = lwres_data_parse(b, &grbn->rdatas[x],
+ &grbn->rdatalen[x]);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+ }
+
+ /*
+ * Parse off the signatures.
+ */
+ for (x = 0 ; x < grbn->nsigs ; x++) {
+ ret = lwres_data_parse(b, &grbn->sigs[x], &grbn->siglen[x]);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+ }
+
+ if (LWRES_BUFFER_REMAINING(b) != 0) {
+ ret = LWRES_R_TRAILINGDATA;
+ goto out;
+ }
+
+ *structp = grbn;
+ return (LWRES_R_SUCCESS);
+
+ out:
+ if (grbn != NULL) {
+ if (grbn->rdatas != NULL)
+ CTXFREE(grbn->rdatas, sizeof(char *) * nrdatas);
+ if (grbn->rdatalen != NULL)
+ CTXFREE(grbn->rdatalen,
+ sizeof(lwres_uint16_t) * nrdatas);
+ if (grbn->sigs != NULL)
+ CTXFREE(grbn->sigs, sizeof(char *) * nsigs);
+ if (grbn->siglen != NULL)
+ CTXFREE(grbn->siglen, sizeof(lwres_uint16_t) * nsigs);
+ CTXFREE(grbn, sizeof(lwres_grbnresponse_t));
+ }
+
+ return (ret);
+}
+
+void
+lwres_grbnrequest_free(lwres_context_t *ctx, lwres_grbnrequest_t **structp)
+{
+ lwres_grbnrequest_t *grbn;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(structp != NULL && *structp != NULL);
+
+ grbn = *structp;
+ *structp = NULL;
+
+ CTXFREE(grbn, sizeof(lwres_grbnrequest_t));
+}
+
+void
+lwres_grbnresponse_free(lwres_context_t *ctx, lwres_grbnresponse_t **structp)
+{
+ lwres_grbnresponse_t *grbn;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(structp != NULL && *structp != NULL);
+
+ grbn = *structp;
+ *structp = NULL;
+
+ if (grbn->nrdatas > 0) {
+ CTXFREE(grbn->rdatas, sizeof(char *) * grbn->nrdatas);
+ CTXFREE(grbn->rdatalen,
+ sizeof(lwres_uint16_t) * grbn->nrdatas);
+ }
+ if (grbn->nsigs > 0) {
+ CTXFREE(grbn->sigs, sizeof(char *) * grbn->nsigs);
+ CTXFREE(grbn->siglen, sizeof(lwres_uint16_t) * grbn->nsigs);
+ }
+ if (grbn->base != NULL)
+ CTXFREE(grbn->base, grbn->baselen);
+ CTXFREE(grbn, sizeof(lwres_grbnresponse_t));
+}
diff --git a/lib/liblwres/lwres_noop.c b/lib/liblwres/lwres_noop.c
new file mode 100644
index 000000000..a75fba351
--- /dev/null
+++ b/lib/liblwres/lwres_noop.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: lwres_noop.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <lwres/lwbuffer.h>
+#include <lwres/lwpacket.h>
+#include <lwres/lwres.h>
+#include <lwres/result.h>
+
+#include "context_p.h"
+#include "assert_p.h"
+
+lwres_result_t
+lwres_nooprequest_render(lwres_context_t *ctx, lwres_nooprequest_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b)
+{
+ unsigned char *buf;
+ size_t buflen;
+ int ret;
+ size_t payload_length;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(req != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+
+ payload_length = sizeof(lwres_uint16_t) + req->datalength;
+
+ buflen = LWRES_LWPACKET_LENGTH + payload_length;
+ buf = CTXMALLOC(buflen);
+ if (buf == NULL)
+ return (LWRES_R_NOMEMORY);
+ lwres_buffer_init(b, buf, buflen);
+
+ pkt->length = buflen;
+ pkt->version = LWRES_LWPACKETVERSION_0;
+ pkt->pktflags &= ~LWRES_LWPACKETFLAG_RESPONSE;
+ pkt->opcode = LWRES_OPCODE_NOOP;
+ pkt->result = 0;
+ pkt->authtype = 0;
+ pkt->authlength = 0;
+
+ ret = lwres_lwpacket_renderheader(b, pkt);
+ if (ret != LWRES_R_SUCCESS) {
+ lwres_buffer_invalidate(b);
+ CTXFREE(buf, buflen);
+ return (ret);
+ }
+
+ INSIST(SPACE_OK(b, payload_length));
+
+ /*
+ * Put the length and the data. We know this will fit because we
+ * just checked for it.
+ */
+ lwres_buffer_putuint16(b, req->datalength);
+ lwres_buffer_putmem(b, req->data, req->datalength);
+
+ INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_noopresponse_render(lwres_context_t *ctx, lwres_noopresponse_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b)
+{
+ unsigned char *buf;
+ size_t buflen;
+ int ret;
+ size_t payload_length;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(req != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+
+ payload_length = sizeof(lwres_uint16_t) + req->datalength;
+
+ buflen = LWRES_LWPACKET_LENGTH + payload_length;
+ buf = CTXMALLOC(buflen);
+ if (buf == NULL)
+ return (LWRES_R_NOMEMORY);
+ lwres_buffer_init(b, buf, buflen);
+
+ pkt->length = buflen;
+ pkt->version = LWRES_LWPACKETVERSION_0;
+ pkt->pktflags |= LWRES_LWPACKETFLAG_RESPONSE;
+ pkt->opcode = LWRES_OPCODE_NOOP;
+ pkt->authtype = 0;
+ pkt->authlength = 0;
+
+ ret = lwres_lwpacket_renderheader(b, pkt);
+ if (ret != LWRES_R_SUCCESS) {
+ lwres_buffer_invalidate(b);
+ CTXFREE(buf, buflen);
+ return (ret);
+ }
+
+ INSIST(SPACE_OK(b, payload_length));
+
+ /*
+ * Put the length and the data. We know this will fit because we
+ * just checked for it.
+ */
+ lwres_buffer_putuint16(b, req->datalength);
+ lwres_buffer_putmem(b, req->data, req->datalength);
+
+ INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_nooprequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt, lwres_nooprequest_t **structp)
+{
+ int ret;
+ lwres_nooprequest_t *req;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(b != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(structp != NULL && *structp == NULL);
+
+ if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0)
+ return (LWRES_R_FAILURE);
+
+ req = CTXMALLOC(sizeof(lwres_nooprequest_t));
+ if (req == NULL)
+ return (LWRES_R_NOMEMORY);
+
+ if (!SPACE_REMAINING(b, sizeof(lwres_uint16_t))) {
+ ret = LWRES_R_UNEXPECTEDEND;
+ goto out;
+ }
+ req->datalength = lwres_buffer_getuint16(b);
+
+ if (!SPACE_REMAINING(b, req->datalength)) {
+ ret = LWRES_R_UNEXPECTEDEND;
+ goto out;
+ }
+ req->data = b->base + b->current;
+ lwres_buffer_forward(b, req->datalength);
+
+ if (LWRES_BUFFER_REMAINING(b) != 0) {
+ ret = LWRES_R_TRAILINGDATA;
+ goto out;
+ }
+
+ /* success! */
+ *structp = req;
+ return (LWRES_R_SUCCESS);
+
+ /* Error return */
+ out:
+ CTXFREE(req, sizeof(lwres_nooprequest_t));
+ return (ret);
+}
+
+lwres_result_t
+lwres_noopresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt, lwres_noopresponse_t **structp)
+{
+ int ret;
+ lwres_noopresponse_t *req;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(b != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(structp != NULL && *structp == NULL);
+
+ if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0)
+ return (LWRES_R_FAILURE);
+
+ req = CTXMALLOC(sizeof(lwres_noopresponse_t));
+ if (req == NULL)
+ return (LWRES_R_NOMEMORY);
+
+ if (!SPACE_REMAINING(b, sizeof(lwres_uint16_t))) {
+ ret = LWRES_R_UNEXPECTEDEND;
+ goto out;
+ }
+ req->datalength = lwres_buffer_getuint16(b);
+
+ if (!SPACE_REMAINING(b, req->datalength)) {
+ ret = LWRES_R_UNEXPECTEDEND;
+ goto out;
+ }
+ req->data = b->base + b->current;
+
+ lwres_buffer_forward(b, req->datalength);
+ if (LWRES_BUFFER_REMAINING(b) != 0) {
+ ret = LWRES_R_TRAILINGDATA;
+ goto out;
+ }
+
+ /* success! */
+ *structp = req;
+ return (LWRES_R_SUCCESS);
+
+ /* Error return */
+ out:
+ CTXFREE(req, sizeof(lwres_noopresponse_t));
+ return (ret);
+}
+
+void
+lwres_noopresponse_free(lwres_context_t *ctx, lwres_noopresponse_t **structp)
+{
+ lwres_noopresponse_t *noop;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(structp != NULL && *structp != NULL);
+
+ noop = *structp;
+ *structp = NULL;
+
+ CTXFREE(noop, sizeof(lwres_noopresponse_t));
+}
+
+void
+lwres_nooprequest_free(lwres_context_t *ctx, lwres_nooprequest_t **structp)
+{
+ lwres_nooprequest_t *noop;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(structp != NULL && *structp != NULL);
+
+ noop = *structp;
+ *structp = NULL;
+
+ CTXFREE(noop, sizeof(lwres_nooprequest_t));
+}
diff --git a/lib/liblwres/lwresutil.c b/lib/liblwres/lwresutil.c
new file mode 100644
index 000000000..60f330e76
--- /dev/null
+++ b/lib/liblwres/lwresutil.c
@@ -0,0 +1,491 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: lwresutil.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <lwres/lwbuffer.h>
+#include <lwres/lwres.h>
+#include <lwres/result.h>
+
+#include "assert_p.h"
+#include "context_p.h"
+
+/*
+ * Requires:
+ *
+ * The "current" pointer in "b" points to encoded raw data.
+ *
+ * Ensures:
+ *
+ * The address of the first byte of the data is returned via "p",
+ * and the length is returned via "len". If NULL, they are not
+ * set.
+ *
+ * On return, the current pointer of "b" will point to the character
+ * following the data length and the data.
+ *
+ */
+lwres_result_t
+lwres_data_parse(lwres_buffer_t *b, unsigned char **p, lwres_uint16_t *len)
+{
+ lwres_uint16_t datalen;
+ unsigned char *data;
+
+ REQUIRE(b != NULL);
+
+ /*
+ * Pull off the length (2 bytes)
+ */
+ if (!SPACE_REMAINING(b, 2))
+ return (LWRES_R_UNEXPECTEDEND);
+ datalen = lwres_buffer_getuint16(b);
+
+ /*
+ * Set the pointer to this string to the right place, then
+ * advance the buffer pointer.
+ */
+ if (!SPACE_REMAINING(b, datalen))
+ return (LWRES_R_UNEXPECTEDEND);
+ data = b->base + b->current;
+ lwres_buffer_forward(b, datalen);
+
+ if (len != NULL)
+ *len = datalen;
+ if (p != NULL)
+ *p = data;
+
+ return (LWRES_R_SUCCESS);
+}
+
+/*
+ * Requires:
+ *
+ * The "current" pointer in "b" point to an encoded string.
+ *
+ * Ensures:
+ *
+ * The address of the first byte of the string is returned via "c",
+ * and the length is returned via "len". If NULL, they are not
+ * set.
+ *
+ * On return, the current pointer of "b" will point to the character
+ * following the string length, the string, and the trailing NULL.
+ *
+ */
+lwres_result_t
+lwres_string_parse(lwres_buffer_t *b, char **c, lwres_uint16_t *len)
+{
+ lwres_uint16_t datalen;
+ char *string;
+
+ REQUIRE(b != NULL);
+
+ /*
+ * Pull off the length (2 bytes)
+ */
+ if (!SPACE_REMAINING(b, 2))
+ return (LWRES_R_UNEXPECTEDEND);
+ datalen = lwres_buffer_getuint16(b);
+
+ /*
+ * Set the pointer to this string to the right place, then
+ * advance the buffer pointer.
+ */
+ if (!SPACE_REMAINING(b, datalen))
+ return (LWRES_R_UNEXPECTEDEND);
+ string = (char *)b->base + b->current;
+ lwres_buffer_forward(b, datalen);
+
+ /*
+ * Skip the "must be zero" byte.
+ */
+ if (!SPACE_REMAINING(b, 1))
+ return (LWRES_R_UNEXPECTEDEND);
+ if (0 != lwres_buffer_getuint8(b))
+ return (LWRES_R_FAILURE);
+
+ if (len != NULL)
+ *len = datalen;
+ if (c != NULL)
+ *c = string;
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_addr_parse(lwres_buffer_t *b, lwres_addr_t *addr)
+{
+ REQUIRE(addr != NULL);
+
+ if (!SPACE_REMAINING(b, 6))
+ return (LWRES_R_UNEXPECTEDEND);
+
+ addr->family = lwres_buffer_getuint32(b);
+ addr->length = lwres_buffer_getuint16(b);
+
+ if (!SPACE_REMAINING(b, addr->length))
+ return (LWRES_R_UNEXPECTEDEND);
+ if (addr->length > LWRES_ADDR_MAXLEN)
+ return (LWRES_R_FAILURE);
+
+ lwres_buffer_getmem(b, addr->address, addr->length);
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_getaddrsbyname(lwres_context_t *ctx, const char *name,
+ lwres_uint32_t addrtypes, lwres_gabnresponse_t **structp)
+{
+ lwres_gabnrequest_t request;
+ lwres_gabnresponse_t *response;
+ int ret;
+ int recvlen;
+ lwres_buffer_t b_in, b_out;
+ lwres_lwpacket_t pkt;
+ lwres_uint32_t serial;
+ char *buffer;
+ char target_name[1024];
+ unsigned int target_length;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(name != NULL);
+ REQUIRE(addrtypes != 0);
+ REQUIRE(structp != NULL && *structp == NULL);
+
+ b_in.base = NULL;
+ b_out.base = NULL;
+ response = NULL;
+ buffer = NULL;
+ serial = lwres_context_nextserial(ctx);
+
+ buffer = CTXMALLOC(LWRES_RECVLENGTH);
+ if (buffer == NULL) {
+ ret = LWRES_R_NOMEMORY;
+ goto out;
+ }
+
+ target_length = strlen(name);
+ if (target_length >= sizeof(target_name))
+ return (LWRES_R_FAILURE);
+ strcpy(target_name, name); /* strcpy is safe */
+
+ /*
+ * Set up our request and render it to a buffer.
+ */
+ request.flags = 0;
+ request.addrtypes = addrtypes;
+ request.name = target_name;
+ request.namelen = target_length;
+ pkt.pktflags = 0;
+ pkt.serial = serial;
+ pkt.result = 0;
+ pkt.recvlength = LWRES_RECVLENGTH;
+
+ again:
+ ret = lwres_gabnrequest_render(ctx, &request, &pkt, &b_out);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ ret = lwres_context_sendrecv(ctx, b_out.base, b_out.length, buffer,
+ LWRES_RECVLENGTH, &recvlen);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ lwres_buffer_init(&b_in, buffer, recvlen);
+ b_in.used = recvlen;
+
+ /*
+ * Parse the packet header.
+ */
+ ret = lwres_lwpacket_parseheader(&b_in, &pkt);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ /*
+ * Sanity check.
+ */
+ if (pkt.serial != serial)
+ goto again;
+ if (pkt.opcode != LWRES_OPCODE_GETADDRSBYNAME)
+ goto again;
+
+ /*
+ * Free what we've transmitted
+ */
+ CTXFREE(b_out.base, b_out.length);
+ b_out.base = NULL;
+ b_out.length = 0;
+
+ if (pkt.result != LWRES_R_SUCCESS) {
+ ret = pkt.result;
+ goto out;
+ }
+
+ /*
+ * Parse the response.
+ */
+ ret = lwres_gabnresponse_parse(ctx, &b_in, &pkt, &response);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+ response->base = buffer;
+ response->baselen = LWRES_RECVLENGTH;
+ buffer = NULL; /* don't free this below */
+
+ *structp = response;
+ return (LWRES_R_SUCCESS);
+
+ out:
+ if (b_out.base != NULL)
+ CTXFREE(b_out.base, b_out.length);
+ if (buffer != NULL)
+ CTXFREE(buffer, LWRES_RECVLENGTH);
+ if (response != NULL)
+ lwres_gabnresponse_free(ctx, &response);
+
+ return (ret);
+}
+
+
+lwres_result_t
+lwres_getnamebyaddr(lwres_context_t *ctx, lwres_uint32_t addrtype,
+ lwres_uint16_t addrlen, const unsigned char *addr,
+ lwres_gnbaresponse_t **structp)
+{
+ lwres_gnbarequest_t request;
+ lwres_gnbaresponse_t *response;
+ int ret;
+ int recvlen;
+ lwres_buffer_t b_in, b_out;
+ lwres_lwpacket_t pkt;
+ lwres_uint32_t serial;
+ char *buffer;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(addrtype != 0);
+ REQUIRE(addrlen != 0);
+ REQUIRE(addr != NULL);
+ REQUIRE(structp != NULL && *structp == NULL);
+
+ b_in.base = NULL;
+ b_out.base = NULL;
+ response = NULL;
+ buffer = NULL;
+ serial = lwres_context_nextserial(ctx);
+
+ buffer = CTXMALLOC(LWRES_RECVLENGTH);
+ if (buffer == NULL) {
+ ret = LWRES_R_NOMEMORY;
+ goto out;
+ }
+
+ /*
+ * Set up our request and render it to a buffer.
+ */
+ request.flags = 0;
+ request.addr.family = addrtype;
+ request.addr.length = addrlen;
+ memcpy(request.addr.address, addr, addrlen);
+ pkt.pktflags = 0;
+ pkt.serial = serial;
+ pkt.result = 0;
+ pkt.recvlength = LWRES_RECVLENGTH;
+
+ again:
+ ret = lwres_gnbarequest_render(ctx, &request, &pkt, &b_out);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ ret = lwres_context_sendrecv(ctx, b_out.base, b_out.length, buffer,
+ LWRES_RECVLENGTH, &recvlen);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ lwres_buffer_init(&b_in, buffer, recvlen);
+ b_in.used = recvlen;
+
+ /*
+ * Parse the packet header.
+ */
+ ret = lwres_lwpacket_parseheader(&b_in, &pkt);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ /*
+ * Sanity check.
+ */
+ if (pkt.serial != serial)
+ goto again;
+ if (pkt.opcode != LWRES_OPCODE_GETNAMEBYADDR)
+ goto again;
+
+ /*
+ * Free what we've transmitted
+ */
+ CTXFREE(b_out.base, b_out.length);
+ b_out.base = NULL;
+ b_out.length = 0;
+
+ if (pkt.result != LWRES_R_SUCCESS) {
+ ret = pkt.result;
+ goto out;
+ }
+
+ /*
+ * Parse the response.
+ */
+ ret = lwres_gnbaresponse_parse(ctx, &b_in, &pkt, &response);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+ response->base = buffer;
+ response->baselen = LWRES_RECVLENGTH;
+ buffer = NULL; /* don't free this below */
+
+ *structp = response;
+ return (LWRES_R_SUCCESS);
+
+ out:
+ if (b_out.base != NULL)
+ CTXFREE(b_out.base, b_out.length);
+ if (buffer != NULL)
+ CTXFREE(buffer, LWRES_RECVLENGTH);
+ if (response != NULL)
+ lwres_gnbaresponse_free(ctx, &response);
+
+ return (ret);
+}
+
+lwres_result_t
+lwres_getrdatabyname(lwres_context_t *ctx, const char *name,
+ lwres_uint16_t rdclass, lwres_uint16_t rdtype,
+ lwres_uint32_t flags, lwres_grbnresponse_t **structp)
+{
+ int ret;
+ int recvlen;
+ lwres_buffer_t b_in, b_out;
+ lwres_lwpacket_t pkt;
+ lwres_uint32_t serial;
+ char *buffer;
+ lwres_grbnrequest_t request;
+ lwres_grbnresponse_t *response;
+ char target_name[1024];
+ unsigned int target_length;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(name != NULL);
+ REQUIRE(structp != NULL && *structp == NULL);
+
+ b_in.base = NULL;
+ b_out.base = NULL;
+ response = NULL;
+ buffer = NULL;
+ serial = lwres_context_nextserial(ctx);
+
+ buffer = CTXMALLOC(LWRES_RECVLENGTH);
+ if (buffer == NULL) {
+ ret = LWRES_R_NOMEMORY;
+ goto out;
+ }
+
+ target_length = strlen(name);
+ if (target_length >= sizeof(target_name))
+ return (LWRES_R_FAILURE);
+ strcpy(target_name, name); /* strcpy is safe */
+
+ /*
+ * Set up our request and render it to a buffer.
+ */
+ request.rdclass = rdclass;
+ request.rdtype = rdtype;
+ request.flags = flags;
+ request.name = target_name;
+ request.namelen = target_length;
+ pkt.pktflags = 0;
+ pkt.serial = serial;
+ pkt.result = 0;
+ pkt.recvlength = LWRES_RECVLENGTH;
+
+ again:
+ ret = lwres_grbnrequest_render(ctx, &request, &pkt, &b_out);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ ret = lwres_context_sendrecv(ctx, b_out.base, b_out.length, buffer,
+ LWRES_RECVLENGTH, &recvlen);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ lwres_buffer_init(&b_in, buffer, recvlen);
+ b_in.used = recvlen;
+
+ /*
+ * Parse the packet header.
+ */
+ ret = lwres_lwpacket_parseheader(&b_in, &pkt);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ /*
+ * Sanity check.
+ */
+ if (pkt.serial != serial)
+ goto again;
+ if (pkt.opcode != LWRES_OPCODE_GETRDATABYNAME)
+ goto again;
+
+ /*
+ * Free what we've transmitted
+ */
+ CTXFREE(b_out.base, b_out.length);
+ b_out.base = NULL;
+ b_out.length = 0;
+
+ if (pkt.result != LWRES_R_SUCCESS) {
+ ret = pkt.result;
+ goto out;
+ }
+
+ /*
+ * Parse the response.
+ */
+ ret = lwres_grbnresponse_parse(ctx, &b_in, &pkt, &response);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+ response->base = buffer;
+ response->baselen = LWRES_RECVLENGTH;
+ buffer = NULL; /* don't free this below */
+
+ *structp = response;
+ return (LWRES_R_SUCCESS);
+
+ out:
+ if (b_out.base != NULL)
+ CTXFREE(b_out.base, b_out.length);
+ if (buffer != NULL)
+ CTXFREE(buffer, LWRES_RECVLENGTH);
+ if (response != NULL)
+ lwres_grbnresponse_free(ctx, &response);
+
+ return (ret);
+}
diff --git a/lib/liblwres/man/Makefile.in b/lib/liblwres/man/Makefile.in
new file mode 100644
index 000000000..d06f370ad
--- /dev/null
+++ b/lib/liblwres/man/Makefile.in
@@ -0,0 +1,232 @@
+# Copyright (C) 2001 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 INTERNET SOFTWARE CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SOFTWARE CONSORTIUM 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.
+
+# $Id: Makefile.in,v 1.1 2004/03/15 20:35:25 as Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+@BIND9_MAKE_RULES@
+
+# Alphabetically
+#MANPAGES = lwres.3 lwres_addr_parse.3 lwres_buffer.3 \
+# lwres_buffer_add.3 lwres_buffer_back.3 lwres_buffer_clear.3 \
+# lwres_buffer_first.3 lwres_buffer_forward.3 \
+# lwres_buffer_getmem.3 lwres_buffer_getuint16.3 \
+# lwres_buffer_getuint32.3 lwres_buffer_getuint8.3 \
+# lwres_buffer_init.3 lwres_buffer_invalidate.3 \
+# lwres_buffer_putmem.3 lwres_buffer_putuint16.3 \
+# lwres_buffer_putuint32.3 lwres_buffer_putuint8.3 \
+# lwres_buffer_subtract.3 lwres_conf_clear.3 \
+# lwres_conf_get.3 lwres_conf_init.3 \
+# lwres_conf_parse.3 lwres_conf_print.3 \
+# lwres_config.3 lwres_context.3 \
+# lwres_context_allocmem.3 lwres_context_create.3 \
+# lwres_context_destroy.3 lwres_context_freemem.3 \
+# lwres_context_initserial.3 lwres_context_nextserial.3 \
+# lwres_context_sendrecv.3 lwres_endhostent.3 \
+# lwres_endhostent_r.3 lwres_freeaddrinfo.3 \
+# lwres_freehostent.3 lwres_gabn.3 \
+# lwres_gabnrequest_free.3 lwres_gabnrequest_parse.3 \
+# lwres_gabnrequest_render.3 lwres_gabnresponse_free.3 \
+# lwres_gabnresponse_parse.3 lwres_gabnresponse_render.3 \
+# lwres_gai_strerror.3 lwres_getaddrinfo.3 \
+# lwres_getaddrsbyname.3 lwres_gethostbyaddr.3 \
+# lwres_gethostbyaddr_r.3 lwres_gethostbyname.3 \
+# lwres_gethostbyname2.3 lwres_gethostbyname_r.3 \
+# lwres_gethostent.3 lwres_gethostent_r.3 \
+# lwres_getipnode.3 lwres_getipnodebyaddr.3 \
+# lwres_getipnodebyname.3 lwres_getnamebyaddr.3 \
+# lwres_getnameinfo.3 lwres_getrrsetbyname.3 \
+# lwres_gnba.3 lwres_gnbarequest_free.3 \
+# lwres_gnbarequest_parse.3 lwres_gnbarequest_render.3 \
+# lwres_gnbaresponse_free.3 lwres_gnbaresponse_parse.3 \
+# lwres_gnbaresponse_render.3 lwres_herror.3 \
+# lwres_hstrerror.3 lwres_inetntop.3 \
+# lwres_lwpacket_parseheader.3 lwres_lwpacket_renderheader.3 \
+# lwres_net_ntop.3 lwres_noop.3 \
+# lwres_nooprequest_free.3 lwres_nooprequest_parse.3 \
+# lwres_nooprequest_render.3 lwres_noopresponse_free.3 \
+# lwres_noopresponse_parse.3 lwres_noopresponse_render.3 \
+# lwres_packet.3 lwres_resutil.3 \
+# lwres_sethostent.3 lwres_sethostent_r.3 \
+# lwres_string_parse.3
+
+
+MANPAGES = lwres.3 lwres_buffer.3 lwres_config.3 lwres_context.3 \
+ lwres_gabn.3 lwres_gai_strerror.3 lwres_getaddrinfo.3 \
+ lwres_gethostent.3 lwres_getipnode.3 lwres_getnameinfo.3 \
+ lwres_getrrsetbyname.3 lwres_gnba.3 lwres_hstrerror.3 lwres_inetntop.3 \
+ lwres_noop.3 lwres_packet.3 lwres_resutil.3
+
+HTMLPAGES = lwres.html lwres_buffer.html lwres_config.html lwres_context.html \
+ lwres_gabn.html lwres_gai_strerror.html lwres_getaddrinfo.html \
+ lwres_gethostent.html lwres_getipnode.html lwres_getnameinfo.html \
+ lwres_getrrsetbyname.html lwres_gnba.html lwres_hstrerror.html lwres_inetntop.html \
+ lwres_noop.html lwres_packet.html lwres_resutil.html
+
+MANOBJS = ${MANPAGES} ${HTMLPAGES}
+
+doc man:: ${MANOBJS}
+
+docclean manclean maintainer-clean::
+ rm -f ${MANOBJS}
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man3
+
+man3 = ${DESTDIR}${mandir}/man3
+
+install:: installdirs
+ for m in ${MANPAGES}; do ${INSTALL_DATA} ${srcdir}/$$m ${DESTDIR}${mandir}/man3; done
+ rm -f ${man3}/lwres_addr_parse.3
+ @LN@ ${man3}/lwres_resutil.3 ${man3}/lwres_addr_parse.3
+ rm -f ${man3}/lwres_buffer_add.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_add.3
+ rm -f ${man3}/lwres_buffer_back.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_back.3
+ rm -f ${man3}/lwres_buffer_clear.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_clear.3
+ rm -f ${man3}/lwres_buffer_first.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_first.3
+ rm -f ${man3}/lwres_buffer_forward.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_forward.3
+ rm -f ${man3}/lwres_buffer_getmem.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_getmem.3
+ rm -f ${man3}/lwres_buffer_getuint16.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_getuint16.3
+ rm -f ${man3}/lwres_buffer_getuint32.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_getuint32.3
+ rm -f ${man3}/lwres_buffer_getuint8.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_getuint8.3
+ rm -f ${man3}/lwres_buffer_init.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_init.3
+ rm -f ${man3}/lwres_buffer_invalidate.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_invalidate.3
+ rm -f ${man3}/lwres_buffer_putmem.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_putmem.3
+ rm -f ${man3}/lwres_buffer_putuint16.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_putuint16.3
+ rm -f ${man3}/lwres_buffer_putuint32.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_putuint32.3
+ rm -f ${man3}/lwres_buffer_putuint8.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_putuint8.3
+ rm -f ${man3}/lwres_buffer_subtract.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_subtract.3
+ rm -f ${man3}/lwres_conf_clear.3
+ @LN@ ${man3}/lwres_config.3 ${man3}/lwres_conf_clear.3
+ rm -f ${man3}/lwres_conf_get.3
+ @LN@ ${man3}/lwres_config.3 ${man3}/lwres_conf_get.3
+ rm -f ${man3}/lwres_conf_init.3
+ @LN@ ${man3}/lwres_config.3 ${man3}/lwres_conf_init.3
+ rm -f ${man3}/lwres_conf_parse.3
+ @LN@ ${man3}/lwres_config.3 ${man3}/lwres_conf_parse.3
+ rm -f ${man3}/lwres_conf_print.3
+ @LN@ ${man3}/lwres_config.3 ${man3}/lwres_conf_print.3
+ rm -f ${man3}/lwres_context_allocmem.3
+ @LN@ ${man3}/lwres_context.3 ${man3}/lwres_context_allocmem.3
+ rm -f ${man3}/lwres_context_create.3
+ @LN@ ${man3}/lwres_context.3 ${man3}/lwres_context_create.3
+ rm -f ${man3}/lwres_context_destroy.3
+ @LN@ ${man3}/lwres_context.3 ${man3}/lwres_context_destroy.3
+ rm -f ${man3}/lwres_context_freemem.3
+ @LN@ ${man3}/lwres_context.3 ${man3}/lwres_context_freemem.3
+ rm -f ${man3}/lwres_context_initserial.3
+ @LN@ ${man3}/lwres_context.3 ${man3}/lwres_context_initserial.3
+ rm -f ${man3}/lwres_context_nextserial.3
+ @LN@ ${man3}/lwres_context.3 ${man3}/lwres_context_nextserial.3
+ rm -f ${man3}/lwres_context_sendrecv.3
+ @LN@ ${man3}/lwres_context.3 ${man3}/lwres_context_sendrecv.3
+ rm -f ${man3}/lwres_endhostent.3
+ @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_endhostent.3
+ rm -f ${man3}/lwres_endhostent_r.3
+ @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_endhostent_r.3
+ rm -f ${man3}/lwres_freeaddrinfo.3
+ @LN@ ${man3}/lwres_getaddrinfo.3 ${man3}/lwres_freeaddrinfo.3
+ rm -f ${man3}/lwres_freehostent.3
+ @LN@ ${man3}/lwres_getipnode.3 ${man3}/lwres_freehostent.3
+ rm -f ${man3}/lwres_gabnrequest_free.3
+ @LN@ ${man3}/lwres_gabn.3 ${man3}/lwres_gabnrequest_free.3
+ rm -f ${man3}/lwres_gabnrequest_parse.3
+ @LN@ ${man3}/lwres_gabn.3 ${man3}/lwres_gabnrequest_parse.3
+ rm -f ${man3}/lwres_gabnrequest_render.3
+ @LN@ ${man3}/lwres_gabn.3 ${man3}/lwres_gabnrequest_render.3
+ rm -f ${man3}/lwres_gabnresponse_free.3
+ @LN@ ${man3}/lwres_gabn.3 ${man3}/lwres_gabnresponse_free.3
+ rm -f ${man3}/lwres_gabnresponse_parse.3
+ @LN@ ${man3}/lwres_gabn.3 ${man3}/lwres_gabnresponse_parse.3
+ rm -f ${man3}/lwres_gabnresponse_render.3
+ @LN@ ${man3}/lwres_gabn.3 ${man3}/lwres_gabnresponse_render.3
+ rm -f ${man3}/lwres_getaddrsbyname.3
+ @LN@ ${man3}/lwres_resutil.3 ${man3}/lwres_getaddrsbyname.3
+ rm -f ${man3}/lwres_gethostbyaddr.3
+ @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_gethostbyaddr.3
+ rm -f ${man3}/lwres_gethostbyaddr_r.3
+ @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_gethostbyaddr_r.3
+ rm -f ${man3}/lwres_gethostbyname.3
+ @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_gethostbyname.3
+ rm -f ${man3}/lwres_gethostbyname2.3
+ @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_gethostbyname2.3
+ rm -f ${man3}/lwres_gethostbyname_r.3
+ @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_gethostbyname_r.3
+ rm -f ${man3}/lwres_gethostent_r.3
+ @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_gethostent_r.3
+ rm -f ${man3}/lwres_getipnodebyaddr.3
+ @LN@ ${man3}/lwres_getipnode.3 ${man3}/lwres_getipnodebyaddr.3
+ rm -f ${man3}/lwres_getipnodebyname.3
+ @LN@ ${man3}/lwres_getipnode.3 ${man3}/lwres_getipnodebyname.3
+ rm -f ${man3}/lwres_getnamebyaddr.3
+ @LN@ ${man3}/lwres_resutil.3 ${man3}/lwres_getnamebyaddr.3
+ rm -f ${man3}/lwres_gnbarequest_free.3
+ @LN@ ${man3}/lwres_gnba.3 ${man3}/lwres_gnbarequest_free.3
+ rm -f ${man3}/lwres_gnbarequest_parse.3
+ @LN@ ${man3}/lwres_gnba.3 ${man3}/lwres_gnbarequest_parse.3
+ rm -f ${man3}/lwres_gnbarequest_render.3
+ @LN@ ${man3}/lwres_gnba.3 ${man3}/lwres_gnbarequest_render.3
+ rm -f ${man3}/lwres_gnbaresponse_free.3
+ @LN@ ${man3}/lwres_gnba.3 ${man3}/lwres_gnbaresponse_free.3
+ rm -f ${man3}/lwres_gnbaresponse_parse.3
+ @LN@ ${man3}/lwres_gnba.3 ${man3}/lwres_gnbaresponse_parse.3
+ rm -f ${man3}/lwres_gnbaresponse_render.3
+ @LN@ ${man3}/lwres_gnba.3 ${man3}/lwres_gnbaresponse_render.3
+ rm -f ${man3}/lwres_herror.3
+ @LN@ ${man3}/lwres_hstrerror.3 ${man3}/lwres_herror.3
+ rm -f ${man3}/lwres_lwpacket_parseheader.3
+ @LN@ ${man3}/lwres_packet.3 ${man3}/lwres_lwpacket_parseheader.3
+ rm -f ${man3}/lwres_lwpacket_renderheader.3
+ @LN@ ${man3}/lwres_packet.3 ${man3}/lwres_lwpacket_renderheader.3
+ rm -f ${man3}/lwres_net_ntop.3
+ @LN@ ${man3}/lwres_inetntop.3 ${man3}/lwres_net_ntop.3
+ rm -f ${man3}/lwres_nooprequest_free.3
+ @LN@ ${man3}/lwres_noop.3 ${man3}/lwres_nooprequest_free.3
+ rm -f ${man3}/lwres_nooprequest_parse.3
+ @LN@ ${man3}/lwres_noop.3 ${man3}/lwres_nooprequest_parse.3
+ rm -f ${man3}/lwres_nooprequest_render.3
+ @LN@ ${man3}/lwres_noop.3 ${man3}/lwres_nooprequest_render.3
+ rm -f ${man3}/lwres_noopresponse_free.3
+ @LN@ ${man3}/lwres_noop.3 ${man3}/lwres_noopresponse_free.3
+ rm -f ${man3}/lwres_noopresponse_parse.3
+ @LN@ ${man3}/lwres_noop.3 ${man3}/lwres_noopresponse_parse.3
+ rm -f ${man3}/lwres_noopresponse_render.3
+ @LN@ ${man3}/lwres_noop.3 ${man3}/lwres_noopresponse_render.3
+ rm -f ${man3}/lwres_sethostent.3
+ @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_sethostent.3
+ rm -f ${man3}/lwres_sethostent_r.3
+ @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_sethostent_r.3
+ rm -f ${man3}/lwres_string_parse.3
+ @LN@ ${man3}/lwres_resutil.3 ${man3}/lwres_string_parse.3
diff --git a/lib/liblwres/man/lwres.3 b/lib/liblwres/man/lwres.3
new file mode 100644
index 000000000..f2393912d
--- /dev/null
+++ b/lib/liblwres/man/lwres.3
@@ -0,0 +1,158 @@
+.\"
+.\" Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM 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.
+.\"
+.TH "LWRES" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres \- introduction to the lightweight resolver library
+.SH SYNOPSIS
+\fB#include <lwres/lwres.h>\fR
+.SH "DESCRIPTION"
+.PP
+The BIND 9 lightweight resolver library is a simple, name service
+independent stub resolver library. It provides hostname-to-address
+and address-to-hostname lookup services to applications by
+transmitting lookup requests to a resolver daemon
+\fBlwresd\fR
+running on the local host. The resover daemon performs the
+lookup using the DNS or possibly other name service protocols,
+and returns the results to the application through the library.
+The library and resolver daemon communicate using a simple
+UDP-based protocol.
+.SH "OVERVIEW"
+.PP
+The lwresd library implements multiple name service APIs.
+The standard
+\fBgethostbyname()\fR,
+\fBgethostbyaddr()\fR,
+\fBgethostbyname_r()\fR,
+\fBgethostbyaddr_r()\fR,
+\fBgetaddrinfo()\fR,
+\fBgetipnodebyname()\fR,
+and
+\fBgetipnodebyaddr()\fR
+functions are all supported. To allow the lwres library to coexist
+with system libraries that define functions of the same name,
+the library defines these functions with names prefixed by
+lwres_.
+To define the standard names, applications must include the
+header file
+\fI<lwres/netdb.h>\fR
+which contains macro definitions mapping the standard function names
+into
+lwres_
+prefixed ones. Operating system vendors who integrate the lwres
+library into their base distributions should rename the functions
+in the library proper so that the renaming macros are not needed.
+.PP
+The library also provides a native API consisting of the functions
+\fBlwres_getaddrsbyname()\fR
+and
+\fBlwres_getnamebyaddr()\fR.
+These may be called by applications that require more detailed
+control over the lookup process than the standard functions
+provide.
+.PP
+In addition to these name service independent address lookup
+functions, the library implements a new, experimental API
+for looking up arbitrary DNS resource records, using the
+\fBlwres_getaddrsbyname()\fR
+function.
+.PP
+Finally, there is a low-level API for converting lookup
+requests and responses to and from raw lwres protocol packets.
+This API can be used by clients requiring nonblocking operation,
+and is also used when implementing the server side of the lwres
+protocol, for example in the
+\fBlwresd\fR
+resolver daemon. The use of this low-level API in clients
+and servers is outlined in the following sections.
+.SH "CLIENT-SIDE LOW-LEVEL API CALL FLOW"
+.PP
+When a client program wishes to make an lwres request using the
+native low-level API, it typically performs the following
+sequence of actions.
+.PP
+(1) Allocate or use an existing \fBlwres_packet_t\fR,
+called pkt below.
+.PP
+(2) Set \fBpkt.recvlength\fR to the maximum length we will accept.
+This is done so the receiver of our packets knows how large our receive
+buffer is. The "default" is a constant in
+\fIlwres.h\fR: LWRES_RECVLENGTH = 4096.
+.PP
+(3) Set \fBpkt.serial\fR
+to a unique serial number. This value is echoed
+back to the application by the remote server.
+.PP
+(4) Set \fBpkt.pktflags\fR. Usually this is set to 0.
+.PP
+(5) Set \fBpkt.result\fR to 0.
+.PP
+(6) Call \fBlwres_*request_render()\fR,
+or marshall in the data using the primitives
+such as \fBlwres_packet_render()\fR
+and storing the packet data.
+.PP
+(7) Transmit the resulting buffer.
+.PP
+(8) Call \fBlwres_*response_parse()\fR
+to parse any packets received.
+.PP
+(9) Verify that the opcode and serial match a request, and process the
+packet specific information contained in the body.
+.SH "SERVER-SIDE LOW-LEVEL API CALL FLOW"
+.PP
+When implementing the server side of the lightweight resolver
+protocol using the lwres library, a sequence of actions like the
+following is typically involved in processing each request packet.
+.PP
+Note that the same \fBlwres_packet_t\fR is used
+in both the \fB_parse()\fR and \fB_render()\fR calls,
+with only a few modifications made
+to the packet header's contents between uses. This method is recommended
+as it keeps the serial, opcode, and other fields correct.
+.PP
+(1) When a packet is received, call \fBlwres_*request_parse()\fR to
+unmarshall it. This returns a \fBlwres_packet_t\fR (also called pkt, below)
+as well as a data specific type, such as \fBlwres_gabnrequest_t\fR.
+.PP
+(2) Process the request in the data specific type.
+.PP
+(3) Set the \fBpkt.result\fR,
+\fBpkt.recvlength\fR as above. All other fields can
+be left untouched since they were filled in by the \fB*_parse()\fR call
+above. If using \fBlwres_*response_render()\fR,
+\fBpkt.pktflags\fR will be set up
+properly. Otherwise, the LWRES_LWPACKETFLAG_RESPONSE bit should be
+set.
+.PP
+(4) Call the data specific rendering function, such as
+\fBlwres_gabnresponse_render()\fR.
+.PP
+(5) Send the resulting packet to the client.
+.PP
+.SH "SEE ALSO"
+.PP
+\fBlwres_gethostent\fR(3),
+\fBlwres_getipnode\fR(3),
+\fBlwres_getnameinfo\fR(3),
+\fBlwres_noop\fR(3),
+\fBlwres_gabn\fR(3),
+\fBlwres_gnba\fR(3),
+\fBlwres_context\fR(3),
+\fBlwres_config\fR(3),
+\fBresolver\fR(5),
+\fBlwresd\fR(8).
diff --git a/lib/liblwres/man/lwres.docbook b/lib/liblwres/man/lwres.docbook
new file mode 100644
index 000000000..15378e908
--- /dev/null
+++ b/lib/liblwres/man/lwres.docbook
@@ -0,0 +1,244 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+
+<!-- $Id: lwres.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+<refentryinfo>
+
+<date>Jun 30, 2000</date>
+</refentryinfo>
+<refmeta>
+<refentrytitle>lwres</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+<refnamediv>
+<refname>lwres</refname>
+<refpurpose>introduction to the lightweight resolver library</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/lwres.h&gt;</funcsynopsisinfo>
+</funcsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+<title>DESCRIPTION</title>
+<para>
+The BIND 9 lightweight resolver library is a simple, name service
+independent stub resolver library. It provides hostname-to-address
+and address-to-hostname lookup services to applications by
+transmitting lookup requests to a resolver daemon
+<command>lwresd</command>
+running on the local host. The resover daemon performs the
+lookup using the DNS or possibly other name service protocols,
+and returns the results to the application through the library.
+The library and resolver daemon communicate using a simple
+UDP-based protocol.
+</para>
+</refsect1>
+
+<refsect1>
+<title>OVERVIEW</title>
+<para>
+The lwresd library implements multiple name service APIs.
+The standard
+<function>gethostbyname()</function>,
+<function>gethostbyaddr()</function>,
+<function>gethostbyname_r()</function>,
+<function>gethostbyaddr_r()</function>,
+<function>getaddrinfo()</function>,
+<function>getipnodebyname()</function>,
+and
+<function>getipnodebyaddr()</function>
+functions are all supported. To allow the lwres library to coexist
+with system libraries that define functions of the same name,
+the library defines these functions with names prefixed by
+<literal>lwres_</literal>.
+To define the standard names, applications must include the
+header file
+<filename>&lt;lwres/netdb.h&gt;</filename>
+which contains macro definitions mapping the standard function names
+into
+<literal>lwres_</literal>
+prefixed ones. Operating system vendors who integrate the lwres
+library into their base distributions should rename the functions
+in the library proper so that the renaming macros are not needed.
+</para>
+<para>
+The library also provides a native API consisting of the functions
+<function>lwres_getaddrsbyname()</function>
+and
+<function>lwres_getnamebyaddr()</function>.
+These may be called by applications that require more detailed
+control over the lookup process than the standard functions
+provide.
+</para>
+<para>
+In addition to these name service independent address lookup
+functions, the library implements a new, experimental API
+for looking up arbitrary DNS resource records, using the
+<function>lwres_getaddrsbyname()</function>
+function.
+</para>
+<para>
+Finally, there is a low-level API for converting lookup
+requests and responses to and from raw lwres protocol packets.
+This API can be used by clients requiring nonblocking operation,
+and is also used when implementing the server side of the lwres
+protocol, for example in the
+<command>lwresd</command>
+resolver daemon. The use of this low-level API in clients
+and servers is outlined in the following sections.
+</para>
+</refsect1>
+<refsect1>
+<title>CLIENT-SIDE LOW-LEVEL API CALL FLOW</title>
+<para>
+When a client program wishes to make an lwres request using the
+native low-level API, it typically performs the following
+sequence of actions.
+</para>
+<para>
+(1) Allocate or use an existing <type>lwres_packet_t</type>,
+called <varname>pkt</varname> below.
+</para>
+<para>
+(2) Set <structfield>pkt.recvlength</structfield> to the maximum length we will accept.
+This is done so the receiver of our packets knows how large our receive
+buffer is. The "default" is a constant in
+<filename>lwres.h</filename>: <constant>LWRES_RECVLENGTH = 4096</constant>.
+</para>
+<para>
+(3) Set <structfield>pkt.serial</structfield>
+to a unique serial number. This value is echoed
+back to the application by the remote server.
+</para>
+<para>
+(4) Set <structfield>pkt.pktflags</structfield>. Usually this is set to 0.
+</para>
+<para>
+(5) Set <structfield>pkt.result</structfield> to 0.
+</para>
+<para>
+(6) Call <function>lwres_*request_render()</function>,
+or marshall in the data using the primitives
+such as <function>lwres_packet_render()</function>
+and storing the packet data.
+</para>
+<para>
+(7) Transmit the resulting buffer.
+</para>
+<para>
+(8) Call <function>lwres_*response_parse()</function>
+to parse any packets received.
+</para>
+<para>
+(9) Verify that the opcode and serial match a request, and process the
+packet specific information contained in the body.
+</para>
+</refsect1>
+<refsect1>
+<title>SERVER-SIDE LOW-LEVEL API CALL FLOW</title>
+<para>
+When implementing the server side of the lightweight resolver
+protocol using the lwres library, a sequence of actions like the
+following is typically involved in processing each request packet.
+</para>
+<para>
+Note that the same <type>lwres_packet_t</type> is used
+in both the <function>_parse()</function> and <function>_render()</function> calls,
+with only a few modifications made
+to the packet header's contents between uses. This method is recommended
+as it keeps the serial, opcode, and other fields correct.
+</para>
+<para>
+(1) When a packet is received, call <function>lwres_*request_parse()</function> to
+unmarshall it. This returns a <type>lwres_packet_t</type> (also called <varname>pkt</varname>, below)
+as well as a data specific type, such as <type>lwres_gabnrequest_t</type>.
+</para>
+<para>
+(2) Process the request in the data specific type.
+</para>
+<para>
+(3) Set the <structfield>pkt.result</structfield>,
+<structfield>pkt.recvlength</structfield> as above. All other fields can
+be left untouched since they were filled in by the <function>*_parse()</function> call
+above. If using <function>lwres_*response_render()</function>,
+<structfield>pkt.pktflags</structfield> will be set up
+properly. Otherwise, the <constant>LWRES_LWPACKETFLAG_RESPONSE</constant> bit should be
+set.
+</para>
+<para>
+(4) Call the data specific rendering function, such as
+<function>lwres_gabnresponse_render()</function>.
+</para>
+<para>
+(5) Send the resulting packet to the client.
+</para>
+<para>
+</para>
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>lwres_gethostent</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_getipnode</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_getnameinfo</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_noop</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_gabn</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_gnba</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_context</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_config</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>resolver</refentrytitle><manvolnum>5</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwresd</refentrytitle><manvolnum>8</manvolnum>
+</citerefentry>.
+
+</para>
+</refsect1>
+</refentry>
diff --git a/lib/liblwres/man/lwres.html b/lib/liblwres/man/lwres.html
new file mode 100644
index 000000000..7b9f88dcb
--- /dev/null
+++ b/lib/liblwres/man/lwres.html
@@ -0,0 +1,444 @@
+<!--
+ - Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres&nbsp;--&nbsp;introduction to the lightweight resolver library</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN11"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN12"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/lwres.h&gt;</PRE
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN14"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>The BIND 9 lightweight resolver library is a simple, name service
+independent stub resolver library. It provides hostname-to-address
+and address-to-hostname lookup services to applications by
+transmitting lookup requests to a resolver daemon
+<B
+CLASS="COMMAND"
+>lwresd</B
+>
+running on the local host. The resover daemon performs the
+lookup using the DNS or possibly other name service protocols,
+and returns the results to the application through the library.
+The library and resolver daemon communicate using a simple
+UDP-based protocol.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN18"
+></A
+><H2
+>OVERVIEW</H2
+><P
+>The lwresd library implements multiple name service APIs.
+The standard
+<TT
+CLASS="FUNCTION"
+>gethostbyname()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>gethostbyaddr()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>gethostbyname_r()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>gethostbyaddr_r()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>getaddrinfo()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>getipnodebyname()</TT
+>,
+and
+<TT
+CLASS="FUNCTION"
+>getipnodebyaddr()</TT
+>
+functions are all supported. To allow the lwres library to coexist
+with system libraries that define functions of the same name,
+the library defines these functions with names prefixed by
+<TT
+CLASS="LITERAL"
+>lwres_</TT
+>.
+To define the standard names, applications must include the
+header file
+<TT
+CLASS="FILENAME"
+>&lt;lwres/netdb.h&gt;</TT
+>
+which contains macro definitions mapping the standard function names
+into
+<TT
+CLASS="LITERAL"
+>lwres_</TT
+>
+prefixed ones. Operating system vendors who integrate the lwres
+library into their base distributions should rename the functions
+in the library proper so that the renaming macros are not needed.</P
+><P
+>The library also provides a native API consisting of the functions
+<TT
+CLASS="FUNCTION"
+>lwres_getaddrsbyname()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_getnamebyaddr()</TT
+>.
+These may be called by applications that require more detailed
+control over the lookup process than the standard functions
+provide.</P
+><P
+>In addition to these name service independent address lookup
+functions, the library implements a new, experimental API
+for looking up arbitrary DNS resource records, using the
+<TT
+CLASS="FUNCTION"
+>lwres_getaddrsbyname()</TT
+>
+function.</P
+><P
+>Finally, there is a low-level API for converting lookup
+requests and responses to and from raw lwres protocol packets.
+This API can be used by clients requiring nonblocking operation,
+and is also used when implementing the server side of the lwres
+protocol, for example in the
+<B
+CLASS="COMMAND"
+>lwresd</B
+>
+resolver daemon. The use of this low-level API in clients
+and servers is outlined in the following sections.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN38"
+></A
+><H2
+>CLIENT-SIDE LOW-LEVEL API CALL FLOW</H2
+><P
+>When a client program wishes to make an lwres request using the
+native low-level API, it typically performs the following
+sequence of actions.</P
+><P
+>(1) Allocate or use an existing <SPAN
+CLASS="TYPE"
+>lwres_packet_t</SPAN
+>,
+called <TT
+CLASS="VARNAME"
+>pkt</TT
+> below.</P
+><P
+>(2) Set <TT
+CLASS="STRUCTFIELD"
+><I
+>pkt.recvlength</I
+></TT
+> to the maximum length we will accept.
+This is done so the receiver of our packets knows how large our receive
+buffer is. The "default" is a constant in
+<TT
+CLASS="FILENAME"
+>lwres.h</TT
+>: <TT
+CLASS="CONSTANT"
+>LWRES_RECVLENGTH = 4096</TT
+>.</P
+><P
+>(3) Set <TT
+CLASS="STRUCTFIELD"
+><I
+>pkt.serial</I
+></TT
+>
+to a unique serial number. This value is echoed
+back to the application by the remote server.</P
+><P
+>(4) Set <TT
+CLASS="STRUCTFIELD"
+><I
+>pkt.pktflags</I
+></TT
+>. Usually this is set to 0.</P
+><P
+>(5) Set <TT
+CLASS="STRUCTFIELD"
+><I
+>pkt.result</I
+></TT
+> to 0.</P
+><P
+>(6) Call <TT
+CLASS="FUNCTION"
+>lwres_*request_render()</TT
+>,
+or marshall in the data using the primitives
+such as <TT
+CLASS="FUNCTION"
+>lwres_packet_render()</TT
+>
+and storing the packet data.</P
+><P
+>(7) Transmit the resulting buffer.</P
+><P
+>(8) Call <TT
+CLASS="FUNCTION"
+>lwres_*response_parse()</TT
+>
+to parse any packets received.</P
+><P
+>(9) Verify that the opcode and serial match a request, and process the
+packet specific information contained in the body.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN61"
+></A
+><H2
+>SERVER-SIDE LOW-LEVEL API CALL FLOW</H2
+><P
+>When implementing the server side of the lightweight resolver
+protocol using the lwres library, a sequence of actions like the
+following is typically involved in processing each request packet.</P
+><P
+>Note that the same <SPAN
+CLASS="TYPE"
+>lwres_packet_t</SPAN
+> is used
+in both the <TT
+CLASS="FUNCTION"
+>_parse()</TT
+> and <TT
+CLASS="FUNCTION"
+>_render()</TT
+> calls,
+with only a few modifications made
+to the packet header's contents between uses. This method is recommended
+as it keeps the serial, opcode, and other fields correct.</P
+><P
+>(1) When a packet is received, call <TT
+CLASS="FUNCTION"
+>lwres_*request_parse()</TT
+> to
+unmarshall it. This returns a <SPAN
+CLASS="TYPE"
+>lwres_packet_t</SPAN
+> (also called <TT
+CLASS="VARNAME"
+>pkt</TT
+>, below)
+as well as a data specific type, such as <SPAN
+CLASS="TYPE"
+>lwres_gabnrequest_t</SPAN
+>.</P
+><P
+>(2) Process the request in the data specific type.</P
+><P
+>(3) Set the <TT
+CLASS="STRUCTFIELD"
+><I
+>pkt.result</I
+></TT
+>,
+<TT
+CLASS="STRUCTFIELD"
+><I
+>pkt.recvlength</I
+></TT
+> as above. All other fields can
+be left untouched since they were filled in by the <TT
+CLASS="FUNCTION"
+>*_parse()</TT
+> call
+above. If using <TT
+CLASS="FUNCTION"
+>lwres_*response_render()</TT
+>,
+<TT
+CLASS="STRUCTFIELD"
+><I
+>pkt.pktflags</I
+></TT
+> will be set up
+properly. Otherwise, the <TT
+CLASS="CONSTANT"
+>LWRES_LWPACKETFLAG_RESPONSE</TT
+> bit should be
+set.</P
+><P
+>(4) Call the data specific rendering function, such as
+<TT
+CLASS="FUNCTION"
+>lwres_gabnresponse_render()</TT
+>.</P
+><P
+>(5) Send the resulting packet to the client.</P
+><P
+></P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN85"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_gethostent</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_getipnode</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_getnameinfo</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_noop</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_gabn</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_gnba</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_context</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_config</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>resolver</SPAN
+>(5)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwresd</SPAN
+>(8)</SPAN
+>.&#13;</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/lib/liblwres/man/lwres_buffer.3 b/lib/liblwres/man/lwres_buffer.3
new file mode 100644
index 000000000..8077fc2ef
--- /dev/null
+++ b/lib/liblwres/man/lwres_buffer.3
@@ -0,0 +1,277 @@
+.\"
+.\" Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM 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.
+.\"
+.TH "LWRES_BUFFER" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_buffer_init, lwres_buffer_invalidate, lwres_buffer_add, lwres_buffer_subtract, lwres_buffer_clear, lwres_buffer_first, lwres_buffer_forward, lwres_buffer_back, lwres_buffer_getuint8, lwres_buffer_putuint8, lwres_buffer_getuint16, lwres_buffer_putuint16, lwres_buffer_getuint32, lwres_buffer_putuint32, lwres_buffer_putmem, lwres_buffer_getmem \- lightweight resolver buffer management
+.SH SYNOPSIS
+\fB#include <lwres/lwbuffer.h>
+.sp
+.na
+void
+lwres_buffer_init(lwres_buffer_t *b, void *base, unsigned int length);
+.ad
+.sp
+.na
+void
+lwres_buffer_invalidate(lwres_buffer_t *b);
+.ad
+.sp
+.na
+void
+lwres_buffer_add(lwres_buffer_t *b, unsigned int n);
+.ad
+.sp
+.na
+void
+lwres_buffer_subtract(lwres_buffer_t *b, unsigned int n);
+.ad
+.sp
+.na
+void
+lwres_buffer_clear(lwres_buffer_t *b);
+.ad
+.sp
+.na
+void
+lwres_buffer_first(lwres_buffer_t *b);
+.ad
+.sp
+.na
+void
+lwres_buffer_forward(lwres_buffer_t *b, unsigned int n);
+.ad
+.sp
+.na
+void
+lwres_buffer_back(lwres_buffer_t *b, unsigned int n);
+.ad
+.sp
+.na
+lwres_uint8_t
+lwres_buffer_getuint8(lwres_buffer_t *b);
+.ad
+.sp
+.na
+void
+lwres_buffer_putuint8(lwres_buffer_t *b, lwres_uint8_t val);
+.ad
+.sp
+.na
+lwres_uint16_t
+lwres_buffer_getuint16(lwres_buffer_t *b);
+.ad
+.sp
+.na
+void
+lwres_buffer_putuint16(lwres_buffer_t *b, lwres_uint16_t val);
+.ad
+.sp
+.na
+lwres_uint32_t
+lwres_buffer_getuint32(lwres_buffer_t *b);
+.ad
+.sp
+.na
+void
+lwres_buffer_putuint32(lwres_buffer_t *b, lwres_uint32_t val);
+.ad
+.sp
+.na
+void
+lwres_buffer_putmem(lwres_buffer_t *b, const unsigned char *base, unsigned int length);
+.ad
+.sp
+.na
+void
+lwres_buffer_getmem(lwres_buffer_t *b, unsigned char *base, unsigned int length);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+These functions provide bounds checked access to a region of memory
+where data is being read or written.
+They are based on, and similar to, the
+isc_buffer_
+functions in the ISC library.
+.PP
+A buffer is a region of memory, together with a set of related
+subregions.
+The \fBused region\fR and the
+\fBavailable\fR region are disjoint, and
+their union is the buffer's region.
+The used region extends from the beginning of the buffer region to the
+last used byte.
+The available region extends from one byte greater than the last used
+byte to the end of the buffer's region.
+The size of the used region can be changed using various
+buffer commands.
+Initially, the used region is empty.
+.PP
+The used region is further subdivided into two disjoint regions: the
+\fBconsumed region\fR and the \fBremaining region\fR.
+The union of these two regions is the used region.
+The consumed region extends from the beginning of the used region to
+the byte before the \fBcurrent\fR offset (if any).
+The \fBremaining\fR region the current pointer to the end of the used
+region.
+The size of the consumed region can be changed using various
+buffer commands.
+Initially, the consumed region is empty.
+.PP
+The \fBactive region\fR is an (optional) subregion of the remaining
+region.
+It extends from the current offset to an offset in the
+remaining region.
+Initially, the active region is empty.
+If the current offset advances beyond the chosen offset,
+the active region will also be empty.
+.PP
+.sp
+.nf
+
+ /------------entire length---------------\\\\
+ /----- used region -----\\\\/-- available --\\\\
+ +----------------------------------------+
+ | consumed | remaining | |
+ +----------------------------------------+
+ a b c d e
+
+ a == base of buffer.
+ b == current pointer. Can be anywhere between a and d.
+ c == active pointer. Meaningful between b and d.
+ d == used pointer.
+ e == length of buffer.
+
+ a-e == entire length of buffer.
+ a-d == used region.
+ a-b == consumed region.
+ b-d == remaining region.
+ b-c == optional active region.
+.sp
+.fi
+.PP
+\fBlwres_buffer_init()\fR
+initializes the
+\fBlwres_buffer_t\fR
+\fI*b\fR
+and assocates it with the memory region of size
+\fIlength\fR
+bytes starting at location
+\fIbase.\fR
+.PP
+\fBlwres_buffer_invalidate()\fR
+marks the buffer
+\fI*b\fR
+as invalid. Invalidating a buffer after use is not required,
+but makes it possible to catch its possible accidental use.
+.PP
+The functions
+\fBlwres_buffer_add()\fR
+and
+\fBlwres_buffer_subtract()\fR
+respectively increase and decrease the used space in
+buffer
+\fI*b\fR
+by
+\fIn\fR
+bytes.
+\fBlwres_buffer_add()\fR
+checks for buffer overflow and
+\fBlwres_buffer_subtract()\fR
+checks for underflow.
+These functions do not allocate or deallocate memory.
+They just change the value of
+\fBused\fR.
+.PP
+A buffer is re-initialised by
+\fBlwres_buffer_clear()\fR.
+The function sets
+\fBused\fR ,
+\fBcurrent\fR
+and
+\fBactive\fR
+to zero.
+.PP
+\fBlwres_buffer_first\fR
+makes the consumed region of buffer
+\fI*p\fR
+empty by setting
+\fBcurrent\fR
+to zero (the start of the buffer).
+.PP
+\fBlwres_buffer_forward()\fR
+increases the consumed region of buffer
+\fI*b\fR
+by
+\fIn\fR
+bytes, checking for overflow.
+Similarly,
+\fBlwres_buffer_back()\fR
+decreases buffer
+\fIb\fR's
+consumed region by
+\fIn\fR
+bytes and checks for underflow.
+.PP
+\fBlwres_buffer_getuint8()\fR
+reads an unsigned 8-bit integer from
+\fI*b\fR
+and returns it.
+\fBlwres_buffer_putuint8()\fR
+writes the unsigned 8-bit integer
+\fIval\fR
+to buffer
+\fI*b\fR.
+.PP
+\fBlwres_buffer_getuint16()\fR
+and
+\fBlwres_buffer_getuint32()\fR
+are identical to
+\fBlwres_buffer_putuint8()\fR
+except that they respectively read an unsigned 16-bit or 32-bit integer
+in network byte order from
+\fIb\fR.
+Similarly,
+\fBlwres_buffer_putuint16()\fR
+and
+\fBlwres_buffer_putuint32()\fR
+writes the unsigned 16-bit or 32-bit integer
+\fIval\fR
+to buffer
+\fIb\fR,
+in network byte order.
+.PP
+Arbitrary amounts of data are read or written from a lightweight
+resolver buffer with
+\fBlwres_buffer_getmem()\fR
+and
+\fBlwres_buffer_putmem()\fR
+respectively.
+\fBlwres_buffer_putmem()\fR
+copies
+\fIlength\fR
+bytes of memory at
+\fIbase\fR
+to
+\fIb\fR.
+Conversely,
+\fBlwres_buffer_getmem()\fR
+copies
+\fIlength\fR
+bytes of memory from
+\fIb\fR
+to
+\fIbase\fR.
diff --git a/lib/liblwres/man/lwres_buffer.docbook b/lib/liblwres/man/lwres_buffer.docbook
new file mode 100644
index 000000000..8f9d55889
--- /dev/null
+++ b/lib/liblwres/man/lwres_buffer.docbook
@@ -0,0 +1,378 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+
+<!-- $Id: lwres_buffer.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+<refentryinfo>
+<date>Jun 30, 2000</date>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>lwres_buffer</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>lwres_buffer_init</refname>
+<refname>lwres_buffer_invalidate</refname>
+<refname>lwres_buffer_add</refname>
+<refname>lwres_buffer_subtract</refname>
+<refname>lwres_buffer_clear</refname>
+<refname>lwres_buffer_first</refname>
+<refname>lwres_buffer_forward</refname>
+<refname>lwres_buffer_back</refname>
+<refname>lwres_buffer_getuint8</refname>
+<refname>lwres_buffer_putuint8</refname>
+<refname>lwres_buffer_getuint16</refname>
+<refname>lwres_buffer_putuint16</refname>
+<refname>lwres_buffer_getuint32</refname>
+<refname>lwres_buffer_putuint32</refname>
+<refname>lwres_buffer_putmem</refname>
+<refname>lwres_buffer_getmem</refname>
+<refpurpose>lightweight resolver buffer management</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+
+<funcsynopsis>
+<funcsynopsisinfo>
+#include &lt;lwres/lwbuffer.h&gt;
+</funcsynopsisinfo>
+
+<funcprototype>
+
+<funcdef>
+void
+<function>lwres_buffer_init</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>void *base</paramdef>
+<paramdef>unsigned int length</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+void
+<function>lwres_buffer_invalidate</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_buffer_add</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>unsigned int n</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+void
+<function>lwres_buffer_subtract</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>unsigned int n</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+void
+<function>lwres_buffer_clear</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+void
+<function>lwres_buffer_first</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+void
+<function>lwres_buffer_forward</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>unsigned int n</paramdef>
+</funcprototype>
+<funcprototype>
+
+<funcdef>
+void
+<function>lwres_buffer_back</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>unsigned int n</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+lwres_uint8_t
+<function>lwres_buffer_getuint8</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+void
+<function>lwres_buffer_putuint8</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>lwres_uint8_t val</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+lwres_uint16_t
+<function>lwres_buffer_getuint16</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+void
+<function>lwres_buffer_putuint16</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>lwres_uint16_t val</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+lwres_uint32_t
+<function>lwres_buffer_getuint32</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+void
+<function>lwres_buffer_putuint32</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>lwres_uint32_t val</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+void
+<function>lwres_buffer_putmem</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>const unsigned char *base</paramdef>
+<paramdef>unsigned int length</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+void
+<function>lwres_buffer_getmem</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>unsigned char *base</paramdef>
+<paramdef>unsigned int length</paramdef>
+</funcprototype>
+
+</funcsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+
+<title>DESCRIPTION</title>
+<para>
+These functions provide bounds checked access to a region of memory
+where data is being read or written.
+They are based on, and similar to, the
+<literal>isc_buffer_</literal>
+functions in the ISC library.
+</para>
+<para>
+A buffer is a region of memory, together with a set of related
+subregions.
+The <emphasis>used region</emphasis> and the
+<emphasis>available</emphasis> region are disjoint, and
+their union is the buffer's region.
+The used region extends from the beginning of the buffer region to the
+last used byte.
+The available region extends from one byte greater than the last used
+byte to the end of the buffer's region.
+The size of the used region can be changed using various
+buffer commands.
+Initially, the used region is empty.
+</para>
+<para>
+The used region is further subdivided into two disjoint regions: the
+<emphasis>consumed region</emphasis> and the <emphasis>remaining region</emphasis>.
+The union of these two regions is the used region.
+The consumed region extends from the beginning of the used region to
+the byte before the <emphasis>current</emphasis> offset (if any).
+The <emphasis>remaining</emphasis> region the current pointer to the end of the used
+region.
+The size of the consumed region can be changed using various
+buffer commands.
+Initially, the consumed region is empty.
+</para>
+<para>
+The <emphasis>active region</emphasis> is an (optional) subregion of the remaining
+region.
+It extends from the current offset to an offset in the
+remaining region.
+Initially, the active region is empty.
+If the current offset advances beyond the chosen offset,
+the active region will also be empty.
+</para>
+<para>
+<programlisting>
+
+ /------------entire length---------------\\
+ /----- used region -----\\/-- available --\\
+ +----------------------------------------+
+ | consumed | remaining | |
+ +----------------------------------------+
+ a b c d e
+
+ a == base of buffer.
+ b == current pointer. Can be anywhere between a and d.
+ c == active pointer. Meaningful between b and d.
+ d == used pointer.
+ e == length of buffer.
+
+ a-e == entire length of buffer.
+ a-d == used region.
+ a-b == consumed region.
+ b-d == remaining region.
+ b-c == optional active region.
+</programlisting>
+</para>
+<para>
+<function>lwres_buffer_init()</function>
+initializes the
+<type>lwres_buffer_t</type>
+<parameter>*b</parameter>
+and assocates it with the memory region of size
+<parameter>length</parameter>
+bytes starting at location
+<parameter>base.</parameter>
+</para>
+<para>
+<function>lwres_buffer_invalidate()</function>
+marks the buffer
+<parameter>*b</parameter>
+as invalid. Invalidating a buffer after use is not required,
+but makes it possible to catch its possible accidental use.
+</para>
+<para>
+The functions
+<function>lwres_buffer_add()</function>
+and
+<function>lwres_buffer_subtract()</function>
+respectively increase and decrease the used space in
+buffer
+<parameter>*b</parameter>
+by
+<parameter>n</parameter>
+bytes.
+<function>lwres_buffer_add()</function>
+checks for buffer overflow and
+<function>lwres_buffer_subtract()</function>
+checks for underflow.
+These functions do not allocate or deallocate memory.
+They just change the value of
+<structfield>used</structfield>.
+</para>
+<para>
+A buffer is re-initialised by
+<function>lwres_buffer_clear()</function>.
+The function sets
+<structfield>used</structfield> ,
+<structfield>current</structfield>
+and
+<structfield>active</structfield>
+to zero.
+</para>
+<para>
+<function>lwres_buffer_first</function>
+makes the consumed region of buffer
+<parameter>*p</parameter>
+empty by setting
+<structfield>current</structfield>
+to zero (the start of the buffer).
+</para>
+<para>
+<function>lwres_buffer_forward()</function>
+increases the consumed region of buffer
+<parameter>*b</parameter>
+by
+<parameter>n</parameter>
+bytes, checking for overflow.
+Similarly,
+<function>lwres_buffer_back()</function>
+decreases buffer
+<parameter>b</parameter>'s
+consumed region by
+<parameter>n</parameter>
+bytes and checks for underflow.
+</para>
+<para>
+<function>lwres_buffer_getuint8()</function>
+reads an unsigned 8-bit integer from
+<parameter>*b</parameter>
+and returns it.
+<function>lwres_buffer_putuint8()</function>
+writes the unsigned 8-bit integer
+<parameter>val</parameter>
+to buffer
+<parameter>*b</parameter>.
+</para>
+<para>
+<function>lwres_buffer_getuint16()</function>
+and
+<function>lwres_buffer_getuint32()</function>
+are identical to
+<function>lwres_buffer_putuint8()</function>
+except that they respectively read an unsigned 16-bit or 32-bit integer
+in network byte order from
+<parameter>b</parameter>.
+Similarly,
+<function>lwres_buffer_putuint16()</function>
+and
+<function>lwres_buffer_putuint32()</function>
+writes the unsigned 16-bit or 32-bit integer
+<parameter>val</parameter>
+to buffer
+<parameter>b</parameter>,
+in network byte order.
+</para>
+<para>
+Arbitrary amounts of data are read or written from a lightweight
+resolver buffer with
+<function>lwres_buffer_getmem()</function>
+and
+<function>lwres_buffer_putmem()</function>
+respectively.
+<function>lwres_buffer_putmem()</function>
+copies
+<parameter>length</parameter>
+bytes of memory at
+<parameter>base</parameter>
+to
+<parameter>b</parameter>.
+Conversely,
+<function>lwres_buffer_getmem()</function>
+copies
+<parameter>length</parameter>
+bytes of memory from
+<parameter>b</parameter>
+to
+<parameter>base</parameter>.
+</para>
+</refsect1>
+</refentry>
diff --git a/lib/liblwres/man/lwres_buffer.html b/lib/liblwres/man/lwres_buffer.html
new file mode 100644
index 000000000..ae2ffd50c
--- /dev/null
+++ b/lib/liblwres/man/lwres_buffer.html
@@ -0,0 +1,608 @@
+<!--
+ - Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_buffer</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_buffer</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_buffer_init, lwres_buffer_invalidate, lwres_buffer_add, lwres_buffer_subtract, lwres_buffer_clear, lwres_buffer_first, lwres_buffer_forward, lwres_buffer_back, lwres_buffer_getuint8, lwres_buffer_putuint8, lwres_buffer_getuint16, lwres_buffer_putuint16, lwres_buffer_getuint32, lwres_buffer_putuint32, lwres_buffer_putmem, lwres_buffer_getmem&nbsp;--&nbsp;lightweight resolver buffer management</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN26"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN27"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/lwbuffer.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_init</CODE
+>(lwres_buffer_t *b, void *base, unsigned int length);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_invalidate</CODE
+>(lwres_buffer_t *b);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_add</CODE
+>(lwres_buffer_t *b, unsigned int n);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_subtract</CODE
+>(lwres_buffer_t *b, unsigned int n);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_clear</CODE
+>(lwres_buffer_t *b);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_first</CODE
+>(lwres_buffer_t *b);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_forward</CODE
+>(lwres_buffer_t *b, unsigned int n);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_back</CODE
+>(lwres_buffer_t *b, unsigned int n);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_uint8_t
+lwres_buffer_getuint8</CODE
+>(lwres_buffer_t *b);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_putuint8</CODE
+>(lwres_buffer_t *b, lwres_uint8_t val);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_uint16_t
+lwres_buffer_getuint16</CODE
+>(lwres_buffer_t *b);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_putuint16</CODE
+>(lwres_buffer_t *b, lwres_uint16_t val);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_uint32_t
+lwres_buffer_getuint32</CODE
+>(lwres_buffer_t *b);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_putuint32</CODE
+>(lwres_buffer_t *b, lwres_uint32_t val);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_putmem</CODE
+>(lwres_buffer_t *b, const unsigned char *base, unsigned int length);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_getmem</CODE
+>(lwres_buffer_t *b, unsigned char *base, unsigned int length);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN106"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>These functions provide bounds checked access to a region of memory
+where data is being read or written.
+They are based on, and similar to, the
+<TT
+CLASS="LITERAL"
+>isc_buffer_</TT
+>
+functions in the ISC library.</P
+><P
+>A buffer is a region of memory, together with a set of related
+subregions.
+The <I
+CLASS="EMPHASIS"
+>used region</I
+> and the
+<I
+CLASS="EMPHASIS"
+>available</I
+> region are disjoint, and
+their union is the buffer's region.
+The used region extends from the beginning of the buffer region to the
+last used byte.
+The available region extends from one byte greater than the last used
+byte to the end of the buffer's region.
+The size of the used region can be changed using various
+buffer commands.
+Initially, the used region is empty.</P
+><P
+>The used region is further subdivided into two disjoint regions: the
+<I
+CLASS="EMPHASIS"
+>consumed region</I
+> and the <I
+CLASS="EMPHASIS"
+>remaining region</I
+>.
+The union of these two regions is the used region.
+The consumed region extends from the beginning of the used region to
+the byte before the <I
+CLASS="EMPHASIS"
+>current</I
+> offset (if any).
+The <I
+CLASS="EMPHASIS"
+>remaining</I
+> region the current pointer to the end of the used
+region.
+The size of the consumed region can be changed using various
+buffer commands.
+Initially, the consumed region is empty.</P
+><P
+>The <I
+CLASS="EMPHASIS"
+>active region</I
+> is an (optional) subregion of the remaining
+region.
+It extends from the current offset to an offset in the
+remaining region.
+Initially, the active region is empty.
+If the current offset advances beyond the chosen offset,
+the active region will also be empty.</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>
+ /------------entire length---------------\\
+ /----- used region -----\\/-- available --\\
+ +----------------------------------------+
+ | consumed | remaining | |
+ +----------------------------------------+
+ a b c d e
+
+ a == base of buffer.
+ b == current pointer. Can be anywhere between a and d.
+ c == active pointer. Meaningful between b and d.
+ d == used pointer.
+ e == length of buffer.
+
+ a-e == entire length of buffer.
+ a-d == used region.
+ a-b == consumed region.
+ b-d == remaining region.
+ b-c == optional active region.</PRE
+></P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_buffer_init()</TT
+>
+initializes the
+<SPAN
+CLASS="TYPE"
+>lwres_buffer_t</SPAN
+>
+<TT
+CLASS="PARAMETER"
+><I
+>*b</I
+></TT
+>
+and assocates it with the memory region of size
+<TT
+CLASS="PARAMETER"
+><I
+>length</I
+></TT
+>
+bytes starting at location
+<TT
+CLASS="PARAMETER"
+><I
+>base.</I
+></TT
+></P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_buffer_invalidate()</TT
+>
+marks the buffer
+<TT
+CLASS="PARAMETER"
+><I
+>*b</I
+></TT
+>
+as invalid. Invalidating a buffer after use is not required,
+but makes it possible to catch its possible accidental use.</P
+><P
+>The functions
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_add()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_subtract()</TT
+>
+respectively increase and decrease the used space in
+buffer
+<TT
+CLASS="PARAMETER"
+><I
+>*b</I
+></TT
+>
+by
+<TT
+CLASS="PARAMETER"
+><I
+>n</I
+></TT
+>
+bytes.
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_add()</TT
+>
+checks for buffer overflow and
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_subtract()</TT
+>
+checks for underflow.
+These functions do not allocate or deallocate memory.
+They just change the value of
+<TT
+CLASS="STRUCTFIELD"
+><I
+>used</I
+></TT
+>.</P
+><P
+>A buffer is re-initialised by
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_clear()</TT
+>.
+The function sets
+<TT
+CLASS="STRUCTFIELD"
+><I
+>used</I
+></TT
+> ,
+<TT
+CLASS="STRUCTFIELD"
+><I
+>current</I
+></TT
+>
+and
+<TT
+CLASS="STRUCTFIELD"
+><I
+>active</I
+></TT
+>
+to zero.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_buffer_first</TT
+>
+makes the consumed region of buffer
+<TT
+CLASS="PARAMETER"
+><I
+>*p</I
+></TT
+>
+empty by setting
+<TT
+CLASS="STRUCTFIELD"
+><I
+>current</I
+></TT
+>
+to zero (the start of the buffer).</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_buffer_forward()</TT
+>
+increases the consumed region of buffer
+<TT
+CLASS="PARAMETER"
+><I
+>*b</I
+></TT
+>
+by
+<TT
+CLASS="PARAMETER"
+><I
+>n</I
+></TT
+>
+bytes, checking for overflow.
+Similarly,
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_back()</TT
+>
+decreases buffer
+<TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+>'s
+consumed region by
+<TT
+CLASS="PARAMETER"
+><I
+>n</I
+></TT
+>
+bytes and checks for underflow.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_buffer_getuint8()</TT
+>
+reads an unsigned 8-bit integer from
+<TT
+CLASS="PARAMETER"
+><I
+>*b</I
+></TT
+>
+and returns it.
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_putuint8()</TT
+>
+writes the unsigned 8-bit integer
+<TT
+CLASS="PARAMETER"
+><I
+>val</I
+></TT
+>
+to buffer
+<TT
+CLASS="PARAMETER"
+><I
+>*b</I
+></TT
+>.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_buffer_getuint16()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_getuint32()</TT
+>
+are identical to
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_putuint8()</TT
+>
+except that they respectively read an unsigned 16-bit or 32-bit integer
+in network byte order from
+<TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+>.
+Similarly,
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_putuint16()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_putuint32()</TT
+>
+writes the unsigned 16-bit or 32-bit integer
+<TT
+CLASS="PARAMETER"
+><I
+>val</I
+></TT
+>
+to buffer
+<TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+>,
+in network byte order.</P
+><P
+>Arbitrary amounts of data are read or written from a lightweight
+resolver buffer with
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_getmem()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_putmem()</TT
+>
+respectively.
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_putmem()</TT
+>
+copies
+<TT
+CLASS="PARAMETER"
+><I
+>length</I
+></TT
+>
+bytes of memory at
+<TT
+CLASS="PARAMETER"
+><I
+>base</I
+></TT
+>
+to
+<TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+>.
+Conversely,
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_getmem()</TT
+>
+copies
+<TT
+CLASS="PARAMETER"
+><I
+>length</I
+></TT
+>
+bytes of memory from
+<TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+>
+to
+<TT
+CLASS="PARAMETER"
+><I
+>base</I
+></TT
+>.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/lib/liblwres/man/lwres_config.3 b/lib/liblwres/man/lwres_config.3
new file mode 100644
index 000000000..9a93cc0e7
--- /dev/null
+++ b/lib/liblwres/man/lwres_config.3
@@ -0,0 +1,105 @@
+.\"
+.\" Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM 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.
+.\"
+.TH "LWRES_CONFIG" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_conf_init, lwres_conf_clear, lwres_conf_parse, lwres_conf_print, lwres_conf_get \- lightweight resolver configuration
+.SH SYNOPSIS
+\fB#include <lwres/lwres.h>
+.sp
+.na
+void
+lwres_conf_init(lwres_context_t *ctx);
+.ad
+.sp
+.na
+void
+lwres_conf_clear(lwres_context_t *ctx);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_conf_parse(lwres_context_t *ctx, const char *filename);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_conf_print(lwres_context_t *ctx, FILE *fp);
+.ad
+.sp
+.na
+lwres_conf_t *
+lwres_conf_get(lwres_context_t *ctx);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+\fBlwres_conf_init()\fR
+creates an empty
+\fBlwres_conf_t\fR
+structure for lightweight resolver context
+\fIctx\fR.
+.PP
+\fBlwres_conf_clear()\fR
+frees up all the internal memory used by
+that
+\fBlwres_conf_t\fR
+structure in resolver context
+\fIctx\fR.
+.PP
+\fBlwres_conf_parse()\fR
+opens the file
+\fIfilename\fR
+and parses it to initialise the resolver context
+\fIctx\fR's
+\fBlwres_conf_t\fR
+structure.
+.PP
+\fBlwres_conf_print()\fR
+prints the
+\fBlwres_conf_t\fR
+structure for resolver context
+\fIctx\fR
+to the
+\fBFILE\fR
+\fIfp\fR.
+.SH "RETURN VALUES"
+.PP
+\fBlwres_conf_parse()\fR
+returns
+LWRES_R_SUCCESS
+if it successfully read and parsed
+\fIfilename\fR.
+It returns
+LWRES_R_FAILURE
+if
+\fIfilename\fR
+could not be opened or contained incorrect
+resolver statements.
+.PP
+\fBlwres_conf_print()\fR
+returns
+LWRES_R_SUCCESS
+unless an error occurred when converting the network addresses to a
+numeric host address string.
+If this happens, the function returns
+LWRES_R_FAILURE.
+.SH "SEE ALSO"
+.PP
+\fBstdio\fR(3),
+\fBresolver\fR(5).
+.SH "FILES"
+.PP
+\fI/etc/resolv.conf\fR
diff --git a/lib/liblwres/man/lwres_config.docbook b/lib/liblwres/man/lwres_config.docbook
new file mode 100644
index 000000000..03ec6c211
--- /dev/null
+++ b/lib/liblwres/man/lwres_config.docbook
@@ -0,0 +1,159 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+
+<!-- $Id: lwres_config.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+<refentryinfo>
+
+<date>Jun 30, 2000</date>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>lwres_config</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>lwres_conf_init</refname>
+<refname>lwres_conf_clear</refname>
+<refname>lwres_conf_parse</refname>
+<refname>lwres_conf_print</refname>
+<refname>lwres_conf_get</refname>
+<refpurpose>lightweight resolver configuration</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/lwres.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_conf_init</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_conf_clear</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_conf_parse</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>const char *filename</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_conf_print</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>FILE *fp</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_conf_t *
+<function>lwres_conf_get</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+</funcprototype>
+</funcsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+<title>DESCRIPTION</title>
+<para>
+<function>lwres_conf_init()</function>
+creates an empty
+<type>lwres_conf_t</type>
+structure for lightweight resolver context
+<parameter>ctx</parameter>.
+</para>
+<para>
+<function>lwres_conf_clear()</function>
+frees up all the internal memory used by
+that
+<type>lwres_conf_t</type>
+structure in resolver context
+<parameter>ctx</parameter>.
+</para>
+<para>
+<function>lwres_conf_parse()</function>
+opens the file
+<parameter>filename</parameter>
+and parses it to initialise the resolver context
+<parameter>ctx</parameter>'s
+<type>lwres_conf_t</type>
+structure.
+</para>
+<para>
+<function>lwres_conf_print()</function>
+prints the
+<type>lwres_conf_t</type>
+structure for resolver context
+<parameter>ctx</parameter>
+to the
+<type>FILE</type>
+<parameter>fp</parameter>.
+</para>
+</refsect1>
+<refsect1>
+
+<title>RETURN VALUES</title>
+<para>
+<function>lwres_conf_parse()</function>
+returns
+<errorcode>LWRES_R_SUCCESS</errorcode>
+if it successfully read and parsed
+<parameter>filename</parameter>.
+It returns
+<errorcode>LWRES_R_FAILURE</errorcode>
+if
+<parameter>filename</parameter>
+could not be opened or contained incorrect
+resolver statements.
+</para>
+<para>
+<function>lwres_conf_print()</function>
+returns
+<errorcode>LWRES_R_SUCCESS</errorcode>
+unless an error occurred when converting the network addresses to a
+numeric host address string.
+If this happens, the function returns
+<errorcode>LWRES_R_FAILURE</errorcode>.
+</para>
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>stdio</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+<citerefentry>
+<refentrytitle>resolver</refentrytitle><manvolnum>5</manvolnum>
+</citerefentry>.
+</refsect1>
+<refsect1>
+<title>FILES</title>
+<para>
+<filename>/etc/resolv.conf</filename>
+</para>
+</refsect1>
+</refentry>
diff --git a/lib/liblwres/man/lwres_config.html b/lib/liblwres/man/lwres_config.html
new file mode 100644
index 000000000..67fbcdd88
--- /dev/null
+++ b/lib/liblwres/man/lwres_config.html
@@ -0,0 +1,295 @@
+<!--
+ - Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_config</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_config</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_conf_init, lwres_conf_clear, lwres_conf_parse, lwres_conf_print, lwres_conf_get&nbsp;--&nbsp;lightweight resolver configuration</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN15"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN16"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/lwres.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_conf_init</CODE
+>(lwres_context_t *ctx);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_conf_clear</CODE
+>(lwres_context_t *ctx);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_conf_parse</CODE
+>(lwres_context_t *ctx, const char *filename);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_conf_print</CODE
+>(lwres_context_t *ctx, FILE *fp);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_conf_t *
+lwres_conf_get</CODE
+>(lwres_context_t *ctx);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN40"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_conf_init()</TT
+>
+creates an empty
+<SPAN
+CLASS="TYPE"
+>lwres_conf_t</SPAN
+>
+structure for lightweight resolver context
+<TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+>.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_conf_clear()</TT
+>
+frees up all the internal memory used by
+that
+<SPAN
+CLASS="TYPE"
+>lwres_conf_t</SPAN
+>
+structure in resolver context
+<TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+>.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_conf_parse()</TT
+>
+opens the file
+<TT
+CLASS="PARAMETER"
+><I
+>filename</I
+></TT
+>
+and parses it to initialise the resolver context
+<TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+>'s
+<SPAN
+CLASS="TYPE"
+>lwres_conf_t</SPAN
+>
+structure.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_conf_print()</TT
+>
+prints the
+<SPAN
+CLASS="TYPE"
+>lwres_conf_t</SPAN
+>
+structure for resolver context
+<TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+>
+to the
+<SPAN
+CLASS="TYPE"
+>FILE</SPAN
+>
+<TT
+CLASS="PARAMETER"
+><I
+>fp</I
+></TT
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN61"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_conf_parse()</TT
+>
+returns
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_SUCCESS</SPAN
+>
+if it successfully read and parsed
+<TT
+CLASS="PARAMETER"
+><I
+>filename</I
+></TT
+>.
+It returns
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_FAILURE</SPAN
+>
+if
+<TT
+CLASS="PARAMETER"
+><I
+>filename</I
+></TT
+>
+could not be opened or contained incorrect
+resolver statements.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_conf_print()</TT
+>
+returns
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_SUCCESS</SPAN
+>
+unless an error occurred when converting the network addresses to a
+numeric host address string.
+If this happens, the function returns
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_FAILURE</SPAN
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN73"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>stdio</SPAN
+>(3)</SPAN
+>,
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>resolver</SPAN
+>(5)</SPAN
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN82"
+></A
+><H2
+>FILES</H2
+><P
+><TT
+CLASS="FILENAME"
+>/etc/resolv.conf</TT
+></P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/lib/liblwres/man/lwres_context.3 b/lib/liblwres/man/lwres_context.3
new file mode 100644
index 000000000..d55c14fef
--- /dev/null
+++ b/lib/liblwres/man/lwres_context.3
@@ -0,0 +1,194 @@
+.\"
+.\" Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM 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.
+.\"
+.TH "LWRES_CONTEXT" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_context_create, lwres_context_destroy, lwres_context_nextserial, lwres_context_initserial, lwres_context_freemem, lwres_context_allocmem, lwres_context_sendrecv \- lightweight resolver context management
+.SH SYNOPSIS
+\fB#include <lwres/lwres.h>
+.sp
+.na
+lwres_result_t
+lwres_context_create(lwres_context_t **contextp, void *arg, lwres_malloc_t malloc_function, lwres_free_t free_function);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_context_destroy(lwres_context_t **contextp);
+.ad
+.sp
+.na
+void
+lwres_context_initserial(lwres_context_t *ctx, lwres_uint32_t serial);
+.ad
+.sp
+.na
+lwres_uint32_t
+lwres_context_nextserial(lwres_context_t *ctx);
+.ad
+.sp
+.na
+void
+lwres_context_freemem(lwres_context_t *ctx, void *mem, size_t len);
+.ad
+.sp
+.na
+void
+lwres_context_allocmem(lwres_context_t *ctx, size_t len);
+.ad
+.sp
+.na
+void *
+lwres_context_sendrecv(lwres_context_t *ctx, void *sendbase, int sendlen, void *recvbase, int recvlen, int *recvd_len);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+\fBlwres_context_create()\fR
+creates a
+\fBlwres_context_t\fR
+structure for use in lightweight resolver operations.
+It holds a socket and other data needed for communicating
+with a resolver daemon.
+The new
+\fBlwres_context_t\fR
+is returned throught
+\fIcontextp\fR,
+a pointer to a
+\fBlwres_context_t\fR
+pointer. This
+\fBlwres_context_t\fR
+pointer must initially be NULL, and is modified
+to point to the newly created
+\fBlwres_context_t\fR.
+.PP
+When the lightweight resolver needs to perform dynamic memory
+allocation, it will call
+\fImalloc_function\fR
+to allocate memory and
+\fIfree_function\fR
+to free it. If
+\fImalloc_function\fR
+and
+\fIfree_function\fR
+are NULL, memory is allocated using
+\&.Xr malloc 3
+and
+\fBfree\fR(3).
+It is not permitted to have a NULL
+\fImalloc_function\fR
+and a non-NULL
+\fIfree_function\fR
+or vice versa.
+\fIarg\fR
+is passed as the first parameter to the memory
+allocation functions.
+If
+\fImalloc_function\fR
+and
+\fIfree_function\fR
+are NULL,
+\fIarg\fR
+is unused and should be passed as NULL.
+.PP
+Once memory for the structure has been allocated,
+it is initialized using
+\fBlwres_conf_init\fR(3)
+and returned via
+\fI*contextp\fR.
+.PP
+\fBlwres_context_destroy()\fR
+destroys a
+\fBlwres_context_t\fR,
+closing its socket.
+\fIcontextp\fR
+is a pointer to a pointer to the context that is to be destroyed.
+The pointer will be set to NULL when the context has been destroyed.
+.PP
+The context holds a serial number that is used to identify resolver
+request packets and associate responses with the corresponding requests.
+This serial number is controlled using
+\fBlwres_context_initserial()\fR
+and
+\fBlwres_context_nextserial()\fR.
+\fBlwres_context_initserial()\fR
+sets the serial number for context
+\fI*ctx\fR
+to
+\fIserial\fR.
+\fBlwres_context_nextserial()\fR
+increments the serial number and returns the previous value.
+.PP
+Memory for a lightweight resolver context is allocated and freed using
+\fBlwres_context_allocmem()\fR
+and
+\fBlwres_context_freemem()\fR.
+These use whatever allocations were defined when the context was
+created with
+\fBlwres_context_create()\fR.
+\fBlwres_context_allocmem()\fR
+allocates
+\fIlen\fR
+bytes of memory and if successful returns a pointer to the allocated
+storage.
+\fBlwres_context_freemem()\fR
+frees
+\fIlen\fR
+bytes of space starting at location
+\fImem\fR.
+.PP
+\fBlwres_context_sendrecv()\fR
+performs I/O for the context
+\fIctx\fR.
+Data are read and written from the context's socket.
+It writes data from
+\fIsendbase\fR
+\(em typically a lightweight resolver query packet \(em
+and waits for a reply which is copied to the receive buffer at
+\fIrecvbase\fR.
+The number of bytes that were written to this receive buffer is
+returned in
+\fI*recvd_len\fR.
+.SH "RETURN VALUES"
+.PP
+\fBlwres_context_create()\fR
+returns
+LWRES_R_NOMEMORY
+if memory for the
+\fBstruct lwres_context\fR
+could not be allocated,
+LWRES_R_SUCCESS
+otherwise.
+.PP
+Successful calls to the memory allocator
+\fBlwres_context_allocmem()\fR
+return a pointer to the start of the allocated space.
+It returns NULL if memory could not be allocated.
+.PP
+LWRES_R_SUCCESS
+is returned when
+\fBlwres_context_sendrecv()\fR
+completes successfully.
+LWRES_R_IOERROR
+is returned if an I/O error occurs and
+LWRES_R_TIMEOUT
+is returned if
+\fBlwres_context_sendrecv()\fR
+times out waiting for a response.
+.SH "SEE ALSO"
+.PP
+\fBlwres_conf_init\fR(3),
+\fBmalloc\fR(3),
+\fBfree\fR(3).
diff --git a/lib/liblwres/man/lwres_context.docbook b/lib/liblwres/man/lwres_context.docbook
new file mode 100644
index 000000000..9cdfa7525
--- /dev/null
+++ b/lib/liblwres/man/lwres_context.docbook
@@ -0,0 +1,283 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+
+<!-- $Id: lwres_context.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+<refentryinfo>
+
+
+<date>Jun 30, 2000</date>
+</refentryinfo>
+<refmeta>
+<refentrytitle>lwres_context</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+<refnamediv>
+<refname>lwres_context_create</refname>
+<refname>lwres_context_destroy</refname>
+<refname>lwres_context_nextserial</refname>
+<refname>lwres_context_initserial</refname>
+<refname>lwres_context_freemem</refname>
+<refname>lwres_context_allocmem</refname>
+<refname>lwres_context_sendrecv</refname>
+<refpurpose>lightweight resolver context management</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/lwres.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_context_create</function></funcdef>
+<paramdef>lwres_context_t **contextp</paramdef>
+<paramdef>void *arg</paramdef>
+<paramdef>lwres_malloc_t malloc_function</paramdef>
+<paramdef>lwres_free_t free_function</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_context_destroy</function></funcdef>
+<paramdef>lwres_context_t **contextp</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_context_initserial</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_uint32_t serial</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_uint32_t
+<function>lwres_context_nextserial</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_context_freemem</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>void *mem</paramdef>
+<paramdef>size_t len</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_context_allocmem</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>size_t len</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void *
+<function>lwres_context_sendrecv</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>void *sendbase</paramdef>
+<paramdef>int sendlen</paramdef>
+<paramdef>void *recvbase</paramdef>
+<paramdef>int recvlen</paramdef>
+<paramdef>int *recvd_len</paramdef>
+</funcprototype>
+</funcsynopsis>
+</refsynopsisdiv>
+<refsect1>
+<title>DESCRIPTION</title>
+<para>
+<function>lwres_context_create()</function>
+creates a
+<type>lwres_context_t</type>
+structure for use in lightweight resolver operations.
+It holds a socket and other data needed for communicating
+with a resolver daemon.
+The new
+<type>lwres_context_t</type>
+is returned throught
+<parameter>contextp</parameter>,
+
+a pointer to a
+<type>lwres_context_t</type>
+pointer. This
+<type>lwres_context_t</type>
+pointer must initially be NULL, and is modified
+to point to the newly created
+<type>lwres_context_t</type>.
+
+</para>
+<para>
+When the lightweight resolver needs to perform dynamic memory
+allocation, it will call
+<parameter>malloc_function</parameter>
+to allocate memory and
+<parameter>free_function</parameter>
+
+to free it. If
+<parameter>malloc_function</parameter>
+and
+<parameter>free_function</parameter>
+
+are NULL, memory is allocated using
+.Xr malloc 3
+and
+<citerefentry>
+<refentrytitle>free</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>.
+
+It is not permitted to have a NULL
+<parameter>malloc_function</parameter>
+and a non-NULL
+<parameter>free_function</parameter>
+or vice versa.
+<parameter>arg</parameter>
+is passed as the first parameter to the memory
+allocation functions.
+If
+<parameter>malloc_function</parameter>
+and
+<parameter>free_function</parameter>
+are NULL,
+<parameter>arg</parameter>
+
+is unused and should be passed as NULL.
+</para>
+<para>
+Once memory for the structure has been allocated,
+it is initialized using
+<citerefentry>
+<refentrytitle>lwres_conf_init</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>
+
+and returned via
+<parameter>*contextp</parameter>.
+
+</para>
+<para>
+<function>lwres_context_destroy()</function>
+destroys a
+<type>lwres_context_t</type>,
+
+closing its socket.
+<parameter>contextp</parameter>
+is a pointer to a pointer to the context that is to be destroyed.
+The pointer will be set to NULL when the context has been destroyed.
+</para>
+<para>
+The context holds a serial number that is used to identify resolver
+request packets and associate responses with the corresponding requests.
+This serial number is controlled using
+<function>lwres_context_initserial()</function>
+and
+<function>lwres_context_nextserial()</function>.
+<function>lwres_context_initserial()</function>
+sets the serial number for context
+<parameter>*ctx</parameter>
+to
+<parameter>serial</parameter>.
+
+<function>lwres_context_nextserial()</function>
+increments the serial number and returns the previous value.
+</para>
+<para>
+Memory for a lightweight resolver context is allocated and freed using
+<function>lwres_context_allocmem()</function>
+and
+<function>lwres_context_freemem()</function>.
+These use whatever allocations were defined when the context was
+created with
+<function>lwres_context_create()</function>.
+<function>lwres_context_allocmem()</function>
+allocates
+<parameter>len</parameter>
+bytes of memory and if successful returns a pointer to the allocated
+storage.
+<function>lwres_context_freemem()</function>
+frees
+<parameter>len</parameter>
+bytes of space starting at location
+<parameter>mem</parameter>.
+
+</para>
+<para>
+<function>lwres_context_sendrecv()</function>
+performs I/O for the context
+<parameter>ctx</parameter>.
+
+Data are read and written from the context's socket.
+It writes data from
+<parameter>sendbase</parameter>
+&mdash; typically a lightweight resolver query packet &mdash;
+and waits for a reply which is copied to the receive buffer at
+<parameter>recvbase</parameter>.
+
+The number of bytes that were written to this receive buffer is
+returned in
+<parameter>*recvd_len</parameter>.
+
+</para>
+</refsect1>
+<refsect1>
+<title>RETURN VALUES</title>
+<para>
+<function>lwres_context_create()</function>
+returns
+<errorcode>LWRES_R_NOMEMORY</errorcode>
+if memory for the
+<type>struct lwres_context</type>
+could not be allocated,
+<errorcode>LWRES_R_SUCCESS</errorcode>
+otherwise.
+</para>
+<para>
+Successful calls to the memory allocator
+<function>lwres_context_allocmem()</function>
+return a pointer to the start of the allocated space.
+It returns NULL if memory could not be allocated.
+</para>
+<para>
+<errorcode>LWRES_R_SUCCESS</errorcode>
+is returned when
+<function>lwres_context_sendrecv()</function>
+completes successfully.
+<errorcode>LWRES_R_IOERROR</errorcode>
+is returned if an I/O error occurs and
+<errorcode>LWRES_R_TIMEOUT</errorcode>
+is returned if
+<function>lwres_context_sendrecv()</function>
+times out waiting for a response.
+</para>
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>lwres_conf_init</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>malloc</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>free</refentrytitle><manvolnum>3
+</manvolnum>
+</citerefentry>.
+</para>
+</refsect1>
+</refentry>
diff --git a/lib/liblwres/man/lwres_context.html b/lib/liblwres/man/lwres_context.html
new file mode 100644
index 000000000..377125c43
--- /dev/null
+++ b/lib/liblwres/man/lwres_context.html
@@ -0,0 +1,519 @@
+<!--
+ - Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_context</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_context</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_context_create, lwres_context_destroy, lwres_context_nextserial, lwres_context_initserial, lwres_context_freemem, lwres_context_allocmem, lwres_context_sendrecv&nbsp;--&nbsp;lightweight resolver context management</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN17"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN18"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/lwres.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_context_create</CODE
+>(lwres_context_t **contextp, void *arg, lwres_malloc_t malloc_function, lwres_free_t free_function);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_context_destroy</CODE
+>(lwres_context_t **contextp);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_context_initserial</CODE
+>(lwres_context_t *ctx, lwres_uint32_t serial);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_uint32_t
+lwres_context_nextserial</CODE
+>(lwres_context_t *ctx);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_context_freemem</CODE
+>(lwres_context_t *ctx, void *mem, size_t len);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_context_allocmem</CODE
+>(lwres_context_t *ctx, size_t len);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void *
+lwres_context_sendrecv</CODE
+>(lwres_context_t *ctx, void *sendbase, int sendlen, void *recvbase, int recvlen, int *recvd_len);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN60"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_context_create()</TT
+>
+creates a
+<SPAN
+CLASS="TYPE"
+>lwres_context_t</SPAN
+>
+structure for use in lightweight resolver operations.
+It holds a socket and other data needed for communicating
+with a resolver daemon.
+The new
+<SPAN
+CLASS="TYPE"
+>lwres_context_t</SPAN
+>
+is returned throught
+<TT
+CLASS="PARAMETER"
+><I
+>contextp</I
+></TT
+>,
+
+a pointer to a
+<SPAN
+CLASS="TYPE"
+>lwres_context_t</SPAN
+>
+pointer. This
+<SPAN
+CLASS="TYPE"
+>lwres_context_t</SPAN
+>
+pointer must initially be NULL, and is modified
+to point to the newly created
+<SPAN
+CLASS="TYPE"
+>lwres_context_t</SPAN
+>.&#13;</P
+><P
+>When the lightweight resolver needs to perform dynamic memory
+allocation, it will call
+<TT
+CLASS="PARAMETER"
+><I
+>malloc_function</I
+></TT
+>
+to allocate memory and
+<TT
+CLASS="PARAMETER"
+><I
+>free_function</I
+></TT
+>
+
+to free it. If
+<TT
+CLASS="PARAMETER"
+><I
+>malloc_function</I
+></TT
+>
+and
+<TT
+CLASS="PARAMETER"
+><I
+>free_function</I
+></TT
+>
+
+are NULL, memory is allocated using
+.Xr malloc 3
+and
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>free</SPAN
+>(3)</SPAN
+>.
+
+It is not permitted to have a NULL
+<TT
+CLASS="PARAMETER"
+><I
+>malloc_function</I
+></TT
+>
+and a non-NULL
+<TT
+CLASS="PARAMETER"
+><I
+>free_function</I
+></TT
+>
+or vice versa.
+<TT
+CLASS="PARAMETER"
+><I
+>arg</I
+></TT
+>
+is passed as the first parameter to the memory
+allocation functions.
+If
+<TT
+CLASS="PARAMETER"
+><I
+>malloc_function</I
+></TT
+>
+and
+<TT
+CLASS="PARAMETER"
+><I
+>free_function</I
+></TT
+>
+are NULL,
+<TT
+CLASS="PARAMETER"
+><I
+>arg</I
+></TT
+>
+
+is unused and should be passed as NULL.</P
+><P
+>Once memory for the structure has been allocated,
+it is initialized using
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_conf_init</SPAN
+>(3)</SPAN
+>
+
+and returned via
+<TT
+CLASS="PARAMETER"
+><I
+>*contextp</I
+></TT
+>.&#13;</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_context_destroy()</TT
+>
+destroys a
+<SPAN
+CLASS="TYPE"
+>lwres_context_t</SPAN
+>,
+
+closing its socket.
+<TT
+CLASS="PARAMETER"
+><I
+>contextp</I
+></TT
+>
+is a pointer to a pointer to the context that is to be destroyed.
+The pointer will be set to NULL when the context has been destroyed.</P
+><P
+>The context holds a serial number that is used to identify resolver
+request packets and associate responses with the corresponding requests.
+This serial number is controlled using
+<TT
+CLASS="FUNCTION"
+>lwres_context_initserial()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_context_nextserial()</TT
+>.
+<TT
+CLASS="FUNCTION"
+>lwres_context_initserial()</TT
+>
+sets the serial number for context
+<TT
+CLASS="PARAMETER"
+><I
+>*ctx</I
+></TT
+>
+to
+<TT
+CLASS="PARAMETER"
+><I
+>serial</I
+></TT
+>.
+
+<TT
+CLASS="FUNCTION"
+>lwres_context_nextserial()</TT
+>
+increments the serial number and returns the previous value.</P
+><P
+>Memory for a lightweight resolver context is allocated and freed using
+<TT
+CLASS="FUNCTION"
+>lwres_context_allocmem()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_context_freemem()</TT
+>.
+These use whatever allocations were defined when the context was
+created with
+<TT
+CLASS="FUNCTION"
+>lwres_context_create()</TT
+>.
+<TT
+CLASS="FUNCTION"
+>lwres_context_allocmem()</TT
+>
+allocates
+<TT
+CLASS="PARAMETER"
+><I
+>len</I
+></TT
+>
+bytes of memory and if successful returns a pointer to the allocated
+storage.
+<TT
+CLASS="FUNCTION"
+>lwres_context_freemem()</TT
+>
+frees
+<TT
+CLASS="PARAMETER"
+><I
+>len</I
+></TT
+>
+bytes of space starting at location
+<TT
+CLASS="PARAMETER"
+><I
+>mem</I
+></TT
+>.&#13;</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_context_sendrecv()</TT
+>
+performs I/O for the context
+<TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+>.
+
+Data are read and written from the context's socket.
+It writes data from
+<TT
+CLASS="PARAMETER"
+><I
+>sendbase</I
+></TT
+>
+&mdash; typically a lightweight resolver query packet &mdash;
+and waits for a reply which is copied to the receive buffer at
+<TT
+CLASS="PARAMETER"
+><I
+>recvbase</I
+></TT
+>.
+
+The number of bytes that were written to this receive buffer is
+returned in
+<TT
+CLASS="PARAMETER"
+><I
+>*recvd_len</I
+></TT
+>.&#13;</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN115"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_context_create()</TT
+>
+returns
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_NOMEMORY</SPAN
+>
+if memory for the
+<SPAN
+CLASS="TYPE"
+>struct lwres_context</SPAN
+>
+could not be allocated,
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_SUCCESS</SPAN
+>
+otherwise.</P
+><P
+>Successful calls to the memory allocator
+<TT
+CLASS="FUNCTION"
+>lwres_context_allocmem()</TT
+>
+return a pointer to the start of the allocated space.
+It returns NULL if memory could not be allocated.</P
+><P
+><SPAN
+CLASS="ERRORCODE"
+>LWRES_R_SUCCESS</SPAN
+>
+is returned when
+<TT
+CLASS="FUNCTION"
+>lwres_context_sendrecv()</TT
+>
+completes successfully.
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_IOERROR</SPAN
+>
+is returned if an I/O error occurs and
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_TIMEOUT</SPAN
+>
+is returned if
+<TT
+CLASS="FUNCTION"
+>lwres_context_sendrecv()</TT
+>
+times out waiting for a response.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN130"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_conf_init</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>malloc</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>free</SPAN
+>(3)</SPAN
+>.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/lib/liblwres/man/lwres_gabn.3 b/lib/liblwres/man/lwres_gabn.3
new file mode 100644
index 000000000..79a22c14f
--- /dev/null
+++ b/lib/liblwres/man/lwres_gabn.3
@@ -0,0 +1,193 @@
+.\"
+.\" Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM 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.
+.\"
+.TH "LWRES_GABN" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_gabnrequest_render, lwres_gabnresponse_render, lwres_gabnrequest_parse, lwres_gabnresponse_parse, lwres_gabnresponse_free, lwres_gabnrequest_free \- lightweight resolver getaddrbyname message handling
+.SH SYNOPSIS
+\fB#include <lwres/lwres.h>
+.sp
+.na
+lwres_result_t
+lwres_gabnrequest_render(lwres_context_t *ctx, lwres_gabnrequest_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_gabnresponse_render(lwres_context_t *ctx, lwres_gabnresponse_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_gabnrequest_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_gabnrequest_t **structp);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_gabnresponse_t **structp);
+.ad
+.sp
+.na
+void
+lwres_gabnresponse_free(lwres_context_t *ctx, lwres_gabnresponse_t **structp);
+.ad
+.sp
+.na
+void
+lwres_gabnrequest_free(lwres_context_t *ctx, lwres_gabnrequest_t **structp);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+These are low-level routines for creating and parsing
+lightweight resolver name-to-address lookup request and
+response messages.
+.PP
+There are four main functions for the getaddrbyname opcode.
+One render function converts a getaddrbyname request structure \(em
+\fBlwres_gabnrequest_t\fR \(em
+to the lighweight resolver's canonical format.
+It is complemented by a parse function that converts a packet in this
+canonical format to a getaddrbyname request structure.
+Another render function converts the getaddrbyname response structure \(em
+\fBlwres_gabnresponse_t\fR \(em
+to the canonical format.
+This is complemented by a parse function which converts a packet in
+canonical format to a getaddrbyname response structure.
+.PP
+These structures are defined in
+\fI<lwres/lwres.h>\fR.
+They are shown below.
+.sp
+.nf
+#define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U
+
+typedef struct lwres_addr lwres_addr_t;
+typedef LWRES_LIST(lwres_addr_t) lwres_addrlist_t;
+
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_uint32_t addrtypes;
+ lwres_uint16_t namelen;
+ char *name;
+} lwres_gabnrequest_t;
+
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ lwres_uint16_t naddrs;
+ char *realname;
+ char **aliases;
+ lwres_uint16_t realnamelen;
+ lwres_uint16_t *aliaslen;
+ lwres_addrlist_t addrs;
+ void *base;
+ size_t baselen;
+} lwres_gabnresponse_t;
+.sp
+.fi
+.PP
+\fBlwres_gabnrequest_render()\fR
+uses resolver context
+\fIctx\fR
+to convert getaddrbyname request structure
+\fIreq\fR
+to canonical format.
+The packet header structure
+\fIpkt\fR
+is initialised and transferred to
+buffer
+\fIb\fR.
+The contents of
+\fI*req\fR
+are then appended to the buffer in canonical format.
+\fBlwres_gabnresponse_render()\fR
+performs the same task, except it converts a getaddrbyname response structure
+\fBlwres_gabnresponse_t\fR
+to the lightweight resolver's canonical format.
+.PP
+\fBlwres_gabnrequest_parse()\fR
+uses context
+\fIctx\fR
+to convert the contents of packet
+\fIpkt\fR
+to a
+\fBlwres_gabnrequest_t\fR
+structure.
+Buffer
+\fIb\fR
+provides space to be used for storing this structure.
+When the function succeeds, the resulting
+\fBlwres_gabnrequest_t\fR
+is made available through
+\fI*structp\fR.
+\fBlwres_gabnresponse_parse()\fR
+offers the same semantics as
+\fBlwres_gabnrequest_parse()\fR
+except it yields a
+\fBlwres_gabnresponse_t\fR
+structure.
+.PP
+\fBlwres_gabnresponse_free()\fR
+and
+\fBlwres_gabnrequest_free()\fR
+release the memory in resolver context
+\fIctx\fR
+that was allocated to the
+\fBlwres_gabnresponse_t\fR
+or
+\fBlwres_gabnrequest_t\fR
+structures referenced via
+\fIstructp\fR.
+Any memory associated with ancillary buffers and strings for those
+structures is also discarded.
+.SH "RETURN VALUES"
+.PP
+The getaddrbyname opcode functions
+\fBlwres_gabnrequest_render()\fR,
+\fBlwres_gabnresponse_render()\fR
+\fBlwres_gabnrequest_parse()\fR
+and
+\fBlwres_gabnresponse_parse()\fR
+all return
+LWRES_R_SUCCESS
+on success.
+They return
+LWRES_R_NOMEMORY
+if memory allocation fails.
+LWRES_R_UNEXPECTEDEND
+is returned if the available space in the buffer
+\fIb\fR
+is too small to accommodate the packet header or the
+\fBlwres_gabnrequest_t\fR
+and
+\fBlwres_gabnresponse_t\fR
+structures.
+\fBlwres_gabnrequest_parse()\fR
+and
+\fBlwres_gabnresponse_parse()\fR
+will return
+LWRES_R_UNEXPECTEDEND
+if the buffer is not empty after decoding the received packet.
+These functions will return
+LWRES_R_FAILURE
+if
+\fBpktflags\fR
+in the packet header structure
+\fBlwres_lwpacket_t\fR
+indicate that the packet is not a response to an earlier query.
+.SH "SEE ALSO"
+.PP
+\fBlwres_packet\fR(3)
diff --git a/lib/liblwres/man/lwres_gabn.docbook b/lib/liblwres/man/lwres_gabn.docbook
new file mode 100644
index 000000000..91f549564
--- /dev/null
+++ b/lib/liblwres/man/lwres_gabn.docbook
@@ -0,0 +1,255 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+
+<!-- $Id: lwres_gabn.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+<refentryinfo>
+
+
+<date>Jun 30, 2000</date>
+</refentryinfo>
+<refmeta>
+<refentrytitle>lwres_gabn</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+<refnamediv>
+<refname>lwres_gabnrequest_render</refname>
+<refname>lwres_gabnresponse_render</refname>
+<refname>lwres_gabnrequest_parse</refname>
+<refname>lwres_gabnresponse_parse</refname>
+<refname>lwres_gabnresponse_free</refname>
+<refname>lwres_gabnrequest_free</refname>
+<refpurpose>lightweight resolver getaddrbyname message handling</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/lwres.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_gabnrequest_render</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_gabnrequest_t *req</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_gabnresponse_render</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_gabnresponse_t *req</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_gabnrequest_parse</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+<paramdef>lwres_gabnrequest_t **structp</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_gabnresponse_parse</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+<paramdef>lwres_gabnresponse_t **structp</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_gabnresponse_free</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_gabnresponse_t **structp</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_gabnrequest_free</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_gabnrequest_t **structp</paramdef>
+</funcprototype>
+</funcsynopsis>
+</refsynopsisdiv>
+<refsect1>
+<title>DESCRIPTION</title>
+<para>
+These are low-level routines for creating and parsing
+lightweight resolver name-to-address lookup request and
+response messages.
+</para><para>
+There are four main functions for the getaddrbyname opcode.
+One render function converts a getaddrbyname request structure &mdash;
+<type>lwres_gabnrequest_t</type> &mdash;
+to the lighweight resolver's canonical format.
+It is complemented by a parse function that converts a packet in this
+canonical format to a getaddrbyname request structure.
+Another render function converts the getaddrbyname response structure &mdash;
+<type>lwres_gabnresponse_t</type> &mdash;
+to the canonical format.
+This is complemented by a parse function which converts a packet in
+canonical format to a getaddrbyname response structure.
+</para>
+<para>
+These structures are defined in
+<filename>&lt;lwres/lwres.h&gt;</filename>.
+They are shown below.
+<programlisting>
+#define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U
+
+typedef struct lwres_addr lwres_addr_t;
+typedef LWRES_LIST(lwres_addr_t) lwres_addrlist_t;
+
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_uint32_t addrtypes;
+ lwres_uint16_t namelen;
+ char *name;
+} lwres_gabnrequest_t;
+
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ lwres_uint16_t naddrs;
+ char *realname;
+ char **aliases;
+ lwres_uint16_t realnamelen;
+ lwres_uint16_t *aliaslen;
+ lwres_addrlist_t addrs;
+ void *base;
+ size_t baselen;
+} lwres_gabnresponse_t;
+</programlisting>
+</para>
+<para>
+<function>lwres_gabnrequest_render()</function>
+uses resolver context
+<parameter>ctx</parameter>
+to convert getaddrbyname request structure
+<parameter>req</parameter>
+to canonical format.
+The packet header structure
+<parameter>pkt</parameter>
+is initialised and transferred to
+buffer
+<parameter>b</parameter>.
+
+The contents of
+<parameter>*req</parameter>
+are then appended to the buffer in canonical format.
+<function>lwres_gabnresponse_render()</function>
+performs the same task, except it converts a getaddrbyname response structure
+<type>lwres_gabnresponse_t</type>
+to the lightweight resolver's canonical format.
+</para>
+<para>
+<function>lwres_gabnrequest_parse()</function>
+uses context
+<parameter>ctx</parameter>
+to convert the contents of packet
+<parameter>pkt</parameter>
+to a
+<type>lwres_gabnrequest_t</type>
+structure.
+Buffer
+<parameter>b</parameter>
+provides space to be used for storing this structure.
+When the function succeeds, the resulting
+<type>lwres_gabnrequest_t</type>
+is made available through
+<parameter>*structp</parameter>.
+
+<function>lwres_gabnresponse_parse()</function>
+offers the same semantics as
+<function>lwres_gabnrequest_parse()</function>
+except it yields a
+<type>lwres_gabnresponse_t</type>
+structure.
+</para>
+<para>
+<function>lwres_gabnresponse_free()</function>
+and
+<function>lwres_gabnrequest_free()</function>
+release the memory in resolver context
+<parameter>ctx</parameter>
+that was allocated to the
+<type>lwres_gabnresponse_t</type>
+or
+<type>lwres_gabnrequest_t</type>
+structures referenced via
+<parameter>structp</parameter>.
+
+Any memory associated with ancillary buffers and strings for those
+structures is also discarded.
+</para>
+</refsect1>
+<refsect1>
+<title>RETURN VALUES</title>
+<para>
+The getaddrbyname opcode functions
+<function>lwres_gabnrequest_render()</function>,
+<function>lwres_gabnresponse_render()</function>
+<function>lwres_gabnrequest_parse()</function>
+and
+<function>lwres_gabnresponse_parse()</function>
+all return
+<errorcode>LWRES_R_SUCCESS</errorcode>
+on success.
+They return
+<errorcode>LWRES_R_NOMEMORY</errorcode>
+if memory allocation fails.
+<errorcode>LWRES_R_UNEXPECTEDEND</errorcode>
+is returned if the available space in the buffer
+<parameter>b</parameter>
+is too small to accommodate the packet header or the
+<type>lwres_gabnrequest_t</type>
+and
+<type>lwres_gabnresponse_t</type>
+structures.
+<function>lwres_gabnrequest_parse()</function>
+and
+<function>lwres_gabnresponse_parse()</function>
+will return
+<errorcode>LWRES_R_UNEXPECTEDEND</errorcode>
+if the buffer is not empty after decoding the received packet.
+These functions will return
+<errorcode>LWRES_R_FAILURE</errorcode>
+if
+<structfield>pktflags</structfield>
+in the packet header structure
+<type>lwres_lwpacket_t</type>
+indicate that the packet is not a response to an earlier query.
+</para>
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>lwres_packet</refentrytitle><manvolnum>3
+</manvolnum>
+</citerefentry>
+</para>
+</refsect1>
+</refentry>
diff --git a/lib/liblwres/man/lwres_gabn.html b/lib/liblwres/man/lwres_gabn.html
new file mode 100644
index 000000000..5611cac6c
--- /dev/null
+++ b/lib/liblwres/man/lwres_gabn.html
@@ -0,0 +1,442 @@
+<!--
+ - Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_gabn</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_gabn</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_gabnrequest_render, lwres_gabnresponse_render, lwres_gabnrequest_parse, lwres_gabnresponse_parse, lwres_gabnresponse_free, lwres_gabnrequest_free&nbsp;--&nbsp;lightweight resolver getaddrbyname message handling</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN16"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN17"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/lwres.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_gabnrequest_render</CODE
+>(lwres_context_t *ctx, lwres_gabnrequest_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_gabnresponse_render</CODE
+>(lwres_context_t *ctx, lwres_gabnresponse_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_gabnrequest_parse</CODE
+>(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_gabnrequest_t **structp);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_gabnresponse_parse</CODE
+>(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_gabnresponse_t **structp);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_gabnresponse_free</CODE
+>(lwres_context_t *ctx, lwres_gabnresponse_t **structp);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_gabnrequest_free</CODE
+>(lwres_context_t *ctx, lwres_gabnrequest_t **structp);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN57"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>These are low-level routines for creating and parsing
+lightweight resolver name-to-address lookup request and
+response messages.</P
+><P
+>There are four main functions for the getaddrbyname opcode.
+One render function converts a getaddrbyname request structure &mdash;
+<SPAN
+CLASS="TYPE"
+>lwres_gabnrequest_t</SPAN
+> &mdash;
+to the lighweight resolver's canonical format.
+It is complemented by a parse function that converts a packet in this
+canonical format to a getaddrbyname request structure.
+Another render function converts the getaddrbyname response structure &mdash;
+<SPAN
+CLASS="TYPE"
+>lwres_gabnresponse_t</SPAN
+> &mdash;
+to the canonical format.
+This is complemented by a parse function which converts a packet in
+canonical format to a getaddrbyname response structure.</P
+><P
+>These structures are defined in
+<TT
+CLASS="FILENAME"
+>&lt;lwres/lwres.h&gt;</TT
+>.
+They are shown below.
+<PRE
+CLASS="PROGRAMLISTING"
+>#define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U
+
+typedef struct lwres_addr lwres_addr_t;
+typedef LWRES_LIST(lwres_addr_t) lwres_addrlist_t;
+
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_uint32_t addrtypes;
+ lwres_uint16_t namelen;
+ char *name;
+} lwres_gabnrequest_t;
+
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ lwres_uint16_t naddrs;
+ char *realname;
+ char **aliases;
+ lwres_uint16_t realnamelen;
+ lwres_uint16_t *aliaslen;
+ lwres_addrlist_t addrs;
+ void *base;
+ size_t baselen;
+} lwres_gabnresponse_t;</PRE
+></P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_gabnrequest_render()</TT
+>
+uses resolver context
+<TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+>
+to convert getaddrbyname request structure
+<TT
+CLASS="PARAMETER"
+><I
+>req</I
+></TT
+>
+to canonical format.
+The packet header structure
+<TT
+CLASS="PARAMETER"
+><I
+>pkt</I
+></TT
+>
+is initialised and transferred to
+buffer
+<TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+>.
+
+The contents of
+<TT
+CLASS="PARAMETER"
+><I
+>*req</I
+></TT
+>
+are then appended to the buffer in canonical format.
+<TT
+CLASS="FUNCTION"
+>lwres_gabnresponse_render()</TT
+>
+performs the same task, except it converts a getaddrbyname response structure
+<SPAN
+CLASS="TYPE"
+>lwres_gabnresponse_t</SPAN
+>
+to the lightweight resolver's canonical format.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_gabnrequest_parse()</TT
+>
+uses context
+<TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+>
+to convert the contents of packet
+<TT
+CLASS="PARAMETER"
+><I
+>pkt</I
+></TT
+>
+to a
+<SPAN
+CLASS="TYPE"
+>lwres_gabnrequest_t</SPAN
+>
+structure.
+Buffer
+<TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+>
+provides space to be used for storing this structure.
+When the function succeeds, the resulting
+<SPAN
+CLASS="TYPE"
+>lwres_gabnrequest_t</SPAN
+>
+is made available through
+<TT
+CLASS="PARAMETER"
+><I
+>*structp</I
+></TT
+>.
+
+<TT
+CLASS="FUNCTION"
+>lwres_gabnresponse_parse()</TT
+>
+offers the same semantics as
+<TT
+CLASS="FUNCTION"
+>lwres_gabnrequest_parse()</TT
+>
+except it yields a
+<SPAN
+CLASS="TYPE"
+>lwres_gabnresponse_t</SPAN
+>
+structure.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_gabnresponse_free()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_gabnrequest_free()</TT
+>
+release the memory in resolver context
+<TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+>
+that was allocated to the
+<SPAN
+CLASS="TYPE"
+>lwres_gabnresponse_t</SPAN
+>
+or
+<SPAN
+CLASS="TYPE"
+>lwres_gabnrequest_t</SPAN
+>
+structures referenced via
+<TT
+CLASS="PARAMETER"
+><I
+>structp</I
+></TT
+>.
+
+Any memory associated with ancillary buffers and strings for those
+structures is also discarded.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN93"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+>The getaddrbyname opcode functions
+<TT
+CLASS="FUNCTION"
+>lwres_gabnrequest_render()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>lwres_gabnresponse_render()</TT
+>
+<TT
+CLASS="FUNCTION"
+>lwres_gabnrequest_parse()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_gabnresponse_parse()</TT
+>
+all return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_SUCCESS</SPAN
+>
+on success.
+They return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_NOMEMORY</SPAN
+>
+if memory allocation fails.
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_UNEXPECTEDEND</SPAN
+>
+is returned if the available space in the buffer
+<TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+>
+is too small to accommodate the packet header or the
+<SPAN
+CLASS="TYPE"
+>lwres_gabnrequest_t</SPAN
+>
+and
+<SPAN
+CLASS="TYPE"
+>lwres_gabnresponse_t</SPAN
+>
+structures.
+<TT
+CLASS="FUNCTION"
+>lwres_gabnrequest_parse()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_gabnresponse_parse()</TT
+>
+will return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_UNEXPECTEDEND</SPAN
+>
+if the buffer is not empty after decoding the received packet.
+These functions will return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_FAILURE</SPAN
+>
+if
+<TT
+CLASS="STRUCTFIELD"
+><I
+>pktflags</I
+></TT
+>
+in the packet header structure
+<SPAN
+CLASS="TYPE"
+>lwres_lwpacket_t</SPAN
+>
+indicate that the packet is not a response to an earlier query.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN112"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_packet</SPAN
+>(3)</SPAN
+></P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/lib/liblwres/man/lwres_gai_strerror.3 b/lib/liblwres/man/lwres_gai_strerror.3
new file mode 100644
index 000000000..a8287e924
--- /dev/null
+++ b/lib/liblwres/man/lwres_gai_strerror.3
@@ -0,0 +1,86 @@
+.\"
+.\" Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM 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.
+.\"
+.TH "LWRES_GAI_STRERROR" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+gai_strerror \- print suitable error string
+.SH SYNOPSIS
+\fB#include <lwres/netdb.h>
+.sp
+.na
+char *
+gai_strerror(int ecode);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+\fBlwres_gai_strerror()\fR
+returns an error message corresponding to an error code returned by
+\fBgetaddrinfo()\fR.
+The following error codes and their meaning are defined in
+\fIinclude/lwres/netdb.h\fR.
+.TP
+\fBEAI_ADDRFAMILY\fR
+address family for hostname not supported
+.TP
+\fBEAI_AGAIN\fR
+temporary failure in name resolution
+.TP
+\fBEAI_BADFLAGS\fR
+invalid value for
+ai_flags
+.TP
+\fBEAI_FAIL\fR
+non-recoverable failure in name resolution
+.TP
+\fBEAI_FAMILY\fR
+ai_family not supported
+.TP
+\fBEAI_MEMORY\fR
+memory allocation failure
+.TP
+\fBEAI_NODATA\fR
+no address associated with hostname
+.TP
+\fBEAI_NONAME\fR
+hostname or servname not provided, or not known
+.TP
+\fBEAI_SERVICE\fR
+servname not supported for ai_socktype
+.TP
+\fBEAI_SOCKTYPE\fR
+ai_socktype not supported
+.TP
+\fBEAI_SYSTEM\fR
+system error returned in errno
+.PP
+The message \fBinvalid error code\fR is returned if
+\fIecode\fR
+is out of range.
+.PP
+ai_flags,
+ai_family
+and
+ai_socktype
+are elements of the
+\fBstruct addrinfo\fR
+used by
+\fBlwres_getaddrinfo()\fR.
+.SH "SEE ALSO"
+.PP
+\fBstrerror\fR(3),
+\fBlwres_getaddrinfo\fR(3),
+\fBgetaddrinfo\fR(3),
+\fBRFC2133\fR.
diff --git a/lib/liblwres/man/lwres_gai_strerror.docbook b/lib/liblwres/man/lwres_gai_strerror.docbook
new file mode 100644
index 000000000..6ffe8fc47
--- /dev/null
+++ b/lib/liblwres/man/lwres_gai_strerror.docbook
@@ -0,0 +1,161 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+
+<!-- $Id: lwres_gai_strerror.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+<refentryinfo>
+
+
+<date>Jun 30, 2000</date>
+</refentryinfo>
+<refmeta>
+<refentrytitle>lwres_gai_strerror</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+<refnamediv>
+<refname>gai_strerror</refname>
+<refpurpose>print suitable error string</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/netdb.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+char *
+<function>gai_strerror</function></funcdef>
+<paramdef>int ecode</paramdef>
+</funcprototype>
+</funcsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+<title>DESCRIPTION</title>
+<para>
+<function>lwres_gai_strerror()</function>
+returns an error message corresponding to an error code returned by
+<function>getaddrinfo()</function>.
+The following error codes and their meaning are defined in
+<filename>include/lwres/netdb.h</filename>.
+<variablelist>
+<varlistentry><term><errorcode>EAI_ADDRFAMILY</errorcode></term>
+<listitem>
+<para>
+address family for hostname not supported
+</para>
+</listitem></varlistentry>
+<varlistentry><term><errorcode>EAI_AGAIN</errorcode></term>
+<listitem>
+<para>
+temporary failure in name resolution
+</para>
+</listitem></varlistentry>
+<varlistentry><term><errorcode>EAI_BADFLAGS</errorcode></term>
+<listitem>
+<para>
+invalid value for
+<constant>ai_flags</constant>
+</para>
+</listitem></varlistentry>
+<varlistentry><term><errorcode>EAI_FAIL</errorcode></term>
+<listitem>
+<para>
+non-recoverable failure in name resolution
+</para>
+</listitem></varlistentry>
+<varlistentry><term><errorcode>EAI_FAMILY</errorcode></term>
+<listitem>
+<para>
+<constant>ai_family</constant> not supported
+</para>
+</listitem></varlistentry>
+<varlistentry><term><errorcode>EAI_MEMORY</errorcode></term>
+<listitem>
+<para>
+memory allocation failure
+</para>
+</listitem></varlistentry>
+<varlistentry><term><errorcode>EAI_NODATA</errorcode></term>
+<listitem>
+<para>
+no address associated with hostname
+</para>
+</listitem></varlistentry>
+<varlistentry><term><errorcode>EAI_NONAME</errorcode></term>
+<listitem>
+<para>
+hostname or servname not provided, or not known
+</para>
+</listitem></varlistentry>
+<varlistentry><term><errorcode>EAI_SERVICE</errorcode></term>
+<listitem>
+<para>
+servname not supported for <constant>ai_socktype</constant>
+</para>
+</listitem></varlistentry>
+<varlistentry><term><errorcode>EAI_SOCKTYPE</errorcode></term>
+<listitem>
+<para>
+<constant>ai_socktype</constant> not supported
+</para>
+</listitem></varlistentry>
+<varlistentry><term><errorcode>EAI_SYSTEM</errorcode></term>
+<listitem>
+<para>
+system error returned in errno
+</para>
+</listitem></varlistentry>
+</variablelist>
+The message <errorname>invalid error code</errorname> is returned if
+<parameter>ecode</parameter>
+is out of range.
+</para>
+<para>
+<constant>ai_flags</constant>,
+<constant>ai_family</constant>
+and
+<constant>ai_socktype</constant>
+are elements of the
+<type>struct addrinfo</type>
+used by
+<function>lwres_getaddrinfo()</function>.
+</para>
+</refsect1>
+
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>strerror</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_getaddrinfo</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>getaddrinfo</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>RFC2133</refentrytitle>
+</citerefentry>.
+</para>
+</refsect1>
+</refentry>
diff --git a/lib/liblwres/man/lwres_gai_strerror.html b/lib/liblwres/man/lwres_gai_strerror.html
new file mode 100644
index 000000000..7f245ba4e
--- /dev/null
+++ b/lib/liblwres/man/lwres_gai_strerror.html
@@ -0,0 +1,294 @@
+<!--
+ - Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_gai_strerror</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_gai_strerror</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>gai_strerror&nbsp;--&nbsp;print suitable error string</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN11"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN12"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/netdb.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>char *
+gai_strerror</CODE
+>(int ecode);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN18"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_gai_strerror()</TT
+>
+returns an error message corresponding to an error code returned by
+<TT
+CLASS="FUNCTION"
+>getaddrinfo()</TT
+>.
+The following error codes and their meaning are defined in
+<TT
+CLASS="FILENAME"
+>include/lwres/netdb.h</TT
+>.
+<P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>EAI_ADDRFAMILY</SPAN
+></DT
+><DD
+><P
+>address family for hostname not supported</P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>EAI_AGAIN</SPAN
+></DT
+><DD
+><P
+>temporary failure in name resolution</P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>EAI_BADFLAGS</SPAN
+></DT
+><DD
+><P
+>invalid value for
+<TT
+CLASS="CONSTANT"
+>ai_flags</TT
+></P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>EAI_FAIL</SPAN
+></DT
+><DD
+><P
+>non-recoverable failure in name resolution</P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>EAI_FAMILY</SPAN
+></DT
+><DD
+><P
+><TT
+CLASS="CONSTANT"
+>ai_family</TT
+> not supported</P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>EAI_MEMORY</SPAN
+></DT
+><DD
+><P
+>memory allocation failure</P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>EAI_NODATA</SPAN
+></DT
+><DD
+><P
+>no address associated with hostname</P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>EAI_NONAME</SPAN
+></DT
+><DD
+><P
+>hostname or servname not provided, or not known</P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>EAI_SERVICE</SPAN
+></DT
+><DD
+><P
+>servname not supported for <TT
+CLASS="CONSTANT"
+>ai_socktype</TT
+></P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>EAI_SOCKTYPE</SPAN
+></DT
+><DD
+><P
+><TT
+CLASS="CONSTANT"
+>ai_socktype</TT
+> not supported</P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>EAI_SYSTEM</SPAN
+></DT
+><DD
+><P
+>system error returned in errno</P
+></DD
+></DL
+></DIV
+>
+The message <SPAN
+CLASS="ERRORNAME"
+>invalid error code</SPAN
+> is returned if
+<TT
+CLASS="PARAMETER"
+><I
+>ecode</I
+></TT
+>
+is out of range.</P
+><P
+><TT
+CLASS="CONSTANT"
+>ai_flags</TT
+>,
+<TT
+CLASS="CONSTANT"
+>ai_family</TT
+>
+and
+<TT
+CLASS="CONSTANT"
+>ai_socktype</TT
+>
+are elements of the
+<SPAN
+CLASS="TYPE"
+>struct addrinfo</SPAN
+>
+used by
+<TT
+CLASS="FUNCTION"
+>lwres_getaddrinfo()</TT
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN92"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>strerror</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_getaddrinfo</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>getaddrinfo</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>RFC2133</SPAN
+></SPAN
+>.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/lib/liblwres/man/lwres_getaddrinfo.3 b/lib/liblwres/man/lwres_getaddrinfo.3
new file mode 100644
index 000000000..b7ea46128
--- /dev/null
+++ b/lib/liblwres/man/lwres_getaddrinfo.3
@@ -0,0 +1,247 @@
+.\"
+.\" Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM 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.
+.\"
+.TH "LWRES_GETADDRINFO" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_getaddrinfo, lwres_freeaddrinfo \- socket address structure to host and service name
+.SH SYNOPSIS
+\fB#include <lwres/netdb.h>
+.sp
+.na
+int
+lwres_getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res);
+.ad
+.sp
+.na
+void
+lwres_freeaddrinfo(struct addrinfo *ai);
+.ad
+\fR.PP
+If the operating system does not provide a
+\fBstruct addrinfo\fR,
+the following structure is used:
+.sp
+.nf
+struct addrinfo {
+ int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
+ int ai_family; /* PF_xxx */
+ int ai_socktype; /* SOCK_xxx */
+ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+ size_t ai_addrlen; /* length of ai_addr */
+ char *ai_canonname; /* canonical name for hostname */
+ struct sockaddr *ai_addr; /* binary address */
+ struct addrinfo *ai_next; /* next structure in linked list */
+};
+.sp
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBlwres_getaddrinfo()\fR
+is used to get a list of IP addresses and port numbers for host
+\fIhostname\fR
+and service
+\fIservname\fR.
+The function is the lightweight resolver's implementation of
+\fBgetaddrinfo()\fR
+as defined in RFC2133.
+\fIhostname\fR
+and
+\fIservname\fR
+are pointers to null-terminated
+strings or
+\fBNULL\fR.
+\fIhostname\fR
+is either a host name or a numeric host address string: a dotted decimal
+IPv4 address or an IPv6 address.
+\fIservname\fR
+is either a decimal port number or a service name as listed in
+\fI/etc/services\fR.
+.PP
+\fIhints\fR
+is an optional pointer to a
+\fBstruct addrinfo\fR.
+This structure can be used to provide hints concerning the type of socket
+that the caller supports or wishes to use.
+The caller can supply the following structure elements in
+\fI*hints\fR:
+.TP
+\fBai_family\fR
+The protocol family that should be used.
+When
+ai_family
+is set to
+\fBPF_UNSPEC\fR,
+it means the caller will accept any protocol family supported by the
+operating system.
+.TP
+\fBai_socktype\fR
+denotes the type of socket \(em
+\fBSOCK_STREAM\fR,
+\fBSOCK_DGRAM\fR
+or
+\fBSOCK_RAW\fR
+\(em that is wanted.
+When
+ai_socktype
+is zero the caller will accept any socket type.
+.TP
+\fBai_protocol\fR
+indicates which transport protocol is wanted: IPPROTO_UDP or
+IPPROTO_TCP.
+If
+ai_protocol
+is zero the caller will accept any protocol.
+.TP
+\fBai_flags\fR
+Flag bits.
+If the
+\fBAI_CANONNAME\fR
+bit is set, a successful call to
+\fBlwres_getaddrinfo()\fR
+will return a a null-terminated string containing the canonical name
+of the specified hostname in
+ai_canonname
+of the first
+\fBaddrinfo\fR
+structure returned.
+Setting the
+\fBAI_PASSIVE\fR
+bit indicates that the returned socket address structure is intended
+for used in a call to
+\fBbind\fR(2).
+In this case, if the hostname argument is a
+\fBNULL\fR
+pointer, then the IP address portion of the socket
+address structure will be set to
+\fBINADDR_ANY\fR
+for an IPv4 address or
+\fBIN6ADDR_ANY_INIT\fR
+for an IPv6 address.
+
+When
+ai_flags
+does not set the
+\fBAI_PASSIVE\fR
+bit, the returned socket address structure will be ready
+for use in a call to
+\fBconnect\fR(2)
+for a connection-oriented protocol or
+\fBconnect\fR(2),
+\fBsendto\fR(2),
+or
+\fBsendmsg\fR(2)
+if a connectionless protocol was chosen.
+The IP address portion of the socket address structure will be
+set to the loopback address if
+\fIhostname\fR
+is a
+\fBNULL\fR
+pointer and
+\fBAI_PASSIVE\fR
+is not set in
+ai_flags.
+
+If
+ai_flags
+is set to
+\fBAI_NUMERICHOST\fR
+it indicates that
+\fIhostname\fR
+should be treated as a numeric string defining an IPv4 or IPv6 address
+and no name resolution should be attempted.
+.PP
+All other elements of the \fBstruct addrinfo\fR passed
+via \fIhints\fR must be zero.
+.PP
+A \fIhints\fR of \fBNULL\fR is treated as if
+the caller provided a \fBstruct addrinfo\fR initialized to zero
+with ai_familyset to
+PF_UNSPEC.
+.PP
+After a successful call to
+\fBlwres_getaddrinfo()\fR,
+\fI*res\fR
+is a pointer to a linked list of one or more
+\fBaddrinfo\fR
+structures.
+Each
+\fBstruct addrinfo\fR
+in this list cn be processed by following
+the
+ai_next
+pointer, until a
+\fBNULL\fR
+pointer is encountered.
+The three members
+ai_family,
+ai_socktype,
+and
+ai_protocol
+in each
+returned
+\fBaddrinfo\fR
+structure contain the corresponding arguments for a call to
+\fBsocket\fR(2).
+For each
+\fBaddrinfo\fR
+structure in the list, the
+ai_addr
+member points to a filled-in socket address structure of length
+ai_addrlen.
+.PP
+All of the information returned by
+\fBlwres_getaddrinfo()\fR
+is dynamically allocated: the addrinfo structures, and the socket
+address structures and canonical host name strings pointed to by the
+addrinfostructures.
+Memory allocated for the dynamically allocated structures created by
+a successful call to
+\fBlwres_getaddrinfo()\fR
+is released by
+\fBlwres_freeaddrinfo()\fR.
+\fIai\fR
+is a pointer to a
+\fBstruct addrinfo\fR
+created by a call to
+\fBlwres_getaddrinfo()\fR.
+.SH "RETURN VALUES"
+.PP
+\fBlwres_getaddrinfo()\fR
+returns zero on success or one of the error codes listed in
+\fBgai_strerror\fR(3)
+if an error occurs.
+If both
+\fIhostname\fR
+and
+\fIservname\fR
+are
+\fBNULL\fR
+\fBlwres_getaddrinfo()\fR
+returns
+EAI_NONAME.
+.SH "SEE ALSO"
+.PP
+\fBlwres\fR(3),
+\fBlwres_getaddrinfo\fR(3),
+\fBlwres_freeaddrinfo\fR(3),
+\fBlwres_gai_strerror\fR(3),
+\fBRFC2133\fR,
+\fBgetservbyname\fR(3),
+\fBbind\fR(2),
+\fBconnect\fR(2),
+\fBsendto\fR(2),
+\fBsendmsg\fR(2),
+\fBsocket\fR(2).
diff --git a/lib/liblwres/man/lwres_getaddrinfo.docbook b/lib/liblwres/man/lwres_getaddrinfo.docbook
new file mode 100644
index 000000000..f89107304
--- /dev/null
+++ b/lib/liblwres/man/lwres_getaddrinfo.docbook
@@ -0,0 +1,372 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+
+<!-- $Id: lwres_getaddrinfo.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+
+<refentryinfo>
+<date>Jun 30, 2000</date>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>lwres_getaddrinfo</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>lwres_getaddrinfo</refname>
+<refname>lwres_freeaddrinfo</refname>
+<refpurpose>socket address structure to host and service name</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/netdb.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+int
+<function>lwres_getaddrinfo</function></funcdef>
+<paramdef>const char *hostname</paramdef>
+<paramdef>const char *servname</paramdef>
+<paramdef>const struct addrinfo *hints</paramdef>
+<paramdef>struct addrinfo **res</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_freeaddrinfo</function></funcdef>
+<paramdef>struct addrinfo *ai</paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<para>
+If the operating system does not provide a
+<type>struct addrinfo</type>,
+the following structure is used:
+
+<programlisting>
+struct addrinfo {
+ int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
+ int ai_family; /* PF_xxx */
+ int ai_socktype; /* SOCK_xxx */
+ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+ size_t ai_addrlen; /* length of ai_addr */
+ char *ai_canonname; /* canonical name for hostname */
+ struct sockaddr *ai_addr; /* binary address */
+ struct addrinfo *ai_next; /* next structure in linked list */
+};
+</programlisting>
+</para>
+
+</refsynopsisdiv>
+
+<refsect1>
+<title>DESCRIPTION</title>
+<para>
+<function>lwres_getaddrinfo()</function>
+is used to get a list of IP addresses and port numbers for host
+<parameter>hostname</parameter>
+and service
+<parameter>servname</parameter>.
+
+The function is the lightweight resolver's implementation of
+<function>getaddrinfo()</function>
+as defined in RFC2133.
+<parameter>hostname</parameter>
+and
+<parameter>servname</parameter>
+are pointers to null-terminated
+strings or
+<type>NULL</type>.
+
+<parameter>hostname</parameter>
+is either a host name or a numeric host address string: a dotted decimal
+IPv4 address or an IPv6 address.
+<parameter>servname</parameter>
+is either a decimal port number or a service name as listed in
+<filename>/etc/services</filename>.
+</para>
+
+<para>
+<parameter>hints</parameter>
+is an optional pointer to a
+<type>struct addrinfo</type>.
+This structure can be used to provide hints concerning the type of socket
+that the caller supports or wishes to use.
+The caller can supply the following structure elements in
+<parameter>*hints</parameter>:
+
+<variablelist>
+<varlistentry><term><constant>ai_family</constant></term>
+<listitem>
+<para>The protocol family that should be used.
+When
+<constant>ai_family</constant>
+is set to
+<type>PF_UNSPEC</type>,
+it means the caller will accept any protocol family supported by the
+operating system.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>ai_socktype</constant></term>
+<listitem>
+<para>
+denotes the type of socket &mdash;
+<type>SOCK_STREAM</type>,
+<type>SOCK_DGRAM</type>
+or
+<type>SOCK_RAW</type>
+&mdash; that is wanted.
+When
+<constant>ai_socktype</constant>
+is zero the caller will accept any socket type.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry><term><constant>ai_protocol</constant></term>
+<listitem>
+<para>
+indicates which transport protocol is wanted: IPPROTO_UDP or
+IPPROTO_TCP.
+If
+<constant>ai_protocol</constant>
+is zero the caller will accept any protocol.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry><term><constant>ai_flags</constant></term>
+<listitem>
+<para>
+Flag bits.
+If the
+<type>AI_CANONNAME</type>
+bit is set, a successful call to
+<function>lwres_getaddrinfo()</function>
+will return a a null-terminated string containing the canonical name
+of the specified hostname in
+<constant>ai_canonname</constant>
+of the first
+<type>addrinfo</type>
+structure returned.
+Setting the
+<type>AI_PASSIVE</type>
+bit indicates that the returned socket address structure is intended
+for used in a call to
+<citerefentry>
+<refentrytitle>bind</refentrytitle><manvolnum>2</manvolnum>
+</citerefentry>.
+
+In this case, if the hostname argument is a
+<type>NULL</type>
+pointer, then the IP address portion of the socket
+address structure will be set to
+<type>INADDR_ANY</type>
+for an IPv4 address or
+<type>IN6ADDR_ANY_INIT</type>
+for an IPv6 address.
+</para>
+<para>
+When
+<constant>ai_flags</constant>
+does not set the
+<type>AI_PASSIVE</type>
+bit, the returned socket address structure will be ready
+for use in a call to
+<citerefentry>
+<refentrytitle>connect</refentrytitle><manvolnum>2
+</manvolnum>
+</citerefentry>
+for a connection-oriented protocol or
+<citerefentry>
+<refentrytitle>connect</refentrytitle><manvolnum>2</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>sendto</refentrytitle><manvolnum>2</manvolnum>
+</citerefentry>,
+
+or
+<citerefentry>
+<refentrytitle>sendmsg</refentrytitle><manvolnum>2
+</manvolnum>
+</citerefentry>
+if a connectionless protocol was chosen.
+The IP address portion of the socket address structure will be
+set to the loopback address if
+<parameter>hostname</parameter>
+is a
+<type>NULL</type>
+pointer and
+<type>AI_PASSIVE</type>
+is not set in
+<constant>ai_flags</constant>.
+</para>
+<para>
+If
+<constant>ai_flags</constant>
+is set to
+<type>AI_NUMERICHOST</type>
+it indicates that
+<parameter>hostname</parameter>
+should be treated as a numeric string defining an IPv4 or IPv6 address
+and no name resolution should be attempted.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</para>
+
+<para>
+All other elements of the <type>struct addrinfo</type> passed
+via <parameter>hints</parameter> must be zero.
+</para>
+
+<para>
+A <parameter>hints</parameter> of <type>NULL</type> is treated as if
+the caller provided a <type>struct addrinfo</type> initialized to zero
+with <constant>ai_family</constant>set to
+<constant>PF_UNSPEC</constant>.
+</para>
+
+<para>
+After a successful call to
+<function>lwres_getaddrinfo()</function>,
+<parameter>*res</parameter>
+is a pointer to a linked list of one or more
+<type>addrinfo</type>
+structures.
+Each
+<type>struct addrinfo</type>
+in this list cn be processed by following
+the
+<constant>ai_next</constant>
+pointer, until a
+<type>NULL</type>
+pointer is encountered.
+The three members
+<constant>ai_family</constant>,
+<constant>ai_socktype</constant>,
+and
+<constant>ai_protocol</constant>
+in each
+returned
+<type>addrinfo</type>
+structure contain the corresponding arguments for a call to
+<citerefentry>
+<refentrytitle>socket</refentrytitle><manvolnum>2</manvolnum>
+</citerefentry>.
+For each
+<type>addrinfo</type>
+structure in the list, the
+<constant>ai_addr</constant>
+member points to a filled-in socket address structure of length
+<constant>ai_addrlen</constant>.
+</para>
+
+<para>
+All of the information returned by
+<function>lwres_getaddrinfo()</function>
+is dynamically allocated: the addrinfo structures, and the socket
+address structures and canonical host name strings pointed to by the
+<constant>addrinfo</constant>structures.
+Memory allocated for the dynamically allocated structures created by
+a successful call to
+<function>lwres_getaddrinfo()</function>
+is released by
+<function>lwres_freeaddrinfo()</function>.
+<parameter>ai</parameter>
+is a pointer to a
+<type>struct addrinfo</type>
+created by a call to
+<function>lwres_getaddrinfo()</function>.
+</para>
+
+</refsect1>
+
+<refsect1>
+<title>RETURN VALUES</title>
+<para>
+<function>lwres_getaddrinfo()</function>
+returns zero on success or one of the error codes listed in
+<citerefentry>
+<refentrytitle>gai_strerror</refentrytitle><manvolnum>3
+</manvolnum>
+</citerefentry>
+if an error occurs.
+If both
+<parameter>hostname</parameter>
+and
+<parameter>servname</parameter>
+are
+<type>NULL</type>
+<function>lwres_getaddrinfo()</function>
+returns
+<errorcode>EAI_NONAME</errorcode>.
+
+</para>
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>lwres</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_getaddrinfo</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_freeaddrinfo</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_gai_strerror</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>RFC2133</refentrytitle>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>getservbyname</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>bind</refentrytitle><manvolnum>2</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>connect</refentrytitle><manvolnum>2</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>sendto</refentrytitle><manvolnum>2</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>sendmsg</refentrytitle><manvolnum>2</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>socket</refentrytitle><manvolnum>2</manvolnum>
+</citerefentry>.
+</para>
+
+</refsect1>
+</refentry>
diff --git a/lib/liblwres/man/lwres_getaddrinfo.html b/lib/liblwres/man/lwres_getaddrinfo.html
new file mode 100644
index 000000000..d04ecc1a2
--- /dev/null
+++ b/lib/liblwres/man/lwres_getaddrinfo.html
@@ -0,0 +1,722 @@
+<!--
+ - Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_getaddrinfo</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_getaddrinfo</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_getaddrinfo, lwres_freeaddrinfo&nbsp;--&nbsp;socket address structure to host and service name</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN12"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN13"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/netdb.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>int
+lwres_getaddrinfo</CODE
+>(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_freeaddrinfo</CODE
+>(struct addrinfo *ai);</CODE
+></P
+><P
+></P
+></DIV
+><P
+>If the operating system does not provide a
+<SPAN
+CLASS="TYPE"
+>struct addrinfo</SPAN
+>,
+the following structure is used:
+
+<PRE
+CLASS="PROGRAMLISTING"
+>struct addrinfo {
+ int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
+ int ai_family; /* PF_xxx */
+ int ai_socktype; /* SOCK_xxx */
+ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+ size_t ai_addrlen; /* length of ai_addr */
+ char *ai_canonname; /* canonical name for hostname */
+ struct sockaddr *ai_addr; /* binary address */
+ struct addrinfo *ai_next; /* next structure in linked list */
+};</PRE
+></P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN29"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_getaddrinfo()</TT
+>
+is used to get a list of IP addresses and port numbers for host
+<TT
+CLASS="PARAMETER"
+><I
+>hostname</I
+></TT
+>
+and service
+<TT
+CLASS="PARAMETER"
+><I
+>servname</I
+></TT
+>.
+
+The function is the lightweight resolver's implementation of
+<TT
+CLASS="FUNCTION"
+>getaddrinfo()</TT
+>
+as defined in RFC2133.
+<TT
+CLASS="PARAMETER"
+><I
+>hostname</I
+></TT
+>
+and
+<TT
+CLASS="PARAMETER"
+><I
+>servname</I
+></TT
+>
+are pointers to null-terminated
+strings or
+<SPAN
+CLASS="TYPE"
+>NULL</SPAN
+>.
+
+<TT
+CLASS="PARAMETER"
+><I
+>hostname</I
+></TT
+>
+is either a host name or a numeric host address string: a dotted decimal
+IPv4 address or an IPv6 address.
+<TT
+CLASS="PARAMETER"
+><I
+>servname</I
+></TT
+>
+is either a decimal port number or a service name as listed in
+<TT
+CLASS="FILENAME"
+>/etc/services</TT
+>.</P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>hints</I
+></TT
+>
+is an optional pointer to a
+<SPAN
+CLASS="TYPE"
+>struct addrinfo</SPAN
+>.
+This structure can be used to provide hints concerning the type of socket
+that the caller supports or wishes to use.
+The caller can supply the following structure elements in
+<TT
+CLASS="PARAMETER"
+><I
+>*hints</I
+></TT
+>:
+
+<P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="CONSTANT"
+>ai_family</TT
+></DT
+><DD
+><P
+>The protocol family that should be used.
+When
+<TT
+CLASS="CONSTANT"
+>ai_family</TT
+>
+is set to
+<SPAN
+CLASS="TYPE"
+>PF_UNSPEC</SPAN
+>,
+it means the caller will accept any protocol family supported by the
+operating system.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>ai_socktype</TT
+></DT
+><DD
+><P
+>denotes the type of socket &mdash;
+<SPAN
+CLASS="TYPE"
+>SOCK_STREAM</SPAN
+>,
+<SPAN
+CLASS="TYPE"
+>SOCK_DGRAM</SPAN
+>
+or
+<SPAN
+CLASS="TYPE"
+>SOCK_RAW</SPAN
+>
+&mdash; that is wanted.
+When
+<TT
+CLASS="CONSTANT"
+>ai_socktype</TT
+>
+is zero the caller will accept any socket type.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>ai_protocol</TT
+></DT
+><DD
+><P
+>indicates which transport protocol is wanted: IPPROTO_UDP or
+IPPROTO_TCP.
+If
+<TT
+CLASS="CONSTANT"
+>ai_protocol</TT
+>
+is zero the caller will accept any protocol.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>ai_flags</TT
+></DT
+><DD
+><P
+>Flag bits.
+If the
+<SPAN
+CLASS="TYPE"
+>AI_CANONNAME</SPAN
+>
+bit is set, a successful call to
+<TT
+CLASS="FUNCTION"
+>lwres_getaddrinfo()</TT
+>
+will return a a null-terminated string containing the canonical name
+of the specified hostname in
+<TT
+CLASS="CONSTANT"
+>ai_canonname</TT
+>
+of the first
+<SPAN
+CLASS="TYPE"
+>addrinfo</SPAN
+>
+structure returned.
+Setting the
+<SPAN
+CLASS="TYPE"
+>AI_PASSIVE</SPAN
+>
+bit indicates that the returned socket address structure is intended
+for used in a call to
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>bind</SPAN
+>(2)</SPAN
+>.
+
+In this case, if the hostname argument is a
+<SPAN
+CLASS="TYPE"
+>NULL</SPAN
+>
+pointer, then the IP address portion of the socket
+address structure will be set to
+<SPAN
+CLASS="TYPE"
+>INADDR_ANY</SPAN
+>
+for an IPv4 address or
+<SPAN
+CLASS="TYPE"
+>IN6ADDR_ANY_INIT</SPAN
+>
+for an IPv6 address.</P
+><P
+>When
+<TT
+CLASS="CONSTANT"
+>ai_flags</TT
+>
+does not set the
+<SPAN
+CLASS="TYPE"
+>AI_PASSIVE</SPAN
+>
+bit, the returned socket address structure will be ready
+for use in a call to
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>connect</SPAN
+>(2)</SPAN
+>
+for a connection-oriented protocol or
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>connect</SPAN
+>(2)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>sendto</SPAN
+>(2)</SPAN
+>,
+
+or
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>sendmsg</SPAN
+>(2)</SPAN
+>
+if a connectionless protocol was chosen.
+The IP address portion of the socket address structure will be
+set to the loopback address if
+<TT
+CLASS="PARAMETER"
+><I
+>hostname</I
+></TT
+>
+is a
+<SPAN
+CLASS="TYPE"
+>NULL</SPAN
+>
+pointer and
+<SPAN
+CLASS="TYPE"
+>AI_PASSIVE</SPAN
+>
+is not set in
+<TT
+CLASS="CONSTANT"
+>ai_flags</TT
+>.</P
+><P
+>If
+<TT
+CLASS="CONSTANT"
+>ai_flags</TT
+>
+is set to
+<SPAN
+CLASS="TYPE"
+>AI_NUMERICHOST</SPAN
+>
+it indicates that
+<TT
+CLASS="PARAMETER"
+><I
+>hostname</I
+></TT
+>
+should be treated as a numeric string defining an IPv4 or IPv6 address
+and no name resolution should be attempted.</P
+></DD
+></DL
+></DIV
+></P
+><P
+>All other elements of the <SPAN
+CLASS="TYPE"
+>struct addrinfo</SPAN
+> passed
+via <TT
+CLASS="PARAMETER"
+><I
+>hints</I
+></TT
+> must be zero.</P
+><P
+>A <TT
+CLASS="PARAMETER"
+><I
+>hints</I
+></TT
+> of <SPAN
+CLASS="TYPE"
+>NULL</SPAN
+> is treated as if
+the caller provided a <SPAN
+CLASS="TYPE"
+>struct addrinfo</SPAN
+> initialized to zero
+with <TT
+CLASS="CONSTANT"
+>ai_family</TT
+>set to
+<TT
+CLASS="CONSTANT"
+>PF_UNSPEC</TT
+>.</P
+><P
+>After a successful call to
+<TT
+CLASS="FUNCTION"
+>lwres_getaddrinfo()</TT
+>,
+<TT
+CLASS="PARAMETER"
+><I
+>*res</I
+></TT
+>
+is a pointer to a linked list of one or more
+<SPAN
+CLASS="TYPE"
+>addrinfo</SPAN
+>
+structures.
+Each
+<SPAN
+CLASS="TYPE"
+>struct addrinfo</SPAN
+>
+in this list cn be processed by following
+the
+<TT
+CLASS="CONSTANT"
+>ai_next</TT
+>
+pointer, until a
+<SPAN
+CLASS="TYPE"
+>NULL</SPAN
+>
+pointer is encountered.
+The three members
+<TT
+CLASS="CONSTANT"
+>ai_family</TT
+>,
+<TT
+CLASS="CONSTANT"
+>ai_socktype</TT
+>,
+and
+<TT
+CLASS="CONSTANT"
+>ai_protocol</TT
+>
+in each
+returned
+<SPAN
+CLASS="TYPE"
+>addrinfo</SPAN
+>
+structure contain the corresponding arguments for a call to
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>socket</SPAN
+>(2)</SPAN
+>.
+For each
+<SPAN
+CLASS="TYPE"
+>addrinfo</SPAN
+>
+structure in the list, the
+<TT
+CLASS="CONSTANT"
+>ai_addr</TT
+>
+member points to a filled-in socket address structure of length
+<TT
+CLASS="CONSTANT"
+>ai_addrlen</TT
+>.</P
+><P
+>All of the information returned by
+<TT
+CLASS="FUNCTION"
+>lwres_getaddrinfo()</TT
+>
+is dynamically allocated: the addrinfo structures, and the socket
+address structures and canonical host name strings pointed to by the
+<TT
+CLASS="CONSTANT"
+>addrinfo</TT
+>structures.
+Memory allocated for the dynamically allocated structures created by
+a successful call to
+<TT
+CLASS="FUNCTION"
+>lwres_getaddrinfo()</TT
+>
+is released by
+<TT
+CLASS="FUNCTION"
+>lwres_freeaddrinfo()</TT
+>.
+<TT
+CLASS="PARAMETER"
+><I
+>ai</I
+></TT
+>
+is a pointer to a
+<SPAN
+CLASS="TYPE"
+>struct addrinfo</SPAN
+>
+created by a call to
+<TT
+CLASS="FUNCTION"
+>lwres_getaddrinfo()</TT
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN142"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_getaddrinfo()</TT
+>
+returns zero on success or one of the error codes listed in
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>gai_strerror</SPAN
+>(3)</SPAN
+>
+if an error occurs.
+If both
+<TT
+CLASS="PARAMETER"
+><I
+>hostname</I
+></TT
+>
+and
+<TT
+CLASS="PARAMETER"
+><I
+>servname</I
+></TT
+>
+are
+<SPAN
+CLASS="TYPE"
+>NULL</SPAN
+>
+<TT
+CLASS="FUNCTION"
+>lwres_getaddrinfo()</TT
+>
+returns
+<SPAN
+CLASS="ERRORCODE"
+>EAI_NONAME</SPAN
+>.&#13;</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN154"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_getaddrinfo</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_freeaddrinfo</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_gai_strerror</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>RFC2133</SPAN
+></SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>getservbyname</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>bind</SPAN
+>(2)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>connect</SPAN
+>(2)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>sendto</SPAN
+>(2)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>sendmsg</SPAN
+>(2)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>socket</SPAN
+>(2)</SPAN
+>.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/lib/liblwres/man/lwres_gethostent.3 b/lib/liblwres/man/lwres_gethostent.3
new file mode 100644
index 000000000..44811ef4d
--- /dev/null
+++ b/lib/liblwres/man/lwres_gethostent.3
@@ -0,0 +1,270 @@
+.\"
+.\" Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM 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.
+.\"
+.TH "LWRES_GETHOSTENT" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_gethostbyname, lwres_gethostbyname2, lwres_gethostbyaddr, lwres_gethostent, lwres_sethostent, lwres_endhostent, lwres_gethostbyname_r, lwres_gethostbyaddr_r, lwres_gethostent_r, lwres_sethostent_r, lwres_endhostent_r \- lightweight resolver get network host entry
+.SH SYNOPSIS
+\fB#include <lwres/netdb.h>
+.sp
+.na
+struct hostent *
+lwres_gethostbyname(const char *name);
+.ad
+.sp
+.na
+struct hostent *
+lwres_gethostbyname2(const char *name, int af);
+.ad
+.sp
+.na
+struct hostent *
+lwres_gethostbyaddr(const char *addr, int len, int type);
+.ad
+.sp
+.na
+struct hostent *
+lwres_gethostent(void);
+.ad
+.sp
+.na
+void
+lwres_sethostent(int stayopen);
+.ad
+.sp
+.na
+void
+lwres_endhostent(void);
+.ad
+.sp
+.na
+struct hostent *
+lwres_gethostbyname_r(const char *name, struct hostent *resbuf, char *buf, int buflen, int *error);
+.ad
+.sp
+.na
+struct hostent *
+lwres_gethostbyaddr_r(const char *addr, int len, int type, struct hostent *resbuf, char *buf, int buflen, int *error);
+.ad
+.sp
+.na
+struct hostent *
+lwres_gethostent_r(struct hostent *resbuf, char *buf, int buflen, int *error);
+.ad
+.sp
+.na
+void
+lwres_sethostent_r(int stayopen);
+.ad
+.sp
+.na
+void
+lwres_endhostent_r(void);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+These functions provide hostname-to-address and
+address-to-hostname lookups by means of the lightweight resolver.
+They are similar to the standard
+\fBgethostent\fR(3)
+functions provided by most operating systems.
+They use a
+\fBstruct hostent\fR
+which is usually defined in
+\fI<namedb.h>\fR.
+.sp
+.nf
+struct hostent {
+ char *h_name; /* official name of host */
+ char **h_aliases; /* alias list */
+ int h_addrtype; /* host address type */
+ int h_length; /* length of address */
+ char **h_addr_list; /* list of addresses from name server */
+};
+#define h_addr h_addr_list[0] /* address, for backward compatibility */
+.sp
+.fi
+.PP
+The members of this structure are:
+.TP
+\fBh_name\fR
+The official (canonical) name of the host.
+.TP
+\fBh_aliases\fR
+A NULL-terminated array of alternate names (nicknames) for the host.
+.TP
+\fBh_addrtype\fR
+The type of address being returned \(em
+\fBPF_INET\fR
+or
+\fBPF_INET6\fR.
+.TP
+\fBh_length\fR
+The length of the address in bytes.
+.TP
+\fBh_addr_list\fR
+A \fBNULL\fR
+terminated array of network addresses for the host.
+Host addresses are returned in network byte order.
+.PP
+For backward compatibility with very old software,
+h_addr
+is the first address in
+h_addr_list.
+.PP
+\fBlwres_gethostent()\fR,
+\fBlwres_sethostent()\fR,
+\fBlwres_endhostent()\fR,
+\fBlwres_gethostent_r()\fR,
+\fBlwres_sethostent_r()\fR
+and
+\fBlwres_endhostent_r()\fR
+provide iteration over the known host entries on systems that
+provide such functionality through facilities like
+\fI/etc/hosts\fR
+or NIS. The lightweight resolver does not currently implement
+these functions; it only provides them as stub functions that always
+return failure.
+.PP
+\fBlwres_gethostbyname()\fR and
+\fBlwres_gethostbyname2()\fR look up the hostname
+\fIname\fR.
+\fBlwres_gethostbyname()\fR always looks for an IPv4
+address while \fBlwres_gethostbyname2()\fR looks for an
+address of protocol family \fIaf\fR: either
+\fBPF_INET\fR or \fBPF_INET6\fR \(em IPv4 or IPV6
+addresses respectively. Successful calls of the functions return a
+\fBstruct hostent\fRfor the name that was looked up.
+\fBNULL\fR is returned if the lookups by
+\fBlwres_gethostbyname()\fR or
+\fBlwres_gethostbyname2()\fR fail.
+.PP
+Reverse lookups of addresses are performed by
+\fBlwres_gethostbyaddr()\fR.
+\fIaddr\fR is an address of length
+\fIlen\fR bytes and protocol family
+\fItype\fR \(em \fBPF_INET\fR or
+\fBPF_INET6\fR.
+\fBlwres_gethostbyname_r()\fR is a thread-safe function
+for forward lookups. If an error occurs, an error code is returned in
+\fI*error\fR.
+\fIresbuf\fR is a pointer to a \fBstruct
+hostent\fR which is initialised by a successful call to
+\fBlwres_gethostbyname_r()\fR .
+\fIbuf\fR is a buffer of length
+\fIlen\fR bytes which is used to store the
+h_name, h_aliases, and
+h_addr_list elements of the \fBstruct
+hostent\fR returned in \fIresbuf\fR.
+Successful calls to \fBlwres_gethostbyname_r()\fR
+return \fIresbuf\fR,
+which is a pointer to the \fBstruct hostent\fR it created.
+.PP
+\fBlwres_gethostbyaddr_r()\fR is a thread-safe function
+that performs a reverse lookup of address \fIaddr\fR
+which is \fIlen\fR bytes long and is of protocol
+family \fItype\fR \(em \fBPF_INET\fR or
+\fBPF_INET6\fR. If an error occurs, the error code is returned
+in \fI*error\fR. The other function parameters are
+identical to those in \fBlwres_gethostbyname_r()\fR.
+\fIresbuf\fR is a pointer to a \fBstruct
+hostent\fR which is initialised by a successful call to
+\fBlwres_gethostbyaddr_r()\fR.
+\fIbuf\fR is a buffer of length
+\fIlen\fR bytes which is used to store the
+h_name, h_aliases, and
+h_addr_list elements of the \fBstruct
+hostent\fR returned in \fIresbuf\fR. Successful
+calls to \fBlwres_gethostbyaddr_r()\fR return
+\fIresbuf\fR, which is a pointer to the
+\fBstruct hostent()\fR it created.
+.SH "RETURN VALUES"
+.PP
+The functions
+\fBlwres_gethostbyname()\fR,
+\fBlwres_gethostbyname2()\fR,
+\fBlwres_gethostbyaddr()\fR,
+and
+\fBlwres_gethostent()\fR
+return NULL to indicate an error. In this case the global variable
+\fBlwres_h_errno\fR
+will contain one of the following error codes defined in
+\fI<lwres/netdb.h>\fR:
+.TP
+\fBHOST_NOT_FOUND\fR
+The host or address was not found.
+.TP
+\fBTRY_AGAIN\fR
+A recoverable error occurred, e.g., a timeout.
+Retrying the lookup may succeed.
+.TP
+\fBNO_RECOVERY\fR
+A non-recoverable error occurred.
+.TP
+\fBNO_DATA\fR
+The name exists, but has no address information
+associated with it (or vice versa in the case
+of a reverse lookup). The code NO_ADDRESS
+is accepted as a synonym for NO_DATA for backwards
+compatibility.
+.PP
+\fBlwres_hstrerror\fR(3)
+translates these error codes to suitable error messages.
+.PP
+\fBlwres_gethostent()\fR
+and
+\fBlwres_gethostent_r()\fR
+always return
+\fBNULL\fR.
+.PP
+Successful calls to \fBlwres_gethostbyname_r()\fR and
+\fBlwres_gethostbyaddr_r()\fR return
+\fIresbuf\fR, a pointer to the \fBstruct
+hostent\fR that was initialised by these functions. They return
+\fBNULL\fR if the lookups fail or if \fIbuf\fR
+was too small to hold the list of addresses and names referenced by
+the h_name, h_aliases, and
+h_addr_list elements of the \fBstruct
+hostent\fR. If \fIbuf\fR was too small, both
+\fBlwres_gethostbyname_r()\fR and
+\fBlwres_gethostbyaddr_r()\fR set the global variable
+\fBerrno\fR to ERANGE.
+.SH "SEE ALSO"
+.PP
+\fBgethostent\fR(3),
+\fBlwres_getipnode\fR(3),
+\fBlwres_hstrerror\fR(3)
+.SH "BUGS"
+.PP
+\fBlwres_gethostbyname()\fR,
+\fBlwres_gethostbyname2()\fR,
+\fBlwres_gethostbyaddr()\fR
+and
+\fBlwres_endhostent()\fR
+are not thread safe; they return pointers to static data and
+provide error codes through a global variable.
+Thread-safe versions for name and address lookup are provided by
+\fBlwres_gethostbyname_r()\fR,
+and
+\fBlwres_gethostbyaddr_r()\fR
+respectively.
+.PP
+The resolver daemon does not currently support any non-DNS
+name services such as
+\fI/etc/hosts\fR
+or
+\fBNIS\fR,
+consequently the above functions don't, either.
diff --git a/lib/liblwres/man/lwres_gethostent.docbook b/lib/liblwres/man/lwres_gethostent.docbook
new file mode 100644
index 000000000..22717821c
--- /dev/null
+++ b/lib/liblwres/man/lwres_gethostent.docbook
@@ -0,0 +1,407 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+
+<!-- $Id: lwres_gethostent.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+
+<refentryinfo>
+<date>Jun 30, 2000</date>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>lwres_gethostent</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>lwres_gethostbyname</refname>
+<refname>lwres_gethostbyname2</refname>
+<refname>lwres_gethostbyaddr</refname>
+<refname>lwres_gethostent</refname>
+<refname>lwres_sethostent</refname>
+<refname>lwres_endhostent</refname>
+<refname>lwres_gethostbyname_r</refname>
+<refname>lwres_gethostbyaddr_r</refname>
+<refname>lwres_gethostent_r</refname>
+<refname>lwres_sethostent_r</refname>
+<refname>lwres_endhostent_r</refname>
+<refpurpose>lightweight resolver get network host entry</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/netdb.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+struct hostent *
+<function>lwres_gethostbyname</function></funcdef>
+<paramdef>const char *name</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+struct hostent *
+<function>lwres_gethostbyname2</function></funcdef>
+<paramdef>const char *name</paramdef>
+<paramdef>int af</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+struct hostent *
+<function>lwres_gethostbyaddr</function></funcdef>
+<paramdef>const char *addr</paramdef>
+<paramdef>int len</paramdef>
+<paramdef>int type</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+struct hostent *
+<function>lwres_gethostent</function></funcdef>
+<paramdef>void</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_sethostent</function></funcdef>
+<paramdef>int stayopen</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_endhostent</function></funcdef>
+<paramdef>void</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+struct hostent *
+<function>lwres_gethostbyname_r</function></funcdef>
+<paramdef>const char *name</paramdef>
+<paramdef>struct hostent *resbuf</paramdef>
+<paramdef>char *buf</paramdef>
+<paramdef>int buflen</paramdef>
+<paramdef>int *error</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+struct hostent *
+<function>lwres_gethostbyaddr_r</function></funcdef>
+<paramdef>const char *addr</paramdef>
+<paramdef>int len</paramdef>
+<paramdef>int type</paramdef>
+<paramdef>struct hostent *resbuf</paramdef>
+<paramdef>char *buf</paramdef>
+<paramdef>int buflen</paramdef>
+<paramdef>int *error</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+struct hostent *
+<function>lwres_gethostent_r</function></funcdef>
+<paramdef>struct hostent *resbuf</paramdef>
+<paramdef>char *buf</paramdef>
+<paramdef>int buflen</paramdef>
+<paramdef>int *error</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_sethostent_r</function></funcdef>
+<paramdef>int stayopen</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_endhostent_r</function></funcdef>
+<paramdef>void</paramdef>
+</funcprototype>
+</funcsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+<title>DESCRIPTION</title>
+<para>
+These functions provide hostname-to-address and
+address-to-hostname lookups by means of the lightweight resolver.
+They are similar to the standard
+<citerefentry>
+<refentrytitle>gethostent</refentrytitle><manvolnum>3
+</manvolnum>
+</citerefentry>
+functions provided by most operating systems.
+They use a
+<type>struct hostent</type>
+which is usually defined in
+<filename>&lt;namedb.h&gt;</filename>.
+
+<programlisting>
+struct hostent {
+ char *h_name; /* official name of host */
+ char **h_aliases; /* alias list */
+ int h_addrtype; /* host address type */
+ int h_length; /* length of address */
+ char **h_addr_list; /* list of addresses from name server */
+};
+#define h_addr h_addr_list[0] /* address, for backward compatibility */
+</programlisting>
+</para>
+<para>
+The members of this structure are:
+<variablelist>
+<varlistentry><term><constant>h_name</constant></term>
+<listitem>
+<para>
+The official (canonical) name of the host.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>h_aliases</constant></term>
+<listitem>
+<para>
+A NULL-terminated array of alternate names (nicknames) for the host.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>h_addrtype</constant></term>
+<listitem>
+<para>
+The type of address being returned &mdash;
+<type>PF_INET</type>
+or
+<type>PF_INET6</type>.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>h_length</constant></term>
+<listitem>
+<para>
+The length of the address in bytes.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>h_addr_list</constant></term>
+<listitem>
+<para>
+A <type>NULL</type>
+terminated array of network addresses for the host.
+Host addresses are returned in network byte order.
+</para>
+</listitem></varlistentry>
+</variablelist>
+</para>
+<para>
+For backward compatibility with very old software,
+<constant>h_addr</constant>
+is the first address in
+<constant>h_addr_list.</constant>
+</para>
+<para>
+<function>lwres_gethostent()</function>,
+<function>lwres_sethostent()</function>,
+<function>lwres_endhostent()</function>,
+<function>lwres_gethostent_r()</function>,
+<function>lwres_sethostent_r()</function>
+and
+<function>lwres_endhostent_r()</function>
+provide iteration over the known host entries on systems that
+provide such functionality through facilities like
+<filename>/etc/hosts</filename>
+or NIS. The lightweight resolver does not currently implement
+these functions; it only provides them as stub functions that always
+return failure.
+</para>
+
+<para>
+<function>lwres_gethostbyname()</function> and
+<function>lwres_gethostbyname2()</function> look up the hostname
+<parameter>name</parameter>.
+<function>lwres_gethostbyname()</function> always looks for an IPv4
+address while <function>lwres_gethostbyname2()</function> looks for an
+address of protocol family <parameter>af</parameter>: either
+<type>PF_INET</type> or <type>PF_INET6</type> &mdash; IPv4 or IPV6
+addresses respectively. Successful calls of the functions return a
+<type>struct hostent</type>for the name that was looked up.
+<type>NULL</type> is returned if the lookups by
+<function>lwres_gethostbyname()</function> or
+<function>lwres_gethostbyname2()</function> fail.
+</para>
+
+<para>
+Reverse lookups of addresses are performed by
+<function>lwres_gethostbyaddr()</function>.
+<parameter>addr</parameter> is an address of length
+<parameter>len</parameter> bytes and protocol family
+<parameter>type</parameter> &mdash; <type>PF_INET</type> or
+<type>PF_INET6</type>.
+<function>lwres_gethostbyname_r()</function> is a thread-safe function
+for forward lookups. If an error occurs, an error code is returned in
+<parameter>*error</parameter>.
+<parameter>resbuf</parameter> is a pointer to a <type>struct
+hostent</type> which is initialised by a successful call to
+<function>lwres_gethostbyname_r()</function> .
+<parameter>buf</parameter> is a buffer of length
+<parameter>len</parameter> bytes which is used to store the
+<constant>h_name</constant>, <constant>h_aliases</constant>, and
+<constant>h_addr_list</constant> elements of the <type>struct
+hostent</type> returned in <parameter>resbuf</parameter>.
+Successful calls to <function>lwres_gethostbyname_r()</function>
+return <parameter>resbuf</parameter>,
+which is a pointer to the <type>struct hostent</type> it created.
+</para>
+
+<para>
+<function>lwres_gethostbyaddr_r()</function> is a thread-safe function
+that performs a reverse lookup of address <parameter>addr</parameter>
+which is <parameter>len</parameter> bytes long and is of protocol
+family <parameter>type</parameter> &mdash; <type>PF_INET</type> or
+<type>PF_INET6</type>. If an error occurs, the error code is returned
+in <parameter>*error</parameter>. The other function parameters are
+identical to those in <function>lwres_gethostbyname_r()</function>.
+<parameter>resbuf</parameter> is a pointer to a <type>struct
+hostent</type> which is initialised by a successful call to
+<function>lwres_gethostbyaddr_r()</function>.
+<parameter>buf</parameter> is a buffer of length
+<parameter>len</parameter> bytes which is used to store the
+<constant>h_name</constant>, <constant>h_aliases</constant>, and
+<constant>h_addr_list</constant> elements of the <type>struct
+hostent</type> returned in <parameter>resbuf</parameter>. Successful
+calls to <function>lwres_gethostbyaddr_r()</function> return
+<parameter>resbuf</parameter>, which is a pointer to the
+<function>struct hostent()</function> it created.
+</para>
+
+</refsect1>
+
+<refsect1>
+<title>RETURN VALUES</title>
+<para>
+The functions
+<function>lwres_gethostbyname()</function>,
+<function>lwres_gethostbyname2()</function>,
+<function>lwres_gethostbyaddr()</function>,
+and
+<function>lwres_gethostent()</function>
+return NULL to indicate an error. In this case the global variable
+<type>lwres_h_errno</type>
+will contain one of the following error codes defined in
+<filename>&lt;lwres/netdb.h&gt;</filename>:
+
+<variablelist>
+<varlistentry><term><constant>HOST_NOT_FOUND</constant></term>
+<listitem>
+<para>
+The host or address was not found.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>TRY_AGAIN</constant></term>
+<listitem>
+<para>
+A recoverable error occurred, e.g., a timeout.
+Retrying the lookup may succeed.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>NO_RECOVERY</constant></term>
+<listitem>
+<para>
+A non-recoverable error occurred.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>NO_DATA</constant></term>
+<listitem>
+<para>
+The name exists, but has no address information
+associated with it (or vice versa in the case
+of a reverse lookup). The code NO_ADDRESS
+is accepted as a synonym for NO_DATA for backwards
+compatibility.
+</para>
+</listitem></varlistentry>
+</variablelist>
+</para>
+
+<para>
+<citerefentry>
+<refentrytitle>lwres_hstrerror</refentrytitle><manvolnum>3
+</manvolnum>
+</citerefentry>
+translates these error codes to suitable error messages.
+</para>
+
+<para>
+<function>lwres_gethostent()</function>
+and
+<function>lwres_gethostent_r()</function>
+always return
+<type>NULL</type>.
+</para>
+
+<para>
+Successful calls to <function>lwres_gethostbyname_r()</function> and
+<function>lwres_gethostbyaddr_r()</function> return
+<parameter>resbuf</parameter>, a pointer to the <type>struct
+hostent</type> that was initialised by these functions. They return
+<type>NULL</type> if the lookups fail or if <parameter>buf</parameter>
+was too small to hold the list of addresses and names referenced by
+the <constant>h_name</constant>, <constant>h_aliases</constant>, and
+<constant>h_addr_list</constant> elements of the <type>struct
+hostent</type>. If <parameter>buf</parameter> was too small, both
+<function>lwres_gethostbyname_r()</function> and
+<function>lwres_gethostbyaddr_r()</function> set the global variable
+<type>errno</type> to <errorcode>ERANGE</errorcode>.
+</para>
+
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>gethostent</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_getipnode</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_hstrerror</refentrytitle><manvolnum>3
+</manvolnum>
+</citerefentry>
+</para>
+</refsect1>
+
+<refsect1>
+<title>BUGS</title>
+<para>
+<function>lwres_gethostbyname()</function>,
+<function>lwres_gethostbyname2()</function>,
+<function>lwres_gethostbyaddr()</function>
+and
+<function>lwres_endhostent()</function>
+are not thread safe; they return pointers to static data and
+provide error codes through a global variable.
+Thread-safe versions for name and address lookup are provided by
+<function>lwres_gethostbyname_r()</function>,
+and
+<function>lwres_gethostbyaddr_r()</function>
+respectively.
+</para>
+<para>
+The resolver daemon does not currently support any non-DNS
+name services such as
+<filename>/etc/hosts</filename>
+or
+<type>NIS</type>,
+consequently the above functions don't, either.
+</para>
+</refsect1>
+</refentry>
diff --git a/lib/liblwres/man/lwres_gethostent.html b/lib/liblwres/man/lwres_gethostent.html
new file mode 100644
index 000000000..28671b86b
--- /dev/null
+++ b/lib/liblwres/man/lwres_gethostent.html
@@ -0,0 +1,827 @@
+<!--
+ - Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_gethostent</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_gethostent</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_gethostbyname, lwres_gethostbyname2, lwres_gethostbyaddr, lwres_gethostent, lwres_sethostent, lwres_endhostent, lwres_gethostbyname_r, lwres_gethostbyaddr_r, lwres_gethostent_r, lwres_sethostent_r, lwres_endhostent_r&nbsp;--&nbsp;lightweight resolver get network host entry</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN21"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN22"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/netdb.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>struct hostent *
+lwres_gethostbyname</CODE
+>(const char *name);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>struct hostent *
+lwres_gethostbyname2</CODE
+>(const char *name, int af);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>struct hostent *
+lwres_gethostbyaddr</CODE
+>(const char *addr, int len, int type);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>struct hostent *
+lwres_gethostent</CODE
+>(void);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_sethostent</CODE
+>(int stayopen);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_endhostent</CODE
+>(void);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>struct hostent *
+lwres_gethostbyname_r</CODE
+>(const char *name, struct hostent *resbuf, char *buf, int buflen, int *error);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>struct hostent *
+lwres_gethostbyaddr_r</CODE
+>(const char *addr, int len, int type, struct hostent *resbuf, char *buf, int buflen, int *error);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>struct hostent *
+lwres_gethostent_r</CODE
+>(struct hostent *resbuf, char *buf, int buflen, int *error);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_sethostent_r</CODE
+>(int stayopen);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_endhostent_r</CODE
+>(void);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN84"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>These functions provide hostname-to-address and
+address-to-hostname lookups by means of the lightweight resolver.
+They are similar to the standard
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>gethostent</SPAN
+>(3)</SPAN
+>
+functions provided by most operating systems.
+They use a
+<SPAN
+CLASS="TYPE"
+>struct hostent</SPAN
+>
+which is usually defined in
+<TT
+CLASS="FILENAME"
+>&lt;namedb.h&gt;</TT
+>.
+
+<PRE
+CLASS="PROGRAMLISTING"
+>struct hostent {
+ char *h_name; /* official name of host */
+ char **h_aliases; /* alias list */
+ int h_addrtype; /* host address type */
+ int h_length; /* length of address */
+ char **h_addr_list; /* list of addresses from name server */
+};
+#define h_addr h_addr_list[0] /* address, for backward compatibility */</PRE
+></P
+><P
+>The members of this structure are:
+<P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="CONSTANT"
+>h_name</TT
+></DT
+><DD
+><P
+>The official (canonical) name of the host.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>h_aliases</TT
+></DT
+><DD
+><P
+>A NULL-terminated array of alternate names (nicknames) for the host.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>h_addrtype</TT
+></DT
+><DD
+><P
+>The type of address being returned &mdash;
+<SPAN
+CLASS="TYPE"
+>PF_INET</SPAN
+>
+or
+<SPAN
+CLASS="TYPE"
+>PF_INET6</SPAN
+>.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>h_length</TT
+></DT
+><DD
+><P
+>The length of the address in bytes.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>h_addr_list</TT
+></DT
+><DD
+><P
+>A <SPAN
+CLASS="TYPE"
+>NULL</SPAN
+>
+terminated array of network addresses for the host.
+Host addresses are returned in network byte order.</P
+></DD
+></DL
+></DIV
+></P
+><P
+>For backward compatibility with very old software,
+<TT
+CLASS="CONSTANT"
+>h_addr</TT
+>
+is the first address in
+<TT
+CLASS="CONSTANT"
+>h_addr_list.</TT
+></P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_gethostent()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>lwres_sethostent()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>lwres_endhostent()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>lwres_gethostent_r()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>lwres_sethostent_r()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_endhostent_r()</TT
+>
+provide iteration over the known host entries on systems that
+provide such functionality through facilities like
+<TT
+CLASS="FILENAME"
+>/etc/hosts</TT
+>
+or NIS. The lightweight resolver does not currently implement
+these functions; it only provides them as stub functions that always
+return failure.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_gethostbyname()</TT
+> and
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyname2()</TT
+> look up the hostname
+<TT
+CLASS="PARAMETER"
+><I
+>name</I
+></TT
+>.
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyname()</TT
+> always looks for an IPv4
+address while <TT
+CLASS="FUNCTION"
+>lwres_gethostbyname2()</TT
+> looks for an
+address of protocol family <TT
+CLASS="PARAMETER"
+><I
+>af</I
+></TT
+>: either
+<SPAN
+CLASS="TYPE"
+>PF_INET</SPAN
+> or <SPAN
+CLASS="TYPE"
+>PF_INET6</SPAN
+> &mdash; IPv4 or IPV6
+addresses respectively. Successful calls of the functions return a
+<SPAN
+CLASS="TYPE"
+>struct hostent</SPAN
+>for the name that was looked up.
+<SPAN
+CLASS="TYPE"
+>NULL</SPAN
+> is returned if the lookups by
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyname()</TT
+> or
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyname2()</TT
+> fail.</P
+><P
+>Reverse lookups of addresses are performed by
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyaddr()</TT
+>.
+<TT
+CLASS="PARAMETER"
+><I
+>addr</I
+></TT
+> is an address of length
+<TT
+CLASS="PARAMETER"
+><I
+>len</I
+></TT
+> bytes and protocol family
+<TT
+CLASS="PARAMETER"
+><I
+>type</I
+></TT
+> &mdash; <SPAN
+CLASS="TYPE"
+>PF_INET</SPAN
+> or
+<SPAN
+CLASS="TYPE"
+>PF_INET6</SPAN
+>.
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyname_r()</TT
+> is a thread-safe function
+for forward lookups. If an error occurs, an error code is returned in
+<TT
+CLASS="PARAMETER"
+><I
+>*error</I
+></TT
+>.
+<TT
+CLASS="PARAMETER"
+><I
+>resbuf</I
+></TT
+> is a pointer to a <SPAN
+CLASS="TYPE"
+>struct
+hostent</SPAN
+> which is initialised by a successful call to
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyname_r()</TT
+> .
+<TT
+CLASS="PARAMETER"
+><I
+>buf</I
+></TT
+> is a buffer of length
+<TT
+CLASS="PARAMETER"
+><I
+>len</I
+></TT
+> bytes which is used to store the
+<TT
+CLASS="CONSTANT"
+>h_name</TT
+>, <TT
+CLASS="CONSTANT"
+>h_aliases</TT
+>, and
+<TT
+CLASS="CONSTANT"
+>h_addr_list</TT
+> elements of the <SPAN
+CLASS="TYPE"
+>struct
+hostent</SPAN
+> returned in <TT
+CLASS="PARAMETER"
+><I
+>resbuf</I
+></TT
+>.
+Successful calls to <TT
+CLASS="FUNCTION"
+>lwres_gethostbyname_r()</TT
+>
+return <TT
+CLASS="PARAMETER"
+><I
+>resbuf</I
+></TT
+>,
+which is a pointer to the <SPAN
+CLASS="TYPE"
+>struct hostent</SPAN
+> it created.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_gethostbyaddr_r()</TT
+> is a thread-safe function
+that performs a reverse lookup of address <TT
+CLASS="PARAMETER"
+><I
+>addr</I
+></TT
+>
+which is <TT
+CLASS="PARAMETER"
+><I
+>len</I
+></TT
+> bytes long and is of protocol
+family <TT
+CLASS="PARAMETER"
+><I
+>type</I
+></TT
+> &mdash; <SPAN
+CLASS="TYPE"
+>PF_INET</SPAN
+> or
+<SPAN
+CLASS="TYPE"
+>PF_INET6</SPAN
+>. If an error occurs, the error code is returned
+in <TT
+CLASS="PARAMETER"
+><I
+>*error</I
+></TT
+>. The other function parameters are
+identical to those in <TT
+CLASS="FUNCTION"
+>lwres_gethostbyname_r()</TT
+>.
+<TT
+CLASS="PARAMETER"
+><I
+>resbuf</I
+></TT
+> is a pointer to a <SPAN
+CLASS="TYPE"
+>struct
+hostent</SPAN
+> which is initialised by a successful call to
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyaddr_r()</TT
+>.
+<TT
+CLASS="PARAMETER"
+><I
+>buf</I
+></TT
+> is a buffer of length
+<TT
+CLASS="PARAMETER"
+><I
+>len</I
+></TT
+> bytes which is used to store the
+<TT
+CLASS="CONSTANT"
+>h_name</TT
+>, <TT
+CLASS="CONSTANT"
+>h_aliases</TT
+>, and
+<TT
+CLASS="CONSTANT"
+>h_addr_list</TT
+> elements of the <SPAN
+CLASS="TYPE"
+>struct
+hostent</SPAN
+> returned in <TT
+CLASS="PARAMETER"
+><I
+>resbuf</I
+></TT
+>. Successful
+calls to <TT
+CLASS="FUNCTION"
+>lwres_gethostbyaddr_r()</TT
+> return
+<TT
+CLASS="PARAMETER"
+><I
+>resbuf</I
+></TT
+>, which is a pointer to the
+<TT
+CLASS="FUNCTION"
+>struct hostent()</TT
+> it created.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN191"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+>The functions
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyname()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyname2()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyaddr()</TT
+>,
+and
+<TT
+CLASS="FUNCTION"
+>lwres_gethostent()</TT
+>
+return NULL to indicate an error. In this case the global variable
+<SPAN
+CLASS="TYPE"
+>lwres_h_errno</SPAN
+>
+will contain one of the following error codes defined in
+<TT
+CLASS="FILENAME"
+>&lt;lwres/netdb.h&gt;</TT
+>:
+
+<P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="CONSTANT"
+>HOST_NOT_FOUND</TT
+></DT
+><DD
+><P
+>The host or address was not found.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>TRY_AGAIN</TT
+></DT
+><DD
+><P
+>A recoverable error occurred, e.g., a timeout.
+Retrying the lookup may succeed.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>NO_RECOVERY</TT
+></DT
+><DD
+><P
+>A non-recoverable error occurred.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>NO_DATA</TT
+></DT
+><DD
+><P
+>The name exists, but has no address information
+associated with it (or vice versa in the case
+of a reverse lookup). The code NO_ADDRESS
+is accepted as a synonym for NO_DATA for backwards
+compatibility.</P
+></DD
+></DL
+></DIV
+></P
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_hstrerror</SPAN
+>(3)</SPAN
+>
+translates these error codes to suitable error messages.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_gethostent()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_gethostent_r()</TT
+>
+always return
+<SPAN
+CLASS="TYPE"
+>NULL</SPAN
+>.</P
+><P
+>Successful calls to <TT
+CLASS="FUNCTION"
+>lwres_gethostbyname_r()</TT
+> and
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyaddr_r()</TT
+> return
+<TT
+CLASS="PARAMETER"
+><I
+>resbuf</I
+></TT
+>, a pointer to the <SPAN
+CLASS="TYPE"
+>struct
+hostent</SPAN
+> that was initialised by these functions. They return
+<SPAN
+CLASS="TYPE"
+>NULL</SPAN
+> if the lookups fail or if <TT
+CLASS="PARAMETER"
+><I
+>buf</I
+></TT
+>
+was too small to hold the list of addresses and names referenced by
+the <TT
+CLASS="CONSTANT"
+>h_name</TT
+>, <TT
+CLASS="CONSTANT"
+>h_aliases</TT
+>, and
+<TT
+CLASS="CONSTANT"
+>h_addr_list</TT
+> elements of the <SPAN
+CLASS="TYPE"
+>struct
+hostent</SPAN
+>. If <TT
+CLASS="PARAMETER"
+><I
+>buf</I
+></TT
+> was too small, both
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyname_r()</TT
+> and
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyaddr_r()</TT
+> set the global variable
+<SPAN
+CLASS="TYPE"
+>errno</SPAN
+> to <SPAN
+CLASS="ERRORCODE"
+>ERANGE</SPAN
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN245"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>gethostent</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_getipnode</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_hstrerror</SPAN
+>(3)</SPAN
+></P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN257"
+></A
+><H2
+>BUGS</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_gethostbyname()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyname2()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyaddr()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_endhostent()</TT
+>
+are not thread safe; they return pointers to static data and
+provide error codes through a global variable.
+Thread-safe versions for name and address lookup are provided by
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyname_r()</TT
+>,
+and
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyaddr_r()</TT
+>
+respectively.</P
+><P
+>The resolver daemon does not currently support any non-DNS
+name services such as
+<TT
+CLASS="FILENAME"
+>/etc/hosts</TT
+>
+or
+<SPAN
+CLASS="TYPE"
+>NIS</SPAN
+>,
+consequently the above functions don't, either.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/lib/liblwres/man/lwres_getipnode.3 b/lib/liblwres/man/lwres_getipnode.3
new file mode 100644
index 000000000..39dfc984a
--- /dev/null
+++ b/lib/liblwres/man/lwres_getipnode.3
@@ -0,0 +1,187 @@
+.\"
+.\" Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM 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.
+.\"
+.TH "LWRES_GETIPNODE" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_getipnodebyname, lwres_getipnodebyaddr, lwres_freehostent \- lightweight resolver nodename / address translation API
+.SH SYNOPSIS
+\fB#include <lwres/netdb.h>
+.sp
+.na
+struct hostent *
+lwres_getipnodebyname(const char *name, int af, int flags, int *error_num);
+.ad
+.sp
+.na
+struct hostent *
+lwres_getipnodebyaddr(const void *src, size_t len, int af, int *error_num);
+.ad
+.sp
+.na
+void
+lwres_freehostent(struct hostent *he);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+These functions perform thread safe, protocol independent
+nodename-to-address and address-to-nodename
+translation as defined in RFC2553.
+.PP
+They use a
+\fBstruct hostent\fR
+which is defined in
+\fInamedb.h\fR:
+.sp
+.nf
+struct hostent {
+ char *h_name; /* official name of host */
+ char **h_aliases; /* alias list */
+ int h_addrtype; /* host address type */
+ int h_length; /* length of address */
+ char **h_addr_list; /* list of addresses from name server */
+};
+#define h_addr h_addr_list[0] /* address, for backward compatibility */
+.sp
+.fi
+.PP
+The members of this structure are:
+.TP
+\fBh_name\fR
+The official (canonical) name of the host.
+.TP
+\fBh_aliases\fR
+A NULL-terminated array of alternate names (nicknames) for the host.
+.TP
+\fBh_addrtype\fR
+The type of address being returned - usually
+\fBPF_INET\fR
+or
+\fBPF_INET6\fR.
+.TP
+\fBh_length\fR
+The length of the address in bytes.
+.TP
+\fBh_addr_list\fR
+A
+\fBNULL\fR
+terminated array of network addresses for the host.
+Host addresses are returned in network byte order.
+.PP
+\fBlwres_getipnodebyname()\fR
+looks up addresses of protocol family
+\fIaf\fR
+for the hostname
+\fIname\fR.
+The
+\fIflags\fR
+parameter contains ORed flag bits to
+specify the types of addresses that are searched
+for, and the types of addresses that are returned.
+The flag bits are:
+.TP
+\fBAI_V4MAPPED\fR
+This is used with an
+\fIaf\fR
+of AF_INET6, and causes IPv4 addresses to be returned as IPv4-mapped
+IPv6 addresses.
+.TP
+\fBAI_ALL\fR
+This is used with an
+\fIaf\fR
+of AF_INET6, and causes all known addresses (IPv6 and IPv4) to be returned.
+If AI_V4MAPPED is also set, the IPv4 addresses are return as mapped
+IPv6 addresses.
+.TP
+\fBAI_ADDRCONFIG\fR
+Only return an IPv6 or IPv4 address if here is an active network
+interface of that type. This is not currently implemented
+in the BIND 9 lightweight resolver, and the flag is ignored.
+.TP
+\fBAI_DEFAULT\fR
+This default sets the
+AI_V4MAPPED
+and
+AI_ADDRCONFIG
+flag bits.
+.PP
+\fBlwres_getipnodebyaddr()\fR
+performs a reverse lookup
+of address
+\fIsrc\fR
+which is
+\fIlen\fR
+bytes long.
+\fIaf\fR
+denotes the protocol family, typically
+\fBPF_INET\fR
+or
+\fBPF_INET6\fR.
+.PP
+\fBlwres_freehostent()\fR
+releases all the memory associated with
+the
+\fBstruct hostent\fR
+pointer
+\fIhe\fR.
+Any memory allocated for the
+h_name,
+h_addr_list
+and
+h_aliases
+is freed, as is the memory for the
+\fBhostent\fR
+structure itself.
+.SH "RETURN VALUES"
+.PP
+If an error occurs,
+\fBlwres_getipnodebyname()\fR
+and
+\fBlwres_getipnodebyaddr()\fR
+set
+\fI*error_num\fR
+to an approriate error code and the function returns a
+\fBNULL\fR
+pointer.
+The error codes and their meanings are defined in
+\fI<lwres/netdb.h>\fR:
+.TP
+\fBHOST_NOT_FOUND\fR
+No such host is known.
+.TP
+\fBNO_ADDRESS\fR
+The server recognised the request and the name but no address is
+available. Another type of request to the name server for the
+domain might return an answer.
+.TP
+\fBTRY_AGAIN\fR
+A temporary and possibly transient error occurred, such as a
+failure of a server to respond. The request may succeed if
+retried.
+.TP
+\fBNO_RECOVERY\fR
+An unexpected failure occurred, and retrying the request
+is pointless.
+.PP
+\fBlwres_hstrerror\fR(3)
+translates these error codes to suitable error messages.
+.SH "SEE ALSO"
+.PP
+\fBRFC2553\fR,
+\fBlwres\fR(3),
+\fBlwres_gethostent\fR(3),
+\fBlwres_getaddrinfo\fR(3),
+\fBlwres_getnameinfo\fR(3),
+\fBlwres_hstrerror\fR(3).
diff --git a/lib/liblwres/man/lwres_getipnode.docbook b/lib/liblwres/man/lwres_getipnode.docbook
new file mode 100644
index 000000000..3d4fa7f15
--- /dev/null
+++ b/lib/liblwres/man/lwres_getipnode.docbook
@@ -0,0 +1,307 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+
+<!-- $Id: lwres_getipnode.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+
+<refentryinfo>
+<date>Jun 30, 2000</date>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>lwres_getipnode</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>lwres_getipnodebyname</refname>
+<refname>lwres_getipnodebyaddr</refname>
+<refname>lwres_freehostent</refname>
+<refpurpose>lightweight resolver nodename / address translation API</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/netdb.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+struct hostent *
+<function>lwres_getipnodebyname</function></funcdef>
+<paramdef>const char *name</paramdef>
+<paramdef>int af</paramdef>
+<paramdef>int flags</paramdef>
+<paramdef>int *error_num</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+struct hostent *
+<function>lwres_getipnodebyaddr</function></funcdef>
+<paramdef>const void *src</paramdef>
+<paramdef>size_t len</paramdef>
+<paramdef>int af</paramdef>
+<paramdef>int *error_num</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_freehostent</function></funcdef>
+<paramdef>struct hostent *he</paramdef>
+</funcprototype>
+</funcsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+<title>DESCRIPTION</title>
+
+<para>
+These functions perform thread safe, protocol independent
+nodename-to-address and address-to-nodename
+translation as defined in RFC2553.
+</para>
+
+<para>
+They use a
+<type>struct hostent</type>
+which is defined in
+<filename>namedb.h</filename>:
+<programlisting>
+struct hostent {
+ char *h_name; /* official name of host */
+ char **h_aliases; /* alias list */
+ int h_addrtype; /* host address type */
+ int h_length; /* length of address */
+ char **h_addr_list; /* list of addresses from name server */
+};
+#define h_addr h_addr_list[0] /* address, for backward compatibility */
+</programlisting>
+</para>
+
+<para>
+The members of this structure are:
+<variablelist>
+<varlistentry><term><constant>h_name</constant></term>
+<listitem>
+<para>
+The official (canonical) name of the host.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>h_aliases</constant></term>
+<listitem>
+<para>
+A NULL-terminated array of alternate names (nicknames) for the host.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>h_addrtype</constant></term>
+<listitem>
+<para>
+The type of address being returned - usually
+<type>PF_INET</type>
+or
+<type>PF_INET6</type>.
+
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>h_length</constant></term>
+<listitem>
+<para>
+The length of the address in bytes.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>h_addr_list</constant></term>
+<listitem>
+<para>
+A
+<type>NULL</type>
+terminated array of network addresses for the host.
+Host addresses are returned in network byte order.
+</para>
+</listitem></varlistentry>
+</variablelist>
+</para>
+<para>
+<function>lwres_getipnodebyname()</function>
+looks up addresses of protocol family
+<parameter>af</parameter>
+
+for the hostname
+<parameter>name</parameter>.
+
+The
+<parameter>flags</parameter>
+parameter contains ORed flag bits to
+specify the types of addresses that are searched
+for, and the types of addresses that are returned.
+The flag bits are:
+<variablelist>
+<varlistentry><term><constant>AI_V4MAPPED</constant></term>
+<listitem>
+<para>
+This is used with an
+<parameter>af</parameter>
+of AF_INET6, and causes IPv4 addresses to be returned as IPv4-mapped
+IPv6 addresses.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>AI_ALL</constant></term>
+<listitem>
+<para>
+This is used with an
+<parameter>af</parameter>
+of AF_INET6, and causes all known addresses (IPv6 and IPv4) to be returned.
+If AI_V4MAPPED is also set, the IPv4 addresses are return as mapped
+IPv6 addresses.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>AI_ADDRCONFIG</constant></term>
+<listitem>
+<para>
+Only return an IPv6 or IPv4 address if here is an active network
+interface of that type. This is not currently implemented
+in the BIND 9 lightweight resolver, and the flag is ignored.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>AI_DEFAULT</constant></term>
+<listitem>
+<para>
+This default sets the
+<constant>AI_V4MAPPED</constant>
+and
+<constant>AI_ADDRCONFIG</constant>
+flag bits.
+</para>
+</listitem></varlistentry>
+</variablelist>
+</para>
+<para>
+<function>lwres_getipnodebyaddr()</function>
+performs a reverse lookup
+of address
+<parameter>src</parameter>
+which is
+<parameter>len</parameter>
+bytes long.
+<parameter>af</parameter>
+denotes the protocol family, typically
+<type>PF_INET</type>
+or
+<type>PF_INET6</type>.
+
+</para>
+<para>
+<function>lwres_freehostent()</function>
+releases all the memory associated with
+the
+<type>struct hostent</type>
+pointer
+<parameter>he</parameter>.
+
+Any memory allocated for the
+<constant>h_name</constant>,
+
+<constant>h_addr_list</constant>
+and
+<constant>h_aliases</constant>
+is freed, as is the memory for the
+<type>hostent</type>
+structure itself.
+</para>
+</refsect1>
+<refsect1>
+<title>RETURN VALUES</title>
+<para>
+If an error occurs,
+<function>lwres_getipnodebyname()</function>
+and
+<function>lwres_getipnodebyaddr()</function>
+set
+<parameter>*error_num</parameter>
+to an approriate error code and the function returns a
+<type>NULL</type>
+pointer.
+The error codes and their meanings are defined in
+<filename>&lt;lwres/netdb.h&gt;</filename>:
+<variablelist>
+<varlistentry><term><constant>HOST_NOT_FOUND</constant></term>
+<listitem>
+<para>
+No such host is known.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>NO_ADDRESS</constant></term>
+<listitem>
+<para>
+The server recognised the request and the name but no address is
+available. Another type of request to the name server for the
+domain might return an answer.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>TRY_AGAIN</constant></term>
+<listitem>
+<para>
+A temporary and possibly transient error occurred, such as a
+failure of a server to respond. The request may succeed if
+retried.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>NO_RECOVERY</constant></term>
+<listitem>
+<para>
+An unexpected failure occurred, and retrying the request
+is pointless.
+</para>
+</listitem></varlistentry>
+</variablelist>
+</para>
+<para>
+<citerefentry>
+<refentrytitle>lwres_hstrerror</refentrytitle><manvolnum>3
+</manvolnum>
+</citerefentry>
+translates these error codes to suitable error messages.
+</para>
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>RFC2553</refentrytitle>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_gethostent</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_getaddrinfo</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_getnameinfo</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_hstrerror</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>.
+</para>
+</refsect1>
+</refentry>
diff --git a/lib/liblwres/man/lwres_getipnode.html b/lib/liblwres/man/lwres_getipnode.html
new file mode 100644
index 000000000..d0a71e69d
--- /dev/null
+++ b/lib/liblwres/man/lwres_getipnode.html
@@ -0,0 +1,529 @@
+<!--
+ - Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_getipnode</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_getipnode</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_getipnodebyname, lwres_getipnodebyaddr, lwres_freehostent&nbsp;--&nbsp;lightweight resolver nodename / address translation API</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN13"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN14"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/netdb.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>struct hostent *
+lwres_getipnodebyname</CODE
+>(const char *name, int af, int flags, int *error_num);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>struct hostent *
+lwres_getipnodebyaddr</CODE
+>(const void *src, size_t len, int af, int *error_num);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_freehostent</CODE
+>(struct hostent *he);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN34"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>These functions perform thread safe, protocol independent
+nodename-to-address and address-to-nodename
+translation as defined in RFC2553.</P
+><P
+>They use a
+<SPAN
+CLASS="TYPE"
+>struct hostent</SPAN
+>
+which is defined in
+<TT
+CLASS="FILENAME"
+>namedb.h</TT
+>:
+<PRE
+CLASS="PROGRAMLISTING"
+>struct hostent {
+ char *h_name; /* official name of host */
+ char **h_aliases; /* alias list */
+ int h_addrtype; /* host address type */
+ int h_length; /* length of address */
+ char **h_addr_list; /* list of addresses from name server */
+};
+#define h_addr h_addr_list[0] /* address, for backward compatibility */</PRE
+></P
+><P
+>The members of this structure are:
+<P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="CONSTANT"
+>h_name</TT
+></DT
+><DD
+><P
+>The official (canonical) name of the host.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>h_aliases</TT
+></DT
+><DD
+><P
+>A NULL-terminated array of alternate names (nicknames) for the host.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>h_addrtype</TT
+></DT
+><DD
+><P
+>The type of address being returned - usually
+<SPAN
+CLASS="TYPE"
+>PF_INET</SPAN
+>
+or
+<SPAN
+CLASS="TYPE"
+>PF_INET6</SPAN
+>.&#13;</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>h_length</TT
+></DT
+><DD
+><P
+>The length of the address in bytes.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>h_addr_list</TT
+></DT
+><DD
+><P
+>A
+<SPAN
+CLASS="TYPE"
+>NULL</SPAN
+>
+terminated array of network addresses for the host.
+Host addresses are returned in network byte order.</P
+></DD
+></DL
+></DIV
+></P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_getipnodebyname()</TT
+>
+looks up addresses of protocol family
+<TT
+CLASS="PARAMETER"
+><I
+>af</I
+></TT
+>
+
+for the hostname
+<TT
+CLASS="PARAMETER"
+><I
+>name</I
+></TT
+>.
+
+The
+<TT
+CLASS="PARAMETER"
+><I
+>flags</I
+></TT
+>
+parameter contains ORed flag bits to
+specify the types of addresses that are searched
+for, and the types of addresses that are returned.
+The flag bits are:
+<P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="CONSTANT"
+>AI_V4MAPPED</TT
+></DT
+><DD
+><P
+>This is used with an
+<TT
+CLASS="PARAMETER"
+><I
+>af</I
+></TT
+>
+of AF_INET6, and causes IPv4 addresses to be returned as IPv4-mapped
+IPv6 addresses.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>AI_ALL</TT
+></DT
+><DD
+><P
+>This is used with an
+<TT
+CLASS="PARAMETER"
+><I
+>af</I
+></TT
+>
+of AF_INET6, and causes all known addresses (IPv6 and IPv4) to be returned.
+If AI_V4MAPPED is also set, the IPv4 addresses are return as mapped
+IPv6 addresses.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>AI_ADDRCONFIG</TT
+></DT
+><DD
+><P
+>Only return an IPv6 or IPv4 address if here is an active network
+interface of that type. This is not currently implemented
+in the BIND 9 lightweight resolver, and the flag is ignored.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>AI_DEFAULT</TT
+></DT
+><DD
+><P
+>This default sets the
+<TT
+CLASS="CONSTANT"
+>AI_V4MAPPED</TT
+>
+and
+<TT
+CLASS="CONSTANT"
+>AI_ADDRCONFIG</TT
+>
+flag bits.</P
+></DD
+></DL
+></DIV
+></P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_getipnodebyaddr()</TT
+>
+performs a reverse lookup
+of address
+<TT
+CLASS="PARAMETER"
+><I
+>src</I
+></TT
+>
+which is
+<TT
+CLASS="PARAMETER"
+><I
+>len</I
+></TT
+>
+bytes long.
+<TT
+CLASS="PARAMETER"
+><I
+>af</I
+></TT
+>
+denotes the protocol family, typically
+<SPAN
+CLASS="TYPE"
+>PF_INET</SPAN
+>
+or
+<SPAN
+CLASS="TYPE"
+>PF_INET6</SPAN
+>.&#13;</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_freehostent()</TT
+>
+releases all the memory associated with
+the
+<SPAN
+CLASS="TYPE"
+>struct hostent</SPAN
+>
+pointer
+<TT
+CLASS="PARAMETER"
+><I
+>he</I
+></TT
+>.
+
+Any memory allocated for the
+<TT
+CLASS="CONSTANT"
+>h_name</TT
+>,
+
+<TT
+CLASS="CONSTANT"
+>h_addr_list</TT
+>
+and
+<TT
+CLASS="CONSTANT"
+>h_aliases</TT
+>
+is freed, as is the memory for the
+<SPAN
+CLASS="TYPE"
+>hostent</SPAN
+>
+structure itself.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN116"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+>If an error occurs,
+<TT
+CLASS="FUNCTION"
+>lwres_getipnodebyname()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_getipnodebyaddr()</TT
+>
+set
+<TT
+CLASS="PARAMETER"
+><I
+>*error_num</I
+></TT
+>
+to an approriate error code and the function returns a
+<SPAN
+CLASS="TYPE"
+>NULL</SPAN
+>
+pointer.
+The error codes and their meanings are defined in
+<TT
+CLASS="FILENAME"
+>&lt;lwres/netdb.h&gt;</TT
+>:
+<P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="CONSTANT"
+>HOST_NOT_FOUND</TT
+></DT
+><DD
+><P
+>No such host is known.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>NO_ADDRESS</TT
+></DT
+><DD
+><P
+>The server recognised the request and the name but no address is
+available. Another type of request to the name server for the
+domain might return an answer.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>TRY_AGAIN</TT
+></DT
+><DD
+><P
+>A temporary and possibly transient error occurred, such as a
+failure of a server to respond. The request may succeed if
+retried.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>NO_RECOVERY</TT
+></DT
+><DD
+><P
+>An unexpected failure occurred, and retrying the request
+is pointless.</P
+></DD
+></DL
+></DIV
+></P
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_hstrerror</SPAN
+>(3)</SPAN
+>
+translates these error codes to suitable error messages.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN149"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>RFC2553</SPAN
+></SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_gethostent</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_getaddrinfo</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_getnameinfo</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_hstrerror</SPAN
+>(3)</SPAN
+>.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/lib/liblwres/man/lwres_getnameinfo.3 b/lib/liblwres/man/lwres_getnameinfo.3
new file mode 100644
index 000000000..61f3ba426
--- /dev/null
+++ b/lib/liblwres/man/lwres_getnameinfo.3
@@ -0,0 +1,84 @@
+.\"
+.\" Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM 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.
+.\"
+.TH "LWRES_GETNAMEINFO" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_getnameinfo \- lightweight resolver socket address structure to hostname and service name
+.SH SYNOPSIS
+\fB#include <lwres/netdb.h>
+.sp
+.na
+int
+lwres_getnameinfo(const struct sockaddr *sa, size_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+This function is equivalent to the \fBgetnameinfo\fR(3) function defined in RFC2133.
+\fBlwres_getnameinfo()\fR returns the hostname for the
+\fBstruct sockaddr\fR \fIsa\fR which is
+\fIsalen\fR bytes long. The hostname is of length
+\fIhostlen\fR and is returned via
+\fI*host.\fR The maximum length of the hostname is
+1025 bytes: NI_MAXHOST.
+.PP
+The name of the service associated with the port number in
+\fIsa\fR is returned in \fI*serv.\fR
+It is \fIservlen\fR bytes long. The maximum length
+of the service name is NI_MAXSERV - 32 bytes.
+.PP
+The \fIflags\fR argument sets the following
+bits:
+.TP
+\fBNI_NOFQDN\fR
+A fully qualified domain name is not required for local hosts.
+The local part of the fully qualified domain name is returned instead.
+.TP
+\fBNI_NUMERICHOST\fR
+Return the address in numeric form, as if calling inet_ntop(),
+instead of a host name.
+.TP
+\fBNI_NAMEREQD\fR
+A name is required. If the hostname cannot be found in the DNS and
+this flag is set, a non-zero error code is returned.
+If the hostname is not found and the flag is not set, the
+address is returned in numeric form.
+.TP
+\fBNI_NUMERICSERV\fR
+The service name is returned as a digit string representing the port number.
+.TP
+\fBNI_DGRAM\fR
+Specifies that the service being looked up is a datagram
+service, and causes getservbyport() to be called with a second
+argument of "udp" instead of its default of "tcp". This is required
+for the few ports (512-514) that have different services for UDP and
+TCP.
+.SH "RETURN VALUES"
+.PP
+\fBlwres_getnameinfo()\fR
+returns 0 on success or a non-zero error code if an error occurs.
+.SH "SEE ALSO"
+.PP
+\fBRFC2133\fR,
+\fBgetservbyport\fR(3),
+\fBlwres\fR(3),
+\fBlwres_getnameinfo\fR(3),
+\fBlwres_getnamebyaddr\fR(3).
+\fBlwres_net_ntop\fR(3).
+.SH "BUGS"
+.PP
+RFC2133 fails to define what the nonzero return values of
+\fBgetnameinfo\fR(3)
+are.
diff --git a/lib/liblwres/man/lwres_getnameinfo.docbook b/lib/liblwres/man/lwres_getnameinfo.docbook
new file mode 100644
index 000000000..56bcd8b9f
--- /dev/null
+++ b/lib/liblwres/man/lwres_getnameinfo.docbook
@@ -0,0 +1,154 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+
+<!-- $Id: lwres_getnameinfo.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+
+<refentryinfo>
+<date>Jun 30, 2000</date>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>lwres_getnameinfo</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>lwres_getnameinfo</refname>
+<refpurpose>lightweight resolver socket address structure to hostname and service name</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/netdb.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+int
+<function>lwres_getnameinfo</function></funcdef>
+<paramdef>const struct sockaddr *sa</paramdef>
+<paramdef>size_t salen</paramdef>
+<paramdef>char *host</paramdef>
+<paramdef>size_t hostlen</paramdef>
+<paramdef>char *serv</paramdef>
+<paramdef>size_t servlen</paramdef>
+<paramdef>int flags</paramdef>
+</funcprototype>
+</funcsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+<title>DESCRIPTION</title>
+
+<para> This function is equivalent to the <citerefentry>
+<refentrytitle>getnameinfo</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry> function defined in RFC2133.
+<function>lwres_getnameinfo()</function> returns the hostname for the
+<type>struct sockaddr</type> <parameter>sa</parameter> which is
+<parameter>salen</parameter> bytes long. The hostname is of length
+<parameter>hostlen</parameter> and is returned via
+<parameter>*host.</parameter> The maximum length of the hostname is
+1025 bytes: <constant>NI_MAXHOST</constant>.</para>
+
+<para> The name of the service associated with the port number in
+<parameter>sa</parameter> is returned in <parameter>*serv.</parameter>
+It is <parameter>servlen</parameter> bytes long. The maximum length
+of the service name is <constant>NI_MAXSERV</constant> - 32 bytes.
+</para>
+
+<para> The <parameter>flags</parameter> argument sets the following
+bits:
+<variablelist>
+<varlistentry><term><constant>NI_NOFQDN</constant></term>
+<listitem>
+<para>
+A fully qualified domain name is not required for local hosts.
+The local part of the fully qualified domain name is returned instead.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>NI_NUMERICHOST</constant></term>
+<listitem>
+<para>
+Return the address in numeric form, as if calling inet_ntop(),
+instead of a host name.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>NI_NAMEREQD</constant></term>
+<listitem>
+<para>
+A name is required. If the hostname cannot be found in the DNS and
+this flag is set, a non-zero error code is returned.
+If the hostname is not found and the flag is not set, the
+address is returned in numeric form.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>NI_NUMERICSERV</constant></term>
+<listitem>
+<para>
+The service name is returned as a digit string representing the port number.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>NI_DGRAM</constant></term>
+<listitem>
+<para>
+Specifies that the service being looked up is a datagram
+service, and causes getservbyport() to be called with a second
+argument of "udp" instead of its default of "tcp". This is required
+for the few ports (512-514) that have different services for UDP and
+TCP.
+</para></listitem></varlistentry>
+</variablelist>
+</para>
+</refsect1>
+
+<refsect1>
+<title>RETURN VALUES</title>
+<para>
+<function>lwres_getnameinfo()</function>
+returns 0 on success or a non-zero error code if an error occurs.
+</para>
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>RFC2133</refentrytitle>
+</citerefentry>,
+<citerefentry>
+<refentrytitle>getservbyport</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+<citerefentry>
+<refentrytitle>lwres</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+<citerefentry>
+<refentrytitle>lwres_getnameinfo</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+<citerefentry>
+<refentrytitle>lwres_getnamebyaddr</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>.
+<citerefentry>
+<refentrytitle>lwres_net_ntop</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>.
+</refsect1>
+<refsect1>
+<title>BUGS</title>
+<para>
+RFC2133 fails to define what the nonzero return values of
+<citerefentry>
+<refentrytitle>getnameinfo</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>
+are.
+</para>
+</refsect1>
+</refentry>
diff --git a/lib/liblwres/man/lwres_getnameinfo.html b/lib/liblwres/man/lwres_getnameinfo.html
new file mode 100644
index 000000000..b98a92848
--- /dev/null
+++ b/lib/liblwres/man/lwres_getnameinfo.html
@@ -0,0 +1,303 @@
+<!--
+ - Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_getnameinfo</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_getnameinfo</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_getnameinfo&nbsp;--&nbsp;lightweight resolver socket address structure to hostname and service name</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN11"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN12"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/netdb.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>int
+lwres_getnameinfo</CODE
+>(const struct sockaddr *sa, size_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN24"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+> This function is equivalent to the <SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>getnameinfo</SPAN
+>(3)</SPAN
+> function defined in RFC2133.
+<TT
+CLASS="FUNCTION"
+>lwres_getnameinfo()</TT
+> returns the hostname for the
+<SPAN
+CLASS="TYPE"
+>struct sockaddr</SPAN
+> <TT
+CLASS="PARAMETER"
+><I
+>sa</I
+></TT
+> which is
+<TT
+CLASS="PARAMETER"
+><I
+>salen</I
+></TT
+> bytes long. The hostname is of length
+<TT
+CLASS="PARAMETER"
+><I
+>hostlen</I
+></TT
+> and is returned via
+<TT
+CLASS="PARAMETER"
+><I
+>*host.</I
+></TT
+> The maximum length of the hostname is
+1025 bytes: <TT
+CLASS="CONSTANT"
+>NI_MAXHOST</TT
+>.</P
+><P
+> The name of the service associated with the port number in
+<TT
+CLASS="PARAMETER"
+><I
+>sa</I
+></TT
+> is returned in <TT
+CLASS="PARAMETER"
+><I
+>*serv.</I
+></TT
+>
+It is <TT
+CLASS="PARAMETER"
+><I
+>servlen</I
+></TT
+> bytes long. The maximum length
+of the service name is <TT
+CLASS="CONSTANT"
+>NI_MAXSERV</TT
+> - 32 bytes.</P
+><P
+> The <TT
+CLASS="PARAMETER"
+><I
+>flags</I
+></TT
+> argument sets the following
+bits:
+<P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="CONSTANT"
+>NI_NOFQDN</TT
+></DT
+><DD
+><P
+>A fully qualified domain name is not required for local hosts.
+The local part of the fully qualified domain name is returned instead.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>NI_NUMERICHOST</TT
+></DT
+><DD
+><P
+>Return the address in numeric form, as if calling inet_ntop(),
+instead of a host name.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>NI_NAMEREQD</TT
+></DT
+><DD
+><P
+>A name is required. If the hostname cannot be found in the DNS and
+this flag is set, a non-zero error code is returned.
+If the hostname is not found and the flag is not set, the
+address is returned in numeric form.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>NI_NUMERICSERV</TT
+></DT
+><DD
+><P
+>The service name is returned as a digit string representing the port number.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>NI_DGRAM</TT
+></DT
+><DD
+><P
+>Specifies that the service being looked up is a datagram
+service, and causes getservbyport() to be called with a second
+argument of "udp" instead of its default of "tcp". This is required
+for the few ports (512-514) that have different services for UDP and
+TCP.</P
+></DD
+></DL
+></DIV
+></P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN70"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_getnameinfo()</TT
+>
+returns 0 on success or a non-zero error code if an error occurs.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN74"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>RFC2133</SPAN
+></SPAN
+>,
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>getservbyport</SPAN
+>(3)</SPAN
+>,
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres</SPAN
+>(3)</SPAN
+>,
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_getnameinfo</SPAN
+>(3)</SPAN
+>,
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_getnamebyaddr</SPAN
+>(3)</SPAN
+>.
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_net_ntop</SPAN
+>(3)</SPAN
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN94"
+></A
+><H2
+>BUGS</H2
+><P
+>RFC2133 fails to define what the nonzero return values of
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>getnameinfo</SPAN
+>(3)</SPAN
+>
+are.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/lib/liblwres/man/lwres_getrrsetbyname.3 b/lib/liblwres/man/lwres_getrrsetbyname.3
new file mode 100644
index 000000000..301630e23
--- /dev/null
+++ b/lib/liblwres/man/lwres_getrrsetbyname.3
@@ -0,0 +1,142 @@
+.\"
+.\" Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM 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.
+.\"
+.TH "LWRES_GETRRSETBYNAME" "3" "Oct 18, 2000" "BIND9" ""
+.SH NAME
+lwres_getrrsetbyname, lwres_freerrset \- retrieve DNS records
+.SH SYNOPSIS
+\fB#include <lwres/netdb.h>
+.sp
+.na
+int
+lwres_getrrsetbyname(const char *hostname, unsigned int rdclass, unsigned int rdtype, unsigned int flags, struct rrsetinfo **res);
+.ad
+.sp
+.na
+void
+lwres_freerrset(struct rrsetinfo *rrset);
+.ad
+\fR.PP
+The following structures are used:
+.sp
+.nf
+struct rdatainfo {
+ unsigned int rdi_length; /* length of data */
+ unsigned char *rdi_data; /* record data */
+};
+
+struct rrsetinfo {
+ unsigned int rri_flags; /* RRSET_VALIDATED... */
+ unsigned int rri_rdclass; /* class number */
+ unsigned int rri_rdtype; /* RR type number */
+ unsigned int rri_ttl; /* time to live */
+ unsigned int rri_nrdatas; /* size of rdatas array */
+ unsigned int rri_nsigs; /* size of sigs array */
+ char *rri_name; /* canonical name */
+ struct rdatainfo *rri_rdatas; /* individual records */
+ struct rdatainfo *rri_sigs; /* individual signatures */
+};
+.sp
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBlwres_getrrsetbyname()\fR
+gets a set of resource records associated with a
+\fIhostname\fR,
+\fIclass\fR,
+and
+\fItype\fR.
+\fIhostname\fR
+is
+a pointer a to null-terminated string. The
+\fIflags\fR
+field is currently unused and must be zero.
+.PP
+After a successful call to
+\fBlwres_getrrsetbyname()\fR,
+\fI*res\fR
+is a pointer to an
+\fBrrsetinfo\fR
+structure, containing a list of one or more
+\fBrdatainfo\fR
+structures containing resource records and potentially another list of
+\fBrdatainfo\fR
+structures containing SIG resource records
+associated with those records.
+The members
+rri_rdclass
+and
+rri_rdtype
+are copied from the parameters.
+rri_ttl
+and
+rri_name
+are properties of the obtained rrset.
+The resource records contained in
+rri_rdatas
+and
+rri_sigs
+are in uncompressed DNS wire format.
+Properties of the rdataset are represented in the
+rri_flags
+bitfield. If the RRSET_VALIDATED bit is set, the data has been DNSSEC
+validated and the signatures verified.
+.PP
+All of the information returned by
+\fBlwres_getrrsetbyname()\fR
+is dynamically allocated: the
+rrsetinfo
+and
+rdatainfo
+structures,
+and the canonical host name strings pointed to by the
+rrsetinfostructure.
+Memory allocated for the dynamically allocated structures created by
+a successful call to
+\fBlwres_getrrsetbyname()\fR
+is released by
+\fBlwres_freerrset()\fR.
+\fIrrset\fR
+is a pointer to a
+\fBstruct rrset\fR
+created by a call to
+\fBlwres_getrrsetbyname()\fR.
+.PP
+.SH "RETURN VALUES"
+.PP
+\fBlwres_getrrsetbyname()\fR
+returns zero on success, and one of the following error
+codes if an error occurred:
+.TP
+\fBERRSET_NONAME\fR
+the name does not exist
+.TP
+\fBERRSET_NODATA\fR
+the name exists, but does not have data of the desired type
+.TP
+\fBERRSET_NOMEMORY\fR
+memory could not be allocated
+.TP
+\fBERRSET_INVAL\fR
+a parameter is invalid
+.TP
+\fBERRSET_FAIL\fR
+other failure
+.TP
+\fB\fR
+.SH "SEE ALSO"
+.PP
+\fBlwres\fR(3).
diff --git a/lib/liblwres/man/lwres_getrrsetbyname.docbook b/lib/liblwres/man/lwres_getrrsetbyname.docbook
new file mode 100644
index 000000000..9151c9c57
--- /dev/null
+++ b/lib/liblwres/man/lwres_getrrsetbyname.docbook
@@ -0,0 +1,208 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+
+<!-- $Id: lwres_getrrsetbyname.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+<refentryinfo>
+
+
+<date>Oct 18, 2000</date>
+</refentryinfo>
+<refmeta>
+<refentrytitle>lwres_getrrsetbyname</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+<refnamediv>
+<refname>lwres_getrrsetbyname</refname>
+<refname>lwres_freerrset</refname>
+<refpurpose>retrieve DNS records</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/netdb.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+int
+<function>lwres_getrrsetbyname</function></funcdef>
+<paramdef>const char *hostname</paramdef>
+<paramdef>unsigned int rdclass</paramdef>
+<paramdef>unsigned int rdtype</paramdef>
+<paramdef>unsigned int flags</paramdef>
+<paramdef>struct rrsetinfo **res</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_freerrset</function></funcdef>
+<paramdef>struct rrsetinfo *rrset</paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<para>
+The following structures are used:
+<programlisting>
+struct rdatainfo {
+ unsigned int rdi_length; /* length of data */
+ unsigned char *rdi_data; /* record data */
+};
+
+struct rrsetinfo {
+ unsigned int rri_flags; /* RRSET_VALIDATED... */
+ unsigned int rri_rdclass; /* class number */
+ unsigned int rri_rdtype; /* RR type number */
+ unsigned int rri_ttl; /* time to live */
+ unsigned int rri_nrdatas; /* size of rdatas array */
+ unsigned int rri_nsigs; /* size of sigs array */
+ char *rri_name; /* canonical name */
+ struct rdatainfo *rri_rdatas; /* individual records */
+ struct rdatainfo *rri_sigs; /* individual signatures */
+};
+</programlisting>
+</para>
+</refsynopsisdiv>
+
+<refsect1>
+<title>DESCRIPTION</title>
+<para>
+<function>lwres_getrrsetbyname()</function>
+gets a set of resource records associated with a
+<parameter>hostname</parameter>,
+
+<parameter>class</parameter>,
+
+and
+<parameter>type</parameter>.
+
+<parameter>hostname</parameter>
+is
+a pointer a to null-terminated string. The
+<parameter>flags</parameter>
+field is currently unused and must be zero.
+</para>
+<para>
+After a successful call to
+<function>lwres_getrrsetbyname()</function>,
+
+<parameter>*res</parameter>
+is a pointer to an
+<type>rrsetinfo</type>
+structure, containing a list of one or more
+<type>rdatainfo</type>
+structures containing resource records and potentially another list of
+<type>rdatainfo</type>
+structures containing SIG resource records
+associated with those records.
+The members
+<constant>rri_rdclass</constant>
+and
+<constant>rri_rdtype</constant>
+are copied from the parameters.
+<constant>rri_ttl</constant>
+and
+<constant>rri_name</constant>
+are properties of the obtained rrset.
+The resource records contained in
+<constant>rri_rdatas</constant>
+and
+<constant>rri_sigs</constant>
+are in uncompressed DNS wire format.
+Properties of the rdataset are represented in the
+<constant>rri_flags</constant>
+bitfield. If the RRSET_VALIDATED bit is set, the data has been DNSSEC
+validated and the signatures verified.
+</para>
+<para>
+All of the information returned by
+<function>lwres_getrrsetbyname()</function>
+is dynamically allocated: the
+<constant>rrsetinfo</constant>
+and
+<constant>rdatainfo</constant>
+structures,
+and the canonical host name strings pointed to by the
+<constant>rrsetinfo</constant>structure.
+
+Memory allocated for the dynamically allocated structures created by
+a successful call to
+<function>lwres_getrrsetbyname()</function>
+is released by
+<function>lwres_freerrset()</function>.
+
+<parameter>rrset</parameter>
+is a pointer to a
+<type>struct rrset</type>
+created by a call to
+<function>lwres_getrrsetbyname()</function>.
+
+</para>
+<para>
+</para>
+</refsect1>
+<refsect1>
+<title>RETURN VALUES</title>
+<para>
+<function>lwres_getrrsetbyname()</function>
+returns zero on success, and one of the following error
+codes if an error occurred:
+<variablelist>
+
+<varlistentry><term><constant>ERRSET_NONAME</constant></term>
+<listitem><para>
+the name does not exist
+</para></listitem></varlistentry>
+
+<varlistentry><term><constant>ERRSET_NODATA</constant></term>
+<listitem><para>
+the name exists, but does not have data of the desired type
+</para></listitem></varlistentry>
+
+<varlistentry><term><constant>ERRSET_NOMEMORY</constant></term>
+<listitem><para>
+memory could not be allocated
+</para></listitem></varlistentry>
+
+<varlistentry><term><constant>ERRSET_INVAL</constant></term>
+<listitem><para>
+a parameter is invalid
+</para></listitem></varlistentry>
+
+<varlistentry><term><constant>ERRSET_FAIL</constant></term>
+<listitem><para>
+other failure
+</para></listitem></varlistentry>
+
+<varlistentry><term><constant></constant></term>
+<listitem><para>
+</para></listitem></varlistentry>
+
+</variablelist>
+
+</para>
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>lwres</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>.
+</para>
+
+</refsect1>
+</refentry>
diff --git a/lib/liblwres/man/lwres_getrrsetbyname.html b/lib/liblwres/man/lwres_getrrsetbyname.html
new file mode 100644
index 000000000..3e5ab615c
--- /dev/null
+++ b/lib/liblwres/man/lwres_getrrsetbyname.html
@@ -0,0 +1,371 @@
+<!--
+ - Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_getrrsetbyname</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_getrrsetbyname</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_getrrsetbyname, lwres_freerrset&nbsp;--&nbsp;retrieve DNS records</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN12"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN13"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/netdb.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>int
+lwres_getrrsetbyname</CODE
+>(const char *hostname, unsigned int rdclass, unsigned int rdtype, unsigned int flags, struct rrsetinfo **res);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_freerrset</CODE
+>(struct rrsetinfo *rrset);</CODE
+></P
+><P
+></P
+></DIV
+><P
+>The following structures are used:
+<PRE
+CLASS="PROGRAMLISTING"
+>struct rdatainfo {
+ unsigned int rdi_length; /* length of data */
+ unsigned char *rdi_data; /* record data */
+};
+
+struct rrsetinfo {
+ unsigned int rri_flags; /* RRSET_VALIDATED... */
+ unsigned int rri_rdclass; /* class number */
+ unsigned int rri_rdtype; /* RR type number */
+ unsigned int rri_ttl; /* time to live */
+ unsigned int rri_nrdatas; /* size of rdatas array */
+ unsigned int rri_nsigs; /* size of sigs array */
+ char *rri_name; /* canonical name */
+ struct rdatainfo *rri_rdatas; /* individual records */
+ struct rdatainfo *rri_sigs; /* individual signatures */
+};</PRE
+></P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN29"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_getrrsetbyname()</TT
+>
+gets a set of resource records associated with a
+<TT
+CLASS="PARAMETER"
+><I
+>hostname</I
+></TT
+>,
+
+<TT
+CLASS="PARAMETER"
+><I
+>class</I
+></TT
+>,
+
+and
+<TT
+CLASS="PARAMETER"
+><I
+>type</I
+></TT
+>.
+
+<TT
+CLASS="PARAMETER"
+><I
+>hostname</I
+></TT
+>
+is
+a pointer a to null-terminated string. The
+<TT
+CLASS="PARAMETER"
+><I
+>flags</I
+></TT
+>
+field is currently unused and must be zero.</P
+><P
+>After a successful call to
+<TT
+CLASS="FUNCTION"
+>lwres_getrrsetbyname()</TT
+>,
+
+<TT
+CLASS="PARAMETER"
+><I
+>*res</I
+></TT
+>
+is a pointer to an
+<SPAN
+CLASS="TYPE"
+>rrsetinfo</SPAN
+>
+structure, containing a list of one or more
+<SPAN
+CLASS="TYPE"
+>rdatainfo</SPAN
+>
+structures containing resource records and potentially another list of
+<SPAN
+CLASS="TYPE"
+>rdatainfo</SPAN
+>
+structures containing SIG resource records
+associated with those records.
+The members
+<TT
+CLASS="CONSTANT"
+>rri_rdclass</TT
+>
+and
+<TT
+CLASS="CONSTANT"
+>rri_rdtype</TT
+>
+are copied from the parameters.
+<TT
+CLASS="CONSTANT"
+>rri_ttl</TT
+>
+and
+<TT
+CLASS="CONSTANT"
+>rri_name</TT
+>
+are properties of the obtained rrset.
+The resource records contained in
+<TT
+CLASS="CONSTANT"
+>rri_rdatas</TT
+>
+and
+<TT
+CLASS="CONSTANT"
+>rri_sigs</TT
+>
+are in uncompressed DNS wire format.
+Properties of the rdataset are represented in the
+<TT
+CLASS="CONSTANT"
+>rri_flags</TT
+>
+bitfield. If the RRSET_VALIDATED bit is set, the data has been DNSSEC
+validated and the signatures verified. </P
+><P
+>All of the information returned by
+<TT
+CLASS="FUNCTION"
+>lwres_getrrsetbyname()</TT
+>
+is dynamically allocated: the
+<TT
+CLASS="CONSTANT"
+>rrsetinfo</TT
+>
+and
+<TT
+CLASS="CONSTANT"
+>rdatainfo</TT
+>
+structures,
+and the canonical host name strings pointed to by the
+<TT
+CLASS="CONSTANT"
+>rrsetinfo</TT
+>structure.
+
+Memory allocated for the dynamically allocated structures created by
+a successful call to
+<TT
+CLASS="FUNCTION"
+>lwres_getrrsetbyname()</TT
+>
+is released by
+<TT
+CLASS="FUNCTION"
+>lwres_freerrset()</TT
+>.
+
+<TT
+CLASS="PARAMETER"
+><I
+>rrset</I
+></TT
+>
+is a pointer to a
+<SPAN
+CLASS="TYPE"
+>struct rrset</SPAN
+>
+created by a call to
+<TT
+CLASS="FUNCTION"
+>lwres_getrrsetbyname()</TT
+>.&#13;</P
+><P
+></P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN62"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_getrrsetbyname()</TT
+>
+returns zero on success, and one of the following error
+codes if an error occurred:
+<P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="CONSTANT"
+>ERRSET_NONAME</TT
+></DT
+><DD
+><P
+>the name does not exist</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>ERRSET_NODATA</TT
+></DT
+><DD
+><P
+>the name exists, but does not have data of the desired type</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>ERRSET_NOMEMORY</TT
+></DT
+><DD
+><P
+>memory could not be allocated</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>ERRSET_INVAL</TT
+></DT
+><DD
+><P
+>a parameter is invalid</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>ERRSET_FAIL</TT
+></DT
+><DD
+><P
+>other failure</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+></TT
+></DT
+><DD
+><P
+></P
+></DD
+></DL
+></DIV
+>&#13;</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN97"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres</SPAN
+>(3)</SPAN
+>.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/lib/liblwres/man/lwres_gnba.3 b/lib/liblwres/man/lwres_gnba.3
new file mode 100644
index 000000000..515224f77
--- /dev/null
+++ b/lib/liblwres/man/lwres_gnba.3
@@ -0,0 +1,186 @@
+.\"
+.\" Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM 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.
+.\"
+.TH "LWRES_GNBA" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_gnbarequest_render, lwres_gnbaresponse_render, lwres_gnbarequest_parse, lwres_gnbaresponse_parse, lwres_gnbaresponse_free, lwres_gnbarequest_free \- lightweight resolver getnamebyaddress message handling
+.SH SYNOPSIS
+\fB#include <lwres/lwres.h>
+.sp
+.na
+lwres_result_t
+lwres_gnbarequest_render(lwres_context_t *\fIctx\fB, lwres_gnbarequest_t *\fIreq\fB, lwres_lwpacket_t *\fIpkt\fB, lwres_buffer_t *\fIb\fB);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_gnbaresponse_render(lwres_context_t *ctx, lwres_gnbaresponse_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_gnbarequest_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_gnbarequest_t **structp);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_gnbaresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_gnbaresponse_t **structp);
+.ad
+.sp
+.na
+void
+lwres_gnbaresponse_free(lwres_context_t *ctx, lwres_gnbaresponse_t **structp);
+.ad
+.sp
+.na
+void
+lwres_gnbarequest_free(lwres_context_t *ctx, lwres_gnbarequest_t **structp);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+These are low-level routines for creating and parsing
+lightweight resolver address-to-name lookup request and
+response messages.
+.PP
+There are four main functions for the getnamebyaddr opcode.
+One render function converts a getnamebyaddr request structure \(em
+\fBlwres_gnbarequest_t\fR \(em
+to the lightweight resolver's canonical format.
+It is complemented by a parse function that converts a packet in this
+canonical format to a getnamebyaddr request structure.
+Another render function converts the getnamebyaddr response structure \(em
+\fBlwres_gnbaresponse_t\fR
+to the canonical format.
+This is complemented by a parse function which converts a packet in
+canonical format to a getnamebyaddr response structure.
+.PP
+These structures are defined in
+\fIlwres/lwres.h\fR.
+They are shown below.
+.sp
+.nf
+#define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U
+
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_addr_t addr;
+} lwres_gnbarequest_t;
+
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ char *realname;
+ char **aliases;
+ lwres_uint16_t realnamelen;
+ lwres_uint16_t *aliaslen;
+ void *base;
+ size_t baselen;
+} lwres_gnbaresponse_t;
+.sp
+.fi
+.PP
+\fBlwres_gnbarequest_render()\fR
+uses resolver context
+ctx
+to convert getnamebyaddr request structure
+req
+to canonical format.
+The packet header structure
+pkt
+is initialised and transferred to
+buffer
+b.
+The contents of
+*req
+are then appended to the buffer in canonical format.
+\fBlwres_gnbaresponse_render()\fR
+performs the same task, except it converts a getnamebyaddr response structure
+\fBlwres_gnbaresponse_t\fR
+to the lightweight resolver's canonical format.
+.PP
+\fBlwres_gnbarequest_parse()\fR
+uses context
+ctx
+to convert the contents of packet
+pkt
+to a
+\fBlwres_gnbarequest_t\fR
+structure.
+Buffer
+b
+provides space to be used for storing this structure.
+When the function succeeds, the resulting
+\fBlwres_gnbarequest_t\fR
+is made available through
+*structp.
+\fBlwres_gnbaresponse_parse()\fR
+offers the same semantics as
+\fBlwres_gnbarequest_parse()\fR
+except it yields a
+\fBlwres_gnbaresponse_t\fR
+structure.
+.PP
+\fBlwres_gnbaresponse_free()\fR
+and
+\fBlwres_gnbarequest_free()\fR
+release the memory in resolver context
+ctx
+that was allocated to the
+\fBlwres_gnbaresponse_t\fR
+or
+\fBlwres_gnbarequest_t\fR
+structures referenced via
+structp.
+Any memory associated with ancillary buffers and strings for those
+structures is also discarded.
+.SH "RETURN VALUES"
+.PP
+The getnamebyaddr opcode functions
+\fBlwres_gnbarequest_render()\fR,
+\fBlwres_gnbaresponse_render()\fR
+\fBlwres_gnbarequest_parse()\fR
+and
+\fBlwres_gnbaresponse_parse()\fR
+all return
+LWRES_R_SUCCESS
+on success.
+They return
+LWRES_R_NOMEMORY
+if memory allocation fails.
+LWRES_R_UNEXPECTEDEND
+is returned if the available space in the buffer
+b
+is too small to accommodate the packet header or the
+\fBlwres_gnbarequest_t\fR
+and
+\fBlwres_gnbaresponse_t\fR
+structures.
+\fBlwres_gnbarequest_parse()\fR
+and
+\fBlwres_gnbaresponse_parse()\fR
+will return
+LWRES_R_UNEXPECTEDEND
+if the buffer is not empty after decoding the received packet.
+These functions will return
+LWRES_R_FAILURE
+if
+\fBpktflags\fR
+in the packet header structure
+\fBlwres_lwpacket_t\fR
+indicate that the packet is not a response to an earlier query.
+.SH "SEE ALSO"
+.PP
+\fBlwres_packet\fR(3).
diff --git a/lib/liblwres/man/lwres_gnba.docbook b/lib/liblwres/man/lwres_gnba.docbook
new file mode 100644
index 000000000..525452085
--- /dev/null
+++ b/lib/liblwres/man/lwres_gnba.docbook
@@ -0,0 +1,259 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+
+<!-- $Id: lwres_gnba.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+
+<refentryinfo>
+<date>Jun 30, 2000</date>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>lwres_gnba</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>lwres_gnbarequest_render</refname>
+<refname>lwres_gnbaresponse_render</refname>
+<refname>lwres_gnbarequest_parse</refname>
+<refname>lwres_gnbaresponse_parse</refname>
+<refname>lwres_gnbaresponse_free</refname>
+<refname>lwres_gnbarequest_free</refname>
+<refpurpose>lightweight resolver getnamebyaddress message handling</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+
+<funcsynopsis>
+<funcsynopsisinfo>
+#include &lt;lwres/lwres.h&gt;
+</funcsynopsisinfo>
+
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_gnbarequest_render</function>
+</funcdef>
+<paramdef>lwres_context_t *<parameter>ctx</parameter></paramdef>
+<paramdef>lwres_gnbarequest_t *<parameter>req</parameter></paramdef>
+<paramdef>lwres_lwpacket_t *<parameter>pkt</parameter></paramdef>
+<paramdef>lwres_buffer_t *<parameter>b</parameter></paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_gnbaresponse_render</function>
+</funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_gnbaresponse_t *req</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_gnbarequest_parse</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+<paramdef>lwres_gnbarequest_t **structp</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_gnbaresponse_parse</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+<paramdef>lwres_gnbaresponse_t **structp</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+void
+<function>lwres_gnbaresponse_free</function>
+</funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_gnbaresponse_t **structp</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_gnbarequest_free</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_gnbarequest_t **structp</paramdef>
+</funcprototype>
+</funcsynopsis>
+
+</refsynopsisdiv>
+
+<refsect1>
+<title>DESCRIPTION</title>
+<para>
+These are low-level routines for creating and parsing
+lightweight resolver address-to-name lookup request and
+response messages.
+</para>
+<para>
+There are four main functions for the getnamebyaddr opcode.
+One render function converts a getnamebyaddr request structure &mdash;
+<type>lwres_gnbarequest_t</type> &mdash;
+to the lightweight resolver's canonical format.
+It is complemented by a parse function that converts a packet in this
+canonical format to a getnamebyaddr request structure.
+Another render function converts the getnamebyaddr response structure &mdash;
+<type>lwres_gnbaresponse_t</type>
+to the canonical format.
+This is complemented by a parse function which converts a packet in
+canonical format to a getnamebyaddr response structure.
+</para>
+<para>
+These structures are defined in
+<filename>lwres/lwres.h</filename>.
+They are shown below.
+<programlisting>
+#define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U
+
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_addr_t addr;
+} lwres_gnbarequest_t;
+
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ char *realname;
+ char **aliases;
+ lwres_uint16_t realnamelen;
+ lwres_uint16_t *aliaslen;
+ void *base;
+ size_t baselen;
+} lwres_gnbaresponse_t;
+</programlisting>
+</para>
+<para>
+<function>lwres_gnbarequest_render()</function>
+uses resolver context
+<varname>ctx</varname>
+to convert getnamebyaddr request structure
+<varname>req</varname>
+to canonical format.
+The packet header structure
+<varname>pkt</varname>
+is initialised and transferred to
+buffer
+<varname>b</varname>.
+The contents of
+<varname>*req</varname>
+are then appended to the buffer in canonical format.
+<function>lwres_gnbaresponse_render()</function>
+performs the same task, except it converts a getnamebyaddr response structure
+<type>lwres_gnbaresponse_t</type>
+to the lightweight resolver's canonical format.
+</para>
+<para>
+<function>lwres_gnbarequest_parse()</function>
+uses context
+<varname>ctx</varname>
+to convert the contents of packet
+<varname>pkt</varname>
+to a
+<type>lwres_gnbarequest_t</type>
+structure.
+Buffer
+<varname>b</varname>
+provides space to be used for storing this structure.
+When the function succeeds, the resulting
+<type>lwres_gnbarequest_t</type>
+is made available through
+<varname>*structp</varname>.
+<function>lwres_gnbaresponse_parse()</function>
+offers the same semantics as
+<function>lwres_gnbarequest_parse()</function>
+except it yields a
+<type>lwres_gnbaresponse_t</type>
+structure.
+</para>
+<para>
+<function>lwres_gnbaresponse_free()</function>
+and
+<function>lwres_gnbarequest_free()</function>
+release the memory in resolver context
+<varname>ctx</varname>
+that was allocated to the
+<type>lwres_gnbaresponse_t</type>
+or
+<type>lwres_gnbarequest_t</type>
+structures referenced via
+<varname>structp</varname>.
+Any memory associated with ancillary buffers and strings for those
+structures is also discarded.
+</para>
+</refsect1>
+<refsect1>
+<title>RETURN VALUES</title>
+<para>
+The getnamebyaddr opcode functions
+<function>lwres_gnbarequest_render()</function>,
+<function>lwres_gnbaresponse_render()</function>
+<function>lwres_gnbarequest_parse()</function>
+and
+<function>lwres_gnbaresponse_parse()</function>
+all return
+<errorcode>LWRES_R_SUCCESS</errorcode>
+on success.
+They return
+<errorcode>LWRES_R_NOMEMORY</errorcode>
+if memory allocation fails.
+<errorcode>LWRES_R_UNEXPECTEDEND</errorcode>
+is returned if the available space in the buffer
+<varname>b</varname>
+is too small to accommodate the packet header or the
+<type>lwres_gnbarequest_t</type>
+and
+<type>lwres_gnbaresponse_t</type>
+structures.
+<function>lwres_gnbarequest_parse()</function>
+and
+<function>lwres_gnbaresponse_parse()</function>
+will return
+<errorcode>LWRES_R_UNEXPECTEDEND</errorcode>
+if the buffer is not empty after decoding the received packet.
+These functions will return
+<errorcode>LWRES_R_FAILURE</errorcode>
+if
+<structfield>pktflags</structfield>
+in the packet header structure
+<type>lwres_lwpacket_t</type>
+indicate that the packet is not a response to an earlier query.
+</para>
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>lwres_packet</refentrytitle>
+<manvolnum>3</manvolnum>
+</citerefentry>.
+</para>
+</refsect1>
+</refentry>
diff --git a/lib/liblwres/man/lwres_gnba.html b/lib/liblwres/man/lwres_gnba.html
new file mode 100644
index 000000000..98cc04dd6
--- /dev/null
+++ b/lib/liblwres/man/lwres_gnba.html
@@ -0,0 +1,408 @@
+<!--
+ - Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_gnba</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_gnba</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_gnbarequest_render, lwres_gnbaresponse_render, lwres_gnbarequest_parse, lwres_gnbaresponse_parse, lwres_gnbaresponse_free, lwres_gnbarequest_free&nbsp;--&nbsp;lightweight resolver getnamebyaddress message handling</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN16"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN17"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/lwres.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_gnbarequest_render</CODE
+>(lwres_context_t *ctx, lwres_gnbarequest_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_gnbaresponse_render</CODE
+>(lwres_context_t *ctx, lwres_gnbaresponse_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_gnbarequest_parse</CODE
+>(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_gnbarequest_t **structp);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_gnbaresponse_parse</CODE
+>(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_gnbaresponse_t **structp);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_gnbaresponse_free</CODE
+>(lwres_context_t *ctx, lwres_gnbaresponse_t **structp);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_gnbarequest_free</CODE
+>(lwres_context_t *ctx, lwres_gnbarequest_t **structp);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN61"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>These are low-level routines for creating and parsing
+lightweight resolver address-to-name lookup request and
+response messages.</P
+><P
+>There are four main functions for the getnamebyaddr opcode.
+One render function converts a getnamebyaddr request structure &mdash;
+<SPAN
+CLASS="TYPE"
+>lwres_gnbarequest_t</SPAN
+> &mdash;
+to the lightweight resolver's canonical format.
+It is complemented by a parse function that converts a packet in this
+canonical format to a getnamebyaddr request structure.
+Another render function converts the getnamebyaddr response structure &mdash;
+<SPAN
+CLASS="TYPE"
+>lwres_gnbaresponse_t</SPAN
+>
+to the canonical format.
+This is complemented by a parse function which converts a packet in
+canonical format to a getnamebyaddr response structure.</P
+><P
+>These structures are defined in
+<TT
+CLASS="FILENAME"
+>lwres/lwres.h</TT
+>.
+They are shown below.
+<PRE
+CLASS="PROGRAMLISTING"
+>#define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U
+
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_addr_t addr;
+} lwres_gnbarequest_t;
+
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ char *realname;
+ char **aliases;
+ lwres_uint16_t realnamelen;
+ lwres_uint16_t *aliaslen;
+ void *base;
+ size_t baselen;
+} lwres_gnbaresponse_t;</PRE
+></P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_gnbarequest_render()</TT
+>
+uses resolver context
+<TT
+CLASS="VARNAME"
+>ctx</TT
+>
+to convert getnamebyaddr request structure
+<TT
+CLASS="VARNAME"
+>req</TT
+>
+to canonical format.
+The packet header structure
+<TT
+CLASS="VARNAME"
+>pkt</TT
+>
+is initialised and transferred to
+buffer
+<TT
+CLASS="VARNAME"
+>b</TT
+>.
+The contents of
+<TT
+CLASS="VARNAME"
+>*req</TT
+>
+are then appended to the buffer in canonical format.
+<TT
+CLASS="FUNCTION"
+>lwres_gnbaresponse_render()</TT
+>
+performs the same task, except it converts a getnamebyaddr response structure
+<SPAN
+CLASS="TYPE"
+>lwres_gnbaresponse_t</SPAN
+>
+to the lightweight resolver's canonical format.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_gnbarequest_parse()</TT
+>
+uses context
+<TT
+CLASS="VARNAME"
+>ctx</TT
+>
+to convert the contents of packet
+<TT
+CLASS="VARNAME"
+>pkt</TT
+>
+to a
+<SPAN
+CLASS="TYPE"
+>lwres_gnbarequest_t</SPAN
+>
+structure.
+Buffer
+<TT
+CLASS="VARNAME"
+>b</TT
+>
+provides space to be used for storing this structure.
+When the function succeeds, the resulting
+<SPAN
+CLASS="TYPE"
+>lwres_gnbarequest_t</SPAN
+>
+is made available through
+<TT
+CLASS="VARNAME"
+>*structp</TT
+>.
+<TT
+CLASS="FUNCTION"
+>lwres_gnbaresponse_parse()</TT
+>
+offers the same semantics as
+<TT
+CLASS="FUNCTION"
+>lwres_gnbarequest_parse()</TT
+>
+except it yields a
+<SPAN
+CLASS="TYPE"
+>lwres_gnbaresponse_t</SPAN
+>
+structure.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_gnbaresponse_free()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_gnbarequest_free()</TT
+>
+release the memory in resolver context
+<TT
+CLASS="VARNAME"
+>ctx</TT
+>
+that was allocated to the
+<SPAN
+CLASS="TYPE"
+>lwres_gnbaresponse_t</SPAN
+>
+or
+<SPAN
+CLASS="TYPE"
+>lwres_gnbarequest_t</SPAN
+>
+structures referenced via
+<TT
+CLASS="VARNAME"
+>structp</TT
+>.
+Any memory associated with ancillary buffers and strings for those
+structures is also discarded.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN97"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+>The getnamebyaddr opcode functions
+<TT
+CLASS="FUNCTION"
+>lwres_gnbarequest_render()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>lwres_gnbaresponse_render()</TT
+>
+<TT
+CLASS="FUNCTION"
+>lwres_gnbarequest_parse()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_gnbaresponse_parse()</TT
+>
+all return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_SUCCESS</SPAN
+>
+on success.
+They return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_NOMEMORY</SPAN
+>
+if memory allocation fails.
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_UNEXPECTEDEND</SPAN
+>
+is returned if the available space in the buffer
+<TT
+CLASS="VARNAME"
+>b</TT
+>
+is too small to accommodate the packet header or the
+<SPAN
+CLASS="TYPE"
+>lwres_gnbarequest_t</SPAN
+>
+and
+<SPAN
+CLASS="TYPE"
+>lwres_gnbaresponse_t</SPAN
+>
+structures.
+<TT
+CLASS="FUNCTION"
+>lwres_gnbarequest_parse()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_gnbaresponse_parse()</TT
+>
+will return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_UNEXPECTEDEND</SPAN
+>
+if the buffer is not empty after decoding the received packet.
+These functions will return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_FAILURE</SPAN
+>
+if
+<TT
+CLASS="STRUCTFIELD"
+><I
+>pktflags</I
+></TT
+>
+in the packet header structure
+<SPAN
+CLASS="TYPE"
+>lwres_lwpacket_t</SPAN
+>
+indicate that the packet is not a response to an earlier query.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN116"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_packet</SPAN
+>(3)</SPAN
+>.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/lib/liblwres/man/lwres_hstrerror.3 b/lib/liblwres/man/lwres_hstrerror.3
new file mode 100644
index 000000000..dd7fa9c4c
--- /dev/null
+++ b/lib/liblwres/man/lwres_hstrerror.3
@@ -0,0 +1,67 @@
+.\"
+.\" Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM 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.
+.\"
+.TH "LWRES_HSTRERROR" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_herror, lwres_hstrerror \- lightweight resolver error message generation
+.SH SYNOPSIS
+\fB#include <lwres/netdb.h>
+.sp
+.na
+void
+lwres_herror(const char *s);
+.ad
+.sp
+.na
+const char *
+lwres_hstrerror(int err);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+\fBlwres_herror()\fR prints the string
+\fIs\fR on \fBstderr\fR followed by the string
+generated by \fBlwres_hstrerror()\fR for the error code
+stored in the global variable lwres_h_errno.
+.PP
+\fBlwres_hstrerror()\fR returns an appropriate string
+for the error code gievn by \fIerr\fR. The values of
+the error codes and messages are as follows:
+.TP
+\fBNETDB_SUCCESS\fR
+\fBResolver Error 0 (no error)\fR
+.TP
+\fBHOST_NOT_FOUND\fR
+\fBUnknown host\fR
+.TP
+\fBTRY_AGAIN\fR
+\fBHost name lookup failure\fR
+.TP
+\fBNO_RECOVERY\fR
+\fBUnknown server error\fR
+.TP
+\fBNO_DATA\fR
+\fBNo address associated with name\fR
+.SH "RETURN VALUES"
+.PP
+The string \fBUnknown resolver error\fR is returned by
+\fBlwres_hstrerror()\fR
+when the value of
+lwres_h_errno
+is not a valid error code.
+.SH "SEE ALSO"
+.PP
+\fBherror\fR(3),
+\fBlwres_hstrerror\fR(3).
diff --git a/lib/liblwres/man/lwres_hstrerror.docbook b/lib/liblwres/man/lwres_hstrerror.docbook
new file mode 100644
index 000000000..2f4c06a11
--- /dev/null
+++ b/lib/liblwres/man/lwres_hstrerror.docbook
@@ -0,0 +1,124 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+
+<!-- $Id: lwres_hstrerror.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+
+<refentryinfo>
+<date>Jun 30, 2000</date>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>lwres_hstrerror</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>lwres_herror</refname>
+<refname>lwres_hstrerror</refname>
+<refpurpose>lightweight resolver error message generation</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/netdb.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_herror</function></funcdef>
+<paramdef>const char *s</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+const char *
+<function>lwres_hstrerror</function></funcdef>
+<paramdef>int err</paramdef>
+</funcprototype>
+</funcsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+<title>DESCRIPTION</title>
+
+<para>
+<function>lwres_herror()</function> prints the string
+<parameter>s</parameter> on <type>stderr</type> followed by the string
+generated by <function>lwres_hstrerror()</function> for the error code
+stored in the global variable <constant>lwres_h_errno</constant>.
+</para>
+
+<para>
+<function>lwres_hstrerror()</function> returns an appropriate string
+for the error code gievn by <parameter>err</parameter>. The values of
+the error codes and messages are as follows:
+
+<variablelist>
+<varlistentry><term><errorcode>NETDB_SUCCESS</errorcode></term>
+<listitem>
+<para>
+<errorname>Resolver Error 0 (no error)</errorname>
+</para></listitem></varlistentry>
+<varlistentry><term><errorcode>HOST_NOT_FOUND</errorcode></term>
+<listitem>
+<para>
+<errorname>Unknown host</errorname>
+</para></listitem></varlistentry>
+<varlistentry><term><errorcode>TRY_AGAIN</errorcode></term>
+<listitem>
+<para>
+<errorname>Host name lookup failure</errorname>
+</para></listitem></varlistentry>
+<varlistentry><term><errorcode>NO_RECOVERY</errorcode></term>
+<listitem>
+<para>
+<errorname>Unknown server error</errorname>
+</para></listitem></varlistentry>
+<varlistentry><term><errorcode>NO_DATA</errorcode></term>
+<listitem>
+<para>
+<errorname>No address associated with name</errorname>
+</para></listitem></varlistentry>
+</variablelist>
+</para>
+</refsect1>
+
+<refsect1>
+<title>RETURN VALUES</title>
+<para>
+The string <errorname>Unknown resolver error</errorname> is returned by
+<function>lwres_hstrerror()</function>
+when the value of
+<constant>lwres_h_errno</constant>
+is not a valid error code.
+</para>
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>herror</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_hstrerror</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>.
+</para>
+
+</refsect1>
+</refentry>
diff --git a/lib/liblwres/man/lwres_hstrerror.html b/lib/liblwres/man/lwres_hstrerror.html
new file mode 100644
index 000000000..128b7e4f8
--- /dev/null
+++ b/lib/liblwres/man/lwres_hstrerror.html
@@ -0,0 +1,242 @@
+<!--
+ - Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_hstrerror</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_hstrerror</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_herror, lwres_hstrerror&nbsp;--&nbsp;lightweight resolver error message generation</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN12"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN13"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/netdb.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_herror</CODE
+>(const char *s);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>const char *
+lwres_hstrerror</CODE
+>(int err);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN23"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_herror()</TT
+> prints the string
+<TT
+CLASS="PARAMETER"
+><I
+>s</I
+></TT
+> on <SPAN
+CLASS="TYPE"
+>stderr</SPAN
+> followed by the string
+generated by <TT
+CLASS="FUNCTION"
+>lwres_hstrerror()</TT
+> for the error code
+stored in the global variable <TT
+CLASS="CONSTANT"
+>lwres_h_errno</TT
+>.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_hstrerror()</TT
+> returns an appropriate string
+for the error code gievn by <TT
+CLASS="PARAMETER"
+><I
+>err</I
+></TT
+>. The values of
+the error codes and messages are as follows:
+
+<P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>NETDB_SUCCESS</SPAN
+></DT
+><DD
+><P
+><SPAN
+CLASS="ERRORNAME"
+>Resolver Error 0 (no error)</SPAN
+></P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>HOST_NOT_FOUND</SPAN
+></DT
+><DD
+><P
+><SPAN
+CLASS="ERRORNAME"
+>Unknown host</SPAN
+></P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>TRY_AGAIN</SPAN
+></DT
+><DD
+><P
+><SPAN
+CLASS="ERRORNAME"
+>Host name lookup failure</SPAN
+></P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>NO_RECOVERY</SPAN
+></DT
+><DD
+><P
+><SPAN
+CLASS="ERRORNAME"
+>Unknown server error</SPAN
+></P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>NO_DATA</SPAN
+></DT
+><DD
+><P
+><SPAN
+CLASS="ERRORNAME"
+>No address associated with name</SPAN
+></P
+></DD
+></DL
+></DIV
+></P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN65"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+>The string <SPAN
+CLASS="ERRORNAME"
+>Unknown resolver error</SPAN
+> is returned by
+<TT
+CLASS="FUNCTION"
+>lwres_hstrerror()</TT
+>
+when the value of
+<TT
+CLASS="CONSTANT"
+>lwres_h_errno</TT
+>
+is not a valid error code.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN71"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>herror</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_hstrerror</SPAN
+>(3)</SPAN
+>.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/lib/liblwres/man/lwres_inetntop.3 b/lib/liblwres/man/lwres_inetntop.3
new file mode 100644
index 000000000..983a33d85
--- /dev/null
+++ b/lib/liblwres/man/lwres_inetntop.3
@@ -0,0 +1,52 @@
+.\"
+.\" Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM 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.
+.\"
+.TH "LWRES_INETNTOP" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_net_ntop \- lightweight resolver IP address presentation
+.SH SYNOPSIS
+\fB#include <lwres/net.h>
+.sp
+.na
+const char *
+lwres_net_ntop(int af, const void *src, char *dst, size_t size);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+\fBlwres_net_ntop()\fR converts an IP address of
+protocol family \fIaf\fR \(em IPv4 or IPv6 \(em
+at location \fIsrc\fR from network format to its
+conventional representation as a string. For IPv4 addresses, that
+string would be a dotted-decimal. An IPv6 address would be
+represented in colon notation as described in RFC1884.
+.PP
+The generated string is copied to \fIdst\fR provided
+\fIsize\fR indicates it is long enough to store the
+ASCII representation of the address.
+.SH "RETURN VALUES"
+.PP
+If successful, the function returns \fIdst\fR:
+a pointer to a string containing the presentation format of the
+address. \fBlwres_net_ntop()\fR returns
+\fBNULL\fR and sets the global variable
+errno to EAFNOSUPPORT if
+the protocol family given in \fIaf\fR is not
+supported.
+.SH "SEE ALSO"
+.PP
+\fBRFC1884\fR,
+\fBinet_ntop\fR(3),
+\fBerrno\fR(3).
diff --git a/lib/liblwres/man/lwres_inetntop.docbook b/lib/liblwres/man/lwres_inetntop.docbook
new file mode 100644
index 000000000..8daa36351
--- /dev/null
+++ b/lib/liblwres/man/lwres_inetntop.docbook
@@ -0,0 +1,99 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+
+<!-- $Id: lwres_inetntop.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+
+<refentryinfo>
+<date>Jun 30, 2000</date>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>lwres_inetntop</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>lwres_net_ntop</refname>
+<refpurpose>lightweight resolver IP address presentation</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/net.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+const char *
+<function>lwres_net_ntop</function></funcdef>
+<paramdef>int af</paramdef>
+<paramdef>const void *src</paramdef>
+<paramdef>char *dst</paramdef>
+<paramdef>size_t size</paramdef>
+</funcprototype>
+</funcsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+<title>DESCRIPTION</title>
+
+<para>
+<function>lwres_net_ntop()</function> converts an IP address of
+protocol family <parameter>af</parameter> &mdash; IPv4 or IPv6 &mdash;
+at location <parameter>src</parameter> from network format to its
+conventional representation as a string. For IPv4 addresses, that
+string would be a dotted-decimal. An IPv6 address would be
+represented in colon notation as described in RFC1884.
+</para>
+
+<para>
+The generated string is copied to <parameter>dst</parameter> provided
+<parameter>size</parameter> indicates it is long enough to store the
+ASCII representation of the address.
+</para>
+
+</refsect1>
+<refsect1>
+<title>RETURN VALUES</title>
+
+<para>
+If successful, the function returns <parameter>dst</parameter>:
+a pointer to a string containing the presentation format of the
+address. <function>lwres_net_ntop()</function> returns
+<type>NULL</type> and sets the global variable
+<constant>errno</constant> to <errorcode>EAFNOSUPPORT</errorcode> if
+the protocol family given in <parameter>af</parameter> is not
+supported.
+</para>
+
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>RFC1884</refentrytitle>
+</citerefentry>,
+<citerefentry>
+<refentrytitle>inet_ntop</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+<citerefentry>
+<refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>.
+</para>
+</refsect1>
+</refentry>
diff --git a/lib/liblwres/man/lwres_inetntop.html b/lib/liblwres/man/lwres_inetntop.html
new file mode 100644
index 000000000..09d4fea34
--- /dev/null
+++ b/lib/liblwres/man/lwres_inetntop.html
@@ -0,0 +1,186 @@
+<!--
+ - Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_inetntop</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_inetntop</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_net_ntop&nbsp;--&nbsp;lightweight resolver IP address presentation</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN11"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN12"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/net.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>const char *
+lwres_net_ntop</CODE
+>(int af, const void *src, char *dst, size_t size);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN21"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_net_ntop()</TT
+> converts an IP address of
+protocol family <TT
+CLASS="PARAMETER"
+><I
+>af</I
+></TT
+> &mdash; IPv4 or IPv6 &mdash;
+at location <TT
+CLASS="PARAMETER"
+><I
+>src</I
+></TT
+> from network format to its
+conventional representation as a string. For IPv4 addresses, that
+string would be a dotted-decimal. An IPv6 address would be
+represented in colon notation as described in RFC1884.</P
+><P
+>The generated string is copied to <TT
+CLASS="PARAMETER"
+><I
+>dst</I
+></TT
+> provided
+<TT
+CLASS="PARAMETER"
+><I
+>size</I
+></TT
+> indicates it is long enough to store the
+ASCII representation of the address.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN30"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+>If successful, the function returns <TT
+CLASS="PARAMETER"
+><I
+>dst</I
+></TT
+>:
+a pointer to a string containing the presentation format of the
+address. <TT
+CLASS="FUNCTION"
+>lwres_net_ntop()</TT
+> returns
+<SPAN
+CLASS="TYPE"
+>NULL</SPAN
+> and sets the global variable
+<TT
+CLASS="CONSTANT"
+>errno</TT
+> to <SPAN
+CLASS="ERRORCODE"
+>EAFNOSUPPORT</SPAN
+> if
+the protocol family given in <TT
+CLASS="PARAMETER"
+><I
+>af</I
+></TT
+> is not
+supported.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN39"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>RFC1884</SPAN
+></SPAN
+>,
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>inet_ntop</SPAN
+>(3)</SPAN
+>,
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>errno</SPAN
+>(3)</SPAN
+>.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/lib/liblwres/man/lwres_noop.3 b/lib/liblwres/man/lwres_noop.3
new file mode 100644
index 000000000..50d127029
--- /dev/null
+++ b/lib/liblwres/man/lwres_noop.3
@@ -0,0 +1,160 @@
+.\"
+.\" Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM 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.
+.\"
+.TH "LWRES_NOOP" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_nooprequest_render, lwres_noopresponse_render, lwres_nooprequest_parse, lwres_noopresponse_parse, lwres_noopresponse_free, lwres_nooprequest_free \- lightweight resolver no-op message handling
+.SH SYNOPSIS
+\fB#include <lwres/lwres.h>
+.sp
+.na
+lwres_result_t
+lwres_nooprequest_render(lwres_context_t *ctx, lwres_nooprequest_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_noopresponse_render(lwres_context_t *ctx, lwres_noopresponse_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_nooprequest_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_nooprequest_t **structp);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_noopresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_noopresponse_t **structp);
+.ad
+.sp
+.na
+void
+lwres_noopresponse_free(lwres_context_t *ctx, lwres_noopresponse_t **structp);
+.ad
+.sp
+.na
+void
+lwres_nooprequest_free(lwres_context_t *ctx, lwres_nooprequest_t **structp);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+These are low-level routines for creating and parsing
+lightweight resolver no-op request and response messages.
+.PP
+The no-op message is analogous to a \fBping\fR packet:
+a packet is sent to the resolver daemon and is simply echoed back.
+The opcode is intended to allow a client to determine if the server is
+operational or not.
+.PP
+There are four main functions for the no-op opcode.
+One render function converts a no-op request structure \(em
+\fBlwres_nooprequest_t\fR \(em
+to the lighweight resolver's canonical format.
+It is complemented by a parse function that converts a packet in this
+canonical format to a no-op request structure.
+Another render function converts the no-op response structure \(em
+\fBlwres_noopresponse_t\fR
+to the canonical format.
+This is complemented by a parse function which converts a packet in
+canonical format to a no-op response structure.
+.PP
+These structures are defined in
+\fIlwres/lwres.h\fR.
+They are shown below.
+.sp
+.nf
+#define LWRES_OPCODE_NOOP 0x00000000U
+
+typedef struct {
+ lwres_uint16_t datalength;
+ unsigned char *data;
+} lwres_nooprequest_t;
+
+typedef struct {
+ lwres_uint16_t datalength;
+ unsigned char *data;
+} lwres_noopresponse_t;
+.sp
+.fi
+Although the structures have different types, they are identical.
+This is because the no-op opcode simply echos whatever data was sent:
+the response is therefore identical to the request.
+.PP
+\fBlwres_nooprequest_render()\fR uses resolver
+context \fIctx\fR to convert no-op request structure
+\fIreq\fR to canonical format. The packet header
+structure \fIpkt\fR is initialised and transferred to
+buffer \fIb\fR. The contents of
+\fI*req\fR are then appended to the buffer in
+canonical format. \fBlwres_noopresponse_render()\fR
+performs the same task, except it converts a no-op response structure
+\fBlwres_noopresponse_t\fR to the lightweight resolver's
+canonical format.
+.PP
+\fBlwres_nooprequest_parse()\fR uses context
+\fIctx\fR to convert the contents of packet
+\fIpkt\fR to a \fBlwres_nooprequest_t\fR
+structure. Buffer \fIb\fR provides space to be used
+for storing this structure. When the function succeeds, the resulting
+\fBlwres_nooprequest_t\fR is made available through
+\fI*structp\fR.
+\fBlwres_noopresponse_parse()\fR offers the same
+semantics as \fBlwres_nooprequest_parse()\fR except it
+yields a \fBlwres_noopresponse_t\fR structure.
+.PP
+\fBlwres_noopresponse_free()\fR and
+\fBlwres_nooprequest_free()\fR release the memory in
+resolver context \fIctx\fR that was allocated to the
+\fBlwres_noopresponse_t\fR or \fBlwres_nooprequest_t\fR
+structures referenced via \fIstructp\fR.
+.SH "RETURN VALUES"
+.PP
+The no-op opcode functions
+\fBlwres_nooprequest_render()\fR,
+\fBlwres_noopresponse_render()\fR
+\fBlwres_nooprequest_parse()\fR
+and
+\fBlwres_noopresponse_parse()\fR
+all return
+LWRES_R_SUCCESS
+on success.
+They return
+LWRES_R_NOMEMORY
+if memory allocation fails.
+LWRES_R_UNEXPECTEDEND
+is returned if the available space in the buffer
+\fIb\fR
+is too small to accommodate the packet header or the
+\fBlwres_nooprequest_t\fR
+and
+\fBlwres_noopresponse_t\fR
+structures.
+\fBlwres_nooprequest_parse()\fR
+and
+\fBlwres_noopresponse_parse()\fR
+will return
+LWRES_R_UNEXPECTEDEND
+if the buffer is not empty after decoding the received packet.
+These functions will return
+LWRES_R_FAILURE
+if
+pktflags
+in the packet header structure
+\fBlwres_lwpacket_t\fR
+indicate that the packet is not a response to an earlier query.
+.SH "SEE ALSO"
+.PP
+\fBlwres_packet\fR(3)
diff --git a/lib/liblwres/man/lwres_noop.docbook b/lib/liblwres/man/lwres_noop.docbook
new file mode 100644
index 000000000..18762e515
--- /dev/null
+++ b/lib/liblwres/man/lwres_noop.docbook
@@ -0,0 +1,229 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+
+<!-- $Id: lwres_noop.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+
+<refentryinfo>
+<date>Jun 30, 2000</date>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>lwres_noop</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>lwres_nooprequest_render</refname>
+<refname>lwres_noopresponse_render</refname>
+<refname>lwres_nooprequest_parse</refname>
+<refname>lwres_noopresponse_parse</refname>
+<refname>lwres_noopresponse_free</refname>
+<refname>lwres_nooprequest_free</refname>
+<refpurpose>lightweight resolver no-op message handling</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>
+#include &lt;lwres/lwres.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_nooprequest_render</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_nooprequest_t *req</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_noopresponse_render</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_noopresponse_t *req</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_nooprequest_parse</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+<paramdef>lwres_nooprequest_t **structp</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_noopresponse_parse</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+<paramdef>lwres_noopresponse_t **structp</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_noopresponse_free</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_noopresponse_t **structp</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_nooprequest_free</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_nooprequest_t **structp</paramdef>
+</funcprototype>
+</funcsynopsis>
+</refsynopsisdiv>
+<refsect1>
+<title>DESCRIPTION</title>
+<para>
+These are low-level routines for creating and parsing
+lightweight resolver no-op request and response messages.
+</para>
+<para>
+The no-op message is analogous to a <command>ping</command> packet:
+a packet is sent to the resolver daemon and is simply echoed back.
+The opcode is intended to allow a client to determine if the server is
+operational or not.
+</para>
+<para>
+There are four main functions for the no-op opcode.
+One render function converts a no-op request structure &mdash;
+<type>lwres_nooprequest_t</type> &mdash;
+to the lighweight resolver's canonical format.
+It is complemented by a parse function that converts a packet in this
+canonical format to a no-op request structure.
+Another render function converts the no-op response structure &mdash;
+<type>lwres_noopresponse_t</type>
+to the canonical format.
+This is complemented by a parse function which converts a packet in
+canonical format to a no-op response structure.
+</para>
+<para>
+These structures are defined in
+<filename>lwres/lwres.h</filename>.
+
+They are shown below.
+<programlisting>
+#define LWRES_OPCODE_NOOP 0x00000000U
+
+typedef struct {
+ lwres_uint16_t datalength;
+ unsigned char *data;
+} lwres_nooprequest_t;
+
+typedef struct {
+ lwres_uint16_t datalength;
+ unsigned char *data;
+} lwres_noopresponse_t;
+</programlisting>
+Although the structures have different types, they are identical.
+This is because the no-op opcode simply echos whatever data was sent:
+the response is therefore identical to the request.
+</para>
+
+<para>
+<function>lwres_nooprequest_render()</function> uses resolver
+context <parameter>ctx</parameter> to convert no-op request structure
+<parameter>req</parameter> to canonical format. The packet header
+structure <parameter>pkt</parameter> is initialised and transferred to
+buffer <parameter>b</parameter>. The contents of
+<parameter>*req</parameter> are then appended to the buffer in
+canonical format. <function>lwres_noopresponse_render()</function>
+performs the same task, except it converts a no-op response structure
+<type>lwres_noopresponse_t</type> to the lightweight resolver's
+canonical format.
+</para>
+
+<para>
+<function>lwres_nooprequest_parse()</function> uses context
+<parameter>ctx</parameter> to convert the contents of packet
+<parameter>pkt</parameter> to a <type>lwres_nooprequest_t</type>
+structure. Buffer <parameter>b</parameter> provides space to be used
+for storing this structure. When the function succeeds, the resulting
+<type>lwres_nooprequest_t</type> is made available through
+<parameter>*structp</parameter>.
+<function>lwres_noopresponse_parse()</function> offers the same
+semantics as <function>lwres_nooprequest_parse()</function> except it
+yields a <type>lwres_noopresponse_t</type> structure.
+</para>
+
+<para>
+<function>lwres_noopresponse_free()</function> and
+<function>lwres_nooprequest_free()</function> release the memory in
+resolver context <parameter>ctx</parameter> that was allocated to the
+<type>lwres_noopresponse_t</type> or <type>lwres_nooprequest_t</type>
+structures referenced via <parameter>structp</parameter>.
+</para>
+
+</refsect1>
+<refsect1>
+<title>RETURN VALUES</title>
+<para>
+The no-op opcode functions
+<function>lwres_nooprequest_render()</function>,
+
+<function>lwres_noopresponse_render()</function>
+<function>lwres_nooprequest_parse()</function>
+and
+<function>lwres_noopresponse_parse()</function>
+all return
+<errorcode>LWRES_R_SUCCESS</errorcode>
+on success.
+They return
+<errorcode>LWRES_R_NOMEMORY</errorcode>
+if memory allocation fails.
+<errorcode>LWRES_R_UNEXPECTEDEND</errorcode>
+is returned if the available space in the buffer
+<parameter>b</parameter>
+is too small to accommodate the packet header or the
+<type>lwres_nooprequest_t</type>
+and
+<type>lwres_noopresponse_t</type>
+structures.
+<function>lwres_nooprequest_parse()</function>
+and
+<function>lwres_noopresponse_parse()</function>
+will return
+<errorcode>LWRES_R_UNEXPECTEDEND</errorcode>
+if the buffer is not empty after decoding the received packet.
+These functions will return
+<errorcode>LWRES_R_FAILURE</errorcode>
+if
+<constant>pktflags</constant>
+in the packet header structure
+<type>lwres_lwpacket_t</type>
+indicate that the packet is not a response to an earlier query.
+</para>
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>lwres_packet</refentrytitle><manvolnum>3
+</manvolnum>
+</citerefentry>
+</para>
+</refsect1>
+</refentry>
diff --git a/lib/liblwres/man/lwres_noop.html b/lib/liblwres/man/lwres_noop.html
new file mode 100644
index 000000000..fdb5da103
--- /dev/null
+++ b/lib/liblwres/man/lwres_noop.html
@@ -0,0 +1,409 @@
+<!--
+ - Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_noop</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_noop</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_nooprequest_render, lwres_noopresponse_render, lwres_nooprequest_parse, lwres_noopresponse_parse, lwres_noopresponse_free, lwres_nooprequest_free&nbsp;--&nbsp;lightweight resolver no-op message handling</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN16"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN17"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/lwres.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_nooprequest_render</CODE
+>(lwres_context_t *ctx, lwres_nooprequest_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_noopresponse_render</CODE
+>(lwres_context_t *ctx, lwres_noopresponse_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_nooprequest_parse</CODE
+>(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_nooprequest_t **structp);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_noopresponse_parse</CODE
+>(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_noopresponse_t **structp);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_noopresponse_free</CODE
+>(lwres_context_t *ctx, lwres_noopresponse_t **structp);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_nooprequest_free</CODE
+>(lwres_context_t *ctx, lwres_nooprequest_t **structp);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN57"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>These are low-level routines for creating and parsing
+lightweight resolver no-op request and response messages.</P
+><P
+>The no-op message is analogous to a <B
+CLASS="COMMAND"
+>ping</B
+> packet:
+a packet is sent to the resolver daemon and is simply echoed back.
+The opcode is intended to allow a client to determine if the server is
+operational or not.</P
+><P
+>There are four main functions for the no-op opcode.
+One render function converts a no-op request structure &mdash;
+<SPAN
+CLASS="TYPE"
+>lwres_nooprequest_t</SPAN
+> &mdash;
+to the lighweight resolver's canonical format.
+It is complemented by a parse function that converts a packet in this
+canonical format to a no-op request structure.
+Another render function converts the no-op response structure &mdash;
+<SPAN
+CLASS="TYPE"
+>lwres_noopresponse_t</SPAN
+>
+to the canonical format.
+This is complemented by a parse function which converts a packet in
+canonical format to a no-op response structure.</P
+><P
+>These structures are defined in
+<TT
+CLASS="FILENAME"
+>lwres/lwres.h</TT
+>.
+
+They are shown below.
+<PRE
+CLASS="PROGRAMLISTING"
+>#define LWRES_OPCODE_NOOP 0x00000000U
+
+typedef struct {
+ lwres_uint16_t datalength;
+ unsigned char *data;
+} lwres_nooprequest_t;
+
+typedef struct {
+ lwres_uint16_t datalength;
+ unsigned char *data;
+} lwres_noopresponse_t;</PRE
+>
+Although the structures have different types, they are identical.
+This is because the no-op opcode simply echos whatever data was sent:
+the response is therefore identical to the request.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_nooprequest_render()</TT
+> uses resolver
+context <TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+> to convert no-op request structure
+<TT
+CLASS="PARAMETER"
+><I
+>req</I
+></TT
+> to canonical format. The packet header
+structure <TT
+CLASS="PARAMETER"
+><I
+>pkt</I
+></TT
+> is initialised and transferred to
+buffer <TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+>. The contents of
+<TT
+CLASS="PARAMETER"
+><I
+>*req</I
+></TT
+> are then appended to the buffer in
+canonical format. <TT
+CLASS="FUNCTION"
+>lwres_noopresponse_render()</TT
+>
+performs the same task, except it converts a no-op response structure
+<SPAN
+CLASS="TYPE"
+>lwres_noopresponse_t</SPAN
+> to the lightweight resolver's
+canonical format.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_nooprequest_parse()</TT
+> uses context
+<TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+> to convert the contents of packet
+<TT
+CLASS="PARAMETER"
+><I
+>pkt</I
+></TT
+> to a <SPAN
+CLASS="TYPE"
+>lwres_nooprequest_t</SPAN
+>
+structure. Buffer <TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+> provides space to be used
+for storing this structure. When the function succeeds, the resulting
+<SPAN
+CLASS="TYPE"
+>lwres_nooprequest_t</SPAN
+> is made available through
+<TT
+CLASS="PARAMETER"
+><I
+>*structp</I
+></TT
+>.
+<TT
+CLASS="FUNCTION"
+>lwres_noopresponse_parse()</TT
+> offers the same
+semantics as <TT
+CLASS="FUNCTION"
+>lwres_nooprequest_parse()</TT
+> except it
+yields a <SPAN
+CLASS="TYPE"
+>lwres_noopresponse_t</SPAN
+> structure.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_noopresponse_free()</TT
+> and
+<TT
+CLASS="FUNCTION"
+>lwres_nooprequest_free()</TT
+> release the memory in
+resolver context <TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+> that was allocated to the
+<SPAN
+CLASS="TYPE"
+>lwres_noopresponse_t</SPAN
+> or <SPAN
+CLASS="TYPE"
+>lwres_nooprequest_t</SPAN
+>
+structures referenced via <TT
+CLASS="PARAMETER"
+><I
+>structp</I
+></TT
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN95"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+>The no-op opcode functions
+<TT
+CLASS="FUNCTION"
+>lwres_nooprequest_render()</TT
+>,
+
+<TT
+CLASS="FUNCTION"
+>lwres_noopresponse_render()</TT
+>
+<TT
+CLASS="FUNCTION"
+>lwres_nooprequest_parse()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_noopresponse_parse()</TT
+>
+all return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_SUCCESS</SPAN
+>
+on success.
+They return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_NOMEMORY</SPAN
+>
+if memory allocation fails.
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_UNEXPECTEDEND</SPAN
+>
+is returned if the available space in the buffer
+<TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+>
+is too small to accommodate the packet header or the
+<SPAN
+CLASS="TYPE"
+>lwres_nooprequest_t</SPAN
+>
+and
+<SPAN
+CLASS="TYPE"
+>lwres_noopresponse_t</SPAN
+>
+structures.
+<TT
+CLASS="FUNCTION"
+>lwres_nooprequest_parse()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_noopresponse_parse()</TT
+>
+will return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_UNEXPECTEDEND</SPAN
+>
+if the buffer is not empty after decoding the received packet.
+These functions will return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_FAILURE</SPAN
+>
+if
+<TT
+CLASS="CONSTANT"
+>pktflags</TT
+>
+in the packet header structure
+<SPAN
+CLASS="TYPE"
+>lwres_lwpacket_t</SPAN
+>
+indicate that the packet is not a response to an earlier query.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN114"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_packet</SPAN
+>(3)</SPAN
+></P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/lib/liblwres/man/lwres_packet.3 b/lib/liblwres/man/lwres_packet.3
new file mode 100644
index 000000000..d7fb6f077
--- /dev/null
+++ b/lib/liblwres/man/lwres_packet.3
@@ -0,0 +1,149 @@
+.\"
+.\" Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM 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.
+.\"
+.TH "LWRES_PACKET" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_lwpacket_renderheader, lwres_lwpacket_parseheader \- lightweight resolver packet handling functions
+.SH SYNOPSIS
+\fB#include <lwres/lwpacket.h>
+.sp
+.na
+lwres_result_t
+lwres_lwpacket_renderheader(lwres_buffer_t *b, lwres_lwpacket_t *pkt);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_lwpacket_parseheader(lwres_buffer_t *b, lwres_lwpacket_t *pkt);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+These functions rely on a
+\fBstruct lwres_lwpacket\fR
+which is defined in
+\fIlwres/lwpacket.h\fR.
+.sp
+.nf
+typedef struct lwres_lwpacket lwres_lwpacket_t;
+
+struct lwres_lwpacket {
+ lwres_uint32_t length;
+ lwres_uint16_t version;
+ lwres_uint16_t pktflags;
+ lwres_uint32_t serial;
+ lwres_uint32_t opcode;
+ lwres_uint32_t result;
+ lwres_uint32_t recvlength;
+ lwres_uint16_t authtype;
+ lwres_uint16_t authlength;
+};
+.sp
+.fi
+.PP
+The elements of this structure are:
+.TP
+\fBlength\fR
+the overall packet length, including the entire packet header.
+This field is filled in by the lwres_gabn_*() and lwres_gnba_*()
+calls.
+.TP
+\fBversion\fR
+the header format. There is currently only one format,
+\fBLWRES_LWPACKETVERSION_0\fR.
+This field is filled in by the lwres_gabn_*() and lwres_gnba_*()
+calls.
+.TP
+\fBpktflags\fR
+library-defined flags for this packet: for instance whether the packet
+is a request or a reply. Flag values can be set, but not defined by
+the caller.
+This field is filled in by the application wit the exception of the
+LWRES_LWPACKETFLAG_RESPONSE bit, which is set by the library in the
+lwres_gabn_*() and lwres_gnba_*() calls.
+.TP
+\fBserial\fR
+is set by the requestor and is returned in all replies. If two or more
+packets from the same source have the same serial number and are from
+the same source, they are assumed to be duplicates and the latter ones
+may be dropped.
+This field must be set by the application.
+.TP
+\fBopcode\fR
+indicates the operation.
+Opcodes between 0x00000000 and 0x03ffffff are
+reserved for use by the lightweight resolver library. Opcodes between
+0x04000000 and 0xffffffff are application defined.
+This field is filled in by the lwres_gabn_*() and lwres_gnba_*()
+calls.
+.TP
+\fBresult\fR
+is only valid for replies.
+Results between 0x04000000 and 0xffffffff are application defined.
+Results between 0x00000000 and 0x03ffffff are reserved for library use.
+This field is filled in by the lwres_gabn_*() and lwres_gnba_*()
+calls.
+.TP
+\fBrecvlength\fR
+is the maximum buffer size that the receiver can handle on requests
+and the size of the buffer needed to satisfy a request when the buffer
+is too large for replies.
+This field is supplied by the application.
+.TP
+\fBauthtype\fR
+defines the packet level authentication that is used.
+Authorisation types between 0x1000 and 0xffff are application defined
+and types between 0x0000 and 0x0fff are reserved for library use.
+Currently these are not used and must be zero.
+.TP
+\fBauthlen\fR
+gives the length of the authentication data.
+Since packet authentication is currently not used, this must be zero.
+.PP
+The following opcodes are currently defined:
+.TP
+\fBNOOP\fR
+Success is always returned and the packet contents are echoed.
+The lwres_noop_*() functions should be used for this type.
+.TP
+\fBGETADDRSBYNAME\fR
+returns all known addresses for a given name.
+The lwres_gabn_*() functions should be used for this type.
+.TP
+\fBGETNAMEBYADDR\fR
+return the hostname for the given address.
+The lwres_gnba_*() functions should be used for this type.
+.PP
+\fBlwres_lwpacket_renderheader()\fR transfers the
+contents of lightweight resolver packet structure
+\fBlwres_lwpacket_t\fR \fI*pkt\fR in network
+byte order to the lightweight resolver buffer,
+\fI*b\fR.
+.PP
+\fBlwres_lwpacket_parseheader()\fR performs the
+converse operation. It transfers data in network byte order from
+buffer \fI*b\fR to resolver packet
+\fI*pkt\fR. The contents of the buffer
+\fIb\fR should correspond to a
+\fBlwres_lwpacket_t\fR.
+.SH "RETURN VALUES"
+.PP
+Successful calls to
+\fBlwres_lwpacket_renderheader()\fR and
+\fBlwres_lwpacket_parseheader()\fR return
+LWRES_R_SUCCESS. If there is insufficient
+space to copy data between the buffer \fI*b\fR and
+lightweight resolver packet \fI*pkt\fR both functions
+return LWRES_R_UNEXPECTEDEND.
diff --git a/lib/liblwres/man/lwres_packet.docbook b/lib/liblwres/man/lwres_packet.docbook
new file mode 100644
index 000000000..7b9ed38b3
--- /dev/null
+++ b/lib/liblwres/man/lwres_packet.docbook
@@ -0,0 +1,218 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+
+<!-- $Id: lwres_packet.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+
+<refentryinfo>
+<date>Jun 30, 2000</date>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>lwres_packet</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>lwres_lwpacket_renderheader</refname>
+<refname>lwres_lwpacket_parseheader</refname>
+<refpurpose>lightweight resolver packet handling functions</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/lwpacket.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_lwpacket_renderheader</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_lwpacket_parseheader</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+</funcprototype>
+</funcsynopsis>
+</refsynopsisdiv>
+<refsect1>
+<title>DESCRIPTION</title>
+<para>
+These functions rely on a
+<type>struct lwres_lwpacket</type>
+which is defined in
+<filename>lwres/lwpacket.h</filename>.
+
+<programlisting>
+typedef struct lwres_lwpacket lwres_lwpacket_t;
+
+struct lwres_lwpacket {
+ lwres_uint32_t length;
+ lwres_uint16_t version;
+ lwres_uint16_t pktflags;
+ lwres_uint32_t serial;
+ lwres_uint32_t opcode;
+ lwres_uint32_t result;
+ lwres_uint32_t recvlength;
+ lwres_uint16_t authtype;
+ lwres_uint16_t authlength;
+};
+</programlisting>
+</para>
+
+<para>
+The elements of this structure are:
+<variablelist>
+<varlistentry><term><constant>length</constant></term>
+<listitem>
+<para>
+the overall packet length, including the entire packet header.
+This field is filled in by the lwres_gabn_*() and lwres_gnba_*()
+calls.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>version</constant></term>
+<listitem>
+<para>
+the header format. There is currently only one format,
+<type>LWRES_LWPACKETVERSION_0</type>.
+
+This field is filled in by the lwres_gabn_*() and lwres_gnba_*()
+calls.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>pktflags</constant></term>
+<listitem>
+<para>
+library-defined flags for this packet: for instance whether the packet
+is a request or a reply. Flag values can be set, but not defined by
+the caller.
+This field is filled in by the application wit the exception of the
+LWRES_LWPACKETFLAG_RESPONSE bit, which is set by the library in the
+lwres_gabn_*() and lwres_gnba_*() calls.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>serial</constant></term>
+<listitem>
+<para>
+is set by the requestor and is returned in all replies. If two or more
+packets from the same source have the same serial number and are from
+the same source, they are assumed to be duplicates and the latter ones
+may be dropped.
+This field must be set by the application.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>opcode</constant></term>
+<listitem>
+<para>
+indicates the operation.
+Opcodes between 0x00000000 and 0x03ffffff are
+reserved for use by the lightweight resolver library. Opcodes between
+0x04000000 and 0xffffffff are application defined.
+This field is filled in by the lwres_gabn_*() and lwres_gnba_*()
+calls.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>result</constant></term>
+<listitem>
+<para>
+is only valid for replies.
+Results between 0x04000000 and 0xffffffff are application defined.
+Results between 0x00000000 and 0x03ffffff are reserved for library use.
+This field is filled in by the lwres_gabn_*() and lwres_gnba_*()
+calls.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>recvlength</constant></term>
+<listitem>
+<para>
+is the maximum buffer size that the receiver can handle on requests
+and the size of the buffer needed to satisfy a request when the buffer
+is too large for replies.
+This field is supplied by the application.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>authtype</constant></term>
+<listitem>
+<para>
+defines the packet level authentication that is used.
+Authorisation types between 0x1000 and 0xffff are application defined
+and types between 0x0000 and 0x0fff are reserved for library use.
+Currently these are not used and must be zero.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>authlen</constant></term>
+<listitem>
+<para>
+gives the length of the authentication data.
+Since packet authentication is currently not used, this must be zero.
+</para></listitem></varlistentry>
+</variablelist>
+</para>
+<para>
+The following opcodes are currently defined:
+<variablelist>
+<varlistentry><term><constant>NOOP</constant></term>
+<listitem>
+<para>
+Success is always returned and the packet contents are echoed.
+The lwres_noop_*() functions should be used for this type.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>GETADDRSBYNAME</constant></term>
+<listitem>
+<para>
+returns all known addresses for a given name.
+The lwres_gabn_*() functions should be used for this type.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>GETNAMEBYADDR</constant></term>
+<listitem>
+<para>
+return the hostname for the given address.
+The lwres_gnba_*() functions should be used for this type.
+</para></listitem></varlistentry>
+</variablelist>
+</para>
+
+<para>
+<function>lwres_lwpacket_renderheader()</function> transfers the
+contents of lightweight resolver packet structure
+<type>lwres_lwpacket_t</type> <parameter>*pkt</parameter> in network
+byte order to the lightweight resolver buffer,
+<parameter>*b</parameter>.
+</para>
+
+<para>
+<function>lwres_lwpacket_parseheader()</function> performs the
+converse operation. It transfers data in network byte order from
+buffer <parameter>*b</parameter> to resolver packet
+<parameter>*pkt</parameter>. The contents of the buffer
+<parameter>b</parameter> should correspond to a
+<type>lwres_lwpacket_t</type>.
+</para>
+
+</refsect1>
+
+<refsect1>
+<title>RETURN VALUES</title>
+<para> Successful calls to
+<function>lwres_lwpacket_renderheader()</function> and
+<function>lwres_lwpacket_parseheader()</function> return
+<errorcode>LWRES_R_SUCCESS</errorcode>. If there is insufficient
+space to copy data between the buffer <parameter>*b</parameter> and
+lightweight resolver packet <parameter>*pkt</parameter> both functions
+return <errorcode>LWRES_R_UNEXPECTEDEND</errorcode>.
+</para>
+
+</refsect1>
+</refentry>
diff --git a/lib/liblwres/man/lwres_packet.html b/lib/liblwres/man/lwres_packet.html
new file mode 100644
index 000000000..5c5828f49
--- /dev/null
+++ b/lib/liblwres/man/lwres_packet.html
@@ -0,0 +1,373 @@
+<!--
+ - Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_packet</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_packet</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_lwpacket_renderheader, lwres_lwpacket_parseheader&nbsp;--&nbsp;lightweight resolver packet handling functions</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN12"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN13"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/lwpacket.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_lwpacket_renderheader</CODE
+>(lwres_buffer_t *b, lwres_lwpacket_t *pkt);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_lwpacket_parseheader</CODE
+>(lwres_buffer_t *b, lwres_lwpacket_t *pkt);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN25"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>These functions rely on a
+<SPAN
+CLASS="TYPE"
+>struct lwres_lwpacket</SPAN
+>
+which is defined in
+<TT
+CLASS="FILENAME"
+>lwres/lwpacket.h</TT
+>.
+
+<PRE
+CLASS="PROGRAMLISTING"
+>typedef struct lwres_lwpacket lwres_lwpacket_t;
+
+struct lwres_lwpacket {
+ lwres_uint32_t length;
+ lwres_uint16_t version;
+ lwres_uint16_t pktflags;
+ lwres_uint32_t serial;
+ lwres_uint32_t opcode;
+ lwres_uint32_t result;
+ lwres_uint32_t recvlength;
+ lwres_uint16_t authtype;
+ lwres_uint16_t authlength;
+};</PRE
+></P
+><P
+>The elements of this structure are:
+<P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="CONSTANT"
+>length</TT
+></DT
+><DD
+><P
+>the overall packet length, including the entire packet header.
+This field is filled in by the lwres_gabn_*() and lwres_gnba_*()
+calls.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>version</TT
+></DT
+><DD
+><P
+>the header format. There is currently only one format,
+<SPAN
+CLASS="TYPE"
+>LWRES_LWPACKETVERSION_0</SPAN
+>.
+
+This field is filled in by the lwres_gabn_*() and lwres_gnba_*()
+calls.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>pktflags</TT
+></DT
+><DD
+><P
+>library-defined flags for this packet: for instance whether the packet
+is a request or a reply. Flag values can be set, but not defined by
+the caller.
+This field is filled in by the application wit the exception of the
+LWRES_LWPACKETFLAG_RESPONSE bit, which is set by the library in the
+lwres_gabn_*() and lwres_gnba_*() calls.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>serial</TT
+></DT
+><DD
+><P
+>is set by the requestor and is returned in all replies. If two or more
+packets from the same source have the same serial number and are from
+the same source, they are assumed to be duplicates and the latter ones
+may be dropped.
+This field must be set by the application.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>opcode</TT
+></DT
+><DD
+><P
+>indicates the operation.
+Opcodes between 0x00000000 and 0x03ffffff are
+reserved for use by the lightweight resolver library. Opcodes between
+0x04000000 and 0xffffffff are application defined.
+This field is filled in by the lwres_gabn_*() and lwres_gnba_*()
+calls.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>result</TT
+></DT
+><DD
+><P
+>is only valid for replies.
+Results between 0x04000000 and 0xffffffff are application defined.
+Results between 0x00000000 and 0x03ffffff are reserved for library use.
+This field is filled in by the lwres_gabn_*() and lwres_gnba_*()
+calls.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>recvlength</TT
+></DT
+><DD
+><P
+>is the maximum buffer size that the receiver can handle on requests
+and the size of the buffer needed to satisfy a request when the buffer
+is too large for replies.
+This field is supplied by the application.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>authtype</TT
+></DT
+><DD
+><P
+>defines the packet level authentication that is used.
+Authorisation types between 0x1000 and 0xffff are application defined
+and types between 0x0000 and 0x0fff are reserved for library use.
+Currently these are not used and must be zero.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>authlen</TT
+></DT
+><DD
+><P
+>gives the length of the authentication data.
+Since packet authentication is currently not used, this must be zero.</P
+></DD
+></DL
+></DIV
+></P
+><P
+>The following opcodes are currently defined:
+<P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="CONSTANT"
+>NOOP</TT
+></DT
+><DD
+><P
+>Success is always returned and the packet contents are echoed.
+The lwres_noop_*() functions should be used for this type.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>GETADDRSBYNAME</TT
+></DT
+><DD
+><P
+>returns all known addresses for a given name.
+The lwres_gabn_*() functions should be used for this type.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>GETNAMEBYADDR</TT
+></DT
+><DD
+><P
+>return the hostname for the given address.
+The lwres_gnba_*() functions should be used for this type.</P
+></DD
+></DL
+></DIV
+></P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_lwpacket_renderheader()</TT
+> transfers the
+contents of lightweight resolver packet structure
+<SPAN
+CLASS="TYPE"
+>lwres_lwpacket_t</SPAN
+> <TT
+CLASS="PARAMETER"
+><I
+>*pkt</I
+></TT
+> in network
+byte order to the lightweight resolver buffer,
+<TT
+CLASS="PARAMETER"
+><I
+>*b</I
+></TT
+>.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_lwpacket_parseheader()</TT
+> performs the
+converse operation. It transfers data in network byte order from
+buffer <TT
+CLASS="PARAMETER"
+><I
+>*b</I
+></TT
+> to resolver packet
+<TT
+CLASS="PARAMETER"
+><I
+>*pkt</I
+></TT
+>. The contents of the buffer
+<TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+> should correspond to a
+<SPAN
+CLASS="TYPE"
+>lwres_lwpacket_t</SPAN
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN107"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+> Successful calls to
+<TT
+CLASS="FUNCTION"
+>lwres_lwpacket_renderheader()</TT
+> and
+<TT
+CLASS="FUNCTION"
+>lwres_lwpacket_parseheader()</TT
+> return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_SUCCESS</SPAN
+>. If there is insufficient
+space to copy data between the buffer <TT
+CLASS="PARAMETER"
+><I
+>*b</I
+></TT
+> and
+lightweight resolver packet <TT
+CLASS="PARAMETER"
+><I
+>*pkt</I
+></TT
+> both functions
+return <SPAN
+CLASS="ERRORCODE"
+>LWRES_R_UNEXPECTEDEND</SPAN
+>.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/lib/liblwres/man/lwres_resutil.3 b/lib/liblwres/man/lwres_resutil.3
new file mode 100644
index 000000000..6db4825b0
--- /dev/null
+++ b/lib/liblwres/man/lwres_resutil.3
@@ -0,0 +1,151 @@
+.\"
+.\" Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM 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.
+.\"
+.TH "LWRES_RESUTIL" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_string_parse, lwres_addr_parse, lwres_getaddrsbyname, lwres_getnamebyaddr \- lightweight resolver utility functions
+.SH SYNOPSIS
+\fB#include <lwres/lwres.h>
+.sp
+.na
+lwres_result_t
+lwres_string_parse(lwres_buffer_t *b, char **c, lwres_uint16_t *len);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_addr_parse(lwres_buffer_t *b, lwres_addr_t *addr);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_getaddrsbyname(lwres_context_t *ctx, const char *name, lwres_uint32_t addrtypes, lwres_gabnresponse_t **structp);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_getnamebyaddr(lwres_context_t *ctx, lwres_uint32_t addrtype, lwres_uint16_t addrlen, const unsigned char *addr, lwres_gnbaresponse_t **structp);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+\fBlwres_string_parse()\fR retrieves a DNS-encoded
+string starting the current pointer of lightweight resolver buffer
+\fIb\fR: i.e. b->current.
+When the function returns, the address of the first byte of the
+encoded string is returned via \fI*c\fR and the
+length of that string is given by \fI*len\fR. The
+buffer's current pointer is advanced to point at the character
+following the string length, the encoded string, and the trailing
+\fBNULL\fR character.
+.PP
+\fBlwres_addr_parse()\fR extracts an address from the
+buffer \fIb\fR. The buffer's current pointer
+b->current is presumed to point at an encoded
+address: the address preceded by a 32-bit protocol family identifier
+and a 16-bit length field. The encoded address is copied to
+addr->address and
+addr->length indicates the size in bytes of
+the address that was copied. b->current is
+advanced to point at the next byte of available data in the buffer
+following the encoded address.
+.PP
+\fBlwres_getaddrsbyname()\fR
+and
+\fBlwres_getnamebyaddr()\fR
+use the
+\fBlwres_gnbaresponse_t\fR
+structure defined below:
+.sp
+.nf
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ lwres_uint16_t naddrs;
+ char *realname;
+ char **aliases;
+ lwres_uint16_t realnamelen;
+ lwres_uint16_t *aliaslen;
+ lwres_addrlist_t addrs;
+ void *base;
+ size_t baselen;
+} lwres_gabnresponse_t;
+.sp
+.fi
+The contents of this structure are not manipulated directly but
+they are controlled through the
+\fBlwres_gabn\fR(3)
+functions.
+.PP
+The lightweight resolver uses
+\fBlwres_getaddrsbyname()\fR to perform foward lookups.
+Hostname \fIname\fR is looked up using the resolver
+context \fIctx\fR for memory allocation.
+\fIaddrtypes\fR is a bitmask indicating which type of
+addresses are to be looked up. Current values for this bitmask are
+\fBLWRES_ADDRTYPE_V4\fR for IPv4 addresses and
+\fBLWRES_ADDRTYPE_V6\fR for IPv6 addresses. Results of the
+lookup are returned in \fI*structp\fR.
+.PP
+\fBlwres_getnamebyaddr()\fR performs reverse lookups.
+Resolver context \fIctx\fR is used for memory
+allocation. The address type is indicated by
+\fIaddrtype\fR: \fBLWRES_ADDRTYPE_V4\fR or
+\fBLWRES_ADDRTYPE_V6\fR. The address to be looked up is given
+by \fIaddr\fR and its length is
+\fIaddrlen\fR bytes. The result of the function call
+is made available through \fI*structp\fR.
+.SH "RETURN VALUES"
+.PP
+Successful calls to
+\fBlwres_string_parse()\fR
+and
+\fBlwres_addr_parse()\fR
+return
+LWRES_R_SUCCESS.
+Both functions return
+LWRES_R_FAILURE
+if the buffer is corrupt or
+LWRES_R_UNEXPECTEDEND
+if the buffer has less space than expected for the components of the
+encoded string or address.
+.PP
+\fBlwres_getaddrsbyname()\fR
+returns
+LWRES_R_SUCCESS
+on success and it returns
+LWRES_R_NOTFOUND
+if the hostname
+\fIname\fR
+could not be found.
+.PP
+LWRES_R_SUCCESS
+is returned by a successful call to
+\fBlwres_getnamebyaddr()\fR.
+.PP
+Both
+\fBlwres_getaddrsbyname()\fR
+and
+\fBlwres_getnamebyaddr()\fR
+return
+LWRES_R_NOMEMORY
+when memory allocation requests fail and
+LWRES_R_UNEXPECTEDEND
+if the buffers used for sending queries and receiving replies are too
+small.
+.SH "SEE ALSO"
+.PP
+\fBlwres_buffer\fR(3),
+\fBlwres_gabn\fR(3).
diff --git a/lib/liblwres/man/lwres_resutil.docbook b/lib/liblwres/man/lwres_resutil.docbook
new file mode 100644
index 000000000..72d6dc614
--- /dev/null
+++ b/lib/liblwres/man/lwres_resutil.docbook
@@ -0,0 +1,221 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+
+<!-- $Id: lwres_resutil.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+
+<refentryinfo>
+<date>Jun 30, 2000</date>
+</refentryinfo>
+
+<refmeta>
+ <refentrytitle>lwres_resutil</refentrytitle>
+ <manvolnum>3</manvolnum>
+ <refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>lwres_string_parse</refname>
+<refname>lwres_addr_parse</refname>
+<refname>lwres_getaddrsbyname</refname>
+<refname>lwres_getnamebyaddr</refname>
+<refpurpose>lightweight resolver utility functions</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/lwres.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_string_parse</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>char **c</paramdef>
+<paramdef>lwres_uint16_t *len</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_addr_parse</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>lwres_addr_t *addr</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_getaddrsbyname</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>const char *name</paramdef>
+<paramdef>lwres_uint32_t addrtypes</paramdef>
+<paramdef>lwres_gabnresponse_t **structp</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_getnamebyaddr</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_uint32_t addrtype</paramdef>
+<paramdef>lwres_uint16_t addrlen</paramdef>
+<paramdef>const unsigned char *addr</paramdef>
+<paramdef>lwres_gnbaresponse_t **structp</paramdef>
+</funcprototype>
+</funcsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+<title>DESCRIPTION</title>
+
+<para>
+<function>lwres_string_parse()</function> retrieves a DNS-encoded
+string starting the current pointer of lightweight resolver buffer
+<parameter>b</parameter>: i.e. <constant>b-&gt;current</constant>.
+When the function returns, the address of the first byte of the
+encoded string is returned via <parameter>*c</parameter> and the
+length of that string is given by <parameter>*len</parameter>. The
+buffer's current pointer is advanced to point at the character
+following the string length, the encoded string, and the trailing
+<type>NULL</type> character.
+</para>
+
+<para>
+<function>lwres_addr_parse()</function> extracts an address from the
+buffer <parameter>b</parameter>. The buffer's current pointer
+<constant>b-&gt;current</constant> is presumed to point at an encoded
+address: the address preceded by a 32-bit protocol family identifier
+and a 16-bit length field. The encoded address is copied to
+<constant>addr-&gt;address</constant> and
+<constant>addr-&gt;length</constant> indicates the size in bytes of
+the address that was copied. <constant>b-&gt;current</constant> is
+advanced to point at the next byte of available data in the buffer
+following the encoded address.
+</para>
+
+<para>
+<function>lwres_getaddrsbyname()</function>
+and
+<function>lwres_getnamebyaddr()</function>
+use the
+<type>lwres_gnbaresponse_t</type>
+structure defined below:
+<programlisting>
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ lwres_uint16_t naddrs;
+ char *realname;
+ char **aliases;
+ lwres_uint16_t realnamelen;
+ lwres_uint16_t *aliaslen;
+ lwres_addrlist_t addrs;
+ void *base;
+ size_t baselen;
+} lwres_gabnresponse_t;
+</programlisting>
+The contents of this structure are not manipulated directly but
+they are controlled through the
+<citerefentry>
+<refentrytitle>lwres_gabn</refentrytitle><manvolnum>3
+</manvolnum>
+</citerefentry>
+functions.
+</para>
+
+<para>
+The lightweight resolver uses
+<function>lwres_getaddrsbyname()</function> to perform foward lookups.
+Hostname <parameter>name</parameter> is looked up using the resolver
+context <parameter>ctx</parameter> for memory allocation.
+<parameter>addrtypes</parameter> is a bitmask indicating which type of
+addresses are to be looked up. Current values for this bitmask are
+<type>LWRES_ADDRTYPE_V4</type> for IPv4 addresses and
+<type>LWRES_ADDRTYPE_V6</type> for IPv6 addresses. Results of the
+lookup are returned in <parameter>*structp</parameter>.
+</para>
+
+<para>
+<function>lwres_getnamebyaddr()</function> performs reverse lookups.
+Resolver context <parameter>ctx</parameter> is used for memory
+allocation. The address type is indicated by
+<parameter>addrtype</parameter>: <type>LWRES_ADDRTYPE_V4</type> or
+<type>LWRES_ADDRTYPE_V6</type>. The address to be looked up is given
+by <parameter>addr</parameter> and its length is
+<parameter>addrlen</parameter> bytes. The result of the function call
+is made available through <parameter>*structp</parameter>.
+</para>
+</refsect1>
+
+<refsect1>
+<title>RETURN VALUES</title>
+<para>
+Successful calls to
+<function>lwres_string_parse()</function>
+and
+<function>lwres_addr_parse()</function>
+return
+<errorcode>LWRES_R_SUCCESS.</errorcode>
+Both functions return
+<errorcode>LWRES_R_FAILURE</errorcode>
+if the buffer is corrupt or
+<errorcode>LWRES_R_UNEXPECTEDEND</errorcode>
+if the buffer has less space than expected for the components of the
+encoded string or address.
+</para>
+<para>
+<function>lwres_getaddrsbyname()</function>
+returns
+<errorcode>LWRES_R_SUCCESS</errorcode>
+on success and it returns
+<errorcode>LWRES_R_NOTFOUND</errorcode>
+if the hostname
+<parameter>name</parameter>
+could not be found.
+</para>
+<para>
+<errorcode>LWRES_R_SUCCESS</errorcode>
+is returned by a successful call to
+<function>lwres_getnamebyaddr()</function>.
+</para>
+
+<para>
+Both
+<function>lwres_getaddrsbyname()</function>
+and
+<function>lwres_getnamebyaddr()</function>
+return
+<errorcode>LWRES_R_NOMEMORY</errorcode>
+when memory allocation requests fail and
+<errorcode>LWRES_R_UNEXPECTEDEND</errorcode>
+if the buffers used for sending queries and receiving replies are too
+small.
+</para>
+
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>lwres_buffer</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_gabn</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>.
+</para>
+
+</refsect1>
+</refentry>
diff --git a/lib/liblwres/man/lwres_resutil.html b/lib/liblwres/man/lwres_resutil.html
new file mode 100644
index 000000000..ae3a2f646
--- /dev/null
+++ b/lib/liblwres/man/lwres_resutil.html
@@ -0,0 +1,412 @@
+<!--
+ - Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM 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.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_resutil</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_resutil</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_string_parse, lwres_addr_parse, lwres_getaddrsbyname, lwres_getnamebyaddr&nbsp;--&nbsp;lightweight resolver utility functions</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN14"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN15"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/lwres.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_string_parse</CODE
+>(lwres_buffer_t *b, char **c, lwres_uint16_t *len);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_addr_parse</CODE
+>(lwres_buffer_t *b, lwres_addr_t *addr);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_getaddrsbyname</CODE
+>(lwres_context_t *ctx, const char *name, lwres_uint32_t addrtypes, lwres_gabnresponse_t **structp);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_getnamebyaddr</CODE
+>(lwres_context_t *ctx, lwres_uint32_t addrtype, lwres_uint16_t addrlen, const unsigned char *addr, lwres_gnbaresponse_t **structp);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN43"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_string_parse()</TT
+> retrieves a DNS-encoded
+string starting the current pointer of lightweight resolver buffer
+<TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+>: i.e. <TT
+CLASS="CONSTANT"
+>b-&gt;current</TT
+>.
+When the function returns, the address of the first byte of the
+encoded string is returned via <TT
+CLASS="PARAMETER"
+><I
+>*c</I
+></TT
+> and the
+length of that string is given by <TT
+CLASS="PARAMETER"
+><I
+>*len</I
+></TT
+>. The
+buffer's current pointer is advanced to point at the character
+following the string length, the encoded string, and the trailing
+<SPAN
+CLASS="TYPE"
+>NULL</SPAN
+> character.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_addr_parse()</TT
+> extracts an address from the
+buffer <TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+>. The buffer's current pointer
+<TT
+CLASS="CONSTANT"
+>b-&gt;current</TT
+> is presumed to point at an encoded
+address: the address preceded by a 32-bit protocol family identifier
+and a 16-bit length field. The encoded address is copied to
+<TT
+CLASS="CONSTANT"
+>addr-&gt;address</TT
+> and
+<TT
+CLASS="CONSTANT"
+>addr-&gt;length</TT
+> indicates the size in bytes of
+the address that was copied. <TT
+CLASS="CONSTANT"
+>b-&gt;current</TT
+> is
+advanced to point at the next byte of available data in the buffer
+following the encoded address.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_getaddrsbyname()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_getnamebyaddr()</TT
+>
+use the
+<SPAN
+CLASS="TYPE"
+>lwres_gnbaresponse_t</SPAN
+>
+structure defined below:
+<PRE
+CLASS="PROGRAMLISTING"
+>typedef struct {
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ lwres_uint16_t naddrs;
+ char *realname;
+ char **aliases;
+ lwres_uint16_t realnamelen;
+ lwres_uint16_t *aliaslen;
+ lwres_addrlist_t addrs;
+ void *base;
+ size_t baselen;
+} lwres_gabnresponse_t;</PRE
+>
+The contents of this structure are not manipulated directly but
+they are controlled through the
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_gabn</SPAN
+>(3)</SPAN
+>
+functions.</P
+><P
+>The lightweight resolver uses
+<TT
+CLASS="FUNCTION"
+>lwres_getaddrsbyname()</TT
+> to perform foward lookups.
+Hostname <TT
+CLASS="PARAMETER"
+><I
+>name</I
+></TT
+> is looked up using the resolver
+context <TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+> for memory allocation.
+<TT
+CLASS="PARAMETER"
+><I
+>addrtypes</I
+></TT
+> is a bitmask indicating which type of
+addresses are to be looked up. Current values for this bitmask are
+<SPAN
+CLASS="TYPE"
+>LWRES_ADDRTYPE_V4</SPAN
+> for IPv4 addresses and
+<SPAN
+CLASS="TYPE"
+>LWRES_ADDRTYPE_V6</SPAN
+> for IPv6 addresses. Results of the
+lookup are returned in <TT
+CLASS="PARAMETER"
+><I
+>*structp</I
+></TT
+>.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_getnamebyaddr()</TT
+> performs reverse lookups.
+Resolver context <TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+> is used for memory
+allocation. The address type is indicated by
+<TT
+CLASS="PARAMETER"
+><I
+>addrtype</I
+></TT
+>: <SPAN
+CLASS="TYPE"
+>LWRES_ADDRTYPE_V4</SPAN
+> or
+<SPAN
+CLASS="TYPE"
+>LWRES_ADDRTYPE_V6</SPAN
+>. The address to be looked up is given
+by <TT
+CLASS="PARAMETER"
+><I
+>addr</I
+></TT
+> and its length is
+<TT
+CLASS="PARAMETER"
+><I
+>addrlen</I
+></TT
+> bytes. The result of the function call
+is made available through <TT
+CLASS="PARAMETER"
+><I
+>*structp</I
+></TT
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN84"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+>Successful calls to
+<TT
+CLASS="FUNCTION"
+>lwres_string_parse()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_addr_parse()</TT
+>
+return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_SUCCESS.</SPAN
+>
+Both functions return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_FAILURE</SPAN
+>
+if the buffer is corrupt or
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_UNEXPECTEDEND</SPAN
+>
+if the buffer has less space than expected for the components of the
+encoded string or address.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_getaddrsbyname()</TT
+>
+returns
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_SUCCESS</SPAN
+>
+on success and it returns
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_NOTFOUND</SPAN
+>
+if the hostname
+<TT
+CLASS="PARAMETER"
+><I
+>name</I
+></TT
+>
+could not be found.</P
+><P
+><SPAN
+CLASS="ERRORCODE"
+>LWRES_R_SUCCESS</SPAN
+>
+is returned by a successful call to
+<TT
+CLASS="FUNCTION"
+>lwres_getnamebyaddr()</TT
+>.</P
+><P
+>Both
+<TT
+CLASS="FUNCTION"
+>lwres_getaddrsbyname()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_getnamebyaddr()</TT
+>
+return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_NOMEMORY</SPAN
+>
+when memory allocation requests fail and
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_UNEXPECTEDEND</SPAN
+>
+if the buffers used for sending queries and receiving replies are too
+small.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN105"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_buffer</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_gabn</SPAN
+>(3)</SPAN
+>.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/lib/liblwres/unix/include/lwres/net.h b/lib/liblwres/unix/include/lwres/net.h
new file mode 100644
index 000000000..cb17700cd
--- /dev/null
+++ b/lib/liblwres/unix/include/lwres/net.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: net.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_NET_H
+#define LWRES_NET_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*
+ * Basic Networking Types
+ *
+ * This module is responsible for defining the following basic networking
+ * types:
+ *
+ * struct in_addr
+ * struct in6_addr
+ * struct sockaddr
+ * struct sockaddr_in
+ * struct sockaddr_in6
+ *
+ * It ensures that the AF_ and PF_ macros are defined.
+ *
+ * It declares ntoh[sl]() and hton[sl]().
+ *
+ * It declares lwres_net_aton(), lwres_net_ntop(), and lwres_net_pton().
+ *
+ * It ensures that INADDR_LOOPBACK, INADDR_ANY and IN6ADDR_ANY_INIT
+ * are defined.
+ */
+
+/***
+ *** Imports.
+ ***/
+
+#include <lwres/platform.h> /* Required for LWRES_PLATFORM_*. */
+
+#include <sys/types.h>
+#include <sys/socket.h> /* Contractual promise. */
+#include <sys/time.h>
+#include <sys/un.h>
+
+#include <netinet/in.h> /* Contractual promise. */
+#include <arpa/inet.h> /* Contractual promise. */
+#ifdef LWRES_PLATFORM_NEEDNETINETIN6H
+#include <netinet/in6.h> /* Required on UnixWare. */
+#endif
+#ifdef LWRES_PLATFORM_NEEDNETINET6IN6H
+#include <netinet6/in6.h> /* Required on BSD/OS for in6_pktinfo. */
+#endif
+
+#include <lwres/lang.h>
+
+#ifndef LWRES_PLATFORM_HAVEIPV6
+#include <lwres/ipv6.h> /* Contractual promise. */
+#endif
+
+#ifdef LWRES_PLATFORM_HAVEINADDR6
+#define in6_addr in_addr6 /* Required for pre RFC2133 implementations. */
+#endif
+
+/*
+ * Required for some pre RFC2133 implementations.
+ * IN6ADDR_ANY_INIT and IN6ADDR_LOOPBACK_INIT were added in
+ * draft-ietf-ipngwg-bsd-api-04.txt or draft-ietf-ipngwg-bsd-api-05.txt.
+ * If 's6_addr' is defined then assume that there is a union and three
+ * levels otherwise assume two levels required.
+ */
+#ifndef IN6ADDR_ANY_INIT
+#ifdef s6_addr
+#define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
+#else
+#define IN6ADDR_ANY_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } }
+#endif
+#endif
+
+#ifndef IN6ADDR_LOOPBACK_INIT
+#ifdef s6_addr
+#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
+#else
+#define IN6ADDR_LOOPBACK_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } }
+#endif
+#endif
+
+#ifndef AF_INET6
+#define AF_INET6 99
+#endif
+
+#ifndef PF_INET6
+#define PF_INET6 AF_INET6
+#endif
+
+#ifndef INADDR_LOOPBACK
+#define INADDR_LOOPBACK 0x7f000001UL
+#endif
+
+LWRES_LANG_BEGINDECLS
+
+const char *
+lwres_net_ntop(int af, const void *src, char *dst, size_t size);
+
+int
+lwres_net_pton(int af, const char *src, void *dst);
+
+int
+lwres_net_aton(const char *cp, struct in_addr *addr);
+
+LWRES_LANG_ENDDECLS
+
+#endif /* LWRES_NET_H */
diff --git a/lib/liblwres/version.c b/lib/liblwres/version.c
new file mode 100644
index 000000000..ce0380d23
--- /dev/null
+++ b/lib/liblwres/version.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2000, 2001 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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+
+/* $Id: version.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+char lwres_version[] = VERSION;
+
+unsigned int lwres_libinterface = LIBINTERFACE;
+unsigned int lwres_librevision = LIBREVISION;
+unsigned int lwres_libage = LIBAGE;