diff -Nru glibc-2.3.3/resolv/res_hconf.c libc-mdns/resolv/res_hconf.c
--- glibc-2.3.3/resolv/res_hconf.c	2004-11-04 15:14:48.265197552 -0500
+++ libc-mdns/resolv/res_hconf.c	2004-11-04 15:01:40.000000000 -0500
@@ -59,6 +59,7 @@
 #define ENV_TRIM_ADD	"RESOLV_ADD_TRIM_DOMAINS"
 #define ENV_MULTI	"RESOLV_MULTI"
 #define ENV_REORDER	"RESOLV_REORDER"
+#define ENV_MDNS	"RESOLV_MDNS"
 
 static const char *arg_service_list (const char *, int, const char *,
 				     unsigned int);
@@ -81,7 +82,8 @@
   {"multi",		arg_bool,		HCONF_FLAG_MULTI},
   {"nospoof",		arg_bool,		HCONF_FLAG_SPOOF},
   {"spoofalert",	arg_bool,		HCONF_FLAG_SPOOFALERT},
-  {"reorder",		arg_bool,		HCONF_FLAG_REORDER}
+  {"reorder",		arg_bool,		HCONF_FLAG_REORDER},
+  {"mdns",		arg_bool,		HCONF_FLAG_MDNS}
 };
 
 /* Structure containing the state.  */
@@ -431,6 +433,9 @@
 
   memset (&_res_hconf, '\0', sizeof (_res_hconf));
 
+  /* Default for mdns is "on".  */
+  _res_hconf.flags |= HCONF_FLAG_MDNS;
+ 
   hconf_name = getenv (ENV_HOSTCONF);
   if (hconf_name == NULL)
     hconf_name = _PATH_HOSTCONF;
@@ -483,6 +488,10 @@
       arg_trimdomain_list (ENV_TRIM_OVERR, 1, envval, 0);
     }
 
+  envval = getenv (ENV_MDNS);
+  if (envval)
+    arg_bool (ENV_MDNS, 1, envval, HCONF_FLAG_MDNS);
+
   _res_hconf.initialized = 1;
 }
 
diff -Nru glibc-2.3.3/resolv/res_hconf.h libc-mdns/resolv/res_hconf.h
--- glibc-2.3.3/resolv/res_hconf.h	2001-07-06 00:55:39.000000000 -0400
+++ libc-mdns/resolv/res_hconf.h	2004-11-04 15:01:40.000000000 -0500
@@ -44,6 +44,7 @@
 #  define HCONF_FLAG_SPOOFALERT	(1 << 2) /* syslog warning of spoofed */
 #  define HCONF_FLAG_REORDER	(1 << 3) /* list best address first */
 #  define HCONF_FLAG_MULTI	(1 << 4) /* see comments for gethtbyname() */
+#  define HCONF_FLAG_MDNS	(1 << 5) /* Disable MDNS support */
 };
 extern struct hconf _res_hconf;
 
diff -Nru glibc-2.3.3/resolv/res_query.c libc-mdns/resolv/res_query.c
--- glibc-2.3.3/resolv/res_query.c	2004-11-04 15:14:48.268197096 -0500
+++ libc-mdns/resolv/res_query.c	2004-11-04 15:01:40.000000000 -0500
@@ -82,6 +82,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "res_hconf.h"
+
 /* Options.  Leave them on. */
 /* #undef DEBUG */
 
