]> git.saurik.com Git - apple/mdnsresponder.git/commitdiff
mDNSResponder-320.10.80.tar.gz v320.10.80
authorApple <opensource@apple.com>
Mon, 31 Oct 2011 23:10:04 +0000 (23:10 +0000)
committerApple <opensource@apple.com>
Mon, 31 Oct 2011 23:10:04 +0000 (23:10 +0000)
13 files changed:
Clients/dns-sd.c
Makefile
mDNSPosix/Identify.c
mDNSPosix/Makefile
mDNSPosix/ReadMe.txt
mDNSPosix/Responder.c
mDNSPosix/Services.txt
mDNSPosix/mDNSPosix.c
mDNSPosix/mDNSUNP.c
mDNSPosix/mDNSUNP.h
mDNSShared/CommonServices.h
mDNSShared/dns_sd.h
mDNSShared/uds_daemon.c

index bf6cc1039057a7ba6a8f3e17f62a3b8971158e3a..c73c22160e3caa05ef69513036391cf65939b67c 100644 (file)
@@ -170,7 +170,11 @@ cl dns-sd.c -I../mDNSShared -DNOT_HAVE_GETOPT ws2_32.lib ..\mDNSWindows\DLL\Rele
        #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))
index 75a0f5768a03302db287a530f9e32a1a30345e63..7233229afe30d47466a191e201631165ee8b12a1 100644 (file)
--- 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"
 
index 2ca9fc6f2dfffe1fabdd63035e5783905539dfc1..66f7410ae8ed4ae0cfc548e2dd5ae40adb3ab5fb 100644 (file)
@@ -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 <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);
        }
index 6ca90136778e9bba9dee9cbe1c8e670d61d639b6..55d7f8d7b717b0f1e9dfd550bc0cb090b6578bbe 100755 (executable)
@@ -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
index d4bff853b4c1b13801a209b2fb04b8ed85d4cde2..c2f56412a60dc8645912dba62ef9651cb5aac826 100755 (executable)
@@ -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
 ----------
index 21109b835cd495636d9c05cfe7145d6b721a10a0..38639ea1a917e5e9fc92eb5e5e9a15c3b8ba9607 100755 (executable)
@@ -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 <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)
index f5870bb96a028fa82b88ae31ba60ad85734c9714..f8d69786a4ec57953fbdfed0c694422ea517dc73 100755 (executable)
@@ -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
index 3db5266ff217d9d060f4a451d2e7e7cc5ddbcffc..74a21618edde52ede63005c8fce5bbb24d4b35fb 100755 (executable)
@@ -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;
index e8fc649a5d99a12588a82a6abd33c86161950e10..8027676cfe3bafc7d58bc271f03846533a77210b 100755 (executable)
@@ -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;
         }
index 59b5501b37bf5c58a42879893a8f275f3eb94753..6b04601f5095287e926f656e4b5200887e10614f 100755 (executable)
 
 #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
index 1261f1d5ab3e0e3cb5ce4f65bbeff6f7ac6dadf7..be49257df3328cdaec97b66b6601aaad6eee0d66 100644 (file)
        #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
index 56c1d30bc70528460d105c137f0bae963c6995c2..607ebcd11846639f5dd2e2c2c6ce7f55c5337614 100644 (file)
@@ -77,7 +77,7 @@
  */
 
 #ifndef _DNS_SD_H
-#define _DNS_SD_H 3201000
+#define _DNS_SD_H 3201080
 
 #ifdef  __cplusplus
     extern "C" {
index a2588e7d01a9571be706c4db6426175ff0a99961..cfdc1bda411a1e2851e8b362fb0cdf06e248a363 100644 (file)
@@ -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);