this repo has no description
at fixPythonPipStalling 320 lines 9.1 kB view raw
1/* 2 * Copyright (c) 2002-2018 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24/* 25 * Modification History 26 * 27 * August 5, 2002 Allan Nathanson <ajn@apple.com> 28 * - split code out from eventmon.c 29 */ 30 31#include "eventmon.h" 32#include "ev_ipv4.h" 33 34#define IP_FORMAT "%d.%d.%d.%d" 35#define IP_CH(ip, i) (((u_char *)(ip))[i]) 36#define IP_LIST(ip) IP_CH(ip,0),IP_CH(ip,1),IP_CH(ip,2),IP_CH(ip,3) 37 38 39static void 40appendAddress(CFMutableDictionaryRef dict, CFStringRef key, struct in_addr *address) 41{ 42 CFStringRef addr; 43 CFArrayRef addrs; 44 CFMutableArrayRef newAddrs; 45 46 addrs = CFDictionaryGetValue(dict, key); 47 if (addrs) { 48 newAddrs = CFArrayCreateMutableCopy(NULL, 0, addrs); 49 } else { 50 newAddrs = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); 51 } 52 53 addr = CFStringCreateWithFormat(NULL, NULL, CFSTR(IP_FORMAT), IP_LIST(address)); 54 CFArrayAppendValue(newAddrs, addr); 55 CFRelease(addr); 56 57 CFDictionarySetValue(dict, key, newAddrs); 58 CFRelease(newAddrs); 59 return; 60} 61 62 63static CFMutableDictionaryRef 64copyIF(CFStringRef key, CFMutableDictionaryRef oldIFs, CFMutableDictionaryRef newIFs) 65{ 66 CFDictionaryRef dict = NULL; 67 CFMutableDictionaryRef newDict = NULL; 68 69 if (CFDictionaryGetValueIfPresent(newIFs, key, (const void **)&dict)) { 70 newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict); 71 } else { 72 dict = SCDynamicStoreCopyValue(store, key); 73 if (dict) { 74 CFDictionarySetValue(oldIFs, key, dict); 75 if (isA_CFDictionary(dict)) { 76 newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict); 77 CFDictionaryRemoveValue(newDict, kSCPropNetIPv4Addresses); 78 CFDictionaryRemoveValue(newDict, kSCPropNetIPv4SubnetMasks); 79 CFDictionaryRemoveValue(newDict, kSCPropNetIPv4DestAddresses); 80 CFDictionaryRemoveValue(newDict, kSCPropNetIPv4BroadcastAddresses); 81 } 82 CFRelease(dict); 83 } 84 } 85 86 if (!newDict) { 87 newDict = CFDictionaryCreateMutable(NULL, 88 0, 89 &kCFTypeDictionaryKeyCallBacks, 90 &kCFTypeDictionaryValueCallBacks); 91 } 92 93 return newDict; 94} 95 96 97static void 98updateStore(const void *key, const void *value, void *context) 99{ 100 CFDictionaryRef dict; 101 CFDictionaryRef newDict = (CFDictionaryRef)value; 102 CFDictionaryRef oldIFs = (CFDictionaryRef)context; 103 104 dict = CFDictionaryGetValue(oldIFs, key); 105 106 if (!dict || !CFEqual(dict, newDict)) { 107 if (CFDictionaryGetCount(newDict) > 0) { 108 SC_log(LOG_DEBUG, "Update interface configuration: %@: %@", key, newDict); 109 SCDynamicStoreSetValue(store, key, newDict); 110 } else if (dict) { 111 CFDictionaryRef oldDict; 112 113 oldDict = SCDynamicStoreCopyValue(store, key); 114 if (oldDict != NULL) { 115 SC_log(LOG_DEBUG, "Update interface configuration: %@: <removed>", key); 116 CFRelease(oldDict); 117 } 118 SCDynamicStoreRemoveValue(store, key); 119 } 120 network_changed = TRUE; 121 } 122 123 return; 124} 125 126 127__private_extern__ 128void 129ipv4_interface_update(struct ifaddrs *ifap, const char *if_name) 130{ 131 struct ifaddrs *ifa; 132 struct ifaddrs *ifap_temp = NULL; 133 CFStringRef interface; 134 boolean_t interfaceFound = FALSE; 135 CFStringRef key = NULL; 136 CFMutableDictionaryRef oldIFs; 137 CFMutableDictionaryRef newDict = NULL; 138 CFMutableDictionaryRef newIFs; 139 140 oldIFs = CFDictionaryCreateMutable(NULL, 141 0, 142 &kCFTypeDictionaryKeyCallBacks, 143 &kCFTypeDictionaryValueCallBacks); 144 newIFs = CFDictionaryCreateMutable(NULL, 145 0, 146 &kCFTypeDictionaryKeyCallBacks, 147 &kCFTypeDictionaryValueCallBacks); 148 149 if (!ifap) { 150 if (getifaddrs(&ifap_temp) == -1) { 151 SC_log(LOG_NOTICE, "getifaddrs() failed: %s", strerror(errno)); 152 goto error; 153 } 154 ifap = ifap_temp; 155 } 156 157 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 158 struct sockaddr_in *sin; 159 160 if (ifa->ifa_addr->sa_family != AF_INET) { 161 continue; /* sorry, not interested */ 162 } 163 164 /* check if this is the requested interface */ 165 if (if_name) { 166 if (strncmp(if_name, ifa->ifa_name, IFNAMSIZ) == 0) { 167 interfaceFound = TRUE; /* yes, this is the one I want */ 168 } else { 169 continue; /* sorry, not interested */ 170 } 171 } 172 173 interface = CFStringCreateWithCString(NULL, ifa->ifa_name, kCFStringEncodingMacRoman); 174 key = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, 175 kSCDynamicStoreDomainState, 176 interface, 177 kSCEntNetIPv4); 178 CFRelease(interface); 179 180 newDict = copyIF(key, oldIFs, newIFs); 181 182 /* ALIGN: cast ok, this should be aligned (getifaddrs). */ 183 sin = (struct sockaddr_in *)(void *)ifa->ifa_addr; 184 appendAddress(newDict, kSCPropNetIPv4Addresses, &sin->sin_addr); 185 186 if (ifa->ifa_flags & IFF_POINTOPOINT) { 187 struct sockaddr_in *dst; 188 189 /* ALIGN: cast ok, this should be aligned (getifaddrs). */ 190 dst = (struct sockaddr_in *)(void *)ifa->ifa_dstaddr; 191 appendAddress(newDict, kSCPropNetIPv4DestAddresses, &dst->sin_addr); 192 } else { 193 struct sockaddr_in *brd; 194 struct sockaddr_in *msk; 195 196 /* ALIGN: cast ok, this should be aligned (getifaddrs). */ 197 brd = (struct sockaddr_in *)(void *)ifa->ifa_broadaddr; 198 appendAddress(newDict, kSCPropNetIPv4BroadcastAddresses,&brd->sin_addr); 199 200 /* ALIGN: cast ok, this should be aligned (getifaddrs). */ 201 msk = (struct sockaddr_in *)(void *)ifa->ifa_netmask; 202 appendAddress(newDict, kSCPropNetIPv4SubnetMasks, &msk->sin_addr); 203 } 204 205 CFDictionarySetValue(newIFs, key, newDict); 206 CFRelease(newDict); 207 CFRelease(key); 208 } 209 210 /* if the last address[es] were removed from the target interface */ 211 if (if_name && !interfaceFound) { 212 interface = CFStringCreateWithCString(NULL, if_name, kCFStringEncodingMacRoman); 213 key = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, 214 kSCDynamicStoreDomainState, 215 interface, 216 kSCEntNetIPv4); 217 CFRelease(interface); 218 219 newDict = copyIF(key, oldIFs, newIFs); 220 221 CFDictionarySetValue(newIFs, key, newDict); 222 CFRelease(newDict); 223 CFRelease(key); 224 } 225 226 CFDictionaryApplyFunction(newIFs, updateStore, oldIFs); 227 228 error : 229 230 if (ifap_temp) freeifaddrs(ifap_temp); 231 CFRelease(oldIFs); 232 CFRelease(newIFs); 233 234 return; 235} 236 237__private_extern__ 238void 239ipv4_arp_collision(const char *if_name, struct in_addr ip_addr, int hw_len, const void * hw_addr) 240{ 241 uint8_t * hw_addr_bytes = (uint8_t *)hw_addr; 242 int i; 243 CFStringRef if_name_cf; 244 CFMutableStringRef key; 245 CFStringRef prefix; 246 247 if_name_cf = CFStringCreateWithCString(NULL, if_name, 248 kCFStringEncodingASCII); 249 prefix = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, 250 kSCDynamicStoreDomainState, 251 if_name_cf, 252 kSCEntNetIPv4ARPCollision); 253 key = CFStringCreateMutableCopy(NULL, 0, prefix); 254 CFStringAppendFormat(key, NULL, CFSTR("/" IP_FORMAT), 255 IP_LIST(&ip_addr)); 256 for (i = 0; i < hw_len; i++) { 257 CFStringAppendFormat(key, NULL, CFSTR("%s%02x"), 258 (i == 0) ? "/" : ":", hw_addr_bytes[i]); 259 } 260 SC_log(LOG_DEBUG, "Post ARP collision: %@", key); 261 SCDynamicStoreNotifyValue(store, key); 262 CFRelease(key); 263 CFRelease(prefix); 264 CFRelease(if_name_cf); 265 return; 266} 267 268#if !TARGET_OS_IPHONE 269__private_extern__ 270void 271ipv4_port_in_use(uint16_t port, pid_t req_pid) 272{ 273 CFStringRef key; 274 275 key = SCDynamicStoreKeyCreate(NULL, 276 CFSTR("%@/%@/Protocol/%@/%@/%d/%d"), 277 kSCDynamicStoreDomainState, 278 kSCCompNetwork, 279 kSCEntNetIPv4, 280 kSCEntNetIPv4PortInUse, 281 port, req_pid); 282 SC_log(LOG_DEBUG, "Post port-in-use: %@", key); 283 SCDynamicStoreNotifyValue(store, key); 284 CFRelease(key); 285 return; 286} 287#endif /* !TARGET_OS_IPHONE */ 288 289static void 290interface_notify_entity(const char * if_name, const char * type, CFStringRef entity) 291{ 292 CFStringRef if_name_cf; 293 CFStringRef key; 294 295 if_name_cf = CFStringCreateWithCString(NULL, if_name, 296 kCFStringEncodingASCII); 297 key = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, 298 kSCDynamicStoreDomainState, 299 if_name_cf, 300 entity); 301 CFRelease(if_name_cf); 302 SC_log(LOG_DEBUG, "Post %s: %@", type, key); 303 SCDynamicStoreNotifyValue(store, key); 304 CFRelease(key); 305 return; 306} 307 308__private_extern__ void 309ipv4_router_arp_failure(const char * if_name) 310{ 311 interface_notify_entity(if_name, "Router ARP failure", kSCEntNetIPv4RouterARPFailure); 312 return; 313} 314 315__private_extern__ void 316ipv4_router_arp_alive(const char * if_name) 317{ 318 interface_notify_entity(if_name, "Router ARP alive", kSCEntNetIPv4RouterARPAlive); 319 return; 320}