version 320.10.80
diff --git a/Clients/dns-sd.c b/Clients/dns-sd.c
index bf6cc10..c73c221 100644
--- a/Clients/dns-sd.c
+++ b/Clients/dns-sd.c
@@ -170,7 +170,11 @@
 	#include <arpa/inet.h>		// For inet_addr()
 	#include <net/if.h>			// For if_nametoindex()
 	static const char kFilePathSep = '/';
-	#define SA_LEN(addr) ((addr)->sa_len)
+// #ifndef NOT_HAVE_SA_LEN
+// 	#define SA_LEN(addr) ((addr)->sa_len)
+// #else
+    #define SA_LEN(addr) (((addr)->sa_family == AF_INET6)? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))
+// #endif
 #endif
 
 #if (TEST_NEW_CLIENTSTUB && !defined(__APPLE_API_PRIVATE))
diff --git a/Makefile b/Makefile
index 75a0f57..7233229 100644
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@
 
 include /Developer/Makefiles/pb_makefiles/platform.make
 
-MVERS = "mDNSResponder-320.10"
+MVERS = "mDNSResponder-320.10.80"
 
 DDNSWRITECONFIG = "$(DSTROOT)/Library/Application Support/Bonjour/ddnswriteconfig"
 
diff --git a/mDNSPosix/Identify.c b/mDNSPosix/Identify.c
index 2ca9fc6..66f7410 100644
--- a/mDNSPosix/Identify.c
+++ b/mDNSPosix/Identify.c
@@ -335,8 +335,13 @@
 			if (StopNow == 2) break;
 			}
 #endif
-		else
+		else {
+			if (strlen(arg) >= sizeof(hostname)) {
+				fprintf(stderr, "hostname must be < %d characters\n", (int)sizeof(hostname));
+				goto usage;
+			}
 			strcpy(hostname, arg);
+		}
 	
 		// Now we have the host name; get its A, AAAA, and HINFO
 		if (hostname[0]) DoQuery(&q, hostname, kDNSQType_ANY, &target, InfoCallback);
@@ -368,6 +373,6 @@
 	return(0);
 
 usage:
-	fprintf(stderr, "%s <dot-local hostname> or <IPv4 address> or <IPv6 address> ...\n", progname);
+	fprintf(stderr, "Usage: %s <dot-local hostname> or <IPv4 address> or <IPv6 address> ...\n", progname);
 	return(-1);
 	}
diff --git a/mDNSPosix/Makefile b/mDNSPosix/Makefile
index 6ca9013..55d7f8d 100755
--- a/mDNSPosix/Makefile
+++ b/mDNSPosix/Makefile
@@ -99,12 +99,18 @@
 endif
 else
 
-ifeq ($(os),linux)
-CFLAGS_OS = -DNOT_HAVE_SA_LEN -DUSES_NETLINK -DHAVE_LINUX -DTARGET_OS_LINUX
+# any target that contains the string "linux"
+ifeq ($(findstring linux,$(os)),linux)
+CFLAGS_OS = -D_GNU_SOURCE -DHAVE_IPV6 -DNOT_HAVE_SA_LEN -DUSES_NETLINK -DHAVE_LINUX -DTARGET_OS_LINUX -fno-strict-aliasing
+LD = gcc -shared
 FLEXFLAGS_OS = -l
 JAVACFLAGS_OS += -I$(JDK)/include/linux
+
+# uClibc does not support Name Service Switch
+ifneq ($(os),linux-uclibc)
 OPTIONALTARG = nss_mdns
 OPTINSTALL   = InstalledNSS
+endif
 else
 
 ifeq ($(os),netbsd)
@@ -114,11 +120,9 @@
 
 ifeq ($(os),freebsd)
 # If not already defined, set LOCALBASE to /usr/local
-# FreeBSD requires the startup script to end in ".sh"
 LOCALBASE?=/usr/local
 INSTBASE=$(LOCALBASE)
