]> git.saurik.com Git - apple/configd.git/commitdiff
configd-888.20.5.tar.gz macos-10121 v888.20.5
authorApple <opensource@apple.com>
Tue, 29 Nov 2016 22:00:22 +0000 (22:00 +0000)
committerApple <opensource@apple.com>
Tue, 29 Nov 2016 22:00:22 +0000 (22:00 +0000)
.gitignore [new file with mode: 0644]
Plugins/IPMonitor/dns-configuration.c
Plugins/InterfaceNamer/ifnamer.c
Plugins/PreferencesMonitor/prefsmon.c
Plugins/common/plugin_shared.h [new file with mode: 0644]
SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h
SystemConfiguration.fproj/SCNetworkInterface.c
configd.xcodeproj/project.pbxproj
dnsinfo/dnsinfo.h
dnsinfo/dnsinfo_internal.h
scutil.tproj/net_interface.c

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..7d05b74
--- /dev/null
@@ -0,0 +1,9 @@
+.DS_Store
+*.xcodeproj/project.xcworkspace
+*.xcodeproj/xcuserdata
+.svn
+build
+*~
+*~.c
+*~.h
+*~.m
index 7beea0202293bae6cd72444993d6e5aba739cc89..6fff6a0cc604cb00e6fc33685c4c9eadcc58074e 100644 (file)
@@ -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
        }
index a3f4e9691a1619bcac87c64fb1a7b9b779f01b0e..82ae9858cc0c8726949b789f32ca162e36ad91d9 100644 (file)
@@ -80,6 +80,7 @@
 #include <SystemConfiguration/SCDPlugin.h>
 #include <SystemConfiguration/SCPrivate.h>
 #include <SystemConfiguration/SCValidation.h>
+#include "plugin_shared.h"
 
 #include <IOKit/IOKitLib.h>
 #include <IOKit/IOKitLibPrivate.h>
@@ -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");
index c0d6b9d120c52a79105a2ed35da61a8832f598a9..8a091e2dffedd76f63af03cdb80666509a20cd98 100644 (file)
@@ -37,6 +37,7 @@
 
 #include <TargetConditionals.h>
 #include <fcntl.h>
+#include <net/if.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <SystemConfiguration/SystemConfiguration.h>
 #include <SystemConfiguration/SCPrivate.h>
 #include <SystemConfiguration/SCValidation.h>
+#include "plugin_shared.h"
 
 
+#include <CommonCrypto/CommonDigest.h>
+
 
 /* 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 (file)
index 0000000..bc2a7f3
--- /dev/null
@@ -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 <ajn@apple.com>
+ * - initial revision
+ */
+
+
+#ifndef        _PLUGIN_SHARED_H
+#define        _PLUGIN_SHARED_H
+
+
+#include <CoreFoundation/CoreFoundation.h>
+
+
+#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 */
index 537bab5b432bf6efecc7b9c8200d2ab79f9fa060..306d56c88ae124298c67d7f9135acd1afcf1fc3a 100644 (file)
@@ -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.
index 6e0dace19b1797196ae5228e1aded0bb8c9a124f..20791faf5da8493f21e6414f0932ba01fcd6e030 100644 (file)
@@ -40,6 +40,7 @@
 #include "SCNetworkConfigurationInternal.h"
 #include "SCPreferencesInternal.h"
 #include "SCHelper_client.h"
+#include "plugin_shared.h"
 
 #if    !TARGET_OS_IPHONE
 #include <EAP8021X/EAPClientProperties.h>
 #define        kIOUserEthernetInterfaceRoleKey "InterfaceRole"
 #endif
 
+#ifndef        kIOUSBHostInterfaceClassName
+#define kIOUSBHostInterfaceClassName   "IOUSBHostInterface"
+#endif
+
 #include <string.h>
 #include <sysdir.h>
 #include <mach/mach.h>
@@ -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)
 {
index 6151974ac083ee6d1efec8b13a2cc63337f8da91..0c0c3dfdd279d0cd9099672205ae82c134e4ec06 100644 (file)
                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, ); }; };
                155F49A51C864FE500E47D08 /* qos-marking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "qos-marking.m"; path = "Plugins/QoSMarking/qos-marking.m"; sourceTree = "<group>"; };
                1567333E0DD1FD6500145179 /* entitlements-ios.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "entitlements-ios.plist"; sourceTree = "<group>"; };
                156BD6BB07E0DFA9008698FF /* SCPreferencesSetSpecificPrivate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCPreferencesSetSpecificPrivate.h; sourceTree = "<group>"; };
+               1572AA8B1D8234500021E093 /* plugin_shared.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = plugin_shared.h; sourceTree = "<group>"; };
                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 = "<group>"; };
                15732AAC16EA503300F3AC4C /* configd_sim */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = configd_sim; sourceTree = BUILT_PRODUCTS_DIR; };
                                F9A3780F16A4846E00C57CDC /* IPMonitorControlPrefs.h */,
                                159D53CA07528B36004F8947 /* cache.c */,
                                159D53CB07528B36004F8947 /* cache.h */,
+                               1572AA8B1D8234500021E093 /* plugin_shared.h */,
                        );
                        name = common;
                        path = Plugins/common;
                                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 */,
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               1572AA8C1D8235390021E093 /* plugin_shared.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               1572AA911D82379E0021E093 /* plugin_shared.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               1572AA8F1D82375A0021E093 /* plugin_shared.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               1572AA8D1D8235940021E093 /* plugin_shared.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                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 */,
                                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 */,
index d0239a9acb9ebcb0a2ad0a806a514b2265f74539..6b27c813e87ccd8c6dd5181beb7907e84c5c4556 100644 (file)
@@ -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 <sys/socket.h>
 #include <netinet/in.h>
 
-#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 */
index 9ab6af7b14d4d1caec3e65776df2d0e1859d7a09..71b31fbad875ef5159f19f3cf4b410a30ee9507e 100644 (file)
@@ -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 ? ", " : "");
index 1c12c1912da1bab9d81f5b216d948093a6a0f8ba..a18ef9352d6bc9d01d83bcb39a492dbad5b6eb6e 100644 (file)
@@ -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;