X-Git-Url: https://git.saurik.com/apple/configd.git/blobdiff_plain/edebe297f772e4cdd76278ebb777820466d2917b..78deefe8e371573ba1c4e975adf72db0dddc81f9:/Plugins/KernelEventMonitor/ev_ipv6.c diff --git a/Plugins/KernelEventMonitor/ev_ipv6.c b/Plugins/KernelEventMonitor/ev_ipv6.c index 880713a..4b3e6bc 100644 --- a/Plugins/KernelEventMonitor/ev_ipv6.c +++ b/Plugins/KernelEventMonitor/ev_ipv6.c @@ -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@ - * + * * 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, @@ -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. - * + * * @APPLE_LICENSE_HEADER_END@ */ @@ -30,7 +30,6 @@ #include "eventmon.h" -#include "cache.h" #include "ev_ipv6.h" #define s6_addr16 __u6_addr.__u6_addr16 @@ -41,6 +40,9 @@ #endif #endif /* NOTYET */ +#ifndef kSCEntNetIPv6DuplicatedAddress +#define kSCEntNetIPv6DuplicatedAddress CFSTR("IPv6DuplicatedAddress") +#endif /* kSCEntNetIPv6DuplicatedAddress */ 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; - char str[64]; + char str[INET6_ADDRSTRLEN]; 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) { - SCLog(TRUE, LOG_ERR, CFSTR("inet_ntop() failed: %s"), strerror(errno)); + SC_log(LOG_INFO, "inet_ntop() failed: %s", strerror(errno)); str[0] = '\0'; } @@ -104,7 +106,7 @@ appendPrefixLen(CFMutableDictionaryRef dict, struct sockaddr_in6 *sin6) CFArrayRef prefixLens; CFMutableArrayRef newPrefixLens; - register int byte; + register size_t byte; register int bit; int plen = 0; @@ -185,7 +187,7 @@ appendScopeID(CFMutableDictionaryRef dict, struct sockaddr_in6 *sin6) static CFMutableDictionaryRef -getIF(CFStringRef key, CFMutableDictionaryRef oldIFs, CFMutableDictionaryRef newIFs) +copyIF(CFStringRef key, CFMutableDictionaryRef oldIFs, CFMutableDictionaryRef newIFs) { 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 { - dict = cache_SCDynamicStoreCopyValue(store, key); + dict = SCDynamicStoreCopyValue(store, key); 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) { - cache_SCDynamicStoreSetValue(store, key, newDict); + SC_log(LOG_DEBUG, "Update interface configuration: %@: %@", key, newDict); + SCDynamicStoreSetValue(store, key, newDict); } else if (dict) { - cache_SCDynamicStoreRemoveValue(store, key); + CFDictionaryRef oldDict; + + oldDict = SCDynamicStoreCopyValue(store, key); + if (oldDict != NULL) { + SC_log(LOG_DEBUG, "Update interface configuration: %@: ", key); + CFRelease(oldDict); + } + SCDynamicStoreRemoveValue(store, key); } network_changed = TRUE; } @@ -268,7 +278,7 @@ interface_update_ipv6(struct ifaddrs *ifap, const char *if_name) 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; @@ -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) { - SCLog(TRUE, LOG_NOTICE, CFSTR("interface_update_ipv6: socket open failed, %s"), strerror(errno)); goto error; } } @@ -308,12 +317,13 @@ interface_update_ipv6(struct ifaddrs *ifap, const char *if_name) 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 */ - 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]; @@ -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 */ - 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 */ - 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); - if (ifa->ifa_flags & IFF_POINTOPOINT) { + if (ifa->ifa_flags & IFF_POINTOPOINT + && ifa->ifa_dstaddr != NULL) { 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 */ - 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]; @@ -376,7 +391,7 @@ interface_update_ipv6(struct ifaddrs *ifap, const char *if_name) kSCEntNetIPv6); CFRelease(interface); - newDict = getIF(key, oldIFs, newIFs); + newDict = copyIF(key, oldIFs, newIFs); CFDictionarySetValue(newIFs, key, newDict); CFRelease(newDict); @@ -394,3 +409,70 @@ interface_update_ipv6(struct ifaddrs *ifap, const char *if_name) 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); +}