-STARTUPSCRIPTNAME=mdns.sh
-CFLAGS_OS =
+CFLAGS_OS = -DHAVE_IPV6
 # FreeBSD 4 requires threaded code to be compiled and linked using the "-pthread" option,
 # and requires that the "-lpthread" link option NOT be used
 # This appies only to FreeBSD -- "man cc" on FreeBSD says:
@@ -140,7 +144,8 @@
 # We have to define __MAC_OS_X_VERSION_MIN_REQUIRED=__MAC_OS_X_VERSION_10_4 or on Leopard
 # we get build failures: ‘daemon’ is deprecated (declared at /usr/include/stdlib.h:283)
 CFLAGS_OS = -DHAVE_IPV6 -no-cpp-precomp -Werror -Wdeclaration-after-statement \
-	-D__MAC_OS_X_VERSION_MIN_REQUIRED=__MAC_OS_X_VERSION_10_4 #-Wunreachable-code
+	-D__MAC_OS_X_VERSION_MIN_REQUIRED=__MAC_OS_X_VERSION_10_4 \
+	-D__APPLE_USE_RFC_2292 #-Wunreachable-code
 CC = gcc
 LD = $(CC) -dynamiclib
 LINKOPTS = -lSystem
@@ -150,7 +155,7 @@
 else
 
 $(error ERROR: Must specify target OS on command-line, e.g. "make os=x [target]".\
-Supported operating systems include: x, linux, netbsd, freebsd, openbsd, solaris) 
+Supported operating systems include: x, linux, linux-uclibc, netbsd, freebsd, openbsd, solaris) 
 endif
 endif
 endif
diff --git a/mDNSPosix/ReadMe.txt b/mDNSPosix/ReadMe.txt
index d4bff85..c2f5641 100755
--- a/mDNSPosix/ReadMe.txt
+++ b/mDNSPosix/ReadMe.txt
@@ -297,6 +297,16 @@
 
 6 Aug 2002
 
+Impact: A local network user may cause a denial of the Bonjour service
+Description: An error handling issue exists in the Bonjour Namespace
+Provider. A local network user may send a maliciously crafted multicast
+DNS packet leading to an unexpected termination of the Bonjour service.
+This update addresses the issue by performing additional validation of
+multicast DNS packets. This issue does not affect systems running Mac OS
+X or Windows.
+CVE-ID
+CVE-2011-0220 : JaeSeung Song of the Department of Computing at Imperial
+College London
 
 To Do List
 ----------
diff --git a/mDNSPosix/Responder.c b/mDNSPosix/Responder.c
index 21109b8..38639ea 100755
--- a/mDNSPosix/Responder.c
+++ b/mDNSPosix/Responder.c
@@ -453,11 +453,12 @@
 
         if (gMDNSPlatformPosixVerboseLevel > 0) {
             fprintf(stderr, 
-                    "%s: Registered service %d, name '%s', type '%s', port %ld\n", 
+                    "%s: Registered service %d, name \"%s\", type \"%s\", domain \"%s\",  port %ld\n", 
                     gProgramName, 
                     thisServ->serviceID, 
                     richTextName,
                     serviceType,
+                    serviceDomain,
                     portNumber);
         }
     } else {
@@ -468,108 +469,143 @@
     return status;
 }
 
