From: Apple Date: Mon, 31 Oct 2011 23:10:04 +0000 (+0000) Subject: mDNSResponder-320.10.80.tar.gz X-Git-Tag: v320.10.80^0 X-Git-Url: https://git.saurik.com/apple/mdnsresponder.git/commitdiff_plain/8ec81f6c99056f5c63e0045ca48a7c405058254b mDNSResponder-320.10.80.tar.gz --- 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 @@ cl dns-sd.c -I../mDNSShared -DNOT_HAVE_GETOPT ws2_32.lib ..\mDNSWindows\DLL\Rele #include // For inet_addr() #include // 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 @@ mDNSexport int main(int argc, char **argv) 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 @@ mDNSexport int main(int argc, char **argv) return(0); usage: - fprintf(stderr, "%s or or ...\n", progname); + fprintf(stderr, "Usage: %s or or ...\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 @@ STRIP = strip 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 @@ else 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 @@ ifeq ($(os),x) # 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 @@ JAVACFLAGS_OS = -dynamiclib -I/System/Library/Frameworks/JavaVM.framework/Header 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 @@ Networking, Communications, Hardware 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 @@ static mStatus RegisterOneService(const char * richTextName, 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 @@ static mStatus RegisterOneService(const char * richTextName, 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 . 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) 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: +# +# +# . +# +# +# +# +# +# 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 @@ mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const ms 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 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf #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 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf #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 @@ mDNSlocal int SetupOneInterface(mDNS *const m, struct sockaddr *intfAddr, struct // 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 @@ void plen_to_mask(int plen, char *addr) { /* 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 ifi_info *get_ifi_info_linuxv6(int family, int doaliases) struct sockaddr_in6 *sin6; struct in6_addr *addrptr; int err; + int sockfd = -1; + struct ifreq ifr; res0=NULL; ifihead = NULL; @@ -99,6 +101,10 @@ struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases) 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 @@ struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases) 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 @@ struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases) /* 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 @@ struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases) 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_linuxv6(int family, int doaliases) 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 @@ struct ifi_info *get_ifi_info(int family, int doaliases) 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 @@ struct ifi_info *get_ifi_info(int family, int doaliases) 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 @@ struct ifi_info *get_ifi_info(int family, int doaliases) 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 @@ struct in_pktinfo } #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 @@ struct in_pktinfo #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 +#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 #include +#elif( TARGET_OS_FREEBSD ) + + // FreeBSD + #include + #include + #include + #include + #include + #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 @@ mDNSexport int udsserver_init(dnssd_sock_t skts[], mDNSu32 count) // 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);