From: Apple Date: Tue, 29 Nov 2016 22:00:22 +0000 (+0000) Subject: configd-888.20.5.tar.gz X-Git-Tag: macos-10121^0 X-Git-Url: https://git.saurik.com/apple/configd.git/commitdiff_plain/39719b502407907891ed597d02676859766df03b configd-888.20.5.tar.gz --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7d05b74 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +.DS_Store +*.xcodeproj/project.xcworkspace +*.xcodeproj/xcuserdata +.svn +build +*~ +*~.c +*~.h +*~.m diff --git a/Plugins/IPMonitor/dns-configuration.c b/Plugins/IPMonitor/dns-configuration.c index 7beea02..6fff6a0 100644 --- a/Plugins/IPMonitor/dns-configuration.c +++ b/Plugins/IPMonitor/dns-configuration.c @@ -81,6 +81,13 @@ static CFNumberRef S_pdns_timeout = NULL; #pragma mark DNS resolver flags +static __inline__ boolean_t +dns_resolver_flags_all_queries(uint32_t query_flags) +{ + return ((query_flags & DNS_RESOLVER_FLAGS_REQUEST_ALL_RECORDS) == DNS_RESOLVER_FLAGS_REQUEST_ALL_RECORDS); +} + + static uint32_t @@ -328,6 +335,28 @@ add_supplemental(CFMutableArrayRef resolvers, #define N_QUICK 32 +static void +merge_configuration_flags(CFMutableDictionaryRef newDNS, uint32_t mergeFlags) +{ + uint32_t flags; + CFNumberRef num; + + if (!CFDictionaryGetValueIfPresent(newDNS, DNS_CONFIGURATION_FLAGS_KEY, (const void **)&num) || + !isA_CFNumber(num) || + !CFNumberGetValue(num, kCFNumberSInt32Type, &flags)) { + flags = 0; + } + + flags |= mergeFlags; + + num = CFNumberCreate(NULL, kCFNumberSInt32Type, &flags); + CFDictionarySetValue(newDNS, DNS_CONFIGURATION_FLAGS_KEY, num); + CFRelease(num); + + return; +} + + static void add_supplemental_resolvers(CFMutableArrayRef resolvers, CFDictionaryRef services, @@ -362,8 +391,10 @@ add_supplemental_resolvers(CFMutableArrayRef resolvers, uint32_t dns_resolver_flags; CFStringRef interface; CFMutableDictionaryRef newDNS = NULL; + uint32_t newFlags; CFDictionaryRef service = (CFDictionaryRef)vals[i]; CFStringRef serviceID = (CFStringRef)keys[i]; + Boolean trusted = FALSE; // trusted config w/interface if (!isA_CFDictionary(service)) { continue; @@ -447,31 +478,28 @@ add_supplemental_resolvers(CFMutableArrayRef resolvers, isA_CFBoolean(val) && CFBooleanGetValue(val)) { // leave the [trusted configuration] InterfaceName in place + trusted = TRUE; } else { CFDictionaryRemoveValue(newDNS, kSCPropInterfaceName); } } + // set "supplemental" flag + newFlags = DNS_RESOLVER_FLAGS_SUPPLEMENTAL; + if (scoped_interface != NULL) { - uint32_t flags; - CFNumberRef num; - - // set "scoped" configuration flag(s) - if (!CFDictionaryGetValueIfPresent(newDNS, DNS_CONFIGURATION_FLAGS_KEY, (const void **)&num) || - !isA_CFNumber(num) || - !CFNumberGetValue(num, kCFNumberSInt32Type, &flags)) { - flags = 0; - } - flags |= DNS_RESOLVER_FLAGS_SCOPED; + // set "scoped" configuration flag + newFlags |= DNS_RESOLVER_FLAGS_SCOPED; // add "Request A/AAAA query" flag(s) - flags |= dns_resolver_flags; - - num = CFNumberCreate(NULL, kCFNumberSInt32Type, &flags); - CFDictionarySetValue(newDNS, DNS_CONFIGURATION_FLAGS_KEY, num); - CFRelease(num); + newFlags |= dns_resolver_flags; + } else if (trusted) { + // use the DNS query flags from the supplemental match service + newFlags |= dns_resolver_flags_service(service, 0); } + merge_configuration_flags(newDNS, newFlags); + // add [scoped] resolver entry add_supplemental(resolvers, serviceID, newDNS, defaultOrder, (scoped_interface != NULL)); CFRelease(newDNS); @@ -859,11 +887,10 @@ add_scoped_resolvers(CFMutableArrayRef scoped, for (i = 0; i < n_order; i++) { CFDictionaryRef dns; uint32_t dns_resolver_flags; - uint32_t flags; char if_name[IF_NAMESIZE]; CFStringRef interface; CFMutableDictionaryRef newDNS; - CFNumberRef num; + uint32_t newFlags; CFArrayRef searchDomains; CFDictionaryRef service; CFStringRef serviceID; @@ -917,24 +944,19 @@ add_scoped_resolvers(CFMutableArrayRef scoped, CFRelease(searchDomains); } - // set "scoped" configuration flag(s) - if (!CFDictionaryGetValueIfPresent(newDNS, DNS_CONFIGURATION_FLAGS_KEY, (const void **)&num) || - !isA_CFNumber(num) || - !CFNumberGetValue(num, kCFNumberSInt32Type, &flags)) { - flags = 0; - } - flags |= DNS_RESOLVER_FLAGS_SCOPED; - - // add "Request A/AAAA query" flag(s) + // get "Request A/AAAA query" flag(s) dns_resolver_flags = dns_resolver_flags_service(service, 0); if (dns_resolver_flags == 0) { goto skip; } - flags |= dns_resolver_flags; - num = CFNumberCreate(NULL, kCFNumberSInt32Type, &flags); - CFDictionarySetValue(newDNS, DNS_CONFIGURATION_FLAGS_KEY, num); - CFRelease(num); + // set "scoped" configuration flag + newFlags = DNS_RESOLVER_FLAGS_SCOPED; + + // add "Request A/AAAA query" flag(s) + newFlags |= dns_resolver_flags; + + merge_configuration_flags(newDNS, newFlags); // remove keys we don't want in a [scoped] resolver CFDictionaryRemoveValue(newDNS, kSCPropNetDNSSupplementalMatchDomains); @@ -983,9 +1005,8 @@ add_service_specific_resolvers(CFMutableArrayRef resolvers, CFDictionaryRef serv for (i = 0; i < n_services; i++) { CFDictionaryRef dns; CFNumberRef dns_service_identifier; - CFNumberRef flags_num; - int32_t flags = 0; - CFMutableDictionaryRef new_resolver; + CFMutableDictionaryRef newDNS; + uint32_t newFlags = 0; CFDictionaryRef service = vals[i]; CFStringRef serviceID = keys[i]; @@ -1007,34 +1028,39 @@ add_service_specific_resolvers(CFMutableArrayRef resolvers, CFDictionaryRef serv } CFSetSetValue(seen, dns_service_identifier); - new_resolver = CFDictionaryCreateMutableCopy(NULL, 0, dns); + newDNS = CFDictionaryCreateMutableCopy(NULL, 0, dns); - if (!CFDictionaryGetValueIfPresent(new_resolver, DNS_CONFIGURATION_FLAGS_KEY, (const void **)&flags_num) || - !isA_CFNumber(flags_num) || - !CFNumberGetValue(flags_num, kCFNumberSInt32Type, &flags)) { - flags = 0; - } + if (CFDictionaryContainsKey(newDNS, kSCPropInterfaceName)) { + CFArrayRef searchDomains; - flags |= DNS_RESOLVER_FLAGS_REQUEST_ALL_RECORDS; + // set "scoped" configuration flag + newFlags |= DNS_RESOLVER_FLAGS_SCOPED; - if (CFDictionaryContainsKey(new_resolver, kSCPropInterfaceName)) { - CFDictionarySetValue(new_resolver, DNS_CONFIGURATION_SCOPED_QUERY_KEY, kCFBooleanTrue); - CFDictionaryRemoveValue(new_resolver, kSCPropNetDNSServiceIdentifier); - flags |= DNS_RESOLVER_FLAGS_SCOPED; + CFDictionarySetValue(newDNS, DNS_CONFIGURATION_SCOPED_QUERY_KEY, kCFBooleanTrue); + CFDictionaryRemoveValue(newDNS, kSCPropNetDNSServiceIdentifier); + + // set search list + searchDomains = extract_search_domains(newDNS, NULL); + if (searchDomains != NULL) { + CFDictionarySetValue(newDNS, kSCPropNetDNSSearchDomains, searchDomains); + CFRelease(searchDomains); + } } else { - flags |= DNS_RESOLVER_FLAGS_SERVICE_SPECIFIC; + // set "service specific" configuration flag + newFlags |= DNS_RESOLVER_FLAGS_SERVICE_SPECIFIC; } - flags_num = CFNumberCreate(NULL, kCFNumberSInt32Type, &flags); - CFDictionarySetValue(new_resolver, DNS_CONFIGURATION_FLAGS_KEY, flags_num); - CFRelease(flags_num); + // add "Request A/AAAA query" flag(s) + newFlags |= DNS_RESOLVER_FLAGS_REQUEST_ALL_RECORDS; - CFDictionaryRemoveValue(new_resolver, kSCPropNetDNSSupplementalMatchDomains); - CFDictionaryRemoveValue(new_resolver, kSCPropNetDNSSupplementalMatchOrders); + merge_configuration_flags(newDNS, newFlags); - add_resolver_signature(new_resolver, "Service", serviceID, 0); - add_resolver(resolvers, new_resolver); - CFRelease(new_resolver); + CFDictionaryRemoveValue(newDNS, kSCPropNetDNSSupplementalMatchDomains); + CFDictionaryRemoveValue(newDNS, kSCPropNetDNSSupplementalMatchOrders); + + add_resolver_signature(newDNS, "Service", serviceID, 0); + add_resolver(resolvers, newDNS); + CFRelease(newDNS); } CFRelease(seen); @@ -1335,28 +1361,6 @@ create_resolver(CFDictionaryRef dns) } -static __inline__ Boolean -isDefaultConfiguration(CFDictionaryRef dns) -{ - uint32_t flags; - CFNumberRef num; - - if ((dns != NULL) && - CFDictionaryGetValueIfPresent(dns, DNS_CONFIGURATION_FLAGS_KEY, (const void **)&num) && - (num != NULL) && - CFNumberGetValue(num, kCFNumberSInt32Type, &flags) && - (((flags & DNS_RESOLVER_FLAGS_SCOPED ) != 0) || - ((flags & DNS_RESOLVER_FLAGS_SERVICE_SPECIFIC) != 0)) - ) { - // if scoped or service-specific - return FALSE; - } - - return TRUE; -} - - - static __inline__ Boolean isScopedConfiguration(CFDictionaryRef dns) { @@ -1461,6 +1465,35 @@ compareDomain(const void *val1, const void *val2, void *context) } +static __inline__ Boolean +needsMergeWithDefaultConfiguration(CFDictionaryRef dns) +{ + uint32_t flags; + CFNumberRef num; + + if ((dns != NULL) && + CFDictionaryGetValueIfPresent(dns, DNS_CONFIGURATION_FLAGS_KEY, (const void **)&num) && + (num != NULL) && + CFNumberGetValue(num, kCFNumberSInt32Type, &flags)) { + + // check if merge needed (at all) + if (dns_resolver_flags_all_queries(flags)) { + // if we are already querying for both A/AAAA + return FALSE; + } + + // check if scoped or service-specific + if (((flags & DNS_RESOLVER_FLAGS_SCOPED ) != 0) || + ((flags & DNS_RESOLVER_FLAGS_SERVICE_SPECIFIC) != 0)) { + // yes, skip merge + return FALSE; + } + } + + return TRUE; +} + + __private_extern__ Boolean dns_configuration_set(CFDictionaryRef defaultResolver, @@ -1471,7 +1504,6 @@ dns_configuration_set(CFDictionaryRef defaultResolver, { dns_create_config_t _config; Boolean changed = FALSE; - uint32_t dns_resolver_flags = 0; CFIndex i; CFMutableDictionaryRef myDefault; Boolean myOrderAdded = FALSE; @@ -1564,31 +1596,34 @@ dns_configuration_set(CFDictionaryRef defaultResolver, */ _config = NULL; } else { + uint32_t default_resolver_flags = 0; + Boolean have_default_flags = FALSE; + /* * if default and/or supplemental/scoped resolvers are defined */ _config = _dns_configuration_create(); - CFDictionaryApplyFunction(services, add_dns_resolver_flags, &dns_resolver_flags); - for (i = 0; i < n_resolvers; i++) { - boolean_t is_default_resolver; + Boolean merge_default_flags; CFDictionaryRef resolver; dns_create_resolver_t _resolver; resolver = CFArrayGetValueAtIndex(resolvers, i); - is_default_resolver = isDefaultConfiguration(resolver); - if (is_default_resolver) { + merge_default_flags = needsMergeWithDefaultConfiguration(resolver); + if (merge_default_flags) { CFMutableDictionaryRef new_resolver; - CFNumberRef num; - - new_resolver = CFDictionaryCreateMutableCopy(NULL, 0, resolver); - num = CFNumberCreate(NULL, kCFNumberSInt32Type, &dns_resolver_flags); - CFDictionarySetValue(new_resolver, DNS_CONFIGURATION_FLAGS_KEY, num); - CFRelease(num); + if (!have_default_flags) { + CFDictionaryApplyFunction(services, + add_dns_resolver_flags, + &default_resolver_flags); + have_default_flags = TRUE; + } + new_resolver = CFDictionaryCreateMutableCopy(NULL, 0, resolver); + merge_configuration_flags(new_resolver, default_resolver_flags); resolver = new_resolver; } @@ -1596,7 +1631,7 @@ dns_configuration_set(CFDictionaryRef defaultResolver, _dns_configuration_add_resolver(&_config, _resolver); _dns_resolver_free(&_resolver); - if (is_default_resolver) { + if (merge_default_flags) { CFRelease(resolver); } } @@ -1604,7 +1639,7 @@ dns_configuration_set(CFDictionaryRef defaultResolver, #if !TARGET_OS_IPHONE // add flatfile resolvers - _dnsinfo_flatfile_set_flags(dns_resolver_flags); + _dnsinfo_flatfile_set_flags(default_resolver_flags); _dnsinfo_flatfile_add_resolvers(&_config); #endif // !TARGET_OS_IPHONE } diff --git a/Plugins/InterfaceNamer/ifnamer.c b/Plugins/InterfaceNamer/ifnamer.c index a3f4e96..82ae985 100644 --- a/Plugins/InterfaceNamer/ifnamer.c +++ b/Plugins/InterfaceNamer/ifnamer.c @@ -80,6 +80,7 @@ #include #include #include +#include "plugin_shared.h" #include #include @@ -595,9 +596,6 @@ updateVirtualNetworkInterfaceConfiguration(SCPreferencesRef prefs, #if !TARGET_OS_EMBEDDED -#define BT_PAN_NAME "Bluetooth PAN" -#define BT_PAN_MAC BT_PAN_NAME " (MAC)" - static void updateBTPANInformation(const void *value, void *context) { @@ -625,11 +623,11 @@ updateBTPANInformation(const void *value, void *context) return; } - CFDictionaryAddValue(S_state, CFSTR("_" BT_PAN_NAME "_"), if_name); + CFDictionaryAddValue(S_state, kInterfaceNamerKey_BT_PAN_Name, if_name); addr = CFDictionaryGetValue(dict, CFSTR(kIOMACAddress)); if (isA_CFData(addr)) { - CFDictionaryAddValue(S_state, CFSTR("_" BT_PAN_MAC "_"), addr); + CFDictionaryAddValue(S_state, kInterfaceNamerKey_BT_PAN_Mac, addr); } return; @@ -1708,6 +1706,27 @@ nameInterfaces(CFMutableArrayRef if_list) } #if !TARGET_OS_IPHONE +static Boolean +isRecoveryOS() +{ + static Boolean isRecovery = FALSE; + static dispatch_once_t once; + + /* + * We check to see if the UserEventAgent daemon is present. If not, then + * we are most likely booted into the Recovery OS with no "SCMonitor" + * [UserEventAgent] plugin. + */ + dispatch_once(&once, ^{ + if ((access("/usr/libexec/UserEventAgent", X_OK) == -1) && (errno == ENOENT)) { + isRecovery = TRUE; + } + + }); + + return isRecovery; +} + static void updateNetworkConfiguration(CFArrayRef if_list) { @@ -1769,6 +1788,58 @@ updateNetworkConfiguration(CFArrayRef if_list) } #endif // !TARGET_OS_IPHONE +static void +updatePreConfigured(CFArrayRef interfaces) +{ + CFIndex i; + CFIndex n; + CFMutableArrayRef new_list = NULL; + Boolean updated = FALSE; + + n = (interfaces != NULL) ? CFArrayGetCount(interfaces) : 0; + for (i = 0; i < n; i++) { + SCNetworkInterfaceRef interface; + + interface = CFArrayGetValueAtIndex(interfaces, i); + if (_SCNetworkInterfaceIsApplePreconfigured(interface)) { + CFStringRef bsdName; + + bsdName = SCNetworkInterfaceGetBSDName(interface); + if (bsdName == NULL) { + continue; + } + + // add pre-configured interface + if (new_list == NULL) { + CFArrayRef cur_list; + + cur_list = CFDictionaryGetValue(S_state, kInterfaceNamerKey_PreConfiguredInterfaces); + if (cur_list != NULL) { + new_list = CFArrayCreateMutableCopy(NULL, 0, cur_list); + } else { + new_list = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + } + } + + if (!CFArrayContainsValue(new_list, CFRangeMake(0, CFArrayGetCount(new_list)), bsdName)) { + CFArrayAppendValue(new_list, bsdName); + updated = TRUE; + } + } + } + + if (new_list != NULL) { + if (updated) { + CFDictionarySetValue(S_state, kInterfaceNamerKey_PreConfiguredInterfaces, new_list); + updateStore(); + } + + CFRelease(new_list); + } + + return; +} + static void updateInterfaces() { @@ -1787,6 +1858,11 @@ updateInterfaces() nameInterfaces(S_iflist); } + /* + * Update the list of [Apple] pre-configured interfaces + */ + updatePreConfigured(S_iflist); + if (isQuiet()) { /* * The registry [matching] has quiesced so let's @@ -1800,8 +1876,7 @@ updateInterfaces() updateVirtualNetworkInterfaceConfiguration(NULL, kSCPreferencesNotificationApply, NULL); #if !TARGET_OS_IPHONE - if (access("/usr/libexec/UserEventAgent", X_OK) == -1 - && errno == ENOENT) { + if (isRecoveryOS()) { /* * We are most likely booted into the Recovery OS with no "SCMonitor" * UserEventAgent plugin running so let's make sure we update the @@ -1977,7 +2052,7 @@ quietCallback(void *refcon, os_activity_scope(activity); if (messageType == kIOMessageServiceBusyStateChange) { - addTimestamp(S_state, CFSTR("*QUIET*")); + addTimestamp(S_state, kInterfaceNamerKey_Quiet); SC_log(LOG_INFO, "IOKit quiet"); } @@ -2148,7 +2223,7 @@ timerCallback(CFRunLoopTimerRef timer, void *info) // We've been waiting for IOKit to quiesce and it just // hasn't happenned. Time to just move on! - addTimestamp(S_state, CFSTR("*TIMEOUT*")); + addTimestamp(S_state, kInterfaceNamerKey_Timeout); // log busy nodes SC_log(LOG_ERR, "timed out waiting for IOKit to quiesce"); diff --git a/Plugins/PreferencesMonitor/prefsmon.c b/Plugins/PreferencesMonitor/prefsmon.c index c0d6b9d..8a091e2 100644 --- a/Plugins/PreferencesMonitor/prefsmon.c +++ b/Plugins/PreferencesMonitor/prefsmon.c @@ -37,6 +37,7 @@ #include #include +#include #include #include #include @@ -46,16 +47,23 @@ #include #include #include +#include "plugin_shared.h" +#include + /* globals */ -static SCPreferencesRef prefs = NULL; -static SCDynamicStoreRef store = NULL; +static SCPreferencesRef prefs = NULL; +static SCDynamicStoreRef store = NULL; + +/* InterfaceNamer[.plugin] monitoring globals */ +Boolean haveConfiguration = FALSE; +static CFStringRef namerKey = NULL; +static CFArrayRef preconfigured = NULL; -/* preferences "initialization" globals */ -static CFStringRef initKey = NULL; -static CFRunLoopSourceRef initRls = NULL; +/* KernelEventMonitor[.plugin] monitoring globals */ +static CFStringRef interfacesKey = NULL; /* SCDynamicStore (Setup:) */ static CFMutableDictionaryRef currentPrefs; /* current prefs */ @@ -63,13 +71,19 @@ static CFMutableDictionaryRef newPrefs; /* new prefs */ static CFMutableArrayRef unchangedPrefsKeys; /* new prefs keys which match current */ static CFMutableArrayRef removedPrefsKeys; /* old prefs keys to be removed */ -static Boolean rofs = FALSE; -static Boolean restorePrefs = FALSE; +static Boolean rofs = FALSE; +static Boolean restorePrefs = FALSE; #define MY_PLUGIN_NAME "PreferencesMonitor" #define MY_PLUGIN_ID CFSTR("com.apple.SystemConfiguration." MY_PLUGIN_NAME) +static void +updateConfiguration(SCPreferencesRef prefs, + SCPreferencesNotification notificationType, + void *info); + + static os_log_t __log_PreferencesMonitor() { @@ -322,76 +336,45 @@ establishNewPreferences() } -static Boolean -quiet(Boolean *timeout) +static void +watchSCDynamicStore() { - CFDictionaryRef dict; - Boolean _quiet = FALSE; - Boolean _timeout = FALSE; - - // keep the static analyzer happy - assert(initKey != NULL); - - // check if quiet - dict = SCDynamicStoreCopyValue(store, initKey); - if (dict != NULL) { - if (isA_CFDictionary(dict)) { - if (CFDictionaryContainsKey(dict, CFSTR("*QUIET*"))) { - _quiet = TRUE; - } - if (CFDictionaryContainsKey(dict, CFSTR("*TIMEOUT*"))) { - _timeout = TRUE; - } - } - CFRelease(dict); - } - - if (timeout != NULL) { - *timeout = _timeout; - } - return _quiet; -} + CFMutableArrayRef keys; + Boolean ok; + CFRunLoopSourceRef rls; + /* + * watch for KernelEventMonitor[.bundle] changes (the list of + * active network interfaces) + */ + interfacesKey = SCDynamicStoreKeyCreateNetworkInterface(NULL, + kSCDynamicStoreDomainState); -static void -watchQuietDisable() -{ - if ((initKey == NULL) || (initRls == NULL)) { + /* + * watch for InterfaceNamer[.bundle] changes (quiet, timeout, + * and the list of pre-configured interfaces) + */ + namerKey = SCDynamicStoreKeyCreate(NULL, + CFSTR("%@" "InterfaceNamer"), + kSCDynamicStoreDomainPlugin); + + rls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0); + if (rls == NULL) { + SC_log(LOG_NOTICE, "SCDynamicStoreCreateRunLoopSource() failed: %s", SCErrorString(SCError())); + haveConfiguration = TRUE; return; } + CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode); + CFRelease(rls); - (void) SCDynamicStoreSetNotificationKeys(store, NULL, NULL); - - CFRunLoopSourceInvalidate(initRls); - CFRelease(initRls); - initRls = NULL; - - CFRelease(initKey); - initKey = NULL; - - return; -} - - -static void -watchQuietEnable() -{ - CFArrayRef keys; - Boolean ok; - - initKey = SCDynamicStoreKeyCreate(NULL, - CFSTR("%@" "InterfaceNamer"), - kSCDynamicStoreDomainPlugin); - - initRls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0); - CFRunLoopAddSource(CFRunLoopGetCurrent(), initRls, kCFRunLoopDefaultMode); - - keys = CFArrayCreate(NULL, (const void **)&initKey, 1, &kCFTypeArrayCallBacks); + keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + CFArrayAppendValue(keys, interfacesKey); + CFArrayAppendValue(keys, namerKey); ok = SCDynamicStoreSetNotificationKeys(store, keys, NULL); CFRelease(keys); if (!ok) { SC_log(LOG_NOTICE, "SCDynamicStoreSetNotificationKeys() failed: %s", SCErrorString(SCError())); - watchQuietDisable(); + haveConfiguration = TRUE; } return; @@ -399,6 +382,7 @@ watchQuietEnable() + static Boolean previousConfigurationAvailable() { @@ -419,24 +403,114 @@ done: return (properties != NULL); } + static void -watchQuietCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info) +storeCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info) { - Boolean _quiet; - Boolean _timeout = FALSE; + CFDictionaryRef dict; + CFArrayRef interfaces = NULL; + Boolean quiet = FALSE; + Boolean timeout = FALSE; + Boolean updated = FALSE; - _quiet = quiet(&_timeout); - if (_quiet -#if !TARGET_OS_IPHONE - || _timeout -#endif /* !TARGET_OS_IPHONE */ - ) { - watchQuietDisable(); + /* + * Capture/process KernelEventMonitor[.bundle] info + * 1. get list of active network interfaces + */ + dict = SCDynamicStoreCopyValue(store, interfacesKey); + if (dict != NULL) { + if (isA_CFDictionary(dict)) { + interfaces = CFDictionaryGetValue(dict, kSCPropNetInterfaces); + interfaces = isA_CFArray(interfaces); + if (interfaces != NULL) { + CFRetain(interfaces); + } + } + + CFRelease(dict); + } + + /* + * Capture/process InterfaceNamer[.bundle] info + * 1. check if IORegistry "quiet", "timeout" + * 2. get list of named pre-configured interfaces + * 3. merge list of active interfaces (from KEV) with the + * list of preconfigured interfaces. + */ + dict = SCDynamicStoreCopyValue(store, namerKey); + if (dict != NULL) { + if (isA_CFDictionary(dict)) { + CFArrayRef cur_preconfigured; + CFMutableArrayRef new_preconfigured = NULL; + + if (CFDictionaryContainsKey(dict, kInterfaceNamerKey_Quiet)) { + quiet = TRUE; + } + if (CFDictionaryContainsKey(dict, kInterfaceNamerKey_Timeout)) { + timeout = TRUE; + } + + cur_preconfigured = CFDictionaryGetValue(dict, kInterfaceNamerKey_PreConfiguredInterfaces); + cur_preconfigured = isA_CFArray(cur_preconfigured); + if ((cur_preconfigured != NULL) && (interfaces != NULL)) { + CFIndex i; + CFIndex n; + CFRange r = CFRangeMake(0, CFArrayGetCount(interfaces)); + + n = CFArrayGetCount(cur_preconfigured); + for (i = 0; i < n; i++) { + CFStringRef bsdName; + + bsdName = CFArrayGetValueAtIndex(cur_preconfigured, i); + if (!CFArrayContainsValue(interfaces, r, bsdName)) { + // if interface not currently active + continue; + } + + if (new_preconfigured == NULL) { + new_preconfigured = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + } + CFArrayAppendValue(new_preconfigured, bsdName); + } + } + + if (!_SC_CFEqual(preconfigured, new_preconfigured)) { + SC_log(LOG_INFO, "pre-configured interface list changed"); + + if (preconfigured != NULL) { + CFRelease(preconfigured); + } + if (new_preconfigured != NULL) { + CFRetain(new_preconfigured); + } + preconfigured = new_preconfigured; + + updated = TRUE; + } + + if (new_preconfigured != NULL) { + CFRelease(new_preconfigured); + } + } + + CFRelease(dict); + } + + if (interfaces != NULL) { + CFRelease(interfaces); } - if (_quiet || _timeout) { + if (!haveConfiguration && (quiet || timeout)) { static int logged = 0; + if (quiet +#if !TARGET_OS_IPHONE + || timeout +#endif /* !TARGET_OS_IPHONE */ + ) { + haveConfiguration = TRUE; + } + (void) establishNewPreferences(); if (restorePrefs) { @@ -444,11 +518,16 @@ watchQuietCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info) restorePrefs = FALSE; } - if (_timeout && (logged++ == 0)) { + if (timeout && (logged++ == 0)) { SC_log(LOG_ERR, "Network configuration creation timed out waiting for IORegistry"); } } + if (updated && (changedKeys != NULL)) { + // if pre-configured interface list changed + updateConfiguration(prefs, kSCPreferencesNotificationApply, (void *)store); + } + return; } @@ -577,6 +656,213 @@ flatten(SCPreferencesRef prefs, } +static CF_RETURNS_RETAINED SCNetworkServiceRef +copyInterfaceService(SCNetworkSetRef set, CFStringRef matchName) +{ + CFIndex i; + CFIndex n; + SCNetworkServiceRef service = NULL; + CFArrayRef services; + + services = SCNetworkSetCopyServices(set); + assert(services != NULL); + + n = CFArrayGetCount(services); + for (i = 0; i < n; i++) { + SCNetworkInterfaceRef interface; + + service = CFArrayGetValueAtIndex(services, i); + interface = SCNetworkServiceGetInterface(service); + if (interface != NULL) { + CFStringRef bsdName; + + bsdName = SCNetworkInterfaceGetBSDName(interface); + if (_SC_CFEqual(bsdName, matchName)) { + // if match + CFRetain(service); + break; + } + } + + service = NULL; + } + + CFRelease(services); + return service; +} + + +static CF_RETURNS_RETAINED CFStringRef +copyInterfaceUUID(CFStringRef bsdName) +{ + union { + unsigned char sha1_bytes[CC_SHA1_DIGEST_LENGTH]; + CFUUIDBytes uuid_bytes; + } bytes; + CC_SHA1_CTX ctx; + char if_name[IF_NAMESIZE]; + CFUUIDRef uuid; + CFStringRef uuid_str; + + // start with interface name + bzero(&if_name, sizeof(if_name)); + (void) _SC_cfstring_to_cstring(bsdName, + if_name, + sizeof(if_name), + kCFStringEncodingASCII); + + // create SHA1 hash + bzero(&bytes, sizeof(bytes)); + CC_SHA1_Init(&ctx); + CC_SHA1_Update(&ctx, + if_name, + sizeof(if_name)); + CC_SHA1_Final(bytes.sha1_bytes, &ctx); + + // create UUID string + uuid = CFUUIDCreateFromUUIDBytes(NULL, bytes.uuid_bytes); + uuid_str = CFUUIDCreateString(NULL, uuid); + CFRelease(uuid); + + return uuid_str; +} + + +static void +updatePreConfiguredConfiguration(SCPreferencesRef prefs) +{ + Boolean ok; + CFRange range; + SCNetworkSetRef set; + Boolean updated = FALSE; + + range.length = (preconfigured != NULL) ? CFArrayGetCount(preconfigured) : 0; + if (range.length == 0) { + // if no [preconfigured] interfaces + return; + } + range.location = 0; + + set = SCNetworkSetCopyCurrent(prefs); + if (set != NULL) { + CFArrayRef services; + + /* + * Check for (and remove) and network services associated with + * a pre-configured interface from the prefs. + */ + services = SCNetworkSetCopyServices(set); + if (services != NULL) { + CFIndex n; + + n = CFArrayGetCount(services); + for (CFIndex i = 0; i < n; i++) { + CFStringRef bsdName; + SCNetworkInterfaceRef interface; + SCNetworkServiceRef service; + + service = CFArrayGetValueAtIndex(services, i); + + interface = SCNetworkServiceGetInterface(service); + if (interface == NULL) { + // if no interface + continue; + } + + bsdName = SCNetworkInterfaceGetBSDName(interface); + if (bsdName == NULL) { + // if no interface name + continue; + } + + if (!CFArrayContainsValue(preconfigured, range, bsdName)) { + // if not preconfigured + continue; + } + + // remove [preconfigured] network service from the prefs + SC_log(LOG_NOTICE, "removing network service for %@", bsdName); + SCNetworkServiceRemove(service); + updated = TRUE; + } + + CFRelease(services); + } + + if (updated) { + // commit the updated prefs ... but don't apply + ok = SCPreferencesCommitChanges(prefs); + if (!ok) { + if (SCError() != EROFS) { + SC_log(LOG_NOTICE, "SCPreferencesCommitChanges() failed: %s", + SCErrorString(SCError())); + } + } + } + + /* + * Now, add a new network service for each pre-configured interface + */ + for (CFIndex i = 0; i < range.length; i++) { + CFStringRef bsdName; + SCNetworkInterfaceRef interface; + SCNetworkServiceRef service; + + bsdName = CFArrayGetValueAtIndex(preconfigured, i); + interface = _SCNetworkInterfaceCreateWithBSDName(NULL, bsdName, kIncludeNoVirtualInterfaces); + if (interface == NULL) { + SC_log(LOG_ERR, "could not create network interface for %@", bsdName); + continue; + } + + if (_SCNetworkInterfaceGetIOPath(interface) == NULL) { + // if no [real] interface exists + CFRelease(interface); + continue; + } + + ok = SCNetworkSetEstablishDefaultInterfaceConfiguration(set, interface); + CFRelease(interface); + if (!ok) { + SC_log(LOG_ERR, "could not create network service for %@", bsdName); + continue; + } + + service = copyInterfaceService(set, bsdName); + if (service != NULL) { + CFStringRef serviceID; + + serviceID = copyInterfaceUUID(bsdName); + if (serviceID != NULL) { + ok = _SCNetworkServiceSetServiceID(service, serviceID); + CFRelease(serviceID); + if (!ok) { + SC_log(LOG_ERR, "_SCNetworkServiceSetServiceID() failed: %s", + SCErrorString(SCError())); + // ... and keep whatever random UUID was created for the service + } + } else { + SC_log(LOG_ERR, "could not create serviceID for %@", bsdName); + // ... and we'll use whatever random UUID was created for the service + } + + SC_log(LOG_INFO, "network service %@ added for %@", + SCNetworkServiceGetServiceID(service), + bsdName); + + CFRelease(service); + } else { + SC_log(LOG_ERR, "could not find network service for %@", bsdName); + } + } + + CFRelease(set); + } + + return; +} + + static void updateSCDynamicStore(SCPreferencesRef prefs) { @@ -783,7 +1069,7 @@ updateConfiguration(SCPreferencesRef prefs, current = SCNetworkSetCopyCurrent(prefs); if (current != NULL) { /* network configuration available, disable template creation */ - watchQuietDisable(); + haveConfiguration = TRUE; CFRelease(current); } } @@ -795,6 +1081,9 @@ updateConfiguration(SCPreferencesRef prefs, SC_log(LOG_INFO, "updating configuration"); + /* add any [Apple] pre-configured network services */ + updatePreConfiguredConfiguration(prefs); + /* update SCDynamicStore (Setup:) */ updateSCDynamicStore(prefs); @@ -828,15 +1117,13 @@ __private_extern__ void load_PreferencesMonitor(CFBundleRef bundle, Boolean bundleVerbose) { - Boolean initPrefs = TRUE; - SC_log(LOG_DEBUG, "load() called"); SC_log(LOG_DEBUG, " bundle ID = %@", CFBundleGetIdentifier(bundle)); /* open a SCDynamicStore session to allow cache updates */ store = SCDynamicStoreCreate(NULL, CFSTR("PreferencesMonitor.bundle"), - watchQuietCallback, + storeCallback, NULL); if (store == NULL) { SC_log(LOG_NOTICE, "SCDynamicStoreCreate() failed: %s", SCErrorString(SCError())); @@ -873,7 +1160,7 @@ load_PreferencesMonitor(CFBundleRef bundle, Boolean bundleVerbose) current = SCNetworkSetCopyCurrent(prefs); if (current != NULL) { /* network configuration available, disable template creation */ - initPrefs = FALSE; + haveConfiguration = TRUE; CFRelease(current); } } @@ -896,21 +1183,21 @@ load_PreferencesMonitor(CFBundleRef bundle, Boolean bundleVerbose) } /* - * if no preferences, initialize with a template (now or - * when IOKit has quiesced). + * watch InterfaceNamer and KernelEventMonitor changes to know when + * the IORegistry has quiesced (to create the initial configuration + * template), to track any pre-configured interfaces, and to ensure + * that we create a network service for any active interfaces. */ - if (initPrefs) { - watchQuietEnable(); - watchQuietCallback(store, NULL, NULL); - } + watchSCDynamicStore(); + storeCallback(store, NULL, NULL); return; error : - watchQuietDisable(); if (store != NULL) CFRelease(store); if (prefs != NULL) CFRelease(prefs); + haveConfiguration = TRUE; return; } diff --git a/Plugins/common/plugin_shared.h b/Plugins/common/plugin_shared.h new file mode 100644 index 0000000..bc2a7f3 --- /dev/null +++ b/Plugins/common/plugin_shared.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016 Apple Computer, 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, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * 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@ + */ + +/* + * Modification History + * + * September 8, 2016 Allan Nathanson + * - initial revision + */ + + +#ifndef _PLUGIN_SHARED_H +#define _PLUGIN_SHARED_H + + +#include + + +#pragma mark - +#pragma mark InterfaceNamer.bundle --> others + +/* + * Plugin:InterfaceNamer [SCDynamicStore] dictionary content + */ + +// IORegistry "quiet" (and timeout) +#define kInterfaceNamerKey_Quiet CFSTR("*QUIET*") +#define kInterfaceNamerKey_Timeout CFSTR("*TIMEOUT*") + +// [Apple] pre-configured network interfaces +#define kInterfaceNamerKey_PreConfiguredInterfaces CFSTR("_PreConfigured_") + +// BT-PAN network interfaces +#define BT_PAN_NAME "Bluetooth PAN" +#define kInterfaceNamerKey_BT_PAN_Name CFSTR("_" BT_PAN_NAME "_") +#define kInterfaceNamerKey_BT_PAN_Mac CFSTR("_" BT_PAN_NAME " (MAC)" "_") + + +#endif /* _PLUGIN_SHARED_H */ diff --git a/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h b/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h index 537bab5..306d56c 100644 --- a/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h +++ b/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h @@ -391,6 +391,15 @@ _SCNetworkInterfaceGetIOPath (SCNetworkInterfaceRef interface) __OSX_AVAILAB uint64_t _SCNetworkInterfaceGetIORegistryEntryID (SCNetworkInterfaceRef interface) __OSX_AVAILABLE_STARTING(__MAC_10_8,__IPHONE_5_0); +/*! + @function _SCNetworkInterfaceIsApplePreconfigured + @discussion Identifies if a network interface is internal/pre-configured. + @param interface The network interface. + @result TRUE if the interface is an internal/pre-configured. + */ +Boolean +_SCNetworkInterfaceIsApplePreconfigured (SCNetworkInterfaceRef interface) __OSX_AVAILABLE_STARTING(__MAC_10_12,__IPHONE_10_0); + /*! @function _SCNetworkInterfaceIsBluetoothPAN @discussion Identifies if a network interface is a Bluetooth PAN (GN) device. diff --git a/SystemConfiguration.fproj/SCNetworkInterface.c b/SystemConfiguration.fproj/SCNetworkInterface.c index 6e0dace..20791fa 100644 --- a/SystemConfiguration.fproj/SCNetworkInterface.c +++ b/SystemConfiguration.fproj/SCNetworkInterface.c @@ -40,6 +40,7 @@ #include "SCNetworkConfigurationInternal.h" #include "SCPreferencesInternal.h" #include "SCHelper_client.h" +#include "plugin_shared.h" #if !TARGET_OS_IPHONE #include @@ -78,6 +79,10 @@ #define kIOUserEthernetInterfaceRoleKey "InterfaceRole" #endif +#ifndef kIOUSBHostInterfaceClassName +#define kIOUSBHostInterfaceClassName "IOUSBHostInterface" +#endif + #include #include #include @@ -1711,9 +1716,6 @@ merge_override(SCNetworkInterfacePrivateRef interfacePrivate, } -#define BT_PAN_NAME "Bluetooth PAN" -#define BT_PAN_MAC BT_PAN_NAME " (MAC)" - static Boolean processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate, io_registry_entry_t interface, @@ -1926,7 +1928,8 @@ processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate, while (provider != NULL) { #if !TARGET_OS_SIMULATOR if (CFEqual(provider, CFSTR(kIOUSBDeviceClassName)) || - CFEqual(provider, CFSTR(kIOUSBInterfaceClassName))) { + CFEqual(provider, CFSTR(kIOUSBInterfaceClassName)) || + CFEqual(provider, CFSTR(kIOUSBHostInterfaceClassName))) { // get USB info (if available) processUSBInterface(interfacePrivate, interface, @@ -2670,8 +2673,10 @@ createInterface(io_registry_entry_t interface, processInterface func, static CF_RETURNS_RETAINED CFArrayRef -findMatchingInterfaces(CFDictionaryRef matching, processInterface func, - CFStringRef hidden_key) +findMatchingInterfaces(CFDictionaryRef matching, + processInterface func, + CFStringRef hidden_key, + Boolean keep_pre_configured) { CFMutableArrayRef interfaces; io_registry_entry_t interface; @@ -2698,7 +2703,9 @@ findMatchingInterfaces(CFDictionaryRef matching, processInterface func, match = createInterface(interface, func, hidden_key); if (match != NULL) { - CFArrayAppendValue(interfaces, match); + if (keep_pre_configured || !_SCNetworkInterfaceIsApplePreconfigured(match)) { + CFArrayAppendValue(interfaces, match); + } CFRelease(match); } @@ -3927,7 +3934,10 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator, if (matching == NULL) { goto done; } - matching_interfaces = findMatchingInterfaces(matching, processNetworkInterface, kSCNetworkInterfaceHiddenInterfaceKey); + matching_interfaces = findMatchingInterfaces(matching, + processNetworkInterface, + kSCNetworkInterfaceHiddenInterfaceKey, + TRUE); CFRelease(matching); } } else if (CFEqual(ifType, kSCValNetInterfaceTypePPP)) { @@ -3953,7 +3963,10 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator, sizeof(match_keys)/sizeof(match_keys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - matching_interfaces = findMatchingInterfaces(matching, processSerialInterface, kSCNetworkInterfaceHiddenPortKey); + matching_interfaces = findMatchingInterfaces(matching, + processSerialInterface, + kSCNetworkInterfaceHiddenPortKey, + TRUE); CFRelease(matching); } if (ifUnique == NULL) { @@ -3987,7 +4000,10 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator, sizeof(match_keys)/sizeof(match_keys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - matching_interfaces = findMatchingInterfaces(matching, processSerialInterface, kSCNetworkInterfaceHiddenPortKey); + matching_interfaces = findMatchingInterfaces(matching, + processSerialInterface, + kSCNetworkInterfaceHiddenPortKey, + TRUE); CFRelease(matching); } } @@ -4393,7 +4409,10 @@ __SCNetworkInterfaceCopyAll_IONetworkInterface(void) // get Ethernet, Firewire, Thunderbolt, and AirPort interfaces matching = IOServiceMatching(kIONetworkInterfaceClass); - new_interfaces = findMatchingInterfaces(matching, processNetworkInterface, kSCNetworkInterfaceHiddenInterfaceKey); + new_interfaces = findMatchingInterfaces(matching, + processNetworkInterface, + kSCNetworkInterfaceHiddenInterfaceKey, + FALSE); CFRelease(matching); return new_interfaces; @@ -4421,7 +4440,10 @@ __SCNetworkInterfaceCopyAll_Modem() sizeof(match_keys)/sizeof(match_keys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - new_interfaces = findMatchingInterfaces(matching, processSerialInterface, kSCNetworkInterfaceHiddenPortKey); + new_interfaces = findMatchingInterfaces(matching, + processSerialInterface, + kSCNetworkInterfaceHiddenPortKey, + FALSE); CFRelease(matching); return new_interfaces; @@ -4449,7 +4471,10 @@ __SCNetworkInterfaceCopyAll_RS232() sizeof(match_keys)/sizeof(match_keys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - new_interfaces = findMatchingInterfaces(matching, processSerialInterface, kSCNetworkInterfaceHiddenPortKey); + new_interfaces = findMatchingInterfaces(matching, + processSerialInterface, + kSCNetworkInterfaceHiddenPortKey, + FALSE); CFRelease(matching); return new_interfaces; @@ -4540,8 +4565,8 @@ __waitForInterfaces() dict = SCDynamicStoreCopyValue(store, key); if (dict != NULL) { if (isA_CFDictionary(dict) && - (CFDictionaryContainsKey(dict, CFSTR("*QUIET*")) || - CFDictionaryContainsKey(dict, CFSTR("*TIMEOUT*")))) { + (CFDictionaryContainsKey(dict, kInterfaceNamerKey_Quiet) || + CFDictionaryContainsKey(dict, kInterfaceNamerKey_Timeout))) { quiet = TRUE; } CFRelease(dict); @@ -7122,7 +7147,7 @@ _SCNetworkInterfaceCopyBTPANInterface(void) if (isA_CFDictionary(dict) && CFDictionaryGetValueIfPresent(dict, - CFSTR("_" BT_PAN_NAME "_"), + kInterfaceNamerKey_BT_PAN_Name, (const void **)&if_name) && isA_CFString(if_name)) { CFMutableDictionaryRef entity; @@ -7149,7 +7174,7 @@ _SCNetworkInterfaceCopyBTPANInterface(void) if ((interfacePrivate != NULL) && (interfacePrivate->address == NULL) && CFDictionaryGetValueIfPresent(dict, - CFSTR("_" BT_PAN_MAC "_"), + kInterfaceNamerKey_BT_PAN_Mac, (const void **)&addr) && isA_CFData(addr)) { interfacePrivate->address = CFRetain(addr); @@ -7276,6 +7301,44 @@ _SCNetworkInterfaceCopySlashDevPath(SCNetworkInterfaceRef interface) #pragma mark - +Boolean +_SCNetworkInterfaceIsApplePreconfigured(SCNetworkInterfaceRef interface) +{ +#if !TARGET_OS_SIMULATOR + SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; + + if (!interfacePrivate->hidden) { + // if not HiddenConfiguration + return FALSE; + } + + if ((interfacePrivate->overrides == NULL) || + (!CFDictionaryContainsKey(interfacePrivate->overrides, kSCNetworkProtocolTypeIPv4) && + !CFDictionaryContainsKey(interfacePrivate->overrides, kSCNetworkProtocolTypeIPv6))) { + // if no [IPv4/IPv6] configuration overrides + return FALSE; + } + + if (interfacePrivate->builtin) { + // if built-in (and overrides are present) + return TRUE; + } + + if (isA_CFNumber(interfacePrivate->usb.vid)) { + int vid; + + if (CFNumberGetValue(interfacePrivate->usb.vid, kCFNumberIntType, &vid) && + (vid == kIOUSBVendorIDAppleComputer)) { + // if Apple interface (and overrides are present) + return TRUE; + } + } +#endif // !TARGET_OS_SIMULATOR + + return FALSE; +} + + Boolean _SCNetworkInterfaceIsBluetoothPAN(SCNetworkInterfaceRef interface) { diff --git a/configd.xcodeproj/project.pbxproj b/configd.xcodeproj/project.pbxproj index 6151974..0c0c3df 100644 --- a/configd.xcodeproj/project.pbxproj +++ b/configd.xcodeproj/project.pbxproj @@ -295,6 +295,13 @@ 1565D85018B847590097062B /* SCNetworkMigration.c in Sources */ = {isa = PBXBuildFile; fileRef = 55A3DB9D183C2A8200ED3DB7 /* SCNetworkMigration.c */; }; 1565D85118B847F20097062B /* SCNetworkMigration.c in Sources */ = {isa = PBXBuildFile; fileRef = 55A3DB9D183C2A8200ED3DB7 /* SCNetworkMigration.c */; }; 156BD6BC07E0DFA9008698FF /* SCPreferencesSetSpecificPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 156BD6BB07E0DFA9008698FF /* SCPreferencesSetSpecificPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 1572AA8C1D8235390021E093 /* plugin_shared.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572AA8B1D8234500021E093 /* plugin_shared.h */; }; + 1572AA8D1D8235940021E093 /* plugin_shared.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572AA8B1D8234500021E093 /* plugin_shared.h */; }; + 1572AA8E1D8235A40021E093 /* plugin_shared.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572AA8B1D8234500021E093 /* plugin_shared.h */; }; + 1572AA8F1D82375A0021E093 /* plugin_shared.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572AA8B1D8234500021E093 /* plugin_shared.h */; }; + 1572AA901D8237810021E093 /* plugin_shared.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572AA8B1D8234500021E093 /* plugin_shared.h */; }; + 1572AA911D82379E0021E093 /* plugin_shared.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572AA8B1D8234500021E093 /* plugin_shared.h */; }; + 1572AA921D8237A30021E093 /* plugin_shared.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572AA8B1D8234500021E093 /* plugin_shared.h */; }; 1572C4A90CFB55B400E2776E /* SCSchemaDefinitions.h in Headers */ = {isa = PBXBuildFile; fileRef = 150607DE075A00A300B147BA /* SCSchemaDefinitions.h */; settings = {ATTRIBUTES = (Public, ); }; }; 1572C4AA0CFB55B400E2776E /* SystemConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691305C0722B0099E85F /* SystemConfiguration.h */; settings = {ATTRIBUTES = (Project, Public, ); }; }; 1572C4AB0CFB55B400E2776E /* SCPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691505C0722B0099E85F /* SCPrivate.h */; settings = {ATTRIBUTES = (Private, Project, ); }; }; @@ -1625,6 +1632,7 @@ 155F49A51C864FE500E47D08 /* qos-marking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "qos-marking.m"; path = "Plugins/QoSMarking/qos-marking.m"; sourceTree = ""; }; 1567333E0DD1FD6500145179 /* entitlements-ios.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "entitlements-ios.plist"; sourceTree = ""; }; 156BD6BB07E0DFA9008698FF /* SCPreferencesSetSpecificPrivate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCPreferencesSetSpecificPrivate.h; sourceTree = ""; }; + 1572AA8B1D8234500021E093 /* plugin_shared.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = plugin_shared.h; sourceTree = ""; }; 1572C57E171CCF9500870549 /* pppcontroller_mach_defines.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; name = pppcontroller_mach_defines.h; path = usr/local/include/ppp/pppcontroller_mach_defines.h; sourceTree = SDKROOT; }; 1572EB7A0A506D3B00D02459 /* smb-configuration.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = "smb-configuration.c"; sourceTree = ""; }; 15732AAC16EA503300F3AC4C /* configd_sim */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = configd_sim; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -2391,6 +2399,7 @@ F9A3780F16A4846E00C57CDC /* IPMonitorControlPrefs.h */, 159D53CA07528B36004F8947 /* cache.c */, 159D53CB07528B36004F8947 /* cache.h */, + 1572AA8B1D8234500021E093 /* plugin_shared.h */, ); name = common; path = Plugins/common; @@ -3174,6 +3183,7 @@ 1572C4D40CFB55B400E2776E /* SCNetworkConnectionPrivate.h in Headers */, 1572C4D50CFB55B400E2776E /* SCPreferencesKeychainPrivate.h in Headers */, F9347FF8187C7993003D4178 /* IPMonitorControl.h in Headers */, + 1572AA901D8237810021E093 /* plugin_shared.h in Headers */, F9347FF9187C7993003D4178 /* IPMonitorControlPrivate.h in Headers */, F9347FFA187C7993003D4178 /* symbol_scope.h in Headers */, 1572C4D60CFB55B400E2776E /* SCSchemaDefinitionsPrivate.h in Headers */, @@ -3305,6 +3315,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 1572AA8C1D8235390021E093 /* plugin_shared.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3332,6 +3343,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 1572AA911D82379E0021E093 /* plugin_shared.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3375,6 +3387,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 1572AA8F1D82375A0021E093 /* plugin_shared.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3414,6 +3427,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 1572AA8D1D8235940021E093 /* plugin_shared.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3482,6 +3496,7 @@ 15A1FF3410597F17004C9CC9 /* CaptiveNetwork.h in Headers */, 159A7528107FEAA400A57EAB /* VPNPrivate.h in Headers */, 159A752A107FEAA400A57EAB /* VPNConfiguration.h in Headers */, + 1572AA921D8237A30021E093 /* plugin_shared.h in Headers */, 15C330D3134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */, 727AF25419138699009AB153 /* VPNAppLayerPrivate.h in Headers */, 15D8B22C1450D8450090CECF /* SCD.h in Headers */, @@ -3551,6 +3566,7 @@ 154CF3F407E1EA4D00D8302E /* SCPreferencesGetSpecificPrivate.h in Headers */, C4CDB8171631938000819B44 /* VPNFlow.h in Headers */, 155A1E6C081079CC00F70D98 /* SCNetworkConfigurationPrivate.h in Headers */, + 1572AA8E1D8235A40021E093 /* plugin_shared.h in Headers */, 155B7BF80847776D00F0E262 /* SCHelper_client.h in Headers */, 15D8B22A1450D8450090CECF /* SCD.h in Headers */, 15A297300A13C08C009879B3 /* SCNetworkConnectionPrivate.h in Headers */, diff --git a/dnsinfo/dnsinfo.h b/dnsinfo/dnsinfo.h index d0239a9..6b27c81 100644 --- a/dnsinfo/dnsinfo.h +++ b/dnsinfo/dnsinfo.h @@ -1,15 +1,15 @@ /* - * Copyright (c) 2004-2006, 2008, 2009, 2011-2013, 2015 Apple Inc. All rights reserved. + * Copyright (c) 2004-2006, 2008, 2009, 2011-2013, 2015, 2016 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@ */ @@ -35,7 +35,7 @@ #include #include -#define DNSINFO_VERSION 20140114 +#define DNSINFO_VERSION 20160901 #define DEFAULT_SEARCH_ORDER 200000 /* search order for the "default" resolver domain name */ @@ -80,14 +80,17 @@ typedef struct { #pragma pack() -#define DNS_RESOLVER_FLAGS_SCOPED 1 /* configuration is for scoped questions */ -#define DNS_RESOLVER_FLAGS_REQUEST_A_RECORDS 2 /* always requesting for A dns records in queries */ -#define DNS_RESOLVER_FLAGS_REQUEST_AAAA_RECORDS 4 /* always requesting for AAAA dns records in queries */ -#define DNS_RESOLVER_FLAGS_SERVICE_SPECIFIC 8 /* configuration is service-specific */ +#define DNS_RESOLVER_FLAGS_REQUEST_A_RECORDS 0x0002 /* always requesting for A dns records in queries */ +#define DNS_RESOLVER_FLAGS_REQUEST_AAAA_RECORDS 0x0004 /* always requesting for AAAA dns records in queries */ #define DNS_RESOLVER_FLAGS_REQUEST_ALL_RECORDS \ (DNS_RESOLVER_FLAGS_REQUEST_A_RECORDS | DNS_RESOLVER_FLAGS_REQUEST_AAAA_RECORDS) +#define DNS_RESOLVER_FLAGS_SCOPED 0x1000 /* configuration is for scoped questions */ +#define DNS_RESOLVER_FLAGS_SERVICE_SPECIFIC 0x2000 /* configuration is service-specific */ +#define DNS_RESOLVER_FLAGS_SUPPLEMENTAL 0x4000 /* supplemental match configuration */ + + #pragma pack(4) typedef struct { DNS_VAR(int32_t, n_resolver); /* resolver configurations */ diff --git a/dnsinfo/dnsinfo_internal.h b/dnsinfo/dnsinfo_internal.h index 9ab6af7..71b31fb 100644 --- a/dnsinfo/dnsinfo_internal.h +++ b/dnsinfo/dnsinfo_internal.h @@ -422,6 +422,10 @@ _dns_resolver_log(dns_resolver_t *resolver, int index, Boolean debug) flags &= ~DNS_RESOLVER_FLAGS_SERVICE_SPECIFIC; CFStringAppendFormat(str, NULL, CFSTR("Service-specific%s"), flags != 0 ? ", " : ""); } + if (flags & DNS_RESOLVER_FLAGS_SUPPLEMENTAL) { + flags &= ~DNS_RESOLVER_FLAGS_SUPPLEMENTAL; + CFStringAppendFormat(str, NULL, CFSTR("Supplemental%s"), flags != 0 ? ", " : ""); + } if (flags & DNS_RESOLVER_FLAGS_REQUEST_A_RECORDS) { flags &= ~DNS_RESOLVER_FLAGS_REQUEST_A_RECORDS; CFStringAppendFormat(str, NULL, CFSTR("Request A records%s"), flags != 0 ? ", " : ""); diff --git a/scutil.tproj/net_interface.c b/scutil.tproj/net_interface.c index 1c12c19..a18ef93 100644 --- a/scutil.tproj/net_interface.c +++ b/scutil.tproj/net_interface.c @@ -273,6 +273,13 @@ _find_interface(int argc, char **argv, int *nArgs) goto done; } + // try to select an [Apple] pre-configured / hidden interface by its BSD name + + selected = _SCNetworkInterfaceCreateWithBSDName(NULL, select_name, kIncludeNoVirtualInterfaces); + if (selected != NULL) { + goto done; + } + // try to select the interface by its interface type for (i = 0; i < n; i++) { @@ -764,6 +771,10 @@ _show_interface(SCNetworkInterfaceRef interface, CFStringRef prefix, Boolean sho prefix, isPhysicalEthernet ? "" : " not"); + if (_SCNetworkInterfaceIsApplePreconfigured(interface)) { + SCPrint(TRUE, stdout, CFSTR("%@ is pre-configured\n"), prefix); + } + if (configuration != NULL) { CFMutableDictionaryRef effective;