-static mDNSBool ReadALine(char *buf, size_t bufSize, FILE *fp)
-// Read a line, skipping over any blank lines or lines starting with '#'
+static mDNSBool ReadALine(char *buf, size_t bufSize, FILE *fp, mDNSBool skipBlankLines)
 {
-	mDNSBool good, skip;
+	size_t	len;
+	mDNSBool readNextLine;
+
 	do {
-		good = (fgets(buf, bufSize, fp) != NULL);
-		skip = (good && (buf[0] == '#'));
-	} while (good && skip);
-	if (good)
-	{
-		int		len = strlen( buf);
-		if ( buf[len - 1] == '\r' || buf[len - 1] == '\n')
-			buf[len - 1] = '\0';
-	}
-    return good;
+		readNextLine = mDNSfalse;
+
+		if (fgets(buf, bufSize, fp) == NULL)
+			return mDNSfalse;	// encountered EOF or an error condition
+
+		// These first characters indicate a blank line.
+		if (buf[0] == ' ' || buf[0] == '\t' || buf[0] == '\r' || buf[0] == '\n') {
+			if (!skipBlankLines)
+				return mDNSfalse;
+			readNextLine = mDNStrue;
+		}
+		// always skip comment lines
+		if (buf[0] == '#')
+			readNextLine = mDNStrue;
+
+	} while (readNextLine);
+
+	len = strlen( buf);
+	if ( buf[len - 1] == '\r' || buf[len - 1] == '\n')
+		buf[len - 1] = '\0';
+
+    return mDNStrue;
 }
 
 static mStatus RegisterServicesInFile(const char *filePath)
 {
     mStatus     status = mStatus_NoError;
     FILE *      fp = fopen(filePath, "r");
-    int         junk;
     
     if (fp == NULL) {
-        status = mStatus_UnknownErr;
+        return mStatus_UnknownErr;
     }
-    if (status == mStatus_NoError) {
-        mDNSBool good = mDNStrue;
-        do {
-			int         ch;
-			char name[256];
-			char type[256];
-			const char *dom = kDefaultServiceDomain;
-			char rawText[1024];
-			mDNSu8  text[sizeof(RDataBody)];
-			unsigned int textLen = 0;
-			char port[256];
 
-            // Skip over any blank lines.
-            do ch = fgetc(fp); while ( ch == '\n' || ch == '\r' );
-            if (ch != EOF) good = (ungetc(ch, fp) == ch);
-            
-            // Read three lines, check them for validity, and register the service.
-			good = ReadALine(name, sizeof(name), fp);               
-			if (good) {
-				good = ReadALine(type, sizeof(type), fp);
-			}
-			if (good) {
-				char *p = type;
-				while (*p && *p != ' ') p++;
-				if (*p) {
-					*p = 0;
-					dom = p+1;
-				}
-			}
-			if (good) {
-				good = ReadALine(port, sizeof(port), fp);
-			}
-			if (good) {
-				good =     CheckThatRichTextNameIsUsable(name, mDNSfalse)
-						&& CheckThatServiceTypeIsUsable(type, mDNSfalse)
-						&& CheckThatPortNumberIsUsable(atol(port), mDNSfalse);
-			}
-			if (good) {
-				while (1) {
-					int len;
-					if (!ReadALine(rawText, sizeof(rawText), fp)) break;
-					len = strlen(rawText);
-					if (len <= 255)
-						{
-						unsigned int newlen = textLen + 1 + len;
-						if (len == 0 || newlen >= sizeof(text)) break;
-						text[textLen] = len;
-						mDNSPlatformMemCopy(text + textLen + 1, rawText, len);
-						textLen = newlen;
-						}
-					else
-						fprintf(stderr, "%s: TXT attribute too long for name = %s, type = %s, port = %s\n", 
-							gProgramName, name, type, port);
-				}
-			}
-			if (good) {
-				status = RegisterOneService(name, type, dom, text, textLen, atol(port));
-				if (status != mStatus_NoError) {
-					fprintf(stderr, "%s: Failed to register service, name = %s, type = %s, port = %s\n", 
-							gProgramName, name, type, port);
-					status = mStatus_NoError;       // keep reading
-				}
-			}
-        } while (good && !feof(fp));
+	if (gMDNSPlatformPosixVerboseLevel > 1)
+		fprintf(stderr, "Parsing %s for services\n", filePath);
 
-        if ( ! good ) {
-            fprintf(stderr, "%s: Error reading service file %s\n", gProgramName, filePath);
-        }
-    }
+	do {
+		char nameBuf[256];
+		char * name = nameBuf; 
+		char type[256];
+		const char *dom = kDefaultServiceDomain;
+		char rawText[1024];
+		mDNSu8  text[sizeof(RDataBody)];
+		unsigned int textLen = 0;
+		char port[256];
+		char *p;
+
+		// Read the service name, type, port, and optional text record fields.
+		// Skip blank lines while looking for the next service name.
+		if (! ReadALine(name, sizeof(nameBuf), fp, mDNStrue))
+			break;
+
+		// Special case that allows service name to begin with a '#'
+		// character by escaping it with a '\' to distiguish it from
+		// a comment line.  Remove the leading '\' here before
+		// registering the service.
+		if (name[0] == '\\' && name[1] == '#')
+			name++;
+
+		if (gMDNSPlatformPosixVerboseLevel > 1)
+			fprintf(stderr, "Service name: \"%s\"\n", name);
+
+		// Don't skip blank lines in calls to ReadAline() after finding the
+		// service name since the next blank line indicates the end
+		// of this service record.
+		if (! ReadALine(type, sizeof(type), fp, mDNSfalse))
+			break;
+
+		// see if a domain name is specified
+		p = type;
+		while (*p && *p != ' ' && *p != '\t') p++;
+		if (*p) {
+			*p = 0;	// NULL terminate the <type>.<protocol> string
+			// skip any leading whitespace before domain name
+			p++;
+			while (*p && (*p == ' ' || *p == '\t')) p++;
+			if (*p)
+				dom = p;
+		}
+		if (gMDNSPlatformPosixVerboseLevel > 1) {
+			fprintf(stderr, "Service type: \"%s\"\n", type);
+			fprintf(stderr, "Service domain: \"%s\"\n", dom);
+		}
+
+		if (! ReadALine(port, sizeof(port), fp, mDNSfalse))
+			break;
+		if (gMDNSPlatformPosixVerboseLevel > 1)
+			fprintf(stderr, "Service port: %s\n", port);
+
+		if (   ! CheckThatRichTextNameIsUsable(name, mDNStrue)
+			|| ! CheckThatServiceTypeIsUsable(type, mDNStrue)
+			|| ! CheckThatPortNumberIsUsable(atol(port), mDNStrue))
+			break;
+
+		// read the TXT record fields
+		while (1) {
+			int len;
+			if (!ReadALine(rawText, sizeof(rawText), fp, mDNSfalse)) break;
+			if (gMDNSPlatformPosixVerboseLevel > 1)
+				fprintf(stderr, "Text string: \"%s\"\n", rawText);
+			len = strlen(rawText);
+			if (len <= 255)
+				{
+				unsigned int newlen = textLen + 1 + len;
+				if (len == 0 || newlen >= sizeof(text)) break;
+				text[textLen] = len;
+				mDNSPlatformMemCopy(text + textLen + 1, rawText, len);
+				textLen = newlen;
+				}
+			else
+				fprintf(stderr, "%s: TXT attribute too long for name = %s, type = %s, port = %s\n", 
+					gProgramName, name, type, port);
+		}
+
+		status = RegisterOneService(name, type, dom, text, textLen, atol(port));
+		if (status != mStatus_NoError) {
+			// print error, but try to read and register other services in the file
+			fprintf(stderr, "%s: Failed to register service, name \"%s\", type \"%s\", domain \"%s\", port %s\n", 
+					gProgramName, name, type, dom, port);
+		}
+
+	} while (!feof(fp));
+
+	if (!feof(fp)) {
+		fprintf(stderr, "%s: Error reading service file %s\n", gProgramName, filePath);
+		status = mStatus_UnknownErr;
+	}
     
-    if (fp != NULL) {
-        junk = fclose(fp);
-        assert(junk == 0);
-    }
+	assert(0 == fclose(fp));
     
-    return status;
+	return status;
 }
 
 static mStatus RegisterOurServices(void)
