summaryrefslogtreecommitdiff
path: root/dns
diff options
context:
space:
mode:
authorBruce M Simpson <bms@FreeBSD.org>2007-01-20 14:43:58 +0000
committerBruce M Simpson <bms@FreeBSD.org>2007-01-20 14:43:58 +0000
commit6f85f8fa4c8771de28eabf91ac5d86e4cc11b56b (patch)
tree15bc1073b4982d4f2464060b75ff53df9e086013 /dns
parent- Fix patch with psyco (diff)
Add new port nss_mdns, a libc name service switch module for resolving
hostnames via Avahi's implementation of Multicast DNS. With help from: flameeyes at gentoo dot org
Notes
Notes: svn path=/head/; revision=182859
Diffstat (limited to 'dns')
-rw-r--r--dns/Makefile1
-rw-r--r--dns/nss_mdns/Makefile71
-rw-r--r--dns/nss_mdns/distinfo3
-rw-r--r--dns/nss_mdns/files/patch-configure.ac16
-rw-r--r--dns/nss_mdns/files/patch-src__Makefile.am57
-rw-r--r--dns/nss_mdns/files/patch-src__avahi-test.c10
-rw-r--r--dns/nss_mdns/files/patch-src__bsdnss.c436
-rw-r--r--dns/nss_mdns/files/patch-src__query.c147
-rw-r--r--dns/nss_mdns/pkg-descr6
9 files changed, 747 insertions, 0 deletions
diff --git a/dns/Makefile b/dns/Makefile
index 731ff5957341..a93d98a995a6 100644
--- a/dns/Makefile
+++ b/dns/Makefile
@@ -64,6 +64,7 @@
SUBDIR += nsd2
SUBDIR += nslint
SUBDIR += nsping
+ SUBDIR += nss_mdns
SUBDIR += nss_resinit
SUBDIR += odsclient
SUBDIR += opendd
diff --git a/dns/nss_mdns/Makefile b/dns/nss_mdns/Makefile
new file mode 100644
index 000000000000..8c3a1efbcb79
--- /dev/null
+++ b/dns/nss_mdns/Makefile
@@ -0,0 +1,71 @@
+# New ports collection makefile for: nss_mdns
+# Date Created: Jan 19 2007
+# Whom: Bruce M. Simpson <bms@FreeBSD.org>
+#
+# $FreeBSD$
+#
+
+PORTNAME= nss_mdns
+PORTVERSION= 0.9
+CATEGORIES= dns ipv6
+MASTER_SITES= http://0pointer.de/lennart/projects/nss-mdns/
+DISTNAME= nss-mdns-${PORTVERSION}
+
+MAINTAINER= bms@FreeBSD.org
+COMMENT= NSS module implementing multicast DNS name resolution
+
+USE_AUTOTOOLS= autoconf:259 automake:19 libtool:15
+USE_LDCONFIG= yes
+
+LIB_DEPENDS+= avahi-client:${PORTSDIR}/net/avahi
+
+OPTIONS= \
+ SEARCH_DOMAINS "Honour search domains in resolv.conf" Off
+
+CONFIGURE_ARGS+= \
+ --sysconfdir=/etc \
+ --localstatedir=/var \
+ --disable-static \
+ --enable-shared \
+ --enable-avahi \
+ --disable-legacy \
+ --disable-lynx
+
+#
+# libtool is used, therefore we must perform a GNU make based install,
+# followed by removal of build rubble; we must create our own .so symlinks;
+# we do this from the do-install target so as to avoid causing any
+# problems if we are later packaged.
+#
+do-install:
+ @( cd ${INSTALL_WRKSRC} && ${SETENV} ${MAKE_ENV} ${GMAKE} ${MAKE_FLAGS} ${MAKEFILE} ${MAKE_ARGS} ${INSTALL_TARGET} )
+ ( cd ${PREFIX}/lib ; ${LN} -s nss_mdns.so.1 nss_mdns.so )
+ ${RM} ${PREFIX}/lib/nss_mdns.a ${PREFIX}/lib/nss_mdns.la
+.if !defined(NOPORTDOCS)
+ ${MKDIR} ${DOCSDIR}/
+ ${INSTALL_DATA} ${INSTALL_WRKSRC}/doc/README ${DOCSDIR}
+ ${INSTALL_DATA} ${INSTALL_WRKSRC}/doc/README.html ${DOCSDIR}
+.endif
+
+PLIST_DIRS= \
+ %%PORTDOCS%%%%DOCSDIR%%
+
+# TODO: Print a message about the etc directory used for mdns.allow
+# being relative to ${PREFIX}.
+PLIST_FILES= \
+ lib/nss_mdns.so \
+ lib/nss_mdns.so.1 \
+ %%PORTDOCS%%%%DOCSDIR%%/README \
+ %%PORTDOCS%%%%DOCSDIR%%/README.html
+
+.include <bsd.port.pre.mk>
+
+.if ${OSVERSION} < 600000
+IGNORE= name-service switch support in libc.so.6 or later is required
+.endif
+
+.if defined(WITH_SEARCH_DOMAINS)
+CONFIGURE_ARGS+= --enable-search-domains
+.endif
+
+.include <bsd.port.post.mk>
diff --git a/dns/nss_mdns/distinfo b/dns/nss_mdns/distinfo
new file mode 100644
index 000000000000..300d2e555100
--- /dev/null
+++ b/dns/nss_mdns/distinfo
@@ -0,0 +1,3 @@
+MD5 (nss-mdns-0.9.tar.gz) = bc72f5b19cc6ce8cacde448236b30868
+SHA256 (nss-mdns-0.9.tar.gz) = 0bf226bb3a1716e6eb97355e08a7ffcf09aadfb91ba41ccef2ef1ba7a01719a2
+SIZE (nss-mdns-0.9.tar.gz) = 346397
diff --git a/dns/nss_mdns/files/patch-configure.ac b/dns/nss_mdns/files/patch-configure.ac
new file mode 100644
index 000000000000..17a4e0c65a72
--- /dev/null
+++ b/dns/nss_mdns/files/patch-configure.ac
@@ -0,0 +1,16 @@
+--- configure.ac.orig Mon Jan 1 18:36:21 2007
++++ configure.ac Sat Jan 20 14:34:44 2007
+@@ -83,6 +83,13 @@
+ AC_FUNC_SELECT_ARGTYPES
+ AC_CHECK_FUNCS([gethostbyaddr gethostbyname gettimeofday inet_ntoa memset select socket strcspn strdup strerror strncasecmp strcasecmp strspn])
+
++# FreeBSD has a slightly different NSS interface
++case ${host} in
++ *-freebsd*) freebsd="yes" ;;
++esac
++
++AM_CONDITIONAL([FREEBSD_NSS], [test "x$freebsd" = "xyes"])
++
+ # If using GCC specify some additional parameters
+ if test "x$GCC" = "xyes" ; then
+ CFLAGS="$CFLAGS -pipe -W -Wall -pedantic"
diff --git a/dns/nss_mdns/files/patch-src__Makefile.am b/dns/nss_mdns/files/patch-src__Makefile.am
new file mode 100644
index 000000000000..568df237353d
--- /dev/null
+++ b/dns/nss_mdns/files/patch-src__Makefile.am
@@ -0,0 +1,57 @@
+--- src/Makefile.am.orig Mon Jan 1 18:39:28 2007
++++ src/Makefile.am Sat Jan 20 14:34:44 2007
+@@ -29,13 +29,22 @@
+ # This cool debug trap works on i386/gcc only
+ AM_CFLAGS+='-DDEBUG_TRAP=__asm__("int $$3")'
+
+-lib_LTLIBRARIES= \
++AM_LDFLAGS=-avoid-version -module -export-dynamic
++
++if FREEBSD_NSS
++nss_modules_freebsd= \
++ nss_mdns.la
++else
++nss_modules_glibc= \
+ libnss_mdns.la \
+ libnss_mdns4.la \
+ libnss_mdns6.la \
+ libnss_mdns_minimal.la \
+ libnss_mdns4_minimal.la \
+ libnss_mdns6_minimal.la
++endif
++
++lib_LTLIBRARIES = $(nss_modules_glibc) $(nss_modules_freebsd)
+
+ noinst_PROGRAMS= \
+ nss-test
+@@ -81,6 +90,30 @@
+ libnss_mdns6_minimal_la_SOURCES=$(libnss_mdns_la_SOURCES)
+ libnss_mdns6_minimal_la_CFLAGS=$(libnss_mdns_la_CFLAGS) -DNSS_IPV6_ONLY=1 -DMDNS_MINIMAL
+ libnss_mdns6_minimal_la_LDFLAGS=$(libnss_mdns_la_LDFLAGS)
++
++nss_mdns_la_SOURCES=$(libnss_mdns_la_SOURCES) bsdnss.c
++nss_mdns_la_CFLAGS=$(libnss_mdns_la_CFLAGS)
++nss_mdns_la_LDFLAGS=$(AM_LDFLAGS) -shrext .so.1
++
++nss_mdns_minimal_la_SOURCES=$(nss_mdns_la_SOURCES)
++nss_mdns_minimal_la_CFLAGS=$(nss_mdns_la_CFLAGS) -DMDNS_MINIMAL
++nss_mdns_minimal_la_LDFLAGS=$(nss_mdns_la_LDFLAGS)
++
++nss_mdns4_la_SOURCES=$(nss_mdns_la_SOURCES)
++nss_mdns4_la_CFLAGS=$(nss_mdns_la_CFLAGS) -DNSS_IPV4_ONLY=1
++nss_mdns4_la_LDFLAGS=$(nss_mdns_la_LDFLAGS)
++
++nss_mdns4_minimal_la_SOURCES=$(nss_mdns_la_SOURCES)
++nss_mdns4_minimal_la_CFLAGS=$(nss_mdns_la_CFLAGS) -DNSS_IPV4_ONLY=1 -DMDNS_MINIMAL
++nss_mdns4_minimal_la_LDFLAGS=$(nss_mdns_la_LDFLAGS)
++
++nss_mdns6_la_SOURCES=$(nss_mdns_la_SOURCES)
++nss_mdns6_la_CFLAGS=$(nss_mdns_la_CFLAGS) -DNSS_IPV6_ONLY=1
++nss_mdns6_la_LDFLAGS=$(nss_mdns_la_LDFLAGS)
++
++nss_mdns6_minimal_la_SOURCES=$(nss_mdns_la_SOURCES)
++nss_mdns6_minimal_la_CFLAGS=$(nss_mdns_la_CFLAGS) -DNSS_IPV6_ONLY=1 -DMDNS_MINIMAL
++nss_mdns6_minimal_la_LDFLAGS=$(nss_mdns_la_LDFLAGS)
+
+ avahi_test_SOURCES = \
+ avahi.c avahi.h \
diff --git a/dns/nss_mdns/files/patch-src__avahi-test.c b/dns/nss_mdns/files/patch-src__avahi-test.c
new file mode 100644
index 000000000000..c828ebe5a446
--- /dev/null
+++ b/dns/nss_mdns/files/patch-src__avahi-test.c
@@ -0,0 +1,10 @@
+--- src/avahi-test.c.orig Sat Aug 6 00:51:50 2005
++++ src/avahi-test.c Sat Jan 20 14:34:44 2007
+@@ -19,6 +19,7 @@
+ USA.
+ ***/
+
++#include <sys/socket.h>
+ #include <arpa/inet.h>
+ #include <stdio.h>
+
diff --git a/dns/nss_mdns/files/patch-src__bsdnss.c b/dns/nss_mdns/files/patch-src__bsdnss.c
new file mode 100644
index 000000000000..39d80ae8a48f
--- /dev/null
+++ b/dns/nss_mdns/files/patch-src__bsdnss.c
@@ -0,0 +1,436 @@
+--- src/bsdnss.c.orig Sat Jan 20 14:34:44 2007
++++ src/bsdnss.c Sat Jan 20 14:35:23 2007
+@@ -0,0 +1,433 @@
++/* rcs tags go here when pushed upstream */
++/* Original author: Bruce M. Simpson <bms@FreeBSD.org> */
++
++/***
++ This file is part of nss-mdns.
++·
++ nss-mdns is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2 of the License,
++ or (at your option) any later version.
++·
++ nss-mdns is distributed in the hope that it will be useful, but1
++ WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++·
++ You should have received a copy of the GNU Lesser General Public License
++ along with nss-mdns; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#include <sys/param.h>
++#include <sys/types.h>
++#include <sys/socket.h>
++
++#include <stdarg.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++
++#include <errno.h>
++#include <pwd.h>
++#include <grp.h>
++#include <nss.h>
++
++#include <netinet/in.h>
++#include <netdb.h>
++
++#include "config.h"
++
++#ifdef MDNS_MINIMAL
++/*
++ * FreeBSD support prefers Avahi.
++ */
++#endif
++
++#if defined(NSS_IPV4_ONLY) || defined(NSS_IPV6_ONLY)
++/*
++ * FreeBSD's libc is always built with IPv4 support.
++ * There is no way of telling at compile time with a define if libc
++ * was built with -DINET6 or not; a configure test would be required.
++ * Therefore, distinguishing between the two makes no sense.
++ */
++#define NO_BUILD_BSD_NSS
++#endif
++
++#ifndef NO_BUILD_BSD_NSS
++
++ns_mtab *nss_module_register(const char *source, unsigned int *mtabsize,
++ nss_module_unregister_fn *unreg);
++
++extern enum nss_status _nss_mdns_gethostbyname_r (const char *name, struct hostent * result,
++ char *buffer, size_t buflen, int *errnop,
++ int *h_errnop);
++
++extern enum nss_status _nss_mdns_gethostbyname2_r (const char *name, int af, struct hostent * result,
++ char *buffer, size_t buflen, int *errnop,
++ int *h_errnop);
++extern enum nss_status _nss_mdns_gethostbyaddr_r (struct in_addr * addr, int len, int type,
++ struct hostent * result, char *buffer,
++ size_t buflen, int *errnop, int *h_errnop);
++extern enum nss_status _nss_mdns4_gethostbyname_r (const char *name, struct hostent * result,
++ char *buffer, size_t buflen, int *errnop,
++ int *h_errnop);
++
++extern enum nss_status _nss_mdns4_gethostbyname2_r (const char *name, int af, struct hostent * result,
++ char *buffer, size_t buflen, int *errnop,
++ int *h_errnop);
++extern enum nss_status _nss_mdns4_gethostbyaddr_r (struct in_addr * addr, int len, int type,
++ struct hostent * result, char *buffer,
++ size_t buflen, int *errnop, int *h_errnop);
++extern enum nss_status _nss_mdns6_gethostbyname_r (const char *name, struct hostent * result,
++ char *buffer, size_t buflen, int *errnop,
++ int *h_errnop);
++
++extern enum nss_status _nss_mdns6_gethostbyname2_r (const char *name, int af, struct hostent * result,
++ char *buffer, size_t buflen, int *errnop,
++ int *h_errnop);
++extern enum nss_status _nss_mdns6_gethostbyaddr_r (struct in_addr * addr, int len, int type,
++ struct hostent * result, char *buffer,
++ size_t buflen, int *errnop, int *h_errnop);
++
++typedef enum nss_status (*_bsd_nsstub_fn_t)(const char *, struct hostent *, char *, size_t, int *, int *);
++
++/* XXX: FreeBSD 5.x is not supported. */
++static NSS_METHOD_PROTOTYPE(__nss_bsdcompat_getaddrinfo);
++static NSS_METHOD_PROTOTYPE(__nss_bsdcompat_gethostbyaddr_r);
++static NSS_METHOD_PROTOTYPE(__nss_bsdcompat_gethostbyname2_r);
++static NSS_METHOD_PROTOTYPE(__nss_bsdcompat_ghbyaddr);
++static NSS_METHOD_PROTOTYPE(__nss_bsdcompat_ghbyname);
++
++static ns_mtab methods[] = {
++ /* database, name, method, mdata */
++ { NSDB_HOSTS, "getaddrinfo", __nss_bsdcompat_getaddrinfo, NULL },
++ { NSDB_HOSTS, "gethostbyaddr_r", __nss_bsdcompat_gethostbyaddr_r, NULL },
++ { NSDB_HOSTS, "gethostbyname2_r", __nss_bsdcompat_gethostbyname2_r, NULL },
++ { NSDB_HOSTS, "ghbyaddr", __nss_bsdcompat_ghbyaddr, NULL },
++ { NSDB_HOSTS, "ghbyname", __nss_bsdcompat_ghbyname, NULL },
++};
++
++ns_mtab *
++nss_module_register(const char *source, unsigned int *mtabsize,
++ nss_module_unregister_fn *unreg)
++{
++
++ *mtabsize = sizeof(methods)/sizeof(methods[0]);
++ *unreg = NULL;
++ return (methods);
++}
++
++/*
++ * Calling convention:
++ * ap: const char *name (optional), struct addrinfo *pai (hints, optional)
++ * retval: struct addrinfo **
++ *
++ * TODO: Map all returned hostents, not just the first match.
++ *
++ * name must always be specified by libc; pai is allocated
++ * by libc and must always be specified.
++ *
++ * We can malloc() addrinfo instances and hang them off ai->next;
++ * canonnames may also be malloc()'d.
++ * libc is responsible for mapping our ns error return to gai_strerror().
++ *
++ * libc calls us only to look up qualified hostnames. We don't need to
++ * worry about port numbers; libc will call getservbyname() and explore
++ * the appropriate maps configured in nsswitch.conf(5).
++ *
++ * _errno and _h_errno are unused by getaddrinfo(), as it is
++ * [mostly] OS independent interface implemented by Win32.
++ */
++static int
++__nss_bsdcompat_getaddrinfo(void *retval, void *mdata __unused, va_list ap)
++{
++ struct addrinfo sentinel;
++ struct addrinfo *ai;
++ char *buffer;
++ void *cbufp; /* buffer handed to libc */
++ int *h_errnop;
++ struct hostent *hp;
++ void *mbufp; /* buffer handed to mdns */
++ const char *name;
++ const struct addrinfo *pai;
++ struct sockaddr_storage *pss;
++ struct addrinfo **resultp;
++ int _errno;
++ int _h_errno;
++ size_t mbuflen = 1024;
++ enum nss_status status;
++
++ _h_errno = _errno = 0;
++ status = NSS_STATUS_UNAVAIL;
++
++ name = va_arg(ap, const char *);
++ pai = va_arg(ap, struct addrinfo *);
++ resultp = (struct addrinfo **)retval;
++
++ /* XXX: Will be used to hang off multiple matches later. */
++ memset(&sentinel, 0, sizeof(sentinel));
++
++ if (name == NULL || pai == NULL) {
++ *resultp = sentinel.ai_next;
++ return (NS_UNAVAIL);
++ }
++
++ /* XXX: review this check */
++ if (pai->ai_flags != 0) {
++ *resultp = sentinel.ai_next;
++ return (NS_UNAVAIL);
++ }
++
++ mbufp = malloc((sizeof(struct hostent) + mbuflen));
++ if (mbufp == NULL) {
++ *resultp = sentinel.ai_next;
++ return (NS_UNAVAIL);
++ }
++ hp = (struct hostent *)mbufp;
++ buffer = (char *)(hp + 1);
++
++ cbufp = malloc(sizeof(struct addrinfo) +
++ sizeof(struct sockaddr_storage));
++ if (cbufp == NULL) {
++ free(mbufp);
++ *resultp = sentinel.ai_next;
++ return (NS_UNAVAIL);
++ }
++ ai = (struct addrinfo *)cbufp;
++ pss = (struct sockaddr_storage *)(ai + 1);
++
++ /*
++ * 1. Select which function to call based on the address family.
++ * 2. Map hostent to addrinfo.
++ * 3. Hand-off buffer to libc.
++ */
++ switch (pai->ai_family) {
++ case AF_UNSPEC:
++ status = _nss_mdns_gethostbyname_r(name, hp, buffer, mbuflen,
++ &_errno, &_h_errno);
++ break;
++ case AF_INET:
++ status = _nss_mdns4_gethostbyname_r(name, hp, buffer, mbuflen,
++ &_errno, &_h_errno);
++ break;
++ case AF_INET6:
++ status = _nss_mdns6_gethostbyname_r(name, hp, buffer, mbuflen,
++ &_errno, &_h_errno);
++ break;
++ default:
++ break;
++ }
++ status = __nss_compat_result(status, _errno);
++
++ if (status == NS_SUCCESS) {
++ memset(ai, 0, sizeof(struct addrinfo));
++ memset(pss, 0, sizeof(struct sockaddr_storage));
++ ai->ai_family = hp->h_addrtype;
++ ai->ai_addrlen = hp->h_length;
++ pss->ss_len = hp->h_length;
++ pss->ss_family = hp->h_addrtype;
++ memcpy(&(((struct sockaddr *)pss)->sa_data),
++ hp->h_addr_list[0], hp->h_length);
++ ai->ai_addr = (struct sockaddr *)pss;
++ sentinel.ai_next = ai;
++ free(mbufp);
++ }
++
++ if (sentinel.ai_next == NULL) {
++ free(cbufp);
++ free(mbufp);
++ }
++
++ *resultp = sentinel.ai_next;
++ return (status);
++}
++
++/*
++ * Calling convention:
++ * ap: const u_char *uaddr, socklen_t len, int af, struct hostent *hp,
++ * char *buf, size_t buflen, int ret_errno, int *h_errnop
++ * retval: should be set to NULL or hp passed in
++ */
++static int
++__nss_bsdcompat_gethostbyaddr_r(void *retval, void *mdata __unused, va_list ap)
++{
++ void *addr;
++ char *buf;
++ int *h_errnop;
++ struct hostent *hp;
++ struct hostent **resultp;
++ int af;
++ size_t buflen;
++ int len;
++ int ret_errno;
++ enum nss_status status;
++
++ addr = va_arg(ap, void *);
++ len = va_arg(ap, socklen_t);
++ af = va_arg(ap, int);
++ hp = va_arg(ap, struct hostent *);
++ buf = va_arg(ap, char *);
++ buflen = va_arg(ap, size_t);
++ ret_errno = va_arg(ap, int);
++ h_errnop = va_arg(ap, int *);
++ resultp = (struct hostent **)retval;
++
++ *resultp = NULL;
++ status = _nss_mdns_gethostbyaddr_r(addr, len, af, hp, buf, buflen,
++ &ret_errno, h_errnop);
++
++ status = __nss_compat_result(status, *h_errnop);
++ if (status == NS_SUCCESS)
++ *resultp = hp;
++ return (status);
++}
++
++/*
++ * Calling convention:
++ * ap: const char *name, int af, struct hostent *hp, char *buf,
++ * size_t buflen, int ret_errno, int *h_errnop
++ * retval is a struct hostent **result passed in by the libc client,
++ * which is responsible for allocating storage.
++ */
++static int
++__nss_bsdcompat_gethostbyname2_r(void *retval, void *mdata __unused,
++ va_list ap)
++{
++ char *buf;
++ const char *name;
++ int *h_errnop;
++ struct hostent *hp;
++ struct hostent **resultp;
++ int af;
++ size_t buflen;
++ int ret_errno;
++ enum nss_status status;
++
++ name = va_arg(ap, char *);
++ af = va_arg(ap, int);
++ hp = va_arg(ap, struct hostent *);
++ buf = va_arg(ap, char *);
++ buflen = va_arg(ap, size_t);
++ ret_errno = va_arg(ap, int);
++ h_errnop = va_arg(ap, int *);
++ resultp = (struct hostent **)retval;
++
++ *resultp = NULL;
++ if (hp == NULL)
++ return (NS_UNAVAIL);
++
++ status = _nss_mdns_gethostbyname2_r(name, af, hp, buf, buflen,
++ &ret_errno, h_errnop);
++
++ status = __nss_compat_result(status, *h_errnop);
++ if (status == NS_SUCCESS)
++ *resultp = hp;
++ return (status);
++}
++
++/*
++ * Used by getipnodebyaddr(3).
++ *
++ * Calling convention:
++ * ap: struct in[6]_addr *src, size_t len, int af, int *errp
++ * retval: pointer to a pointer to an uninitialized struct hostent,
++ * in which should be returned a single pointer to on-heap storage.
++ *
++ * This function is responsible for allocating on-heap storage.
++ * The caller is responsible for calling freehostent() on the returned
++ * storage.
++ */
++static int
++__nss_bsdcompat_ghbyaddr(void *retval, void *mdata __unused, va_list ap)
++{
++ char *buffer;
++ void *bufp;
++ int *errp;
++ struct hostent *hp;
++ struct hostent **resultp;
++ void *src;
++ int af;
++ size_t buflen = 1024;
++ size_t len;
++ int h_errnop;
++ enum nss_status status;
++
++ src = va_arg(ap, void *);
++ len = va_arg(ap, size_t);
++ af = va_arg(ap, int);
++ errp = va_arg(ap, int *);
++ resultp = (struct hostent **)retval;
++
++ bufp = malloc((sizeof(struct hostent) + buflen));
++ if (bufp == NULL) {
++ *resultp = NULL;
++ return (NS_UNAVAIL);
++ }
++ hp = (struct hostent *)bufp;
++ buffer = (char *)(hp + 1);
++
++ status = _nss_mdns_gethostbyaddr_r(src, len, af, hp, buffer,
++ buflen, errp, &h_errnop);
++
++ status = __nss_compat_result(status, *errp);
++ if (status != NS_SUCCESS) {
++ free(bufp);
++ hp = NULL;
++ }
++ *resultp = hp;
++ return (status);
++}
++
++/*
++ * Used by getipnodebyname(3).
++ *
++ * Calling convention:
++ * ap: const char *name, int af, int *errp
++ * retval: pointer to a pointer to an uninitialized struct hostent.
++ *
++ * This function is responsible for allocating on-heap storage.
++ * The caller is responsible for calling freehostent() on the returned
++ * storage.
++ */
++static int
++__nss_bsdcompat_ghbyname(void *retval, void *mdata __unused, va_list ap)
++{
++ char *buffer;
++ void *bufp;
++ int *errp;
++ struct hostent *hp;
++ struct hostent **resultp;
++ char *name;
++ int af;
++ size_t buflen = 1024;
++ int h_errnop;
++ enum nss_status status;
++
++ name = va_arg(ap, char *);
++ af = va_arg(ap, int);
++ errp = va_arg(ap, int *);
++ resultp = (struct hostent **)retval;
++
++ bufp = malloc((sizeof(struct hostent) + buflen));
++ if (bufp == NULL) {
++ *resultp = NULL;
++ return (NS_UNAVAIL);
++ }
++ hp = (struct hostent *)bufp;
++ buffer = (char *)(hp + 1);
++
++ status = _nss_mdns_gethostbyname_r(name, hp, buffer, buflen, errp,
++ &h_errnop);
++
++ status = __nss_compat_result(status, *errp);
++ if (status != NS_SUCCESS) {
++ free(bufp);
++ hp = NULL;
++ }
++ *resultp = hp;
++ return (status);
++}
++
++#endif /* !NO_BUILD_BSD_NSS */
diff --git a/dns/nss_mdns/files/patch-src__query.c b/dns/nss_mdns/files/patch-src__query.c
new file mode 100644
index 000000000000..83fddb8e08c0
--- /dev/null
+++ b/dns/nss_mdns/files/patch-src__query.c
@@ -0,0 +1,147 @@
+--- src/query.c.orig Sun Nov 20 00:56:17 2005
++++ src/query.c Sat Jan 20 14:34:44 2007
+@@ -87,13 +87,36 @@
+ if (bind(fd, (struct sockaddr*) &sa, sizeof(sa)) < 0)
+ goto fail;
+
++#ifdef IP_PKTINFO
+ yes = 1;
+- if (setsockopt(fd, IPPROTO_IP, IP_RECVTTL, &yes, sizeof(yes)) < 0)
+- goto fail;
+-
+ if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &yes, sizeof(yes)) < 0)
+ goto fail;
++#else
++
++#ifdef IP_RECVINTERFACE
++ yes = 1;
++ if (setsockopt (fd, IPPROTO_IP, IP_RECVINTERFACE, &yes, sizeof(yes)) < 0)
++ goto fail;
++#elif defined(IP_RECVIF)
++ yes = 1;
++ if (setsockopt (fd, IPPROTO_IP, IP_RECVIF, &yes, sizeof(yes)) < 0)
++ goto fail;
++#endif
++
++#ifdef IP_RECVDSTADDR
++ yes = 1;
++ if (setsockopt (fd, IPPROTO_IP, IP_RECVDSTADDR, &yes, sizeof(yes)) < 0)
++ goto fail;
++#endif
++
++#endif /* IP_PKTINFO */
+
++#ifdef IP_RECVTTL
++ yes = 1;
++ if (setsockopt(fd, IPPROTO_IP, IP_RECVTTL, &yes, sizeof(yes)) < 0)
++ goto fail;
++#endif
++
+ if (set_cloexec(fd) < 0)
+ goto fail;
+
+@@ -113,9 +136,15 @@
+ struct sockaddr_in sa;
+ struct msghdr msg;
+ struct iovec io;
++#ifdef IP_PKTINFO
+ struct cmsghdr *cmsg;
++ uint8_t cmsg_data[CMSG_SPACE(sizeof(struct in_pktinfo))];
+ struct in_pktinfo *pkti;
+- uint8_t cmsg_data[CMSG_LEN(sizeof(struct in_pktinfo))];
++#elif defined(IP_SENDSRCADDR)
++ struct cmsghdr *cmsg;
++ uint8_t cmsg_data[CMSG_SPACE(sizeof(struct in_addr))];
++ struct in_addr *addr;
++#endif
+ int i, n;
+ struct ifreq ifreq[32];
+ struct ifconf ifconf;
+@@ -131,24 +160,43 @@
+ io.iov_base = p->data;
+ io.iov_len = p->size;
+
+- memset(cmsg_data, 0, sizeof(cmsg_data));
+- cmsg = (struct cmsghdr*) cmsg_data;
+- cmsg->cmsg_len = sizeof(cmsg_data);
+- cmsg->cmsg_level = IPPROTO_IP;
+- cmsg->cmsg_type = IP_PKTINFO;
+-
+- pkti = (struct in_pktinfo*) CMSG_DATA(cmsg);
+- pkti->ipi_ifindex = 0;
+-
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_name = &sa;
+ msg.msg_namelen = sizeof(sa);
+ msg.msg_iov = &io;
+ msg.msg_iovlen = 1;
++ msg.msg_flags = 0;
++
++#ifdef IP_PKTINFO
++ memset(cmsg_data, 0, sizeof(cmsg_data));
+ msg.msg_control = cmsg_data;
+ msg.msg_controllen = sizeof(cmsg_data);
+- msg.msg_flags = 0;
++
++ cmsg = CMSG_FIRSTHDR(&msg);
++ cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
++ cmsg->cmsg_level = IPPROTO_IP;
++ cmsg->cmsg_type = IP_PKTINFO;
++
++ pkti = (struct in_pktinfo*) CMSG_DATA(cmsg);
+
++ msg.msg_controllen = cmsg->cmsg_len;
++#elif defined(IP_SENDSRCADDR)
++ memset(cmsg_data, 0, sizeof(cmsg_data));
++ msg.msg_control = cmsg_data;
++ msg.msg_controllen = sizeof(cmsg_data);
++
++ cmsg = CMSG_FIRSTHDR(&msg);
++ cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
++ cmsg->cmsg_level = IPPROTO_IP;
++ cmsg->cmsg_type = IP_SENDSRCADDR;
++
++ addr = (struct in_addr *)CMSG_DATA(cmsg);
++
++ msg.msg_controllen = cmsg->cmsg_len;
++#elif defined(__GNUC__)
++#warning "FIXME: We need some code to set the outgoing interface/local address here if IP_PKTINFO/IP_SENDSRCADDR is not available"
++#endif
++
+ ifconf.ifc_req = ifreq;
+ ifconf.ifc_len = sizeof(ifreq);
+
+@@ -183,6 +231,7 @@
+ if (ioctl(fd, SIOCGIFINDEX, &ifreq[i]) < 0)
+ continue; /* See above why we ignore this error */
+
++#ifdef IP_PKTINFO
+ /* Only send the the packet once per interface. We assume that
+ * multiple addresses assigned to the same interface follow
+ * immediately one after the other.*/
+@@ -190,6 +239,11 @@
+ continue;
+
+ last_index = pkti->ipi_ifindex = ifreq[i].ifr_ifindex;
++#elif defined(IP_SENDSRCADDR)
++ addr->s_addr = ifsa->sin_addr.s_addr;
++#elif defined(__GNUC__)
++#warning "FIXME: We need some code to set the outgoing interface/local address here if IP_PKTINFO/IP_SENDSRCADDR is not available"
++#endif
+
+ for (;;) {
+
+@@ -241,7 +295,12 @@
+ *ret_ttl = 0;
+
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg,cmsg)) {
+- if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_TTL) {
++#ifdef SOL_IP
++ if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_TTL)
++#else
++ if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_TTL)
++#endif
++ {
+ *ret_ttl = (uint8_t) (*(uint32_t*) CMSG_DATA(cmsg));
+ break;
+ }
diff --git a/dns/nss_mdns/pkg-descr b/dns/nss_mdns/pkg-descr
new file mode 100644
index 000000000000..d89a4684eeab
--- /dev/null
+++ b/dns/nss_mdns/pkg-descr
@@ -0,0 +1,6 @@
+nss_mdns is a plugin for libc which provides host name resolution via
+Multicast DNS, building on Avahi.
+Only name resolution is provided; nss_mdns does not advertise services.
+
+Bruce
+bms@FreeBSD.org