]> git.saurik.com Git - apple/configd.git/blobdiff - Plugins/KernelEventMonitor/ev_ipv6.c
configd-1061.101.1.tar.gz
[apple/configd.git] / Plugins / KernelEventMonitor / ev_ipv6.c
index 880713a63e87fcfa574d857d3d3ad856f4ee35ee..4b3e6bc7015747ea94935c1b566af1197905d00c 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2002-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2002-2007, 2011, 2013, 2015, 2017, 2018 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -30,7 +30,6 @@
 
 
 #include "eventmon.h"
 
 
 #include "eventmon.h"
-#include "cache.h"
 #include "ev_ipv6.h"
 
 #define s6_addr16 __u6_addr.__u6_addr16
 #include "ev_ipv6.h"
 
 #define s6_addr16 __u6_addr.__u6_addr16
@@ -41,6 +40,9 @@
 #endif
 #endif /* NOTYET */
 
 #endif
 #endif /* NOTYET */
 
+#ifndef        kSCEntNetIPv6DuplicatedAddress
+#define        kSCEntNetIPv6DuplicatedAddress          CFSTR("IPv6DuplicatedAddress")
+#endif /* kSCEntNetIPv6DuplicatedAddress */
 
 static void
 appendAddress(CFMutableDictionaryRef dict, CFStringRef key, struct sockaddr_in6 *sin6)
 
 static void
 appendAddress(CFMutableDictionaryRef dict, CFStringRef key, struct sockaddr_in6 *sin6)