diff --git a/mDNSPosix/Services.txt b/mDNSPosix/Services.txt
index f5870bb..f8d6978 100755
--- a/mDNSPosix/Services.txt
+++ b/mDNSPosix/Services.txt
@@ -1,15 +1,36 @@
-Tweedlebug
+#
+# Example services file parsed by mDNSResponderPosix.
+# 
+# Lines beginning with '#' are comments/ignored.
+# Blank lines indicate the end of a service record specification.
+# The first character of the service name can be a '#' if you escape it with 
+# backslash to distinguish if from a comment line.
+# ie, "\#serviceName" will be registered as "#serviceName".
+# Note that any line beginning with white space is considered a blank line.
+#
+# The record format is:
+# 
+# <service name>
+# <type>.<protocol> <optional domain>
+# <port number>
+# <zero or more strings for the text record, one string per line>
+#
+# <One or more blank lines between records>
+# 
+# Examples shown below.
+
+serviceName1
 _afpovertcp._tcp.
 548
 name=val1
 
-Tweedlebug2
+serviceName2
 _afpovertcp._tcp. local.
 548
 name=val2
 name2=anotherattribute
 
-Tweedlebug3
+serviceName3
 _afpovertcp._tcp.
 548
 name=val3
diff --git a/mDNSPosix/mDNSPosix.c b/mDNSPosix/mDNSPosix.c
index 3db5266..74a2161 100755
--- a/mDNSPosix/mDNSPosix.c
+++ b/mDNSPosix/mDNSPosix.c
@@ -159,8 +159,12 @@
 	assert(msg != NULL);
 	assert(end != NULL);
 	assert((((char *) end) - ((char *) msg)) > 0);