@@ -280,6 +282,13 @@
 		     *domain && !done;
 		     domain++) {
 
+		        if ((_res_hconf.flags & HCONF_FLAG_MDNS) != 0) {
+			        /* don't add "local" domain if query contains a dot */
+			        if (dots && (!__strcasecmp(*domain, "local") ||
+				             !__strcasecmp(*domain, "local.")))
+				       continue;
+			}
+
 			if (domain[0][0] == '\0' ||
 			    (domain[0][0] == '.' && domain[0][1] == '\0'))
 				root_on_list++;
diff -Nru glibc-2.3.3/resolv/res_send.c libc-mdns/resolv/res_send.c
--- glibc-2.3.3/resolv/res_send.c	2004-11-04 15:14:48.269196944 -0500
+++ libc-mdns/resolv/res_send.c	2004-11-04 15:06:31.000000000 -0500
@@ -85,6 +85,9 @@
 #include <arpa/nameser.h>
 #include <arpa/inet.h>
 #include <sys/ioctl.h>
+#if defined(_LIBC) && defined(linux)
+#include <net/if.h>
+#endif
 
 #include <errno.h>
 #include <fcntl.h>
@@ -96,6 +99,8 @@
 #include <string.h>
 #include <unistd.h>
 
+#include "res_hconf.h"
+
 #if PACKETSZ > 65536
 #define MAXPACKET       PACKETSZ
 #else
@@ -180,6 +185,9 @@
 static int		send_dg(res_state, const u_char *, int,
 				u_char **, int *, int *, int,
 				int *, int *, u_char **);
+static int		send_dg_mdns(res_state, const u_char *, int,
+				u_char **, int *, int *, struct sockaddr_in6 *,
+				int *, int *, u_char **);
 #ifdef DEBUG
 static void		Aerror(const res_state, FILE *, const char *, int,
 			       const struct sockaddr *);
@@ -332,6 +340,35 @@
 		 u_char *ans, int anssiz, u_char **ansp)
 {
 	int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
+	int usemdns;
+	HEADER *qhp = (HEADER *) buf;
+
+	usemdns = 0;
+	if ((_res_hconf.flags & HCONF_FLAG_MDNS) != 0 &&
+	    qhp->qr == 0 && qhp->opcode == QUERY && qhp->qdcount == htons(1)) {
+		/* got one simple query */
+		const u_char *bp, *be;
+		be = buf + buflen;
+		for (bp = buf + NS_HFIXEDSZ; bp < be; )
+			if ((*bp & NS_CMPRSFLGS) != 0)
+				break;
+			else if (*bp) {
+				if (*bp == 5 && !strncasecmp(bp, "\005local\000", 7)) {
+					usemdns = 1;
+					break;
+				}
+				if (*bp == 3 && !strncasecmp(bp, "\003254\003169\007in-addr\004arpa\000", 22)) {
+					usemdns = 1;
+					break;
+				}
+				if (*bp == 1 && !strncasecmp(bp, "\0010\0018\001e\001f\003ip6\004arpa\000", 18)) {
+					usemdns = 2;
+					break;
+				}
+				bp += *bp + 1;
+			} else
+				break;
+	}
 
 	if (statp->nscount == 0) {
 		__set_errno (ESRCH);
@@ -465,10 +502,27 @@
 	 * Send request, RETRY times, or until successful.
 	 */
 	for (try = 0; try < statp->retry; try++) {
-	    for (ns = 0; ns < MAXNS; ns++)
+	    for (ns = 0; ns < (usemdns ? 1 : MAXNS); ns++)
 	    {
 		struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns];
 
+		if (usemdns == 1) {
+			static struct sockaddr_in  mdns4;
+			mdns4.sin_family = AF_INET;
+			mdns4.sin_port = htons(5353);
+			mdns4.sin_addr.s_addr = htonl(0xe00000fb);
+			nsap = (struct sockaddr_in6 *)&mdns4;
+		}
+		if (usemdns == 2) {
+			static struct sockaddr_in6 mdns6;
+			mdns6.sin6_family = AF_INET6;
+			mdns6.sin6_port = htons(5353);
+			mdns6.sin6_addr.s6_addr32[0] = htonl(0xff020000);
+			mdns6.sin6_addr.s6_addr32[3] = htonl(0x000000fb);
+			nsap = &mdns6;
+		}
+
+
 		if (nsap == NULL)
 			goto next_ns;
  same_ns:
@@ -525,8 +579,11 @@
 			resplen = n;
 		} else {
 			/* Use datagrams. */
-			n = send_dg(statp, buf, buflen, &ans, &anssiz, &terrno,
-				    ns, &v_circuit, &gotsomewhere, ansp);
+			if (usemdns)
+				n = send_dg_mdns(statp, buf, buflen, &ans, &anssiz, &terrno, nsap, &v_circuit, &gotsomewhere, ansp);
+			else
+				n = send_dg(statp, buf, buflen, &ans, &anssiz, &terrno,
+					    ns, &v_circuit, &gotsomewhere, ansp);
 			if (n < 0)
 				return (-1);
 			if (n == 0)
@@ -593,8 +650,15 @@
 	if (!v_circuit) {
 		if (!gotsomewhere)
 			__set_errno (ECONNREFUSED);	/* no nameservers found */
-		else
+		else if (!usemdns) {
 			__set_errno (ETIMEDOUT);	/* no answer obtained */
+		} else {
+		    /* treat timeout as host not found */
+		    HEADER *anhp = (HEADER *) ans;
+		    memset(ans, 0, HFIXEDSZ);
+		    anhp->rcode = NXDOMAIN;
+		    return HFIXEDSZ;
+		}
 	} else
 		__set_errno (terrno);
 	return (-1);
@@ -1035,6 +1099,255 @@
 	}
 }
 
+static int
+send_dg_mdns(res_state statp,
+	const u_char *buf, int buflen, u_char **ansp, int *anssizp,
+	int *terrno, struct sockaddr_in6 *nsap, int *v_circuit, int *gotsomewhere, u_char **anscp)
+{
+	const HEADER *hp = (HEADER *) buf;
+	u_char *ans = *ansp;
+	int anssiz = *anssizp;
+	HEADER *anhp = (HEADER *) ans;
+	struct timespec now, timeout, finish;
+	struct pollfd pfd[32];
+        int ptimeout;
+	int fromlen, resplen, seconds, n, s;
+	int on = 1;
+	struct msghdr mhdr;
+        struct iovec iov;
+	u_char cmsgbuf[CMSG_SPACE(sizeof(int))];
+	struct cmsghdr *cmsg;
+	int ttl;
+	struct ifconf ifconf;
+	struct ifreq ifreq[64];
+	int ifreqn;
+	int i, j;
+	int ifidx[32], ifidxn;
+	struct ip_mreqn mreqn;
+
+	s = socket(nsap->sin6_family == AF_INET ? PF_INET : PF_INET6, SOCK_DGRAM, 0);
+	if (s < 0) {
+		*terrno = errno;
+		Perror(statp, stderr, "socket(dg)", errno);
+		return (-1);
+	}
+	ifconf.ifc_len = sizeof(ifreq);
+	ifconf.ifc_req = ifreq;
+	ifidxn = 0;
+	if (ioctl(s, SIOCGIFCONF, &ifconf) == 0) {
+		ifreqn = ifconf.ifc_len / sizeof(*ifreq);
+		for (i = 0 ; i < ifreqn; i++) {
+			if (ioctl(s, SIOCGIFFLAGS, ifreq + i))
+				continue;
+			if (!(ifreq[i].ifr_flags & IFF_MULTICAST))
+				continue;
+			if (ioctl(s, SIOCGIFINDEX, ifreq + i))
+				continue;
+			for (j = 0; j < ifidxn; j++)
+				if (ifidx[j] == ifreq[i].ifr_ifindex)
+					break;
+			if (j < ifidxn)
+			    continue;
+			ifidx[ifidxn++] = ifreq[i].ifr_ifindex;
+			if (ifidxn == sizeof(ifidx)/sizeof(*ifidx))
+				break;
+		}
+	}
+ 	j = 0;
+	for (i = 0; i < (ifidxn ? ifidxn : 1); i++) {
+		if (i) {
+			s = socket(nsap->sin6_family == AF_INET ? PF_INET : PF_INET6, SOCK_DGRAM, 0);
+			if (!s)
+				continue;
+		}
+		if (setsockopt(s, SOL_IP, IP_RECVTTL, &on, sizeof(on))) {
+			*terrno = errno;
+			Perror(statp, stderr, "IP_RECVTTL(dg)", errno);
+			close(s);
+			continue;
+		}
+		if (ifidxn) {
+			memset(&mreqn, 0, sizeof(mreqn));
+			mreqn.imr_ifindex = ifidx[i];
+			if (setsockopt(s, SOL_IP, IP_MULTICAST_IF, &mreqn, sizeof(mreqn))) {
+				*terrno = errno;
+				Perror(statp, stderr, "IP_MULTICAST_IF", errno);
+				close(s);
+				continue;
+			}
+		}
+		if (sendto(s, (char*)buf, buflen, 0,
+			   (struct sockaddr *)nsap, sizeof *nsap) != buflen) {
+			Aerror(statp, stderr, "sendto", errno, *(struct sockaddr_in *)nsap);
+			close(s);
+			continue;
+		}
+		pfd[j].fd = s;
+		pfd[j].events = POLLIN;
+		j++;
+	}
+	/*
+	 * Wait for reply.
+	 */
+	seconds = statp->retrans;
+	if (seconds <= 0)
+		seconds = 1;
+	evNowTime(&now);
+	evConsTime(&timeout, seconds, 0);
+	evAddTime(&finish, &now, &timeout);
+ wait:
+	if (j == 0) {
+		return (0);
+	}
+
+        /* Convert struct timespec in milliseconds.  */
+	ptimeout = timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000;
+	n = __poll (pfd, j, ptimeout);
+	if (n == 0) {
+		Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n"));
+		*gotsomewhere = 1;
+		for (i = 0; i < j; i++)
+			close(pfd[i].fd);
+		return (0);
+	}
+	if (n < 0) {
+		if (errno == EINTR) {
+			evNowTime(&now);
+			if (evCmpTime(finish, now) > 0) {
+				evSubTime(&timeout, &finish, &now);
+				goto wait;
+			}
+		}
+		Perror(statp, stderr, "select", errno);
+		for (i = 0; i < j; i++)
+			close(pfd[i].fd);
+		res_nclose(statp);
+		return (0);
+	}
+	for (i = 0; i < j - 1; i++)
+		if (pfd[j].revents == POLLIN)
+			break;
+	s = pfd[i].fd;
+	__set_errno (0);
+	fromlen = sizeof(struct sockaddr_in6);
+	if (anssiz < MAXPACKET
+	    && anscp
+	    && (ioctl (s, FIONREAD, &resplen) < 0
+		|| anssiz < resplen)) {
+		ans = malloc (MAXPACKET);
+		if (ans == NULL)
+			ans = *ansp;
+		else {
+			anssiz = MAXPACKET;
+			*anssizp = MAXPACKET;
+			*ansp = ans;
+			*anscp = ans;
+			anhp = (HEADER *) ans;
+		}
+	}
+	iov.iov_base = ans;
+	iov.iov_len = anssiz;
+	mhdr.msg_name = 0;
+	mhdr.msg_namelen = 0;
+	mhdr.msg_iov = &iov;
+	mhdr.msg_iovlen = 1;
+	mhdr.msg_control = cmsgbuf;
+	mhdr.msg_controllen = sizeof(cmsgbuf);
+	mhdr.msg_flags = 0;
+	resplen = recvmsg(s, &mhdr, 0);
+	if (resplen <= 0) {
+		if (errno == EAGAIN)
+			goto wait;
+		Perror(statp, stderr, "recvfrom", errno);
+wait2:
+		close(s);
+		if (i < j)
+			memmove(pfd + i, pfd + i + 1, sizeof(*pfd) * (j - i));
+		j--;
+		goto wait;
+	}
+	cmsg = CMSG_FIRSTHDR(&mhdr);
+	for (cmsg = CMSG_FIRSTHDR(&mhdr); cmsg; CMSG_NXTHDR(&mhdr, cmsg))
+		if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_TTL)
+			break;
+	if (!cmsg) {
+		Dprint(statp->options & RES_DEBUG,
+		       (stdout, ";; no TTL found\n"));
+		goto wait2;
+	}
+	ttl = *(int *)CMSG_DATA(cmsg);
+	if (ttl != 255) {
+		Dprint(statp->options & RES_DEBUG,
+		       (stdout, ";; answer with bad TTL: %d \n", ttl));
+		goto wait;
+	}
+	*gotsomewhere = 1;
+	if (resplen < HFIXEDSZ) {
+		/*
+		 * Undersized message.
+		 */
+		Dprint(statp->options & RES_DEBUG,
+		       (stdout, ";; undersized: %d\n",
+			resplen));
+		*terrno = EMSGSIZE;
+		goto wait;
+	}
+	if (hp->id != anhp->id) {
+		/*
+		 * response from old query, ignore it.
+		 * XXX - potential security hazard could
+		 *	 be detected here.
+		 */
+		DprintQ((statp->options & RES_DEBUG) ||
+			(statp->pfcode & RES_PRF_REPLY),
+			(stdout, ";; old answer:\n"),
+			ans, (resplen > anssiz) ? anssiz : resplen);
+		goto wait;
+	}
+	if (!(statp->options & RES_INSECURE2) &&
+	    !res_queriesmatch(buf, buf + buflen,
+			      ans, ans + anssiz)) {
+		/*
+		 * response contains wrong query? ignore it.
+		 * XXX - potential security hazard could
+		 *	 be detected here.
+		 */
+		DprintQ((statp->options & RES_DEBUG) ||
+			(statp->pfcode & RES_PRF_REPLY),
+			(stdout, ";; wrong query name:\n"),
+			ans, (resplen > anssiz) ? anssiz : resplen);
+		goto wait;
+	}
+	if (anhp->rcode == SERVFAIL ||
+	    anhp->rcode == NOTIMP ||
+	    anhp->rcode == REFUSED) {
+		DprintQ(statp->options & RES_DEBUG,
+			(stdout, "server rejected query:\n"),
+			ans, (resplen > anssiz) ? anssiz : resplen);
+		goto wait;
+	}
+	for (i = 0; i < j; i++)
+		close(pfd[i].fd);
+#if 0
+	if (!(statp->options & RES_IGNTC) && anhp->tc) {
+		/*
+		 * To get the rest of answer,
+		 * use TCP with same server.
+		 */
+		Dprint(statp->options & RES_DEBUG,
+		       (stdout, ";; truncated answer\n"));
+		*v_circuit = 1;
+		res_nclose(statp);
+		return (1);
+	}
+#endif
+	/*
+	 * All is well, or the error is fatal.  Signal that the
+	 * next nameserver ought not be tried.
+	 */
+	return (resplen);
+}
+
 #ifdef DEBUG
 static void
 Aerror(const res_state statp, FILE *file, const char *string, int error,