@@ -48,7 +50,7 @@ appendAddress(CFMutableDictionaryRef dict, CFStringRef key, struct sockaddr_in6
        CFStringRef             addr;
        CFArrayRef              addrs;
        CFMutableArrayRef       newAddrs;
        CFStringRef             addr;
        CFArrayRef              addrs;
        CFMutableArrayRef       newAddrs;
-       char                    str[64];
+       char                    str[INET6_ADDRSTRLEN];
 
        addrs = CFDictionaryGetValue(dict, key);
        if (addrs) {
 
        addrs = CFDictionaryGetValue(dict, key);
        if (addrs) {
@@ -58,7 +60,7 @@ appendAddress(CFMutableDictionaryRef dict, CFStringRef key, struct sockaddr_in6
        }
 
        if (inet_ntop(AF_INET6, (const void *)&sin6->sin6_addr, str, sizeof(str)) == NULL) {
        }
 
        if (inet_ntop(AF_INET6, (const void *)&sin6->sin6_addr, str, sizeof(str)) == NULL) {
-               SCLog(TRUE, LOG_ERR, CFSTR("inet_ntop() failed: %s"), strerror(errno));
+               SC_log(LOG_INFO, "inet_ntop() failed: %s", strerror(errno));
                str[0] = '\0';
        }
 
                str[0] = '\0';
        }
 
@@ -104,7 +106,7 @@ appendPrefixLen(CFMutableDictionaryRef dict, struct sockaddr_in6 *sin6)
        CFArrayRef              prefixLens;
        CFMutableArrayRef       newPrefixLens;
 
        CFArrayRef              prefixLens;
        CFMutableArrayRef       newPrefixLens;
 
-       register int            byte;
+       register size_t         byte;
        register int            bit;
        int                     plen            = 0;
 
        register int            bit;
        int                     plen            = 0;
 
@@ -185,7 +187,7 @@ appendScopeID(CFMutableDictionaryRef dict, struct sockaddr_in6 *sin6)
 
 
 static CFMutableDictionaryRef
 
 
 static CFMutableDictionaryRef
-getIF(CFStringRef key, CFMutableDictionaryRef oldIFs, CFMutableDictionaryRef newIFs)
+copyIF(CFStringRef key, CFMutableDictionaryRef oldIFs, CFMutableDictionaryRef newIFs)
 {
        CFDictionaryRef         dict            = NULL;
        CFMutableDictionaryRef  newDict         = NULL;
 {
        CFDictionaryRef         dict            = NULL;
        CFMutableDictionaryRef  newDict         = NULL;
@@ -193,7 +195,7 @@ getIF(CFStringRef key, CFMutableDictionaryRef oldIFs, CFMutableDictionaryRef new
        if (CFDictionaryGetValueIfPresent(newIFs, key, (const void **)&dict)) {
                newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
        } else {
        if (CFDictionaryGetValueIfPresent(newIFs, key, (const void **)&dict)) {
                newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
        } else {
-               dict = cache_SCDynamicStoreCopyValue(store, key);
+               dict = SCDynamicStoreCopyValue(store, key);
                if (dict) {
                        CFDictionarySetValue(oldIFs, key, dict);
                        if (isA_CFDictionary(dict)) {
                if (dict) {
                        CFDictionarySetValue(oldIFs, key, dict);
                        if (isA_CFDictionary(dict)) {
@@ -232,9 +234,17 @@ updateStore(const void *key, const void *value, void *context)
 
        if (!dict || !CFEqual(dict, newDict)) {
                if (CFDictionaryGetCount(newDict) > 0) {
 
        if (!dict || !CFEqual(dict, newDict)) {
                if (CFDictionaryGetCount(newDict) > 0) {
-                       cache_SCDynamicStoreSetValue(store, key, newDict);
+                       SC_log(LOG_DEBUG, "Update interface configuration: %@: %@", key, newDict);
+                       SCDynamicStoreSetValue(store, key, newDict);
                } else if (dict) {
                } else if (dict) {
-                       cache_SCDynamicStoreRemoveValue(store, key);
+                       CFDictionaryRef         oldDict;
+
+                       oldDict = SCDynamicStoreCopyValue(store, key);
+                       if (oldDict != NULL) {
+                               SC_log(LOG_DEBUG, "Update interface configuration: %@: <removed>", key);
+                               CFRelease(oldDict);
+                       }
+                       SCDynamicStoreRemoveValue(store, key);
                }
                network_changed = TRUE;
        }
                }
                network_changed = TRUE;
        }
@@ -268,7 +278,7 @@ interface_update_ipv6(struct ifaddrs *ifap, const char *if_name)
 
        if (!ifap) {
                if (getifaddrs(&ifap_temp) == -1) {
 
        if (!ifap) {
                if (getifaddrs(&ifap_temp) == -1) {
-                       SCLog(TRUE, LOG_ERR, CFSTR("getifaddrs() failed: %s"), strerror(errno));
+                       SC_log(LOG_NOTICE, "getifaddrs() failed: %s", strerror(errno));
                        goto error;
                }
                ifap = ifap_temp;
                        goto error;
                }
                ifap = ifap_temp;
@@ -295,7 +305,6 @@ interface_update_ipv6(struct ifaddrs *ifap, const char *if_name)
                if (sock == -1) {
                        sock = dgram_socket(AF_INET6);
                        if (sock == -1) {
                if (sock == -1) {
                        sock = dgram_socket(AF_INET6);
                        if (sock == -1) {
-                               SCLog(TRUE, LOG_NOTICE, CFSTR("interface_update_ipv6: socket open failed, %s"), strerror(errno));
                                goto error;
                        }
                }
                                goto error;
                        }
                }
@@ -308,12 +317,13 @@ interface_update_ipv6(struct ifaddrs *ifap, const char *if_name)
                                                                          kSCEntNetIPv6);
                CFRelease(interface);
 
                                                                          kSCEntNetIPv6);
                CFRelease(interface);
 
-               newDict = getIF(key, oldIFs, newIFs);
+               newDict = copyIF(key, oldIFs, newIFs);
 
 
-               sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
+               /* ALIGN: ifa->ifa_addr aligned (getifaddrs), cast ok. */
+               sin6 = (struct sockaddr_in6 *)(void *)ifa->ifa_addr;
 
                /* XXX: embedded link local addr check */
 
                /* XXX: embedded link local addr check */
-               if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
+               if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr)) {
                        u_int16_t       index;
 
                        index = sin6->sin6_addr.s6_addr16[1];
                        u_int16_t       index;
 
                        index = sin6->sin6_addr.s6_addr16[1];
@@ -325,29 +335,34 @@ interface_update_ipv6(struct ifaddrs *ifap, const char *if_name)
                        }
                }
 
                        }
                }
 
-               bzero((char *)&ifr6, sizeof(ifr6));
-               strncpy(ifr6.ifr_name, ifa->ifa_name, sizeof(ifr6.ifr_name));
+               memset((char *)&ifr6, 0, sizeof(ifr6));
+               strlcpy(ifr6.ifr_name, ifa->ifa_name, sizeof(ifr6.ifr_name));
                ifr6.ifr_addr = *sin6;
                if (ioctl(sock, SIOCGIFAFLAG_IN6, &ifr6) == -1) {
                        /* if flags not available for this address */
                ifr6.ifr_addr = *sin6;
                if (ioctl(sock, SIOCGIFAFLAG_IN6, &ifr6) == -1) {
                        /* if flags not available for this address */
-                       SCLog(TRUE, LOG_NOTICE, CFSTR("interface_update_ipv6: ioctl failed, %s"), strerror(errno));
+                       SC_log((errno != EADDRNOTAVAIL) ? LOG_NOTICE : LOG_DEBUG, "ioctl() failed: %s",
+                             strerror(errno));
                }
 
                appendAddress  (newDict, kSCPropNetIPv6Addresses, sin6);
 #ifdef NOTYET
                appendScopeID  (newDict, sin6);
 #endif /* NOTYET */
                }
 
                appendAddress  (newDict, kSCPropNetIPv6Addresses, sin6);
 #ifdef NOTYET
                appendScopeID  (newDict, sin6);
 #endif /* NOTYET */
-               appendPrefixLen(newDict, (struct sockaddr_in6 *)ifa->ifa_netmask);
+               /* ALIGN: ifa should be aligned (from getifaddrs), cast ok.
+                * appendPrefixLen expect byte alignment */
+               appendPrefixLen(newDict, (struct sockaddr_in6 *)(void *)ifa->ifa_netmask);
                appendFlags    (newDict, flags6);
 
 
                appendFlags    (newDict, flags6);
 
 
-               if (ifa->ifa_flags & IFF_POINTOPOINT) {
+               if (ifa->ifa_flags & IFF_POINTOPOINT
+                   && ifa->ifa_dstaddr != NULL) {
                        struct sockaddr_in6     *dst6;
 
                        struct sockaddr_in6     *dst6;
 
-                       dst6 = (struct sockaddr_in6 *)ifa->ifa_dstaddr;
+                       /* ALIGN: ifa should be aligned (from getifaddrs), cast ok. */
+                       dst6 = (struct sockaddr_in6 *)(void *)ifa->ifa_dstaddr;
 
                        /* XXX: embedded link local addr check */
 
                        /* XXX: embedded link local addr check */
-                       if (IN6_IS_ADDR_LINKLOCAL(&dst6->sin6_addr)) {
+                       if (IN6_IS_ADDR_LINKLOCAL(&dst6->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&dst6->sin6_addr)) {
                                u_int16_t       index;
 
                                index = dst6->sin6_addr.s6_addr16[1];
                                u_int16_t       index;
 
                                index = dst6->sin6_addr.s6_addr16[1];
@@ -376,7 +391,7 @@ interface_update_ipv6(struct ifaddrs *ifap, const char *if_name)
                                                                          kSCEntNetIPv6);
                CFRelease(interface);
 
                                                                          kSCEntNetIPv6);
                CFRelease(interface);
 
-               newDict = getIF(key, oldIFs, newIFs);
+               newDict = copyIF(key, oldIFs, newIFs);
 
                CFDictionarySetValue(newIFs, key, newDict);
                CFRelease(newDict);
 
                CFDictionarySetValue(newIFs, key, newDict);
                CFRelease(newDict);
@@ -394,3 +409,70 @@ interface_update_ipv6(struct ifaddrs *ifap, const char *if_name)
 
        return;
 }
 
        return;
 }
+
+__private_extern__
+void
+ipv6_duplicated_address(const char * if_name, const struct in6_addr * addr,
+                       int hw_len, const void * hw_addr)
+{
+       uint8_t *               hw_addr_bytes = (uint8_t *)hw_addr;
+       int                     i;
+       CFStringRef             if_name_cf;
+       CFMutableStringRef      key;
+       char                    ntopbuf[INET6_ADDRSTRLEN];
+       CFStringRef             prefix;
+
+       if_name_cf = CFStringCreateWithCString(NULL, if_name,
+                                              kCFStringEncodingASCII);
+       prefix = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
+                                                              kSCDynamicStoreDomainState,
+                                                              if_name_cf,
+                                                              kSCEntNetIPv6DuplicatedAddress);
+       ntopbuf[0] = '\0';
+       (void)inet_ntop(AF_INET6, addr, ntopbuf, sizeof(ntopbuf));
+       key = CFStringCreateMutableCopy(NULL, 0, prefix);
+       CFStringAppendFormat(key, NULL, CFSTR("/%s"), ntopbuf);
+       for (i = 0; i < hw_len; i++) {
+           CFStringAppendFormat(key, NULL, CFSTR("%s%02x"),
+                                (i == 0) ? "/" : ":", hw_addr_bytes[i]);
+       }
+       SCDynamicStoreNotifyValue(store, key);
+       CFRelease(key);
+       CFRelease(prefix);
+       CFRelease(if_name_cf);
+}
+
+__private_extern__
+void
+nat64_prefix_request(const char *if_name)
+{
+       CFStringRef             if_name_cf;
+       CFStringRef             key;
+
+       if_name_cf = CFStringCreateWithCString(NULL, if_name, kCFStringEncodingASCII);
+       key = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
+                                                           kSCDynamicStoreDomainState,
+                                                           if_name_cf,
+                                                           kSCEntNetNAT64PrefixRequest);
+       CFRelease(if_name_cf);
+       SC_log(LOG_DEBUG, "Post NAT64 prefix request: %@", key);
+       SCDynamicStoreNotifyValue(store, key);
+       CFRelease(key);
+}
+
+__private_extern__ void
+ipv6_router_expired(const char *if_name)
+{
+       CFStringRef             if_name_cf;
+       CFStringRef             key;
+
+       if_name_cf = CFStringCreateWithCString(NULL, if_name, kCFStringEncodingASCII);
+       key = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
+                                                           kSCDynamicStoreDomainState,
+                                                           if_name_cf,
+                                                           kSCEntNetIPv6RouterExpired);
+       CFRelease(if_name_cf);
+       SC_log(LOG_DEBUG, "Post IPv6 Router Expired: %@", key);
+       SCDynamicStoreNotifyValue(store, key);
+       CFRelease(key);
+}