-	assert(dstPort.NotAnInteger != 0);
 
+	if (dstPort.NotAnInteger == 0) 
+		{
+		LogMsg("mDNSPlatformSendUDP: Invalid argument -dstPort is set to 0");
+		return PosixErrorToStatus(EINVAL);
+		}
 	if (dst->type == mDNSAddrType_IPv4)
 		{
 		struct sockaddr_in *sin = (struct sockaddr_in*)&to;
@@ -714,7 +718,7 @@
 	#if defined(IPV6_PKTINFO)
 		if (err == 0)
 			{
-				err = setsockopt(*sktPtr, IPPROTO_IPV6, IPV6_PKTINFO, &kOn, sizeof(kOn));
+				err = setsockopt(*sktPtr, IPPROTO_IPV6, IPV6_2292_PKTINFO, &kOn, sizeof(kOn));
 				if (err < 0) { err = errno; perror("setsockopt - IPV6_PKTINFO"); }
 			}
 	#else
@@ -723,7 +727,7 @@
 	#if defined(IPV6_HOPLIMIT)
 		if (err == 0)
 			{
-				err = setsockopt(*sktPtr, IPPROTO_IPV6, IPV6_HOPLIMIT, &kOn, sizeof(kOn));
+				err = setsockopt(*sktPtr, IPPROTO_IPV6, IPV6_2292_HOPLIMIT, &kOn, sizeof(kOn));
 				if (err < 0) { err = errno; perror("setsockopt - IPV6_HOPLIMIT"); }
 			}
 	#endif
@@ -841,6 +845,7 @@
 		// Set up the fields required by the mDNS core.
 		SockAddrTomDNSAddr(intfAddr, &intf->coreIntf.ip, NULL);
 		SockAddrTomDNSAddr(intfMask, &intf->coreIntf.mask, NULL);
+
 		//LogMsg("SetupOneInterface: %#a %#a",  &intf->coreIntf.ip,  &intf->coreIntf.mask);
 		strncpy(intf->coreIntf.ifname, intfName, sizeof(intf->coreIntf.ifname));
 		intf->coreIntf.ifname[sizeof(intf->coreIntf.ifname)-1] = 0;
diff --git a/mDNSPosix/mDNSUNP.c b/mDNSPosix/mDNSUNP.c
index e8fc649..8027676 100755
--- a/mDNSPosix/mDNSUNP.c
+++ b/mDNSPosix/mDNSUNP.c
@@ -82,7 +82,7 @@
 /* Gets IPv6 interface information from the /proc filesystem in linux*/
 struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
 	{
-	struct ifi_info *ifi, *ifihead, **ifipnext;
+		struct ifi_info *ifi, *ifihead, **ifipnext, *ifipold, **ifiptr;
 	FILE *fp;
 	char addr[8][5];
 	int flags, myflags, index, plen, scope;
@@ -92,6 +92,8 @@
 	struct sockaddr_in6 *sin6;
 	struct in6_addr *addrptr;
 	int err;
+	int sockfd = -1;
+	struct ifreq ifr;
 
 	res0=NULL;
 	ifihead = NULL;
@@ -99,6 +101,10 @@
 	lastname[0] = 0;
 
 	if ((fp = fopen(PROC_IFINET6_PATH, "r")) != NULL) {
+		sockfd = socket(AF_INET6, SOCK_DGRAM, 0);
+		if (sockfd < 0) {
+			goto gotError;
+		}
 		while (fscanf(fp,
 					  "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %8s\n",
 					  addr[0],addr[1],addr[2],addr[3],
@@ -115,8 +121,10 @@
 			ifi = (struct ifi_info*)calloc(1, sizeof(struct ifi_info));
 			if (ifi == NULL) {
 				goto gotError;
-				}
-
+			}
+			
+			ifipold   = *ifipnext;       /* need this later */
+			ifiptr    = ifipnext;
 			*ifipnext = ifi;            /* prev points to this new one */
 			ifipnext = &ifi->ifi_next;  /* pointer to next one goes here */
 
@@ -161,9 +169,25 @@
 			/* Add interface index */
 			ifi->ifi_index = index;
 
-			/* If interface is in /proc then it is up*/
-			ifi->ifi_flags = IFF_UP;
-
+			/* Add interface flags*/
+			memcpy(ifr.ifr_name, ifname, IFNAMSIZ);
+			if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
+				if (errno == EADDRNOTAVAIL) {
+					/* 
+					 * If the main interface is configured with no IP address but 
+					 * an alias interface exists with an IP address, you get 
+					 * EADDRNOTAVAIL for the main interface 
+					 */
+					free(ifi->ifi_addr);
+					free(ifi);
+					ifipnext  = ifiptr; 
+					*ifipnext = ifipold;
+					continue;
+				} else {
+					goto gotError;
+				}
+			}
+			ifi->ifi_flags = ifr.ifr_flags;
 			freeaddrinfo(res0);
 			res0=NULL;
 			}
@@ -180,6 +204,9 @@
 		res0=NULL;
 		}
 	done:
+	if (sockfd != -1) {
+		assert(close(sockfd) == 0);
+	}
 	return(ifihead);    /* pointer to first structure in linked list */
 	}
 #endif // defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
