/*
- * 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,
* 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@
*/
#include "eventmon.h"
-#include "cache.h"
#include "ev_ipv6.h"
#define s6_addr16 __u6_addr.__u6_addr16
#endif
#endif /* NOTYET */
+#ifndef kSCEntNetIPv6DuplicatedAddress
+#define kSCEntNetIPv6DuplicatedAddress CFSTR("IPv6DuplicatedAddress")
+#endif /* kSCEntNetIPv6DuplicatedAddress */
static void
appendAddress(CFMutableDictionaryRef dict, CFStringRef key, struct sockaddr_in6 *sin6)
CFStringRef addr;
CFArrayRef addrs;
CFMutableArrayRef newAddrs;
- char str[64];
+ char str[INET6_ADDRSTRLEN];
addrs = CFDictionaryGetValue(dict, key);
if (addrs) {
}
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';
}
CFArrayRef prefixLens;
CFMutableArrayRef newPrefixLens;
- register int byte;
+ register size_t byte;
register int bit;
int plen = 0;
static CFMutableDictionaryRef
-getIF(CFStringRef key, CFMutableDictionaryRef oldIFs, CFMutableDictionaryRef newIFs)
+copyIF(CFStringRef key, CFMutableDictionaryRef oldIFs, CFMutableDictionaryRef newIFs)
{
CFDictionaryRef dict = NULL;
CFMutableDictionaryRef newDict = NULL;
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 || !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: %@: <removed>", key);
+ CFRelease(oldDict);
+ }
+ SCDynamicStoreRemoveValue(store, key);
}
network_changed = TRUE;
}
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;
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;
}
}
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];
}
}
- 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];
kSCEntNetIPv6);
CFRelease(interface);
- newDict = getIF(key, oldIFs, newIFs);
+ newDict = copyIF(key, oldIFs, newIFs);
CFDictionarySetValue(newIFs, key, newDict);
CFRelease(newDict);
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);
+}