#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))
include /Developer/Makefiles/pb_makefiles/platform.make
-MVERS = "mDNSResponder-320.10"
+MVERS = "mDNSResponder-320.10.80"
DDNSWRITECONFIG = "$(DSTROOT)/Library/Application Support/Bonjour/ddnswriteconfig"
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);
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);
}
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)
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:
# 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
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
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
----------
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 {
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
+
+ if (gMDNSPlatformPosixVerboseLevel > 1)
+ fprintf(stderr, "Parsing %s for services\n", 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;
}
- }
- } while (good && !feof(fp));
+ else
+ fprintf(stderr, "%s: TXT attribute too long for name = %s, type = %s, port = %s\n",
+ gProgramName, name, type, port);
+ }
- if ( ! good ) {
- fprintf(stderr, "%s: Error reading service file %s\n", gProgramName, filePath);
- }
- }
+ 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)
-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
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;
#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
#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
// 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;
/* 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;
struct sockaddr_in6 *sin6;
struct in6_addr *addrptr;
int err;
+ int sockfd = -1;
+ struct ifreq ifr;
res0=NULL;
ifihead = NULL;
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],
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 */
/* 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;
}
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
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;
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
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;
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;
}
#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);
#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;
}
#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
#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 ) )
// 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
#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
// - 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
*/
#ifndef _DNS_SD_H
-#define _DNS_SD_H 3201000
+#define _DNS_SD_H 3201080
#ifdef __cplusplus
extern "C" {
// 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);