@@ -187,7 +214,7 @@
 struct ifi_info *get_ifi_info(int family, int doaliases)
 {
     int                 junk;
-    struct ifi_info     *ifi, *ifihead, **ifipnext;
+    struct ifi_info     *ifi, *ifihead, **ifipnext, *ifipold, **ifiptr;
     int                 sockfd, sockf6, len, lastlen, flags, myflags;
 #ifdef NOT_HAVE_IF_NAMETOINDEX
     int                 index = 200;
@@ -279,9 +306,11 @@
         if (ifi == NULL) {
             goto gotError;
         }
-        *ifipnext = ifi;            /* prev points to this new one */
-        ifipnext = &ifi->ifi_next;  /* pointer to next one goes here */
-
+		ifipold   = *ifipnext;       /* need this later */
+		ifiptr    = ifipnext;
+		*ifipnext = ifi;             /* prev points to this new one */
+		ifipnext  = &ifi->ifi_next;  /* pointer to next one goes here */
+		
         ifi->ifi_flags = flags;     /* IFF_xxx values */
         ifi->ifi_myflags = myflags; /* IFI_xxx values */
 #ifndef NOT_HAVE_IF_NAMETOINDEX
@@ -310,7 +339,23 @@
                 memcpy(ifi->ifi_addr, sinptr, sizeof(struct sockaddr_in));
 
 #ifdef  SIOCGIFNETMASK
-				if (ioctl(sockfd, SIOCGIFNETMASK, &ifrcopy) < 0) goto gotError;
+				if (ioctl(sockfd, SIOCGIFNETMASK, &ifrcopy) < 0) {
+					if (errno == EADDRNOTAVAIL) {
+						/* 
+						 * If the main interface is configured with no IP address but 
+						 * an alias interface exists with an IP address, you get 
+						 * EADDRNOTAVAIL for the main interface 
+						 */
+						free(ifi->ifi_addr);
+						free(ifi);
+						ifipnext  = ifiptr; 
+						*ifipnext = ifipold;
+						continue;
+					} else {
+						goto gotError;
+					}				
+				}
+
 				ifi->ifi_netmask = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in));
 				if (ifi->ifi_netmask == NULL) goto gotError;
 				sinptr = (struct sockaddr_in *) &ifrcopy.ifr_addr;
@@ -385,7 +430,22 @@
 				memset(&ifr6, 0, sizeof(ifr6));
 				memcpy(&ifr6.ifr_name,           &ifr->ifr_name, sizeof(ifr6.ifr_name          ));
 				memcpy(&ifr6.ifr_ifru.ifru_addr, &ifr->ifr_addr, sizeof(ifr6.ifr_ifru.ifru_addr));
-				if (ioctl(sockf6, SIOCGIFNETMASK_IN6, &ifr6) < 0) goto gotError;
+				if (ioctl(sockf6, SIOCGIFNETMASK_IN6, &ifr6) < 0) {
+					if (errno == EADDRNOTAVAIL) {
+						/* 
+						 * If the main interface is configured with no IP address but 
+						 * an alias interface exists with an IP address, you get 
+						 * EADDRNOTAVAIL for the main interface 
+						 */
+						free(ifi->ifi_addr);
+						free(ifi);
+						ifipnext  = ifiptr; 
+						*ifipnext = ifipold;
+						continue;
+					} else {
+						goto gotError;
+					}				
+				}
 				ifi->ifi_netmask = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in6));
 				if (ifi->ifi_netmask == NULL) goto gotError;
 				sinptr6 = (struct sockaddr_in6 *) &ifr6.ifr_ifru.ifru_addr;
@@ -576,9 +636,9 @@
         }
 #endif
 
-#if defined(IPV6_PKTINFO) && HAVE_IPV6
-        if (cmptr->cmsg_level == IPPROTO_IPV6 && 
-            cmptr->cmsg_type == IPV6_PKTINFO) {
+#if defined(IPV6_PKTINFO) && HAVE_IPV6 
+		if (cmptr->cmsg_level == IPPROTO_IPV6 && 
+            cmptr->cmsg_type  == IPV6_2292_PKTINFO) {
             struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)&pktp->ipi_addr;
 			struct in6_pktinfo *ip6_info = (struct in6_pktinfo*)CMSG_DATA(cmptr);
 			
@@ -597,7 +657,7 @@
 
 #if defined(IPV6_HOPLIMIT) && HAVE_IPV6
         if (cmptr->cmsg_level == IPPROTO_IPV6 && 
-            cmptr->cmsg_type == IPV6_HOPLIMIT) {
+            cmptr->cmsg_type == IPV6_2292_HOPLIMIT) {
 			*ttl = *(int*)CMSG_DATA(cmptr);
             continue;
         }
diff --git a/mDNSPosix/mDNSUNP.h b/mDNSPosix/mDNSUNP.h
index 59b5501..6b04601 100755
--- a/mDNSPosix/mDNSUNP.h
+++ b/mDNSPosix/mDNSUNP.h
@@ -25,6 +25,15 @@
 
 #ifdef HAVE_LINUX
 #include <linux/socket.h>
+#define IPV6_2292_PKTINFO  IPV6_2292PKTINFO
+#define IPV6_2292_HOPLIMIT IPV6_2292HOPLIMIT
+#else
+// The following are the supported non-linux posix OSes -
+// netbsd, freebsd and openbsd.
+#if HAVE_IPV6
+#define IPV6_2292_PKTINFO  19
+#define IPV6_2292_HOPLIMIT 20
+#endif 
 #endif
 
 #ifdef  __cplusplus
diff --git a/mDNSShared/CommonServices.h b/mDNSShared/CommonServices.h
index 1261f1d..be49257 100644
--- a/mDNSShared/CommonServices.h
+++ b/mDNSShared/CommonServices.h
@@ -54,6 +54,16 @@
 	#endif
 #endif
 
+// FreeBSD
+
+#if( !defined( TARGET_OS_FREEBSD ) )
+	#if( defined( __FreeBSD__ ) )
+		#define TARGET_OS_FREEBSD		1
+	#else
+		#define TARGET_OS_FREEBSD		0
+	#endif
+#endif
+
 // Linux
 
 #if( !defined( TARGET_OS_LINUX ) )
@@ -90,7 +100,7 @@
 	
 	// No predefined macro for VxWorks so just assume VxWorks if nothing else is set.
 	
-	#if( !macintosh && !__MACH__  && !defined( __linux__ ) && !defined ( __SVR4 ) && !defined ( __sun ) && !defined( __PALMOS_TRAPS__ ) && !defined( __PALMOS_ARMLET__ ) && !defined( _WIN32 ) )
+	#if( !macintosh && !__MACH__  && !defined( __FreeBSD__ ) && !defined( __linux__ ) && !defined ( __SVR4 ) && !defined ( __sun ) && !defined( __PALMOS_TRAPS__ ) && !defined( __PALMOS_ARMLET__ ) && !defined( _WIN32 ) )
 		#define	TARGET_OS_VXWORKS		1
 	#else
 		#define	TARGET_OS_VXWORKS		0
@@ -179,6 +189,15 @@
 	#include	<libkern/OSTypes.h>
 	#include	<sys/types.h>
 	
+#elif( TARGET_OS_FREEBSD )
+
+	// FreeBSD
+	#include	<stdint.h>
+	#include	<pthread.h>
+	#include	<netinet/in.h>
+	#include	<arpa/inet.h>
+	#include	<sys/socket.h>
+
 #elif( TARGET_OS_LINUX )
 	
 	// Linux
@@ -455,7 +474,7 @@
 // - Windows
 
 #if( TARGET_LANGUAGE_C_LIKE )
-	#if( !defined(_SSIZE_T) && ( TARGET_OS_WIN32 || !defined( _BSD_SSIZE_T_DEFINED_ ) ) && !TARGET_OS_LINUX && !TARGET_OS_VXWORKS && !TARGET_OS_MAC)
+	#if( !defined(_SSIZE_T) && ( TARGET_OS_WIN32 || !defined( _BSD_SSIZE_T_DEFINED_ ) ) && !TARGET_OS_FREEBSD && !TARGET_OS_LINUX && !TARGET_OS_VXWORKS && !TARGET_OS_MAC)
 		typedef int						ssize_t;
 	#endif
 #endif
diff --git a/mDNSShared/dns_sd.h b/mDNSShared/dns_sd.h
index 56c1d30..607ebcd 100644
--- a/mDNSShared/dns_sd.h
+++ b/mDNSShared/dns_sd.h
@@ -77,7 +77,7 @@
  */
 
 #ifndef _DNS_SD_H
-#define _DNS_SD_H 3201000
+#define _DNS_SD_H 3201080
 
 #ifdef  __cplusplus
     extern "C" {
diff --git a/mDNSShared/uds_daemon.c b/mDNSShared/uds_daemon.c
index a2588e7..cfdc1bd 100644
--- a/mDNSShared/uds_daemon.c
+++ b/mDNSShared/uds_daemon.c
@@ -3994,6 +3994,11 @@
 			// determine whether sa_len is defined on a particular platform.
 			laddr.sun_len = sizeof(struct sockaddr_un);
 			#endif
+			if (strlen(MDNS_UDS_SERVERPATH) >= sizeof(laddr.sun_path))
+				{
+					LogMsg("ERROR: MDNS_UDS_SERVERPATH must be < %d characters", (int)sizeof(laddr.sun_path));
+					goto error;
+				}
 			mDNSPlatformStrCopy(laddr.sun_path, MDNS_UDS_SERVERPATH);
 			ret = bind(listenfd, (struct sockaddr *) &laddr, sizeof(laddr));
 			umask(mask);