]> git.saurik.com Git - apple/configd.git/commitdiff
configd-1061.101.1.tar.gz macos-10154 v1061.101.1
authorApple <opensource@apple.com>
Fri, 1 May 2020 18:25:39 +0000 (18:25 +0000)
committerApple <opensource@apple.com>
Fri, 1 May 2020 18:25:39 +0000 (18:25 +0000)
38 files changed:
Plugins/InterfaceNamer/Makefile
Plugins/InterfaceNamer/ifnamer.c
Plugins/PreferencesMonitor/prefsmon.c
SystemConfiguration.fproj/SCD.c
SystemConfiguration.fproj/SCDHostName.c
SystemConfiguration.fproj/SCDOpen.c
SystemConfiguration.fproj/SCDPrivate.c
SystemConfiguration.fproj/SCNetworkConfigurationInternal.c
SystemConfiguration.fproj/SCNetworkConfigurationInternal.h
SystemConfiguration.fproj/SCNetworkConfigurationPrivate.c [new file with mode: 0644]
SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h
SystemConfiguration.fproj/SCNetworkInterface.c
SystemConfiguration.fproj/SCNetworkMigration.c
SystemConfiguration.fproj/SCNetworkProtocol.c
SystemConfiguration.fproj/SCNetworkService.c
SystemConfiguration.fproj/SCP.c
SystemConfiguration.fproj/SCPCommit.c
SystemConfiguration.fproj/SCPOpen.c
SystemConfiguration.fproj/SCPreferencesInternal.h
SystemConfiguration.fproj/SCPreferencesPrivate.h
SystemConfiguration.fproj/SCPrivate.h
SystemConfiguration.fproj/SCSchemaDefinitions.c
SystemConfiguration.fproj/SCSchemaDefinitions.h
SystemConfiguration.fproj/SCSchemaDefinitionsPrivate.h
SystemConfiguration.fproj/genSCPreferences.c
configd.xcodeproj/project.pbxproj
sctest/SCTestInterfaceNamer.m [new file with mode: 0644]
sctest/SCTestOptions.h
sctest/SCTestUtils.h
sctest/genSCTestOptions.c
sctest/main.m
scutil.tproj/commands.c
scutil.tproj/net.c
scutil.tproj/net.h
scutil.tproj/prefs.c
scutil.tproj/prefs.h
scutil.tproj/scutil.c
scutil.tproj/scutil.h

index 705d8aff6bcb002efb362e3cba69d692ab819f2f..aef0460f6a5a440752108cde29582aa17c0b5158 100644 (file)
@@ -1,13 +1,63 @@
 
 
-ifnamer: ifnamer.c
-       cc -Wall -g -DMAIN               -o ifnamer  ifnamer.c -framework CoreFoundation -framework SystemConfiguration -framework IOKit
+ifeq ($(PLATFORM),)
+PLATFORM=macosx
+endif
 
 
-snapshot: ifnamer.c
-       cc -Wall -g -DTEST_SNAPSHOT      -o snapshot ifnamer.c -framework CoreFoundation -framework SystemConfiguration -framework IOKit
+ifeq ($(PLATFORM),iphoneos)
+# iOS internal SDK
+ARCHS=arm64
+endif
 
 
-uuid: ifnamer.c
-       cc -Wall -g -DTEST_PLATFORM_UUID -o uuid     ifnamer.c -framework CoreFoundation -framework SystemConfiguration -framework IOKit
+ifeq ($(PLATFORM),macosx)
+# Mac OS X internal SDK
+ARCHS=x86_64
+endif
+
+
+ifeq ($(USER),ajn)
+  ifeq ($(PLATFORM),macosx)
+    PLATFORM=macosx$(OSX_VERSION)
+    EXTRA=-target $(ARCHS)-apple-macos$(OSX_VERSION) -F${BUILDIT_DIR}/configd-999.roots/Shared/SDKContentRoot/osx/System/Library/Frameworks
+  endif
+  ifeq ($(PLATFORM),iphoneos)
+    PLATFORM=ios$(EMBEDDED_VERSION)
+    EXTRA=-target $(ARCHS)-apple-ios$(EMBEDDED_VERSION) -F${BUILDIT_DIR}_Embedded/configd-999.roots/Shared/SDKContentRoot/ios/System/Library/Frameworks
+  endif
+  EXTRA+=-DDEBUG
+endif
+
+
+# Mac OS X or iOS internal SDK
+SDK=$(PLATFORM)internal
+SYSROOT=$(shell xcodebuild -version -sdk $(SDK) Path)
+CC = xcrun -sdk $(SDK) cc
+
+
+all : ifnamer snapshot
+
+# ---------- ---------- ---------- ---------- ----------
+
+InterfaceNamerControlPrefs.o : ../../Plugins/common/InterfaceNamerControlPrefs.c ../../Plugins/common/InterfaceNamerControlPrefs.h Makefile
+       $(CC) -DOS_ACTIVITY_OBJECT_API=1 -I../../SystemConfiguration.fproj -I../../IPMonitorControl -I../../Plugins/common ${EXTRA} -I${SYSROOT}/System/Library/Frameworks/System.framework/PrivateHeaders -Wall -g -O0 -c ../../Plugins/common/InterfaceNamerControlPrefs.c
+
+# ---------- ---------- ---------- ---------- ----------
+
+ifnamer.o: ifnamer.c Makefile
+       $(CC) -DOS_ACTIVITY_OBJECT_API=1 -I../../SystemConfiguration.fproj -I../../IPMonitorControl -I../../Plugins/common ${EXTRA} -I${SYSROOT}/System/Library/Frameworks/System.framework/PrivateHeaders -Wall -g -DTEST_INTERFACE_ASSIGNMENT -O0 -c ifnamer.c
+
+ifnamer: ifnamer.o InterfaceNamerControlPrefs.o Makefile
+       $(CC) -o ifnamer ifnamer.o InterfaceNamerControlPrefs.o ${EXTRA} -framework CoreFoundation -framework SystemConfiguration -framework IOKit
+
+# ---------- ---------- ---------- ---------- ----------
+
+snapshot.o: ifnamer.c Makefile
+       $(CC) -DOS_ACTIVITY_OBJECT_API=1 -I../../SystemConfiguration.fproj -I../../IPMonitorControl -I../../Plugins/common ${EXTRA} -I${SYSROOT}/System/Library/Frameworks/System.framework/PrivateHeaders -Wall -g -DTEST_SNAPSHOT -O0 -c -o $@ ifnamer.c
+
+snapshot: snapshot.o InterfaceNamerControlPrefs.o Makefile
+       $(CC) -o snapshot snapshot.o InterfaceNamerControlPrefs.o ${EXTRA} -framework CoreFoundation -framework SystemConfiguration -framework IOKit
+
+# ---------- ---------- ---------- ---------- ----------
 
 clean:
 
 clean:
-       rm -rf ifnamer ifnamer.dSYM snapshot snapshot.dSYM uuid uuid.dSYM
+       rm -rf *.o ifnamer ifnamer.dSYM snapshot snapshot.dSYM
 
 
index 010f3f845dc9bf76d73717dd5369961967b1a8bd..9d3f0dd175afbf4a44ef9ceb705a42d30e48a213 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2001-2019 Apple Inc. All rights reserved.
+ * Copyright (c) 2001-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 #include <SystemConfiguration/SCPrivate.h>
 #include <SystemConfiguration/SCValidation.h>
 #include "SCNetworkConfigurationInternal.h"
 #include <SystemConfiguration/SCPrivate.h>
 #include <SystemConfiguration/SCValidation.h>
 #include "SCNetworkConfigurationInternal.h"
+#include "SCPreferencesInternal.h"
 #include "plugin_shared.h"
 #if    !TARGET_OS_IPHONE
 #include "InterfaceNamerControlPrefs.h"
 #endif // !TARGET_OS_IPHONE
 
 #include "plugin_shared.h"
 #if    !TARGET_OS_IPHONE
 #include "InterfaceNamerControlPrefs.h"
 #endif // !TARGET_OS_IPHONE
 
+#ifdef TEST_INTERFACE_ASSIGNMENT
+#undef INTERFACES_DEFAULT_CONFIG
+#define        INTERFACES_DEFAULT_CONFIG       CFSTR("/tmp/ifnamer-test-NetworkInterfaces.plist")
+#endif // TEST_INTERFACE_ASSIGNMENT
+
 #include <IOKit/IOKitLib.h>
 #include <IOKit/IOKitLibPrivate.h>
 #include <IOKit/IOKitKeysPrivate.h>
 #include <IOKit/IOKitLib.h>
 #include <IOKit/IOKitLibPrivate.h>
 #include <IOKit/IOKitKeysPrivate.h>
@@ -114,11 +120,6 @@ enum {
 };
 #endif // !USE_REGISTRY_ENTRY_ID
 
 };
 #endif // !USE_REGISTRY_ENTRY_ID
 
-#define        kSCNetworkInterfaceActive       "Active"
-#define        kSCNetworkInterfaceInfo         "SCNetworkInterfaceInfo"
-#define        kSCNetworkInterfaceType         "SCNetworkInterfaceType"
-#define        kSCNetworkInterfaceMatchingMACs "MatchingMACs"
-
 #define MY_PLUGIN_NAME                 "InterfaceNamer"
 #define        MY_PLUGIN_ID                    CFSTR("com.apple.SystemConfiguration." MY_PLUGIN_NAME)
 
 #define MY_PLUGIN_NAME                 "InterfaceNamer"
 #define        MY_PLUGIN_ID                    CFSTR("com.apple.SystemConfiguration." MY_PLUGIN_NAME)
 
@@ -289,9 +290,6 @@ addTimestamp(CFMutableDictionaryRef dict, CFStringRef key)
     return;
 }
 
     return;
 }
 
-#define        INTERFACES                      CFSTR("Interfaces")
-#define        NETWORK_INTERFACES_PREFS        CFSTR("NetworkInterfaces.plist")
-
 static CFComparisonResult
 if_unit_compare(const void *val1, const void *val2, void *context)
 {
 static CFComparisonResult
 if_unit_compare(const void *val1, const void *val2, void *context)
 {
@@ -317,57 +315,83 @@ if_unit_compare(const void *val1, const void *val2, void *context)
     return (CFNumberCompare(unit1, unit2, NULL));
 }
 
     return (CFNumberCompare(unit1, unit2, NULL));
 }
 
+static void
+writeInterfaceListForModel(SCPreferencesRef prefs, CFStringRef old_model)
+{
+    Boolean                    ok;
+    CFPropertyListRef          plist;
+    SCPreferencesRef           savedPrefs;
+    CFStringRef                        savedPrefsID;
+
+    savedPrefsID = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@-%@"),
+                                           INTERFACES_DEFAULT_CONFIG,
+                                           old_model);
+    savedPrefs = SCPreferencesCreate(NULL, CFSTR(MY_PLUGIN_NAME ":writeInterfaceListForModel"), savedPrefsID);
+    CFRelease(savedPrefsID);
+    if (savedPrefs == NULL) {
+       SC_log(LOG_NOTICE, "SCPreferencesCreate(\"NetworkInterfaces-<model>.plist\") failed: %s", SCErrorString(SCError()));
+       return;
+    }
+
+    plist = SCPreferencesPathGetValue(prefs, CFSTR("/"));
+    ok = SCPreferencesPathSetValue(savedPrefs, CFSTR("/"), plist);
+    if (!ok) {
+       SC_log(LOG_NOTICE, "SCPreferencesPathSetValue() failed: %s", SCErrorString(SCError()));
+    }
+
+    ok = SCPreferencesCommitChanges(savedPrefs);
+    CFRelease(savedPrefs);
+    if (!ok) {
+       SC_log(LOG_NOTICE, "SCPreferencesCommitChanges(\"NetworkInterfaces-<model>.plist\") failed: %s", SCErrorString(SCError()));
+    }
+
+    return;
+}
+
 static void
 writeInterfaceList(CFArrayRef if_list)
 {
     CFArrayRef         cur_list;
     CFStringRef                new_model;
 static void
 writeInterfaceList(CFArrayRef if_list)
 {
     CFArrayRef         cur_list;
     CFStringRef                new_model;
+    SCPreferencesRef   ni_prefs;
     CFStringRef                old_model;
     CFStringRef                old_model;
-    SCPreferencesRef   prefs;
 
 
-    if (isA_CFArray(if_list) == NULL) {
+    if (!isA_CFArray(if_list)) {
        return;
     }
 
        return;
     }
 
-    prefs = SCPreferencesCreate(NULL, CFSTR(MY_PLUGIN_NAME ":writeInterfaceList"), NETWORK_INTERFACES_PREFS);
-    if (prefs == NULL) {
-       SC_log(LOG_NOTICE, "SCPreferencesCreate() failed: %s", SCErrorString(SCError()));
+    ni_prefs = SCPreferencesCreate(NULL, CFSTR(MY_PLUGIN_NAME ":writeInterfaceList"), INTERFACES_DEFAULT_CONFIG);
+    if (ni_prefs == NULL) {
+       SC_log(LOG_NOTICE, "SCPreferencesCreate(\"NetworkInterfaces.plist\") failed: %s", SCErrorString(SCError()));
        return;
     }
 
        return;
     }
 
-    cur_list = SCPreferencesGetValue(prefs, INTERFACES);
+    cur_list = SCPreferencesGetValue(ni_prefs, INTERFACES);
     if (_SC_CFEqual(cur_list, if_list)) {
        goto done;
     }
 
     if (_SC_CFEqual(cur_list, if_list)) {
        goto done;
     }
 
-    old_model = SCPreferencesGetValue(prefs, MODEL);
+    old_model = SCPreferencesGetValue(ni_prefs, MODEL);
     new_model = _SC_hw_model(FALSE);
     new_model = _SC_hw_model(FALSE);
-    if ((new_model != NULL) && !_SC_CFEqual(old_model, new_model)) {
+    if ((old_model != NULL) && !_SC_CFEqual(old_model, new_model)) {
        // if new hardware
        if ((old_model != NULL) && (cur_list != NULL)) {
        // if new hardware
        if ((old_model != NULL) && (cur_list != NULL)) {
-           CFStringRef history;
-
-           // if interface list was created on other hardware
-           history = CFStringCreateWithFormat(NULL, NULL,
-                                              CFSTR("%@:%@"),
-                                              INTERFACES,
-                                              old_model);
-           SCPreferencesSetValue(prefs, history, cur_list);
-           CFRelease(history);
-
            SC_log(LOG_NOTICE, "Hardware model changed\n"
                               "  created on \"%@\"\n"
                               "  now on     \"%@\"",
                   old_model,
                   new_model);
            SC_log(LOG_NOTICE, "Hardware model changed\n"
                               "  created on \"%@\"\n"
                               "  now on     \"%@\"",
                   old_model,
                   new_model);
+
+           // save the interface list that was created on "other" hardware
+           writeInterfaceListForModel(ni_prefs, old_model);
        }
 
        }
 
-       SCPreferencesSetValue(prefs, MODEL, new_model);
+       SCPreferencesSetValue(ni_prefs, MODEL, new_model);
     }
 
     }
 
-    SCPreferencesSetValue(prefs, INTERFACES, if_list);
+    SCPreferencesSetValue(ni_prefs, INTERFACES, if_list);
 
 
-    if (!SCPreferencesCommitChanges(prefs)) {
+    if (!SCPreferencesCommitChanges(ni_prefs)) {
        if (SCError() != EROFS) {
            SC_log(LOG_NOTICE, "SCPreferencesCommitChanges() failed: %s", SCErrorString(SCError()));
        }
        if (SCError() != EROFS) {
            SC_log(LOG_NOTICE, "SCPreferencesCommitChanges() failed: %s", SCErrorString(SCError()));
        }
@@ -376,80 +400,52 @@ writeInterfaceList(CFArrayRef if_list)
 
 done:
 
 
 done:
 
-    CFRelease(prefs);
+    CFRelease(ni_prefs);
     return;
 }
 
     return;
 }
 
-static CFPropertyListRef
-restoreNIPrefsFromBackup(SCPreferencesRef prefs, CFStringRef current_model)
-{
-    CFPropertyListRef if_list;
-    CFStringRef key;
-
-    key = CFStringCreateWithFormat(NULL, 0, CFSTR("%@:%@"), INTERFACES, current_model);
-    if_list = SCPreferencesGetValue(prefs, key);
-    if_list = isA_CFArray(if_list);
-    if (if_list != NULL) {
-       /* Write the previously backed up Interface list for this hardware */
-       writeInterfaceList(if_list);
-
-       /* Synchronize the prefs */
-       SCPreferencesSynchronize(prefs);
-
-       /* Re-fetch the interface list */
-       if_list = SCPreferencesGetValue(prefs, INTERFACES);
-       if_list = isA_CFArray(if_list);
-       if (if_list != NULL) {
-           /* We do not need the old interface list any more */
-           SCPreferencesRemoveValue(prefs, key);
-           if (!SCPreferencesCommitChanges(prefs)) {
-               if (SCError() != EROFS) {
-                   SC_log(LOG_NOTICE, "SCPreferencesCommitChanges() failed: %s", SCErrorString(SCError()));
-               }
-               if_list = NULL;
-           }
-       }
-    }
-
-    CFRelease(key);
-    return if_list;
-}
-
 static CF_RETURNS_RETAINED CFMutableArrayRef
 readInterfaceList()
 {
 static CF_RETURNS_RETAINED CFMutableArrayRef
 readInterfaceList()
 {
-    CFArrayRef         if_list;
-    CFStringRef                old_model;
-    CFMutableArrayRef  plist   = NULL;
-    SCPreferencesRef   prefs   = NULL;
+    CFArrayRef                 if_list;
+    SCPreferencesRef           ni_prefs;
+    CFStringRef                        old_model;
+    static Boolean             once    = FALSE;
+    CFMutableArrayRef          plist   = NULL;
 
 
-    prefs = SCPreferencesCreate(NULL, CFSTR(MY_PLUGIN_NAME ":readInterfaceList"), NETWORK_INTERFACES_PREFS);
-    if (prefs == NULL) {
+    ni_prefs = SCPreferencesCreate(NULL, CFSTR(MY_PLUGIN_NAME ":readInterfaceList"), INTERFACES_DEFAULT_CONFIG);
+    if (ni_prefs == NULL) {
        SC_log(LOG_NOTICE, "SCPreferencesCreate() failed: %s", SCErrorString(SCError()));
        return (NULL);
     }
 
        SC_log(LOG_NOTICE, "SCPreferencesCreate() failed: %s", SCErrorString(SCError()));
        return (NULL);
     }
 
-    if_list = SCPreferencesGetValue(prefs, INTERFACES);
+    if (!once) {
+       __SCNetworkConfigurationUpgrade(NULL, &ni_prefs, TRUE);
+       once = TRUE;
+    }
+
+    if_list = SCPreferencesGetValue(ni_prefs, INTERFACES);
     if_list = isA_CFArray(if_list);
 
     if_list = isA_CFArray(if_list);
 
-    old_model = SCPreferencesGetValue(prefs, MODEL);
+    old_model = SCPreferencesGetValue(ni_prefs, MODEL);
     if (old_model != NULL) {
        CFStringRef new_model;
 
        new_model = _SC_hw_model(FALSE);
        if (!_SC_CFEqual(old_model, new_model)) {
     if (old_model != NULL) {
        CFStringRef new_model;
 
        new_model = _SC_hw_model(FALSE);
        if (!_SC_CFEqual(old_model, new_model)) {
-           /*  if interface list was created on other hardware,
-               Restore if a backup interface list is present   */
-           if_list = restoreNIPrefsFromBackup(prefs, new_model);
+           /*
+            * If the interface list was created on other hardware then
+            * we start fresh.
+            */
+           if_list = NULL;
        }
     }
 
     if (if_list != NULL) {
        }
     }
 
     if (if_list != NULL) {
-       CFIndex i;
        CFIndex n       = CFArrayGetCount(if_list);
 
        plist = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        CFIndex n       = CFArrayGetCount(if_list);
 
        plist = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-       for (i = 0; i < n; i++) {
+       for (CFIndex i = 0; i < n; i++) {
            CFDictionaryRef     dict;
 
            dict = CFArrayGetValueAtIndex(if_list, i);
            CFDictionaryRef     dict;
 
            dict = CFArrayGetValueAtIndex(if_list, i);
@@ -462,9 +458,15 @@ readInterfaceList()
        }
     }
 
        }
     }
 
-    if (prefs != NULL) {
-       CFRelease(prefs);
+    if (plist != NULL) {
+       CFIndex n       = CFArrayGetCount(plist);
+
+       if (n > 1) {
+           CFArraySortValues(plist, CFRangeMake(0, n), if_unit_compare, NULL);
+       }
     }
     }
+
+    CFRelease(ni_prefs);
     return (plist);
 }
 
     return (plist);
 }
 
@@ -472,7 +474,6 @@ static CF_RETURNS_RETAINED CFMutableArrayRef
 previouslyActiveInterfaces()
 {
     CFMutableArrayRef  active;
 previouslyActiveInterfaces()
 {
     CFMutableArrayRef  active;
-    CFIndex            i;
     CFIndex            n;
 
     if (S_dblist == NULL) {
     CFIndex            n;
 
     if (S_dblist == NULL) {
@@ -482,7 +483,7 @@ previouslyActiveInterfaces()
     active = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
 
     n = CFArrayGetCount(S_dblist);
     active = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
 
     n = CFArrayGetCount(S_dblist);
-    for (i = 0; i < n; i++) {
+    for (CFIndex i = 0; i < n; i++) {
        CFDictionaryRef if_dict;
 
        if_dict = CFArrayGetValueAtIndex(S_dblist, i);
        CFDictionaryRef if_dict;
 
        if_dict = CFArrayGetValueAtIndex(S_dblist, i);
@@ -737,6 +738,10 @@ createInterfaceDict(SCNetworkInterfaceRef interface, CFArrayRef matchingMACs)
                         CFSTR(kIOBuiltin),
                         _SCNetworkInterfaceIsBuiltin(interface) ? kCFBooleanTrue : kCFBooleanFalse);
 
                         CFSTR(kIOBuiltin),
                         _SCNetworkInterfaceIsBuiltin(interface) ? kCFBooleanTrue : kCFBooleanFalse);
 
+    if (_SCNetworkInterfaceIsHiddenConfiguration(interface)) {
+       CFDictionarySetValue(new_if, kSCNetworkInterfaceHiddenConfigurationKey, kCFBooleanTrue);
+    }
+
     CFDictionarySetValue(new_if, CFSTR(kSCNetworkInterfaceActive), kCFBooleanTrue);
 
     if (matchingMACs != NULL) {
     CFDictionarySetValue(new_if, CFSTR(kSCNetworkInterfaceActive), kCFBooleanTrue);
 
     if (matchingMACs != NULL) {
@@ -750,7 +755,6 @@ static CFDictionaryRef
 lookupInterfaceByAddress(CFArrayRef db_list, SCNetworkInterfaceRef interface, CFIndex * where)
 {
     CFDataRef  addr;
 lookupInterfaceByAddress(CFArrayRef db_list, SCNetworkInterfaceRef interface, CFIndex * where)
 {
     CFDataRef  addr;
-    CFIndex    i;
     CFIndex    n;
     CFNumberRef        type;
 
     CFIndex    n;
     CFNumberRef        type;
 
@@ -764,7 +768,7 @@ lookupInterfaceByAddress(CFArrayRef db_list, SCNetworkInterfaceRef interface, CF
     }
 
     n = CFArrayGetCount(db_list);
     }
 
     n = CFArrayGetCount(db_list);
-    for (i = 0; i < n; i++) {
+    for (CFIndex i = 0; i < n; i++) {
        CFDataRef       a;
        CFDictionaryRef dict = CFArrayGetValueAtIndex(db_list, i);
        CFNumberRef     t;
        CFDataRef       a;
        CFDictionaryRef dict = CFArrayGetValueAtIndex(db_list, i);
        CFNumberRef     t;
@@ -784,10 +788,34 @@ lookupInterfaceByAddress(CFArrayRef db_list, SCNetworkInterfaceRef interface, CF
     return (NULL);
 }
 
     return (NULL);
 }
 
+static CFDictionaryRef
+lookupInterfaceByName(CFArrayRef db_list, CFStringRef bsdName, CFIndex * where)
+{
+    CFIndex    n;
+
+    if (db_list == NULL) {
+       return (NULL);
+    }
+
+    n = CFArrayGetCount(db_list);
+    for (CFIndex i = 0; i < n; i++) {
+       CFDictionaryRef dict = CFArrayGetValueAtIndex(db_list, i);
+       CFStringRef     name;
+
+       name = CFDictionaryGetValue(dict, CFSTR(kIOBSDNameKey));
+       if (_SC_CFEqual(name, bsdName)) {
+           if (where) {
+               *where = i;
+           }
+           return (dict);
+       }
+    }
+    return (NULL);
+}
+
 static CFDictionaryRef
 lookupInterfaceByUnit(CFArrayRef db_list, SCNetworkInterfaceRef interface, CFIndex * where)
 {
 static CFDictionaryRef
 lookupInterfaceByUnit(CFArrayRef db_list, SCNetworkInterfaceRef interface, CFIndex * where)
 {
-    CFIndex    i;
     CFIndex    n;
     CFNumberRef        type;
     CFNumberRef        unit;
     CFIndex    n;
     CFNumberRef        type;
     CFNumberRef        unit;
@@ -802,7 +830,7 @@ lookupInterfaceByUnit(CFArrayRef db_list, SCNetworkInterfaceRef interface, CFInd
     }
 
     n = CFArrayGetCount(db_list);
     }
 
     n = CFArrayGetCount(db_list);
-    for (i = 0; i < n; i++) {
+    for (CFIndex i = 0; i < n; i++) {
        CFDictionaryRef dict = CFArrayGetValueAtIndex(db_list, i);
        CFNumberRef     t;
        CFNumberRef     u;
        CFDictionaryRef dict = CFArrayGetValueAtIndex(db_list, i);
        CFNumberRef     t;
        CFNumberRef     u;
@@ -838,7 +866,7 @@ thinInterfaceInfo(CFDictionaryRef info)
     if (CFDictionaryGetValueIfPresent(info, CFSTR(kUSBVendorID), (const void **)&num)
        && isA_CFNumber(num)
        && CFNumberGetValue(num, kCFNumberIntType, &vid)
     if (CFDictionaryGetValueIfPresent(info, CFSTR(kUSBVendorID), (const void **)&num)
        && isA_CFNumber(num)
        && CFNumberGetValue(num, kCFNumberIntType, &vid)
-       && (vid == kIOUSBVendorIDAppleComputer)) {
+       && (vid == kIOUSBAppleVendorID)) {
        CFMutableDictionaryRef  thin;
 
        // if this is an Apple USB device than we trust that
        CFMutableDictionaryRef  thin;
 
        // if this is an Apple USB device than we trust that
@@ -1245,86 +1273,109 @@ insertInterface(CFMutableArrayRef db_list, SCNetworkInterfaceRef interface, CFDi
 }
 
 static void
 }
 
 static void
-replaceInterface(SCNetworkInterfaceRef interface)
+removeInterface(CFMutableArrayRef db_list, SCNetworkInterfaceRef interface, CFDictionaryRef *matched)
 {
     CFDictionaryRef    db_dict;
 {
     CFDictionaryRef    db_dict;
-    CFDictionaryRef    db_dict_match   = NULL;
     int                        n               = 0;
     CFIndex            where;
 
     int                        n               = 0;
     CFIndex            where;
 
-    if (S_dblist == NULL) {
-       S_dblist = CFArrayCreateMutable(NULL, 0,
-                                       &kCFTypeArrayCallBacks);
-    }
-
     // remove any dict that has our type/addr
     while (TRUE) {
     // remove any dict that has our type/addr
     while (TRUE) {
-       db_dict = lookupInterfaceByAddress(S_dblist, interface, &where);
+       db_dict = lookupInterfaceByAddress(db_list, interface, &where);
        if (db_dict == NULL) {
            break;
        }
        if (db_dict == NULL) {
            break;
        }
-       if (db_dict_match == NULL) {
-           db_dict_match = CFRetain(db_dict);
+       if ((matched != NULL) && (*matched == NULL)) {
+           *matched = CFRetain(db_dict);
        }
        }
-       CFArrayRemoveValueAtIndex(S_dblist, where);
+       CFArrayRemoveValueAtIndex(db_list, where);
        n++;
     }
 
     // remove any dict that has the same type/unit
     while (TRUE) {
        n++;
     }
 
     // remove any dict that has the same type/unit
     while (TRUE) {
-       db_dict = lookupInterfaceByUnit(S_dblist, interface, &where);
+       db_dict = lookupInterfaceByUnit(db_list, interface, &where);
        if (db_dict == NULL) {
            break;
        }
        if (db_dict == NULL) {
            break;
        }
-       if (db_dict_match == NULL) {
-           db_dict_match = CFRetain(db_dict);
+       if ((matched != NULL) && (*matched == NULL)) {
+           *matched = CFRetain(db_dict);
        }
        }
-       CFArrayRemoveValueAtIndex(S_dblist, where);
+       CFArrayRemoveValueAtIndex(db_list, where);
        n++;
     }
 
        n++;
     }
 
-    insertInterface(S_dblist, interface, db_dict_match);
-    if (db_dict_match != NULL) {
-       CFRelease(db_dict_match);
+    if (n > 1) {
+       SC_log(LOG_ERR, "Multiple interfaces removed from database (n = %d, %@)", n, interface);
     }
 
     }
 
-    if (n > 1) {
-       SC_log(LOG_ERR, "Multiple interfaces updated (n = %d, %@)", n, interface);
+    return;
+}
+
+static void
+replaceInterface(SCNetworkInterfaceRef interface)
+{
+    CFDictionaryRef    matched = NULL;
+
+    if (S_dblist == NULL) {
+       S_dblist = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+    } else {
+       // remove any matching interfaces
+       removeInterface(S_dblist, interface, &matched);
+    }
+
+    // [re-]insert the new interface
+    insertInterface(S_dblist, interface, matched);
+
+    if (matched != NULL) {
+       CFRelease(matched);
     }
 
     return;
 }
 
     }
 
     return;
 }
 
-static CFNumberRef
-getHighestUnitForType(CFNumberRef if_type)
+static int
+getNextUnitForType(CFNumberRef if_type, int requested)
 {
 {
-    int                i;
-    CFIndex            n;
-    CFNumberRef                ret_unit        = NULL;
+    CFIndex    n;
 
     if (S_dblist == NULL) {
 
     if (S_dblist == NULL) {
-       return (NULL);
+       return requested;
     }
 
     n = CFArrayGetCount(S_dblist);
     }
 
     n = CFArrayGetCount(S_dblist);
-    for (i = 0; i < n; i++) {
+    for (CFIndex i = 0; i < n; i++) {
        CFDictionaryRef dict = CFArrayGetValueAtIndex(S_dblist, i);
        CFNumberRef     type;
 
        type = CFDictionaryGetValue(dict, CFSTR(kIOInterfaceType));
        if (CFEqual(type, if_type)) {
        CFDictionaryRef dict = CFArrayGetValueAtIndex(S_dblist, i);
        CFNumberRef     type;
 
        type = CFDictionaryGetValue(dict, CFSTR(kIOInterfaceType));
        if (CFEqual(type, if_type)) {
+           int         u;
            CFNumberRef unit;
 
            unit = CFDictionaryGetValue(dict, CFSTR(kIOInterfaceUnit));
            CFNumberRef unit;
 
            unit = CFDictionaryGetValue(dict, CFSTR(kIOInterfaceUnit));
-           if (ret_unit == NULL
-               || (CFNumberCompare(unit, ret_unit, NULL)
-                   == kCFCompareGreaterThan)) {
-               ret_unit = unit;
+           if (!isA_CFNumber(unit) ||
+               !CFNumberGetValue(unit, kCFNumberIntType, &u)) {
+               u = 0;
+           }
+
+           if (u < requested) {
+               // if we have not yet found our starting unit #
+               continue;
+           }
+
+           if (u == requested) {
+               // our starting (or now proposed) unit # is "in use" so
+               // let's keep searching
+               requested++;
+               continue;
            }
            }
+
+           // we've found a unit # gap ... so let's re-assign it!
        }
     }
 
        }
     }
 
-    return (ret_unit);
+    return requested;
 }
 
 /*
 }
 
 /*
@@ -1619,13 +1670,35 @@ updateWatchedInterface(void *refCon, io_service_t service, natural_t messageType
 #pragma unused(messageArgument)
     switch (messageType) {
        case kIOMessageServiceIsTerminated : {          // if [watched] interface yanked
 #pragma unused(messageArgument)
     switch (messageType) {
        case kIOMessageServiceIsTerminated : {          // if [watched] interface yanked
-           CFDataRef   watched         = (CFDataRef)refCon;
-           WatchedInfo *watchedInfo    = (WatchedInfo *)(void *)CFDataGetBytePtr(watched);
+           SCNetworkInterfaceRef       remove          = NULL;
+           CFDataRef                   watched         = (CFDataRef)refCon;
+           WatchedInfo                 *watchedInfo    = (WatchedInfo *)(void *)CFDataGetBytePtr(watched);
+
+           remove = watchedInfo->interface;
+           if (!_SCNetworkInterfaceIsBuiltin(remove) &&
+               _SCNetworkInterfaceIsApplePreconfigured(remove)) {
+               // if not built-in *and* pre-configured, retain for cleanup
+               CFRetain(remove);
+           } else {
+               remove = NULL;
+           }
 
            CFRetain(watched);
            watchedInfo->callback(watched, messageType, messageArgument);
            watcherRelease(watched);
            CFRelease(watched);
 
            CFRetain(watched);
            watchedInfo->callback(watched, messageType, messageArgument);
            watcherRelease(watched);
            CFRelease(watched);
+
+           if (remove != NULL) {
+               // if interface is not built-in *and* pre-configured
+               SC_log(LOG_INFO, "Interface released unit %@ (from database)",
+                      _SCNetworkInterfaceGetIOInterfaceUnit(remove));
+               removeInterface(S_dblist, remove, NULL);
+               CFRelease(remove);
+
+               // update the DB with the [remaining] interfaces that have been named
+               writeInterfaceList(S_dblist);
+           }
+
            break;
        }
 
            break;
        }
 
@@ -1714,6 +1787,24 @@ watcherRelease(CFDataRef watched)
     return;
 }
 
     return;
 }
 
+static Boolean
+isWatchedInterface(CFArrayRef watchedInterfaces, SCNetworkInterfaceRef interface)
+{
+    CFIndex    n;
+
+    n = (watchedInterfaces != NULL) ? CFArrayGetCount(watchedInterfaces) : 0;
+    for (CFIndex i = 0; i < n; i++) {
+       CFDataRef       watched         = CFArrayGetValueAtIndex(watchedInterfaces, i);
+       WatchedInfo     *watchedInfo    = (WatchedInfo *)(void *)CFDataGetBytePtr(watched);
+
+       if (CFEqual((watchedInfo->interface), interface)) {
+           return TRUE;
+       }
+    }
+
+    return FALSE;
+}
+
 
 #pragma mark -
 #pragma mark Locked device support [macOS]
 
 #pragma mark -
 #pragma mark Locked device support [macOS]
@@ -2142,13 +2233,25 @@ watchLockedInterface(SCNetworkInterfaceRef interface)
 
 
 #if    TARGET_OS_IPHONE
 
 
 #if    TARGET_OS_IPHONE
+
+#include <SoftLinking/WeakLinking.h>
+WEAK_LINK_FORCE_IMPORT(lockdown_is_host_trusted);
+WEAK_LINK_FORCE_IMPORT(kLockdownNotificationHostAttached);
+WEAK_LINK_FORCE_IMPORT(kLockdownNotificationHostDetached);
+WEAK_LINK_FORCE_IMPORT(kLockdownNotificationTrustedHostAttached);
+WEAK_LINK_FORCE_IMPORT(kLockdownNotificationTrustedPTPAttached);
+
 static Boolean
 haveLockdown()
 {
 static Boolean
 haveLockdown()
 {
-    void * volatile    fn_WeakFunction = (void *)&(lockdown_is_host_trusted);
     Boolean            haveLibrary;
 
     Boolean            haveLibrary;
 
-    haveLibrary = (fn_WeakFunction != NULL) ? TRUE : FALSE;
+    haveLibrary = ((lockdown_is_host_trusted != NULL) &&
+                  (&kLockdownNotificationHostAttached != NULL) &&
+                  (&kLockdownNotificationHostDetached != NULL) &&
+                  (&kLockdownNotificationTrustedHostAttached != NULL) &&
+                  (&kLockdownNotificationTrustedPTPAttached != NULL)
+                 );
     return haveLibrary;
 }
 
     return haveLibrary;
 }
 
@@ -2172,7 +2275,7 @@ shareExcluded()
 
            bsdName = SCNetworkInterfaceGetBSDName(watchedInfo->interface);
            if (bsdName == NULL) {
 
            bsdName = SCNetworkInterfaceGetBSDName(watchedInfo->interface);
            if (bsdName == NULL) {
-               SC_log(LOG_NOTICE, "[trust required] excluded interface w/no BSD name");
+               SC_log(LOG_NOTICE, "[trust required] interface w/no BSD name not excluded");
                SC_log(LOG_NOTICE, "  interface = %@", watchedInfo->interface);
                continue;
            }
                SC_log(LOG_NOTICE, "  interface = %@", watchedInfo->interface);
                continue;
            }
@@ -2323,26 +2426,6 @@ watchTrustedStatus(CFStringRef notification, CFStringRef reason)
     return;
 }
 
     return;
 }
 
-static Boolean
-isWatchedInterface(SCNetworkInterfaceRef interface)
-{
-    Boolean    found   = FALSE;
-    CFIndex    n;
-
-    n = (S_trustRequired != NULL) ? CFArrayGetCount(S_trustRequired) : 0;
-    for (CFIndex i = 0; i < n; i++) {
-       CFDataRef       watched         = CFArrayGetValueAtIndex(S_trustRequired, i);
-       WatchedInfo     *watchedInfo    = (WatchedInfo *)(void *)CFDataGetBytePtr(watched);
-
-       if (CFEqual((watchedInfo->interface), interface)) {
-           found = TRUE;
-           break;
-       }
-    }
-
-    return found;
-}
-
 static void
 updateTrustRequiredInterfaces(CFArrayRef interfaces)
 {
 static void
 updateTrustRequiredInterfaces(CFArrayRef interfaces)
 {
@@ -2354,13 +2437,21 @@ updateTrustRequiredInterfaces(CFArrayRef interfaces)
        SCNetworkInterfaceRef   interface;
 
        interface = CFArrayGetValueAtIndex(interfaces, i);
        SCNetworkInterfaceRef   interface;
 
        interface = CFArrayGetValueAtIndex(interfaces, i);
-       if (_SCNetworkInterfaceIsTrustRequired(interface) && !isWatchedInterface(interface)) {
+       if (_SCNetworkInterfaceIsTrustRequired(interface) &&
+           !isWatchedInterface(S_trustRequired, interface)) {
            CFDataRef   watched;
 
            watched = watcherCreate(interface, trustRequiredInterfaceUpdated);
            if (watched != NULL) {
            CFDataRef   watched;
 
            watched = watcherCreate(interface, trustRequiredInterfaceUpdated);
            if (watched != NULL) {
-               SC_log(LOG_INFO, "watching [trust required] interface: %@",
-                      SCNetworkInterfaceGetBSDName(interface));
+               CFStringRef     bsdName;
+
+               bsdName = SCNetworkInterfaceGetBSDName(interface);
+               if (bsdName != NULL) {
+                   SC_log(LOG_INFO, "watching [trust required] interface: %@", bsdName);
+               } else {
+                   SC_log(LOG_INFO, "watching [trust required] interface w/no BSD name");
+                   SC_log(LOG_INFO, "  interface = %@", interface);
+               }
 
                if (S_trustRequired == NULL) {
                    S_trustRequired = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
 
                if (S_trustRequired == NULL) {
                    S_trustRequired = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
@@ -2426,6 +2517,11 @@ sharePreconfigured()
            WatchedInfo *watchedInfo    = (WatchedInfo *)(void *)CFDataGetBytePtr(watched);
 
            bsdName = SCNetworkInterfaceGetBSDName(watchedInfo->interface);
            WatchedInfo *watchedInfo    = (WatchedInfo *)(void *)CFDataGetBytePtr(watched);
 
            bsdName = SCNetworkInterfaceGetBSDName(watchedInfo->interface);
+           if (bsdName == NULL) {
+               SC_log(LOG_NOTICE, "pre-configured interface w/no BSD name");
+               SC_log(LOG_NOTICE, "  interface = %@", watchedInfo->interface);
+               continue;
+           }
            CFArrayAppendValue(preconfigured, bsdName);
        }
 
            CFArrayAppendValue(preconfigured, bsdName);
        }
 
@@ -2449,8 +2545,15 @@ preconfiguredInterfaceUpdated(CFDataRef watched, natural_t messageType, void *me
 #pragma unused(messageArgument)
     switch (messageType) {
        case kIOMessageServiceIsTerminated : {          // if [locked] interface yanked
 #pragma unused(messageArgument)
     switch (messageType) {
        case kIOMessageServiceIsTerminated : {          // if [locked] interface yanked
-           SC_log(LOG_INFO, "[pre-configured] interface removed: %@",
-                  SCNetworkInterfaceGetBSDName(watchedInfo->interface));
+           CFStringRef bsdName;
+
+           bsdName = SCNetworkInterfaceGetBSDName(watchedInfo->interface);
+           if (bsdName != NULL) {
+               SC_log(LOG_INFO, "[pre-configured] interface removed: %@", bsdName);
+           } else {
+               SC_log(LOG_INFO, "[pre-configured] interface w/no BSD name removed");
+               SC_log(LOG_INFO, "  interface = %@", watchedInfo->interface);
+           }
 
            if (S_preconfigured != NULL) {
                CFIndex i;
 
            if (S_preconfigured != NULL) {
                CFIndex i;
@@ -2492,13 +2595,21 @@ updatePreConfiguredInterfaces(CFArrayRef interfaces)
        SCNetworkInterfaceRef   interface;
 
        interface = CFArrayGetValueAtIndex(interfaces, i);
        SCNetworkInterfaceRef   interface;
 
        interface = CFArrayGetValueAtIndex(interfaces, i);
-       if (_SCNetworkInterfaceIsApplePreconfigured(interface)) {
+       if (_SCNetworkInterfaceIsApplePreconfigured(interface) &&
+           !isWatchedInterface(S_preconfigured, interface)) {
            CFDataRef   watched;
 
            watched = watcherCreate(interface, preconfiguredInterfaceUpdated);
            if (watched != NULL) {
            CFDataRef   watched;
 
            watched = watcherCreate(interface, preconfiguredInterfaceUpdated);
            if (watched != NULL) {
-               SC_log(LOG_INFO, "watching [pre-configured] interface: %@",
-                      SCNetworkInterfaceGetBSDName(interface));
+               CFStringRef     bsdName;
+
+               bsdName = SCNetworkInterfaceGetBSDName(interface);
+               if (bsdName != NULL) {
+                   SC_log(LOG_INFO, "watching [pre-configured] interface: %@", bsdName);
+               } else {
+                   SC_log(LOG_INFO, "watching [pre-configured] interface w/no BSD name");
+                   SC_log(LOG_INFO, "  interface = %@", interface);
+               }
 
                if (S_preconfigured == NULL) {
                    S_preconfigured = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
 
                if (S_preconfigured == NULL) {
                    S_preconfigured = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
@@ -2707,17 +2818,7 @@ nameInterfaces(CFMutableArrayRef if_list)
                    // not built-in (or built-in unit not available), allocate from
                    // the non-reserved slots
                    next_unit = builtinCount(if_list, n, type);
                    // not built-in (or built-in unit not available), allocate from
                    // the non-reserved slots
                    next_unit = builtinCount(if_list, n, type);
-
-                   unit = getHighestUnitForType(type);
-                   if (unit != NULL) {
-                       int     high_unit;
-
-                       CFNumberGetValue(unit, kCFNumberIntType, &high_unit);
-                       if (high_unit >= next_unit) {
-                           next_unit = high_unit + 1;
-                       }
-                   }
-
+                   next_unit = getNextUnitForType(type, next_unit);
                    unit = CFNumberCreate(NULL, kCFNumberIntType, &next_unit);
                }
 
                    unit = CFNumberCreate(NULL, kCFNumberIntType, &next_unit);
                }
 
@@ -2924,7 +3025,123 @@ updateNetworkConfiguration(CFArrayRef if_list)
 #endif // !TARGET_OS_IPHONE
 
 static void
 #endif // !TARGET_OS_IPHONE
 
 static void
-updateInterfaces()
+removeInactiveInterfaces(void)
+{
+    CFIndex    n;
+
+    /*
+     * remove any previous interfaces that were built-in,
+     * were active, and were hidden (pre-configured) that
+     * are no longer plugged in.
+     */
+
+    if ((S_dblist == NULL) || (S_prev_active_list == NULL)) {
+       return;
+    }
+
+    n = CFArrayGetCount(S_prev_active_list);
+    for (CFIndex i = n - 1; i >= 0; i--) {
+       CFBooleanRef            builtin;
+       CFBooleanRef            hidden;
+       CFDictionaryRef         if_dict;
+       CFDictionaryRef         info;
+       CFStringRef             name;
+       CFIndex                 where;
+
+       if_dict = CFArrayGetValueAtIndex(S_prev_active_list, i);
+
+       // Note: keep the following logic in sync with _SCNetworkInterfaceIsApplePreconfigured()
+
+       name = CFDictionaryGetValue(if_dict, CFSTR(kIOBSDNameKey));
+       if (!isA_CFString(name)) {
+           // if no BSD name
+           continue;
+       }
+
+       hidden = CFDictionaryGetValue(if_dict, kSCNetworkInterfaceHiddenConfigurationKey);
+       if (!isA_CFBoolean(hidden) || !CFBooleanGetValue(hidden)) {
+           // if not hidden
+           continue;
+       }
+
+       builtin = CFDictionaryGetValue(if_dict, CFSTR(kIOBuiltin));
+       if (isA_CFBoolean(builtin) && CFBooleanGetValue(builtin)) {
+           // if [hidden] builtin
+           goto remove;
+       }
+
+       info = CFDictionaryGetValue(if_dict, CFSTR(kSCNetworkInterfaceInfo));
+       if (isA_CFDictionary(info)) {
+           int         vid;
+           CFNumberRef vidNum;
+
+           if (CFDictionaryGetValueIfPresent(info, CFSTR(kUSBVendorID), (const void **)&vidNum) &&
+               isA_CFNumber(vidNum) &&
+               CFNumberGetValue(vidNum, kCFNumberIntType, &vid) &&
+               (vid == kIOUSBAppleVendorID)) {
+               // if [hidden] Apple interface
+               goto remove;
+           }
+       }
+
+       continue;
+
+    remove :
+
+       SC_log(LOG_INFO, "Removing no-longer-active \"hidden\" interface: %@", name);
+
+       if (lookupInterfaceByName(S_dblist, name, &where) != NULL) {
+           // remove from the list of interfaces we know about
+           CFArrayRemoveValueAtIndex(S_dblist, where);
+           // remove from the previously active list
+           CFArrayRemoveValueAtIndex(S_prev_active_list, i);
+       }
+    }
+
+    return;
+}
+
+static void
+reportInactiveInterfaces(void)
+{
+    CFIndex    n;
+
+    /*
+     * report any previous interfaces that are not [yet] active
+     */
+
+    if (S_prev_active_list == NULL) {
+       return;
+    }
+
+    n = CFArrayGetCount(S_prev_active_list);
+    if (n > 0) {
+       SC_log(LOG_INFO, "Interface%s not [yet] active",
+              (n > 1) ? "s" : "");
+    }
+    for (CFIndex i = 0; i < n; i++) {
+       CFDictionaryRef         if_dict;
+       CFStringRef             name;
+       CFNumberRef             type;
+       CFNumberRef             unit;
+
+       if_dict = CFArrayGetValueAtIndex(S_prev_active_list, i);
+       name = CFDictionaryGetValue(if_dict, CFSTR(kIOBSDNameKey));
+       type = CFDictionaryGetValue(if_dict, CFSTR(kIOInterfaceType));
+       unit = CFDictionaryGetValue(if_dict, CFSTR(kIOInterfaceUnit));
+       SC_log(LOG_INFO, "  %s%@%sType: %@, Unit: %@",
+              (name != NULL) ? "BSD Name: " : "",
+              (name != NULL) ? name : CFSTR(""),
+              (name != NULL) ? ", " : "",
+              type,
+              unit);
+    }
+
+    return;
+}
+
+static void
+updateInterfaces(void)
 {
     if (S_connect == MACH_PORT_NULL) {
        // if we don't have the "IONetworkStack" connect object
 {
     if (S_connect == MACH_PORT_NULL) {
        // if we don't have the "IONetworkStack" connect object
@@ -2957,14 +3174,16 @@ updateInterfaces()
 
     if (isQuiet()) {
        /*
 
     if (isQuiet()) {
        /*
-        * The registry [matching] has quiesced so let's
-        * - save the DB with the interfaces that have been named
-        * - update the VLAN/BOND configuration
-        * - tell everyone that we've finished (at least for now)
-        * - log those interfaces which are no longer present
-        *   in the HW config (or have yet to show up).
+        * The registry [matching] has quiesced
         */
         */
+
+       // remove any inactive interfaces
+       removeInactiveInterfaces();
+
+       // save the DB with the interfaces that have been named
        writeInterfaceList(S_dblist);
        writeInterfaceList(S_dblist);
+
+       // update the VLAN/BOND configuration
        updateVirtualNetworkInterfaceConfiguration(NULL, kSCPreferencesNotificationApply, NULL);
 
 #if    !TARGET_OS_IPHONE
        updateVirtualNetworkInterfaceConfiguration(NULL, kSCPreferencesNotificationApply, NULL);
 
 #if    !TARGET_OS_IPHONE
@@ -2978,43 +3197,22 @@ updateInterfaces()
        }
 #endif // !TARGET_OS_IPHONE
 
        }
 #endif // !TARGET_OS_IPHONE
 
+       // tell everyone that we've finished (at least for now)
        updateStore();
 
        updateStore();
 
-       if (S_iflist != NULL) {
-           CFRelease(S_iflist);
-           S_iflist = NULL;
-       }
+       // log those interfaces which are no longer present in
+       // the HW config (or have yet to show up).
+       reportInactiveInterfaces();
 
        if (S_prev_active_list != NULL) {
 
        if (S_prev_active_list != NULL) {
-           CFIndex     i;
-           CFIndex     n;
-
-           n = CFArrayGetCount(S_prev_active_list);
-           if (n > 0) {
-               SC_log(LOG_INFO, "Interface%s not [yet] active",
-                      (n > 1) ? "s" : "");
-           }
-           for (i = 0; i < n; i++) {
-               CFDictionaryRef         if_dict;
-               CFStringRef             name;
-               CFNumberRef             type;
-               CFNumberRef             unit;
-
-               if_dict = CFArrayGetValueAtIndex(S_prev_active_list, i);
-               name = CFDictionaryGetValue(if_dict, CFSTR(kIOBSDNameKey));
-               type = CFDictionaryGetValue(if_dict, CFSTR(kIOInterfaceType));
-               unit = CFDictionaryGetValue(if_dict, CFSTR(kIOInterfaceUnit));
-               SC_log(LOG_INFO, "  %s%@%sType: %@, Unit: %@",
-                      (name != NULL) ? "BSD Name: " : "",
-                      (name != NULL) ? name : CFSTR(""),
-                      (name != NULL) ? ", " : "",
-                      type,
-                      unit);
-           }
-
            CFRelease(S_prev_active_list);
            S_prev_active_list = NULL;
        }
            CFRelease(S_prev_active_list);
            S_prev_active_list = NULL;
        }
+
+       if (S_iflist != NULL) {
+           CFRelease(S_iflist);
+           S_iflist = NULL;
+       }
     } else {
        if ((S_prev_active_list != NULL) && (CFArrayGetCount(S_prev_active_list) == 0)) {
            /*
     } else {
        if ((S_prev_active_list != NULL) && (CFArrayGetCount(S_prev_active_list) == 0)) {
            /*
@@ -3607,11 +3805,15 @@ load_InterfaceNamer(CFBundleRef bundle, Boolean bundleVerbose)
 
 //------------------------------------------------------------------------
 // Main function.
 
 //------------------------------------------------------------------------
 // Main function.
-#ifdef MAIN
+#ifdef TEST_INTERFACE_ASSIGNMENT
 int
 main(int argc, char ** argv)
 {
 int
 main(int argc, char ** argv)
 {
-    CFBundleRef bundle;
+#pragma unused(argv)
+    CFBundleRef                bundle;
+    CFMutableArrayRef  interfaces;
+    CFArrayRef         interfaces_all;
+    CFIndex            n;
 
     _sc_log     = FALSE;
     _sc_verbose = (argc > 1) ? TRUE : FALSE;
 
     _sc_log     = FALSE;
     _sc_verbose = (argc > 1) ? TRUE : FALSE;
@@ -3619,9 +3821,41 @@ main(int argc, char ** argv)
     bundle = CFBundleGetMainBundle();
     CFRetain(bundle);  // released in exec_InterfaceNamer
 
     bundle = CFBundleGetMainBundle();
     CFRetain(bundle);  // released in exec_InterfaceNamer
 
-    (void)exec_InterfaceNamer();
+    // setup
+    setup_IOKit(bundle);
+
+    // but, when running this test we know that the IORegistry has already quiesced
+    IOObjectRelease(S_quiet);
+    S_quiet = MACH_PORT_NULL;
+
+    // collect the interfaces
+    interfaces = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+    interfaces_all = SCNetworkInterfaceCopyAll();
+    n = CFArrayGetCount(interfaces_all);
+    for (CFIndex i = 0; i < n; i++) {
+       SCNetworkInterfaceRef           interface               = CFArrayGetValueAtIndex(interfaces_all, i);
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+
+       if (interfacePrivate->type == NULL) {
+           // skip interfaces with a kIOInterfaceType property
+           continue;
+       }
+
+       if (interfacePrivate->unit != NULL) {
+           // remove any already assigned unit #
+           CFRelease(interfacePrivate->unit);
+           interfacePrivate->unit = NULL;
+       }
+
+       CFArrayAppendValue(interfaces, interface);
+    }
+    CFRelease(interfaces_all);
+    SC_log(LOG_INFO, "interfaces = %@", interfaces);
+
+    // exercise the interface naming assignments
+    nameInterfaces(interfaces);
+    CFRelease(interfaces);
 
 
-    /* not reached */
     exit(0);
     return 0;
 }
     exit(0);
     return 0;
 }
@@ -3631,14 +3865,10 @@ main(int argc, char ** argv)
 int
 main(int argc, char ** argv)
 {
 int
 main(int argc, char ** argv)
 {
-    CFStringRef        snapshot;
-
     _sc_log     = FALSE;
     _sc_verbose = (argc > 1) ? TRUE : FALSE;
 
     _sc_log     = FALSE;
     _sc_verbose = (argc > 1) ? TRUE : FALSE;
 
-    snapshot = captureBusy();
-    SCPrint(TRUE, stdout, CFSTR("%@\n"), snapshot);
-    CFRelease(snapshot);
+    captureBusy();
 
     exit(0);
     return 0;
 
     exit(0);
     return 0;
index 23d69a53c5d08662a4e8567dd9142c8671328a2d..db757db3d3916489a2473e920f92dfca5eecd8ce 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2008, 2010, 2012-2019 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2008, 2010, 2012-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 
 
 #include <TargetConditionals.h>
 
 
 #include <TargetConditionals.h>
-#include <fcntl.h>
-#include <net/if.h>
 #include <sys/types.h>
 #include <sys/types.h>
-#include <sys/stat.h>
 #include <unistd.h>
 
 #include <unistd.h>
 
-
 #define        SC_LOG_HANDLE           __log_PreferencesMonitor
 #define SC_LOG_HANDLE_TYPE     static
 #include <SystemConfiguration/SystemConfiguration.h>
 #include <SystemConfiguration/SCPrivate.h>
 #include <SystemConfiguration/SCValidation.h>
 #define        SC_LOG_HANDLE           __log_PreferencesMonitor
 #define SC_LOG_HANDLE_TYPE     static
 #include <SystemConfiguration/SystemConfiguration.h>
 #include <SystemConfiguration/SCPrivate.h>
 #include <SystemConfiguration/SCValidation.h>
+#include "SCNetworkConfigurationInternal.h"
 #include "plugin_shared.h"
 
 
 #include "plugin_shared.h"
 
 
-#include <CommonCrypto/CommonDigest.h>
-
-
 /* globals */
 static SCPreferencesRef                prefs                   = NULL;
 static SCDynamicStoreRef       store                   = NULL;
 /* globals */
 static SCPreferencesRef                prefs                   = NULL;
 static SCDynamicStoreRef       store                   = NULL;
@@ -61,7 +55,7 @@ static SCDynamicStoreRef      store                   = NULL;
 /* InterfaceNamer[.plugin] monitoring globals */
 static CFMutableArrayRef       excluded_interfaces     = NULL;         // of SCNetworkInterfaceRef
 static CFMutableArrayRef       excluded_names          = NULL;         // of CFStringRef (BSD name)
 /* InterfaceNamer[.plugin] monitoring globals */
 static CFMutableArrayRef       excluded_interfaces     = NULL;         // of SCNetworkInterfaceRef
 static CFMutableArrayRef       excluded_names          = NULL;         // of CFStringRef (BSD name)
-Boolean                                haveConfiguration       = FALSE;
+static Boolean                 haveConfiguration       = FALSE;
 static CFStringRef             namerKey                = NULL;
 static CFMutableArrayRef       preconfigured_interfaces= NULL;         // of SCNetworkInterfaceRef
 static CFMutableArrayRef       preconfigured_names     = NULL;         // of CFStringRef (BSD name)
 static CFStringRef             namerKey                = NULL;
 static CFMutableArrayRef       preconfigured_interfaces= NULL;         // of SCNetworkInterfaceRef
 static CFMutableArrayRef       preconfigured_names     = NULL;         // of CFStringRef (BSD name)
@@ -76,7 +70,6 @@ static CFMutableArrayRef      unchangedPrefsKeys;     /* new prefs keys which match curre
 static CFMutableArrayRef       removedPrefsKeys;       /* old prefs keys to be removed */
 
 static Boolean                 rofs                    = FALSE;
 static CFMutableArrayRef       removedPrefsKeys;       /* old prefs keys to be removed */
 
 static Boolean                 rofs                    = FALSE;
-static Boolean                 restorePrefs            = FALSE;
 
 #define MY_PLUGIN_NAME         "PreferencesMonitor"
 #define        MY_PLUGIN_ID            CFSTR("com.apple.SystemConfiguration." MY_PLUGIN_NAME)
 
 #define MY_PLUGIN_NAME         "PreferencesMonitor"
 #define        MY_PLUGIN_ID            CFSTR("com.apple.SystemConfiguration." MY_PLUGIN_NAME)
@@ -101,116 +94,37 @@ __log_PreferencesMonitor(void)
 }
 
 
 }
 
 
-static Boolean
-restorePreferences()
+static void
+savePastConfiguration(CFStringRef old_model)
 {
 {
-       Boolean                 ok = FALSE;
-       CFStringRef             currentModel = NULL;
-       CFMutableStringRef      modelPrefixStr = NULL;
-       CFArrayRef              keyList = NULL;
-       CFIndex                 keyListCount;
-       CFIndex                 idx;
-       Boolean                 modified = FALSE;
-       int                     sc_status = kSCStatusFailed;
-
-       while (TRUE) {
-               ok = SCPreferencesLock(prefs, TRUE);
-               if (ok) {
-                       break;
-               }
+       CFDictionaryRef system;
 
 
-               sc_status = SCError();
-               if (sc_status == kSCStatusStale) {
-                       SCPreferencesSynchronize(prefs);
-               } else {
-                       SC_log(LOG_NOTICE, "Could not acquire network configuration lock: %s",
-                              SCErrorString(sc_status));
-                       return FALSE;
-               }
+       // save "/System" (e.g. host names)
+       system = SCPreferencesGetValue(prefs, kSCPrefSystem);
+       if (system != NULL) {
+               CFRetain(system);
        }
 
        }
 
-       keyList = SCPreferencesCopyKeyList(prefs);
-       if (keyList == NULL) {
-               goto error;
-       }
+       // save the [previous devices] configuration
+       __SCNetworkConfigurationSaveModel(prefs, old_model);
 
 
-       currentModel = _SC_hw_model(FALSE);
-       if (currentModel == NULL) {
-               goto error;
+       if (system != NULL) {
+               // and retain "/System" (e.g. host names)
+               SCPreferencesSetValue(prefs, kSCPrefSystem, system);
+               CFRelease(system);
        }
 
        }
 
-       /* Create "model:" string for prefix-check */
-       modelPrefixStr = CFStringCreateMutableCopy(NULL, 0, currentModel);
-       CFStringAppend(modelPrefixStr, CFSTR(":"));
-
-       keyListCount = CFArrayGetCount(keyList);
-       for (idx = 0; idx < keyListCount; idx++) {
-               CFStringRef existingKey = CFArrayGetValueAtIndex(keyList, idx);
-               CFStringRef key;
-               CFArrayRef splitKey = NULL;
-               CFPropertyListRef value;
-
-               if (isA_CFString(existingKey) == NULL) {
-                       continue;
-               }
-
-               if (!CFStringHasPrefix(existingKey, modelPrefixStr)) {
-                           continue;
-               }
-
-               splitKey = CFStringCreateArrayBySeparatingStrings(NULL, existingKey, CFSTR(":"));
-               key = CFArrayGetValueAtIndex(splitKey, 1);
-               value = SCPreferencesGetValue(prefs, existingKey);
-               SCPreferencesSetValue(prefs, key, value);
-               SCPreferencesRemoveValue(prefs, existingKey);
-               modified = TRUE;
-               CFRelease(splitKey);
-       }
-
-       if (modified) {
-               SCPreferencesRef        ni_prefs = NULL;
-               ni_prefs = SCPreferencesCreate(NULL, MY_PLUGIN_ID, CFSTR("NetworkInterfaces.plist"));
-               if (ni_prefs == NULL) {
-                       goto error;
-               }
-
-               ok = _SCNetworkConfigurationCheckValidityWithPreferences(prefs, ni_prefs, NULL);
-               CFRelease(ni_prefs);
-
-               //Commit the changes only if prefs files valid
-               if (ok) {
-                       if (!SCPreferencesCommitChanges(prefs)) {
-                               if (SCError() != EROFS) {
-                                       SC_log(LOG_NOTICE, "SCPreferencesCommitChanges() failed: %s",
-                                              SCErrorString(SCError()));
-                               }
-                               goto error;
-
-                       }
-
-                       (void) SCPreferencesApplyChanges(prefs);
-               }
-       }
-
-error:
-       (void) SCPreferencesUnlock(prefs);
-
-       if (keyList != NULL) {
-               CFRelease(keyList);
-       }
-       if (modelPrefixStr != NULL) {
-               CFRelease(modelPrefixStr);
-       }
-
-       return modified;
+       return;
 }
 
 }
 
+
 static Boolean
 establishNewPreferences()
 {
        SCNetworkSetRef current         = NULL;
        CFStringRef     new_model;
        Boolean         ok              = FALSE;
 static Boolean
 establishNewPreferences()
 {
        SCNetworkSetRef current         = NULL;
        CFStringRef     new_model;
        Boolean         ok              = FALSE;
+       CFStringRef     old_model;
        int             sc_status       = kSCStatusFailed;
        SCNetworkSetRef set             = NULL;
        Boolean         updated         = FALSE;
        int             sc_status       = kSCStatusFailed;
        SCNetworkSetRef set             = NULL;
        Boolean         updated         = FALSE;
@@ -231,58 +145,18 @@ establishNewPreferences()
                }
        }
 
                }
        }
 
-       /* Ensure that the preferences has the new model */
+       // check if we need to regenerate the configuration for a new model
+       old_model = SCPreferencesGetValue(prefs, MODEL);
        new_model = _SC_hw_model(FALSE);
        new_model = _SC_hw_model(FALSE);
-
-       /* Need to regenerate the new configuration for new model */
-       if (new_model != NULL) {
-               CFStringRef     old_model;
-
-               old_model = SCPreferencesGetValue(prefs, MODEL);
-               if ((old_model != NULL) && !_SC_CFEqual(old_model, new_model)) {
-                       CFIndex         count;
-                       CFIndex         index;
-                       CFArrayRef      keys;
-
-                       keys = SCPreferencesCopyKeyList(prefs);
-                       count = (keys != NULL) ? CFArrayGetCount(keys) : 0;
-                       // if new hardware
-                       for (index = 0; index < count; index++) {
-                               CFStringRef             existing_key;
-
-                               existing_key = CFArrayGetValueAtIndex(keys, index);
-                               if (isA_CFString(existing_key) != NULL) {
-                                       CFStringRef             new_key;
-                                       CFPropertyListRef       value;
-
-                                       /* If it already contains a Model
-                                          or if it already contains a MODEL:KEY key skip it*/
-                                       if (CFEqual(existing_key, MODEL)
-                                           || CFStringFind(existing_key, CFSTR(":"), 0).location
-                                           != kCFNotFound) {
-                                               continue;
-                                       }
-
-                                       value = SCPreferencesGetValue(prefs, existing_key);
-
-                                       /* Create a new key as OLD_MODEL:OLD_KEY */
-                                       new_key = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@:%@"),
-                                                                          old_model, existing_key);
-                                       SCPreferencesSetValue(prefs, new_key, value);
-                                       if (!CFEqual(existing_key, kSCPrefSystem)) {
-                                               /* preserve existing host names */
-                                               SCPreferencesRemoveValue(prefs, existing_key);
-                                       }
-                                       CFRelease(new_key);
-                               }
-                       }
-
-                       if (keys != NULL) {
-                               CFRelease(keys);
-                       }
-               }
-               /* Set the new model */
-               SCPreferencesSetValue(prefs, MODEL, new_model);
+       if ((old_model != NULL) && !_SC_CFEqual(old_model, new_model)) {
+               SC_log(LOG_NOTICE, "Hardware model changed\n"
+                                  "  created on \"%@\"\n"
+                                  "  now on     \"%@\"",
+                      old_model,
+                      new_model);
+
+               // save (and clean) the configuration that was created for "other" hardware
+               savePastConfiguration(old_model);
        }
 
        current = SCNetworkSetCopyCurrent(prefs);
        }
 
        current = SCNetworkSetCopyCurrent(prefs);
@@ -389,27 +263,6 @@ watchSCDynamicStore()
 }
 
 
 }
 
 
-static Boolean
-previousConfigurationAvailable()
-{
-       CFStringRef             backupKey = NULL;
-       CFStringRef             currentModel = NULL;
-       CFPropertyListRef       properties = NULL;
-
-       currentModel = _SC_hw_model(FALSE);
-       if (currentModel == NULL) {
-               goto done;
-       }
-
-       /* Currently relying only if a backup of "Sets" is present */
-       backupKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@:Sets"), currentModel);
-       properties = SCPreferencesGetValue(prefs, backupKey);
-       CFRelease(backupKey);
-done:
-       return (properties != NULL);
-}
-
-
 static Boolean
 findInterfaces(CFArrayRef interfaces, CFMutableArrayRef *matched_interfaces, CFMutableArrayRef *matched_names)
 {
 static Boolean
 findInterfaces(CFArrayRef interfaces, CFMutableArrayRef *matched_interfaces, CFMutableArrayRef *matched_names)
 {
@@ -571,11 +424,6 @@ storeCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info)
 
                (void) establishNewPreferences();
 
 
                (void) establishNewPreferences();
 
-               if (restorePrefs) {
-                       (void) restorePreferences();
-                       restorePrefs = FALSE;
-               }
-
                if (timeout && (logged++ == 0)) {
                        SC_log(LOG_ERR, "Network configuration creation timed out waiting for IORegistry");
                }
                if (timeout && (logged++ == 0)) {
                        SC_log(LOG_ERR, "Network configuration creation timed out waiting for IORegistry");
                }
@@ -715,42 +563,6 @@ flatten(SCPreferencesRef   prefs,
 }
 
 
 }
 
 
-static CF_RETURNS_RETAINED CFStringRef
-copyInterfaceUUID(CFStringRef bsdName)
-{
-       union {
-               unsigned char   sha256_bytes[CC_SHA256_DIGEST_LENGTH];
-               CFUUIDBytes     uuid_bytes;
-       } bytes;
-       CC_SHA256_CTX   ctx;
-       char            if_name[IF_NAMESIZE];
-       CFUUIDRef       uuid;
-       CFStringRef     uuid_str;
-
-       // start with interface name
-       memset(&if_name, 0, sizeof(if_name));
-       (void) _SC_cfstring_to_cstring(bsdName,
-                                      if_name,
-                                      sizeof(if_name),
-                                      kCFStringEncodingASCII);
-
-       // create SHA256 hash
-       memset(&bytes, 0, sizeof(bytes));
-       CC_SHA256_Init(&ctx);
-       CC_SHA256_Update(&ctx,
-                      if_name,
-                      sizeof(if_name));
-       CC_SHA256_Final(bytes.sha256_bytes, &ctx);
-
-       // create UUID string
-       uuid = CFUUIDCreateFromUUIDBytes(NULL, bytes.uuid_bytes);
-       uuid_str = CFUUIDCreateString(NULL, uuid);
-       CFRelease(uuid);
-
-       return uuid_str;
-}
-
-
 static void
 excludeConfigurations(SCPreferencesRef prefs)
 {
 static void
 excludeConfigurations(SCPreferencesRef prefs)
 {
@@ -908,42 +720,12 @@ updatePreConfiguredConfiguration(SCPreferencesRef prefs)
                CFStringRef             bsdName;
                SCNetworkInterfaceRef   interface       = CFArrayGetValueAtIndex(preconfigured_interfaces, i);
                SCNetworkServiceRef     service;
                CFStringRef             bsdName;
                SCNetworkInterfaceRef   interface       = CFArrayGetValueAtIndex(preconfigured_interfaces, i);
                SCNetworkServiceRef     service;
-               CFStringRef             serviceID;
 
                bsdName = SCNetworkInterfaceGetBSDName(interface);
 
                // create network service
 
                bsdName = SCNetworkInterfaceGetBSDName(interface);
 
                // create network service
-               service = SCNetworkServiceCreate(prefs, interface);
+               service = _SCNetworkServiceCreatePreconfigured(prefs, interface);
                if (service == NULL) {
                if (service == NULL) {
-                       SC_log(LOG_ERR, "could not create network service for \"%@\": %s",
-                              bsdName,
-                              SCErrorString(SCError()));
-                       continue;
-               }
-
-               // update network service to use a consistent 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
-               }
-
-               // establish [template] configuration
-               ok = SCNetworkServiceEstablishDefaultConfiguration(service);
-               if (!ok) {
-                       SC_log(LOG_ERR, "could not establish network service for \"%@\": %s",
-                              bsdName,
-                              SCErrorString(SCError()));
-                       SCNetworkServiceRemove(service);
-                       CFRelease(service);
                        continue;
                }
 
                        continue;
                }
 
@@ -1215,6 +997,13 @@ prime_PreferencesMonitor()
 }
 
 
 }
 
 
+#ifndef        MAIN
+#define        PREFERENCES_MONITOR_PLIST       NULL
+#else  // !MAIN
+#define        PREFERENCES_MONITOR_PLIST       CFSTR("/tmp/preferences.plist")
+#endif // !MAIN
+
+
 __private_extern__
 void
 load_PreferencesMonitor(CFBundleRef bundle, Boolean bundleVerbose)
 __private_extern__
 void
 load_PreferencesMonitor(CFBundleRef bundle, Boolean bundleVerbose)
@@ -1235,27 +1024,34 @@ load_PreferencesMonitor(CFBundleRef bundle, Boolean bundleVerbose)
        }
 
        /* open a SCPreferences session */
        }
 
        /* open a SCPreferences session */
-#ifndef        MAIN
-       prefs = SCPreferencesCreate(NULL, CFSTR("PreferencesMonitor.bundle"), NULL);
-#else  // !MAIN
-       prefs = SCPreferencesCreate(NULL, CFSTR("PreferencesMonitor.bundle"), CFSTR("/tmp/preferences.plist"));
-#endif // !MAIN
+       prefs = SCPreferencesCreateWithOptions(NULL,
+                                              MY_PLUGIN_ID,
+                                              PREFERENCES_MONITOR_PLIST,
+                                              NULL,    // authorization
+                                              NULL);
        if (prefs != NULL) {
                Boolean         need_update = FALSE;
        if (prefs != NULL) {
                Boolean         need_update = FALSE;
-               CFStringRef     new_model;
+               CFStringRef     new_model;
+               CFStringRef     old_model;
+
+               // check if we need to update the configuration
+               __SCNetworkConfigurationUpgrade(&prefs, NULL, TRUE);
 
 
+               // check if we need to regenerate the configuration for a new model
+               old_model = SCPreferencesGetValue(prefs, MODEL);
                new_model = _SC_hw_model(FALSE);
                new_model = _SC_hw_model(FALSE);
+               if ((old_model != NULL) && !_SC_CFEqual(old_model, new_model)) {
+                       SC_log(LOG_NOTICE, "Hardware model changed\n"
+                                          "  created on \"%@\"\n"
+                                          "  now on     \"%@\"",
+                              old_model,
+                              new_model);
 
 
-               /* Need to regenerate the new configuration for new model */
-               if (new_model != NULL) {
-                       CFStringRef     old_model;
+                       // save (and clean) the configuration that was created for "other" hardware
+                       savePastConfiguration(old_model);
 
 
-                       old_model = SCPreferencesGetValue(prefs, MODEL);
-                       if (old_model != NULL && !_SC_CFEqual(old_model, new_model)) {
-                               // if new hardware
-                               need_update = TRUE;
-                               restorePrefs = previousConfigurationAvailable();
-                       }
+                       // ... and we'll update the configuration later (when the IORegistry quiesces)
+                       need_update = TRUE;
                }
 
                if (!need_update) {
                }
 
                if (!need_update) {
index 3fc0dc04de35dd0329bfeb25c8988b5782cfc51a..74a6777b65d89ae6b4adb457095ba810fd52eabd 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2008, 2010-2019 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2008, 2010-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 /* framework variables */
 int    _sc_debug       = FALSE;        /* non-zero if debugging enabled */
 int    _sc_verbose     = FALSE;        /* non-zero if verbose logging enabled */
 /* framework variables */
 int    _sc_debug       = FALSE;        /* non-zero if debugging enabled */
 int    _sc_verbose     = FALSE;        /* non-zero if verbose logging enabled */
-int    _sc_log         = TRUE;         /* 0 if SC messages should be written to stdout/stderr,
-                                        1 if SC messages should be logged w/os_log(3),
-                                        2 if SC messages should be written to stdout/stderr AND logged */
+int    _sc_log         = 1;            /* 0 if SC messages should be written to stdout/stderr,
+                                          1 if SC messages should be logged w/os_log(3),
+                                          2 if SC messages should be logged AND written to stdout/stderr
+                                          3 if SC messages should be logged AND written to stdout/stderr (w/o timestamp) */
 
 
 #pragma mark -
 
 
 #pragma mark -
@@ -504,6 +505,7 @@ __SC_Log(int level, CFStringRef format_CF, os_log_t log, os_log_type_t type, con
         * 0 if SC messages should be written to stdout/stderr
         * 1 if SC messages should be logged w/os_log(3)
         * 2 if SC messages should be written to stdout/stderr AND logged
         * 0 if SC messages should be written to stdout/stderr
         * 1 if SC messages should be logged w/os_log(3)
         * 2 if SC messages should be written to stdout/stderr AND logged
+        * 3 if SC messages should be logged AND written to stdout/stderr (w/o timestamp)
         */
 
        if (_sc_log > 0) {
         */
 
        if (_sc_log > 0) {
@@ -532,7 +534,7 @@ __SC_Log(int level, CFStringRef format_CF, os_log_t log, os_log_type_t type, con
                __SCPrint(stdout,
                          format_CF,
                          args_print,
                __SCPrint(stdout,
                          format_CF,
                          args_print,
-                         (_sc_log > 0),        // trace
+                         (_sc_log == 2),       // trace
                          TRUE);                // add newline
                va_end(args_print);
        }
                          TRUE);                // add newline
                va_end(args_print);
        }
@@ -559,6 +561,7 @@ SCLog(Boolean condition, int level, CFStringRef formatString, ...)
         * 0 if SC messages should be written to stdout/stderr
         * 1 if SC messages should be logged w/os_log(3)
         * 2 if SC messages should be written to stdout/stderr AND logged
         * 0 if SC messages should be written to stdout/stderr
         * 1 if SC messages should be logged w/os_log(3)
         * 2 if SC messages should be written to stdout/stderr AND logged
+        * 3 if SC messages should be logged AND written to stdout/stderr (w/o timestamp)
         */
 
        if (_sc_log > 0) {
         */
 
        if (_sc_log > 0) {
@@ -591,7 +594,7 @@ SCLog(Boolean condition, int level, CFStringRef formatString, ...)
                __SCPrint((LOG_PRI(level) > LOG_NOTICE) ? stderr : stdout,
                          formatString,
                          formatArguments_print,
                __SCPrint((LOG_PRI(level) > LOG_NOTICE) ? stderr : stdout,
                          formatString,
                          formatArguments_print,
-                         (_sc_log > 0),        // trace
+                         (_sc_log == 2),       // trace
                          TRUE);                // add newline
                va_end(formatArguments_print);
        }
                          TRUE);                // add newline
                va_end(formatArguments_print);
        }
index 7fabbb656f157e517328670e9c1ed682bec896cb..8c047e18e4f6ad54f5d152631888afc5c3226efc 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2008, 2011, 2013-2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2008, 2011, 2013-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -35,6 +35,7 @@
 #include <CoreFoundation/CoreFoundation.h>
 #include <CoreFoundation/CFStringDefaultEncoding.h>    // for __CFStringGetUserDefaultEncoding
 #include "SCPreferencesInternal.h"
 #include <CoreFoundation/CoreFoundation.h>
 #include <CoreFoundation/CFStringDefaultEncoding.h>    // for __CFStringGetUserDefaultEncoding
 #include "SCPreferencesInternal.h"
+#include "SCNetworkConfigurationInternal.h"
 #include "dy_framework.h"
 
 
 #include "dy_framework.h"
 
 
@@ -227,12 +228,7 @@ SCPreferencesSetComputerName(SCPreferencesRef      prefs,
                CFDictionaryRemoveValue(newDict, kSCPropSystemComputerNameRegion);
        }
 
                CFDictionaryRemoveValue(newDict, kSCPropSystemComputerNameRegion);
        }
 
-       if (CFDictionaryGetCount(newDict) > 0) {
-               ok = SCPreferencesPathSetValue(prefs, path, newDict);
-       } else {
-               ok = SCPreferencesPathRemoveValue(prefs, path);
-       }
-
+       ok = __SCNetworkConfigurationSetValue(prefs, path, newDict, FALSE);
        if (ok) {
                if (name != NULL) {
                        SC_log(LOG_NOTICE, "attempting to set the computer name to \"%@\"", name);
        if (ok) {
                if (name != NULL) {
                        SC_log(LOG_NOTICE, "attempting to set the computer name to \"%@\"", name);
@@ -327,12 +323,7 @@ SCPreferencesSetHostName(SCPreferencesRef  prefs,
                CFDictionaryRemoveValue(newDict, kSCPropSystemHostName);
        }
 
                CFDictionaryRemoveValue(newDict, kSCPropSystemHostName);
        }
 
-       if (CFDictionaryGetCount(newDict) > 0) {
-               ok = SCPreferencesPathSetValue(prefs, path, newDict);
-       } else {
-               ok = SCPreferencesPathRemoveValue(prefs, path);
-       }
-
+       ok = __SCNetworkConfigurationSetValue(prefs, path, newDict, FALSE);
        if (ok) {
                if (name != NULL) {
                        SC_log(LOG_NOTICE, "attempting to set the host name to \"%@\"", name);
        if (ok) {
                if (name != NULL) {
                        SC_log(LOG_NOTICE, "attempting to set the host name to \"%@\"", name);
@@ -571,12 +562,7 @@ SCPreferencesSetLocalHostName(SCPreferencesRef     prefs,
                CFDictionaryRemoveValue(newDict, kSCPropNetLocalHostName);
        }
 
                CFDictionaryRemoveValue(newDict, kSCPropNetLocalHostName);
        }
 
-       if (CFDictionaryGetCount(newDict) > 0) {
-               ok = SCPreferencesPathSetValue(prefs, path, newDict);
-       } else {
-               ok = SCPreferencesPathRemoveValue(prefs, path);
-       }
-
+       ok = __SCNetworkConfigurationSetValue(prefs, path, newDict, FALSE);
        if (ok) {
                if (name != NULL) {
                        SC_log(LOG_NOTICE, "attempting to set the local host name to \"%@\"", name);
        if (ok) {
                if (name != NULL) {
                        SC_log(LOG_NOTICE, "attempting to set the local host name to \"%@\"", name);
index d43a2a1db41e31cfb3d6a8ba429547bf30509742..7ef633b05d9cade278b4dcc3de64102069aa38f5 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2006, 2008-2019 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2006, 2008-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -44,7 +44,6 @@
 #include "config.h"            /* MiG generated file */
 #include "SCD.h"
 
 #include "config.h"            /* MiG generated file */
 #include "SCD.h"
 
-static CFStringRef             _sc_bundleID    = NULL;
 static pthread_mutex_t         _sc_lock        = PTHREAD_MUTEX_INITIALIZER;
 static mach_port_t             _sc_server      = MACH_PORT_NULL;
 static unsigned int            _sc_store_cnt   = 0;
 static pthread_mutex_t         _sc_lock        = PTHREAD_MUTEX_INITIALIZER;
 static mach_port_t             _sc_server      = MACH_PORT_NULL;
 static unsigned int            _sc_store_cnt   = 0;
@@ -222,38 +221,12 @@ static pthread_once_t initialized = PTHREAD_ONCE_INIT;
 static void
 __SCDynamicStoreInitialize(void)
 {
 static void
 __SCDynamicStoreInitialize(void)
 {
-       CFBundleRef     bundle;
-
        /* register with CoreFoundation */
        __kSCDynamicStoreTypeID = _CFRuntimeRegisterClass(&__SCDynamicStoreClass);
 
        /* add handler to cleanup after fork() */
        (void) pthread_atfork(NULL, NULL, childForkHandler);
 
        /* register with CoreFoundation */
        __kSCDynamicStoreTypeID = _CFRuntimeRegisterClass(&__SCDynamicStoreClass);
 
        /* add handler to cleanup after fork() */
        (void) pthread_atfork(NULL, NULL, childForkHandler);
 
-       /* get the application/executable/bundle name */
-       bundle = CFBundleGetMainBundle();
-       if (bundle != NULL) {
-               _sc_bundleID = CFBundleGetIdentifier(bundle);
-               if (_sc_bundleID != NULL) {
-                       CFRetain(_sc_bundleID);
-               } else {
-                       CFURLRef        url;
-
-                       url = CFBundleCopyExecutableURL(bundle);
-                       if (url != NULL) {
-                               _sc_bundleID = CFURLCopyPath(url);
-                               CFRelease(url);
-                       }
-               }
-
-               if (_sc_bundleID != NULL) {
-                       if (CFEqual(_sc_bundleID, CFSTR("/"))) {
-                               CFRelease(_sc_bundleID);
-                               _sc_bundleID = CFStringCreateWithFormat(NULL, NULL, CFSTR("(%d)"), getpid());
-                       }
-               }
-       }
-
        return;
 }
 
        return;
 }
 
@@ -805,11 +778,7 @@ SCDynamicStoreCreateWithOptions(CFAllocatorRef             allocator,
        }
 
        // set "name"
        }
 
        // set "name"
-       if (_sc_bundleID != NULL) {
-               storePrivate->name = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@:%@"), _sc_bundleID, name);
-       } else {
-               storePrivate->name = CFRetain(name);
-       }
+       storePrivate->name = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@:%@"), _SC_getApplicationBundleID(), name);
 
        // set "options"
 
 
        // set "options"
 
index 485d12289af570ecf57817516f8f83dc31fab183..b48c76b3fbceb54861d75c5dfaacc7c3fa99fc0a 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2019 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -917,6 +917,46 @@ _SC_unschedule(CFTypeRef obj, CFRunLoopRef runLoop, CFStringRef runLoopMode, CFM
 #pragma mark Bundle
 
 
 #pragma mark Bundle
 
 
+CFStringRef
+_SC_getApplicationBundleID(void)
+{
+       static CFStringRef      bundleID        = NULL;
+       static dispatch_once_t  once;
+
+       dispatch_once(&once, ^{
+               CFBundleRef     bundle;
+
+               bundle = CFBundleGetMainBundle();
+               if (bundle != NULL) {
+                       bundleID = CFBundleGetIdentifier(bundle);
+                       if (bundleID != NULL) {
+                               CFRetain(bundleID);
+                       } else {
+                               CFURLRef        url;
+
+                               url = CFBundleCopyExecutableURL(bundle);
+                               if (url != NULL) {
+                                       bundleID = CFURLCopyPath(url);
+                                       CFRelease(url);
+                               }
+                       }
+
+                       if (bundleID != NULL) {
+                               if (CFEqual(bundleID, CFSTR("/"))) {
+                                       CFRelease(bundleID);
+                                       bundleID = NULL;
+                               }
+                       }
+               }
+               if (bundleID == NULL) {
+                       bundleID = CFStringCreateWithFormat(NULL, NULL, CFSTR("Unknown(%d)"), getpid());
+               }
+       });
+
+       return bundleID;
+}
+
+
 #define SYSTEMCONFIGURATION_BUNDLE_ID          CFSTR("com.apple.SystemConfiguration")
 #define        SYSTEMCONFIGURATION_FRAMEWORK_PATH_LEN  (sizeof(SYSTEMCONFIGURATION_FRAMEWORK_PATH) - 1)
 
 #define SYSTEMCONFIGURATION_BUNDLE_ID          CFSTR("com.apple.SystemConfiguration")
 #define        SYSTEMCONFIGURATION_FRAMEWORK_PATH_LEN  (sizeof(SYSTEMCONFIGURATION_FRAMEWORK_PATH) - 1)
 
index c8db81ecf1f93b401ab01abe7d538c4d96f34a04..d64b6df1fb5a796ae5b37698de6236ae7256a851 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004-2007, 2009, 2010-2013, 2015-2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2007, 2009, 2010-2013, 2015-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -29,8 +29,8 @@
  */
 
 
  */
 
 
-#include "SCPreferencesInternal.h"
 #include "SCNetworkConfigurationInternal.h"
 #include "SCNetworkConfigurationInternal.h"
+#include "SCPreferencesInternal.h"
 
 #include <sys/ioctl.h>
 #include <net/if.h>
 
 #include <sys/ioctl.h>
 #include <net/if.h>
@@ -49,40 +49,54 @@ __log_SCNetworkConfiguration(void)
 }
 
 
 }
 
 
-__private_extern__ CFDictionaryRef
-__getPrefsConfiguration(SCPreferencesRef prefs, CFStringRef path)
+static Boolean
+isEffectivelyEmptyConfiguration(CFDictionaryRef config)
 {
 {
-       CFDictionaryRef config;
+       Boolean         empty   = FALSE;
        CFIndex         n;
 
        CFIndex         n;
 
-       config = SCPreferencesPathGetValue(prefs, path);
-
        n = isA_CFDictionary(config) ? CFDictionaryGetCount(config) : 0;
        switch (n) {
                case 0 :
        n = isA_CFDictionary(config) ? CFDictionaryGetCount(config) : 0;
        switch (n) {
                case 0 :
-                       // ignore empty configuration entities
-                       config = NULL;
+                       // if no keys
+                       empty = TRUE;
                        break;
                case 1 :
                        if (CFDictionaryContainsKey(config, kSCResvInactive)) {
                                // ignore [effectively] empty configuration entities
                        break;
                case 1 :
                        if (CFDictionaryContainsKey(config, kSCResvInactive)) {
                                // ignore [effectively] empty configuration entities
-                               config = NULL;
+                               empty = TRUE;
                        }
                        break;
                default :
                        break;
        }
 
                        }
                        break;
                default :
                        break;
        }
 
+       return empty;
+}
+
+
+__private_extern__ CFDictionaryRef
+__SCNetworkConfigurationGetValue(SCPreferencesRef prefs, CFStringRef path)
+{
+       CFDictionaryRef config;
+
+       config = SCPreferencesPathGetValue(prefs, path);
+       if (isEffectivelyEmptyConfiguration(config)) {
+               // ignore [effectively] empty configuration entities
+               config = NULL;
+       }
+
        return config;
 }
 
 
 __private_extern__ Boolean
        return config;
 }
 
 
 __private_extern__ Boolean
-__setPrefsConfiguration(SCPreferencesRef       prefs,
-                       CFStringRef             path,
-                       CFDictionaryRef         config,
-                       Boolean                 keepInactive)
+__SCNetworkConfigurationSetValue(SCPreferencesRef      prefs,
+                                CFStringRef            path,
+                                CFDictionaryRef        config,
+                                Boolean                keepInactive)
 {
 {
+       Boolean                 changed;
        CFDictionaryRef         curConfig;
        CFMutableDictionaryRef  newConfig       = NULL;
        Boolean                 ok;
        CFDictionaryRef         curConfig;
        CFMutableDictionaryRef  newConfig       = NULL;
        Boolean                 ok;
@@ -93,6 +107,7 @@ __setPrefsConfiguration(SCPreferencesRef     prefs,
        }
 
        curConfig = SCPreferencesPathGetValue(prefs, path);
        }
 
        curConfig = SCPreferencesPathGetValue(prefs, path);
+       curConfig = isA_CFDictionary(curConfig);
 
        if (config != NULL) {
                newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config);
 
        if (config != NULL) {
                newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config);
@@ -115,16 +130,20 @@ __setPrefsConfiguration(SCPreferencesRef  prefs,
                }
        }
 
                }
        }
 
+       // check if the configuration changed
+       changed = !_SC_CFEqual(curConfig, newConfig);
+
        // set new configuration
        // set new configuration
-       if (_SC_CFEqual(curConfig, newConfig)) {
+       if (!changed) {
                // if no change
                if (newConfig != NULL) CFRelease(newConfig);
                ok = TRUE;
        } else if (newConfig != NULL) {
                // if no change
                if (newConfig != NULL) CFRelease(newConfig);
                ok = TRUE;
        } else if (newConfig != NULL) {
-               // if new configuration (or we are preserving a disabled state)
+               // if new configuration (or we are preserving a disabled state), update the prefs
                ok = SCPreferencesPathSetValue(prefs, path, newConfig);
                CFRelease(newConfig);
        } else {
                ok = SCPreferencesPathSetValue(prefs, path, newConfig);
                CFRelease(newConfig);
        } else {
+               // update the prefs
                ok = SCPreferencesPathRemoveValue(prefs, path);
                if (!ok && (SCError() == kSCStatusNoKey)) {
                        ok = TRUE;
                ok = SCPreferencesPathRemoveValue(prefs, path);
                if (!ok && (SCError() == kSCStatusNoKey)) {
                        ok = TRUE;
@@ -154,9 +173,10 @@ __setPrefsEnabled(SCPreferencesRef      prefs,
                  CFStringRef           path,
                  Boolean               enabled)
 {
                  CFStringRef           path,
                  Boolean               enabled)
 {
-       CFDictionaryRef         curConfig;
-       CFMutableDictionaryRef  newConfig       = NULL;
-       Boolean                 ok              = FALSE;
+       Boolean                                 changed;
+       CFDictionaryRef                         curConfig;
+       CFMutableDictionaryRef                  newConfig       = NULL;
+       Boolean                                 ok              = FALSE;
 
        // preserve current configuration
        curConfig = SCPreferencesPathGetValue(prefs, path);
 
        // preserve current configuration
        curConfig = SCPreferencesPathGetValue(prefs, path);
@@ -182,13 +202,17 @@ __setPrefsEnabled(SCPreferencesRef      prefs,
                }
        }
 
                }
        }
 
+       // check if the configuration changed
+       changed = !_SC_CFEqual(curConfig, newConfig);
+
        // set new configuration
        // set new configuration
-       if (_SC_CFEqual(curConfig, newConfig)) {
+       if (!changed) {
                // if no change
                if (newConfig != NULL) CFRelease(newConfig);
                ok = TRUE;
        } else if (newConfig != NULL) {
                // if updated configuration (or we are establishing as disabled)
                // if no change
                if (newConfig != NULL) CFRelease(newConfig);
                ok = TRUE;
        } else if (newConfig != NULL) {
                // if updated configuration (or we are establishing as disabled)
+
                ok = SCPreferencesPathSetValue(prefs, path, newConfig);
                CFRelease(newConfig);
        } else {
                ok = SCPreferencesPathSetValue(prefs, path, newConfig);
                CFRelease(newConfig);
        } else {
@@ -671,3 +695,48 @@ __str_to_rank(CFStringRef rankStr, SCNetworkServicePrimaryRank *rank)
 
        return TRUE;
 }
 
        return TRUE;
 }
+
+
+#define        kSCNetworkConfigurationFlagsBypassSystemInterfaces              (1<<0)
+#define        kSCNetworkConfigurationFlagsBypassSystemInterfacesForced        (1<<1)
+
+
+Boolean
+_SCNetworkConfigurationBypassSystemInterfaces(SCPreferencesRef prefs)
+{
+       Boolean         bypass;
+       uint32_t        nc_flags;
+
+       nc_flags = __SCPreferencesGetNetworkConfigurationFlags(prefs);
+       bypass = ((nc_flags & kSCNetworkConfigurationFlagsBypassSystemInterfaces) != 0);
+       if (bypass ||
+           (nc_flags & kSCNetworkConfigurationFlagsBypassSystemInterfacesForced) != 0) {
+               // if bypass flag explicitly requested
+               return bypass;
+       }
+
+       if (!__SCPreferencesUsingDefaultPrefs(prefs)) {
+               // if not using the default prefs (i.e. /L/P/SC/preferences.plist)
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+
+void
+_SCNetworkConfigurationSetBypassSystemInterfaces(SCPreferencesRef prefs, Boolean shouldBypass)
+{
+       uint32_t        nc_flags;
+
+       nc_flags = __SCPreferencesGetNetworkConfigurationFlags(prefs);
+       if (shouldBypass) {
+               nc_flags |= kSCNetworkConfigurationFlagsBypassSystemInterfaces;
+       } else {
+               nc_flags &= ~kSCNetworkConfigurationFlagsBypassSystemInterfaces;
+       }
+       nc_flags |= kSCNetworkConfigurationFlagsBypassSystemInterfacesForced;
+       __SCPreferencesSetNetworkConfigurationFlags(prefs, nc_flags);
+
+       return;
+}
index dc2f7bc2618c5d591a03197cee307c9f045c985f..94703449df417535c19dfeb6fd66fa018e0701ad 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004-2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -39,6 +39,9 @@
 #include <IOKit/IOKitLib.h>
 
 
 #include <IOKit/IOKitLib.h>
 
 
+#define        NETWORK_CONFIGURATION_VERSION   20191120
+
+
 typedef struct {
 
        // base CFType information
 typedef struct {
 
        // base CFType information
@@ -166,6 +169,7 @@ typedef struct {
        } usb;
 
        // misc
        } usb;
 
        // misc
+       CFArrayRef              matchingMACs;
        unsigned int            sort_order;             // sort order for this interface
 
        // for BOND interfaces
        unsigned int            sort_order;             // sort order for this interface
 
        // for BOND interfaces
@@ -199,10 +203,18 @@ typedef struct {
 
 __BEGIN_DECLS
 
 
 __BEGIN_DECLS
 
+#pragma mark -
+#pragma mark SCNetworkConfiguration (internal)
+
+
+Boolean
+__SCNetworkConfigurationBackup                         (SCPreferencesRef               prefs)          SPI_AVAILABLE(macos(10.15.4), ios(13.4), tvos(13.4), watchos(6.2), bridgeos(4.0));
+
 
 #pragma mark -
 #pragma mark SCNetworkInterface configuration (internal)
 
 
 #pragma mark -
 #pragma mark SCNetworkInterface configuration (internal)
 
+
 Boolean
 __SCNetworkInterfaceMatchesName                        (CFStringRef            name,
                                                 CFStringRef            key);
 Boolean
 __SCNetworkInterfaceMatchesName                        (CFStringRef            name,
                                                 CFStringRef            key);
@@ -210,17 +222,6 @@ __SCNetworkInterfaceMatchesName                    (CFStringRef            name,
 CFArrayRef
 __SCNetworkInterfaceCopyAll_IONetworkInterface (Boolean                keep_pre_configured);
 
 CFArrayRef
 __SCNetworkInterfaceCopyAll_IONetworkInterface (Boolean                keep_pre_configured);
 
-/*!
- @function __SCNetworkInterfaceCopyStorageEntity
- @discussion Create interface entity of network interface as seen in
- NetworkInterfaces.plist
- @param interface The network interface from which interface entity is create
- @result Dictionary which contains information about interface entity
- You must release the returned value.
- */
-CFDictionaryRef
-__SCNetworkInterfaceCopyStorageEntity          (SCNetworkInterfaceRef  interface);
-
 /*!
  @function __SCNetworkInterfaceCopyStoredWithPreferences
  @discussion Create an array of network interfaces, which is present in the preferences
 /*!
  @function __SCNetworkInterfaceCopyStoredWithPreferences
  @discussion Create an array of network interfaces, which is present in the preferences
@@ -371,7 +372,6 @@ __SCNetworkInterfaceSetDeepConfiguration    (SCNetworkSetRef        set,
  @discussion Will allow the caller to set IO Interface Unit
  @param interface The network interface
  @param unit The new interface unit to set
  @discussion Will allow the caller to set IO Interface Unit
  @param interface The network interface
  @param unit The new interface unit to set
-
  */
 void
 __SCNetworkInterfaceSetIOInterfaceUnit         (SCNetworkInterfaceRef interface,
  */
 void
 __SCNetworkInterfaceSetIOInterfaceUnit         (SCNetworkInterfaceRef interface,
@@ -402,6 +402,36 @@ _SCNetworkInterfaceCacheOpen(void);
 void
 _SCNetworkInterfaceCacheClose(void);
 
 void
 _SCNetworkInterfaceCacheClose(void);
 
+
+#pragma mark -
+#pragma mark SCNetworkInterface (NetworkInterfaces.plist) configuration (internal)
+
+
+#define kSCNetworkInterfaceActive                      "Active"
+#define kSCNetworkInterfaceInfo                                "SCNetworkInterfaceInfo"
+#define kSCNetworkInterfaceType                                "SCNetworkInterfaceType"
+#define kSCNetworkInterfaceBSDName                     kIOBSDNameKey
+#define kSCNetworkInterfaceIOBuiltin                   kIOBuiltin
+#define kSCNetworkInterfaceIOInterfaceNamePrefix       kIOInterfaceNamePrefix
+#define kSCNetworkInterfaceIOInterfaceType             kIOInterfaceType
+#define kSCNetworkInterfaceIOInterfaceUnit             kIOInterfaceUnit
+#define kSCNetworkInterfaceIOMACAddress                        kIOMACAddress
+#define kSCNetworkInterfaceIOPathMatch                 kIOPathMatchKey
+#define kSCNetworkInterfaceMatchingMACs                        "MatchingMACs"
+
+
+/*!
+       @function __SCNetworkInterfaceCopyStorageEntity
+       @discussion Create interface entity of network interface as seen in
+               NetworkInterfaces.plist
+       @param interface The network interface from which interface entity is create
+       @result Dictionary which contains information about interface entity.
+               You must release the returned value.
+ */
+CFDictionaryRef
+__SCNetworkInterfaceCopyStorageEntity          (SCNetworkInterfaceRef  interface);
+
+
 #pragma mark -
 #pragma mark SCNetworkProtocol configuration (internal)
 
 #pragma mark -
 #pragma mark SCNetworkProtocol configuration (internal)
 
@@ -447,8 +477,8 @@ Boolean
 __SCNetworkServiceIsPPTP                       (SCNetworkServiceRef    service);
 
 
 __SCNetworkServiceIsPPTP                       (SCNetworkServiceRef    service);
 
 
-SCPreferencesRef
-__SCNetworkCreateDefaultNIPrefs                        (CFStringRef            prefsID);
+void
+__SCNetworkPopulateDefaultNIPrefs              (SCPreferencesRef       ni_prefs);
 
 /*!
  @function __SCNetworkServiceMigrateNew
 
 /*!
  @function __SCNetworkServiceMigrateNew
@@ -471,6 +501,7 @@ __SCNetworkServiceAddProtocolToService              (SCNetworkServiceRef            service,
                                                 CFDictionaryRef                configuration,
                                                 Boolean                        enabled);
 
                                                 CFDictionaryRef                configuration,
                                                 Boolean                        enabled);
 
+
 #pragma mark -
 #pragma mark SCNetworkSet configuration (internal)
 
 #pragma mark -
 #pragma mark SCNetworkSet configuration (internal)
 
@@ -501,11 +532,11 @@ __copyProtocolTemplate                            (CFStringRef            interfaceType,
                                                 CFStringRef            protocolType);
 
 CFDictionaryRef
                                                 CFStringRef            protocolType);
 
 CFDictionaryRef
-__getPrefsConfiguration                                (SCPreferencesRef       prefs,
+__SCNetworkConfigurationGetValue               (SCPreferencesRef       prefs,
                                                 CFStringRef            path);
 
 Boolean
                                                 CFStringRef            path);
 
 Boolean
-__setPrefsConfiguration                                (SCPreferencesRef       prefs,
+__SCNetworkConfigurationSetValue               (SCPreferencesRef       prefs,
                                                 CFStringRef            path,
                                                 CFDictionaryRef        config,
                                                 Boolean                keepInactive);
                                                 CFStringRef            path,
                                                 CFDictionaryRef        config,
                                                 Boolean                keepInactive);
diff --git a/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.c b/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.c
new file mode 100644 (file)
index 0000000..9bab431
--- /dev/null
@@ -0,0 +1,1169 @@
+/*
+ * Copyright (c) 2019, 2020 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,
+ * 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
+ *
+ * October 4, 2018             Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
+
+#define        USE_SC_LOG_OR_PRINT     1               // use '_sc_log' to control os_log, printf
+
+#include "SCNetworkConfigurationInternal.h"
+#include "SCPreferencesInternal.h"
+#include <IOKit/IOBSD.h>
+
+
+static Boolean
+savePreferences(SCPreferencesRef       prefs,
+               CFStringRef             save_prefsID,
+               CFStringRef             prefix,
+               Boolean                 remove,
+               CFStringRef             extra_key,
+               CFPropertyListRef       extra_value)
+{
+       const CFStringRef       keys[] = {
+               kSCPrefCurrentSet,
+               MODEL,
+               kSCPrefNetworkServices,
+               kSCPrefSets,
+               kSCPrefSystem,
+               kSCPrefVersion,
+               kSCPrefVirtualNetworkInterfaces
+       };
+       Boolean                 ok;
+       SCPreferencesRef        save_prefs;
+
+       // open [companion] backup
+       save_prefs = SCPreferencesCreateCompanion(prefs, save_prefsID);
+
+       for (CFIndex i = 0; i < (CFIndex)(sizeof(keys)/sizeof(keys[0])); i++) {
+               CFStringRef     key     = keys[i];
+               CFStringRef     src_key;
+               CFTypeRef       val;
+
+               src_key = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), prefix, key);
+               val = SCPreferencesGetValue(prefs, src_key);
+               if (val != NULL) {
+                       SCPreferencesSetValue(save_prefs, key, val);
+                       if (remove) {
+                               SCPreferencesRemoveValue(prefs, src_key);
+                       }
+               }
+               CFRelease(src_key);
+       }
+
+       if (extra_key != NULL) {
+               SCPreferencesSetValue(save_prefs, extra_key, extra_value);
+       }
+
+       ok = SCPreferencesCommitChanges(save_prefs);
+       CFRelease(save_prefs);
+       if (!ok) {
+               SC_log(LOG_ERR, "could not save preferences (%@): %s",
+                      save_prefsID,
+                      SCErrorString(SCError()));
+       }
+       return ok;
+}
+
+
+__private_extern__
+Boolean
+__SCNetworkConfigurationBackup(SCPreferencesRef prefs)
+{
+       Boolean         ok;
+       CFStringRef     save_prefsID;
+       struct tm       tm_now;
+       struct timeval  tv_now;
+
+       SC_log(LOG_NOTICE, "creating [configuration] backup");
+
+       (void)gettimeofday(&tv_now, NULL);
+       (void)localtime_r(&tv_now.tv_sec, &tm_now);
+       save_prefsID = CFStringCreateWithFormat(NULL,
+                                                NULL,
+                                                CFSTR("preferences-%4d-%02d-%02d-%02d%02d%02d.plist"),
+                                                tm_now.tm_year + 1900,
+                                                tm_now.tm_mon + 1,
+                                                tm_now.tm_mday,
+                                                tm_now.tm_hour,
+                                                tm_now.tm_min,
+                                                tm_now.tm_sec);
+       ok = savePreferences(prefs, save_prefsID, CFSTR(""), FALSE, NULL, NULL);
+       CFRelease(save_prefsID);
+       return ok;
+}
+
+
+Boolean
+__SCNetworkConfigurationSaveModel(SCPreferencesRef prefs, CFStringRef model)
+{
+       Boolean         ok;
+       CFStringRef     save_prefsID;
+
+       SC_log(LOG_NOTICE, "creating [per-device] backup: %@", model);
+
+       save_prefsID = CFStringCreateWithFormat(NULL, NULL, CFSTR("preferences-%@.plist"), model);
+       ok = savePreferences(prefs, save_prefsID, CFSTR(""), TRUE, MODEL, model);
+       CFRelease(save_prefsID);
+       return ok;
+}
+
+
+static Boolean
+needsUpdate(SCPreferencesRef prefs, int new_version)
+{
+       CFNumberRef     num;
+       int             old_version     = 0;
+
+       if (prefs == NULL) {
+               // if no prefs, no updated needed
+               return FALSE;
+       }
+
+       num = SCPreferencesGetValue(prefs, kSCPrefVersion);
+       if (!isA_CFNumber(num) ||
+           !CFNumberGetValue(num, kCFNumberIntType, &old_version)) {
+               old_version = 0;
+       }
+       if (old_version == new_version) {
+               // if no update is needed
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+
+static Boolean
+lockWithSync(SCPreferencesRef prefs)
+{
+       Boolean         ok;
+
+       assert(prefs != NULL);
+       ok = SCPreferencesLock(prefs, TRUE);
+       if (!ok && (SCError() == kSCStatusStale)) {
+               SCPreferencesSynchronize(prefs);
+               ok = SCPreferencesLock(prefs, TRUE);
+       }
+
+       return ok;
+}
+
+
+Boolean
+__SCNetworkConfigurationUpgrade(SCPreferencesRef       *prefs_p,
+                               SCPreferencesRef        *ni_prefs_p,
+                               Boolean                 commit)
+{
+       SCPreferencesRef        ni_prefs        = NULL;
+       Boolean                 ni_prefs_added  = FALSE;
+       const int               new_version     = NETWORK_CONFIGURATION_VERSION;
+       CFNumberRef             num;
+       Boolean                 ok              = FALSE;
+       SCPreferencesRef        prefs           = NULL;
+       Boolean                 prefs_added     = FALSE;
+
+       //
+       // The following table describes how the SPI is called (input parameters), what actions
+       // are performed, and whether any changes should be committed as part of the call.
+       //
+       // +====================+===========================+===========================+========+
+       // |                    |     preferences.plist     |  NetworkInterfaces.plist  |        |
+       // |                    +=============+=============+=============+=============+ COMMIT |
+       // |                    |     ptr     |    plist    |     ptr     |    plist    |        |
+       // +====================+=============+=============+=============+=============+========+
+       // | InterfaceNamer     |    NULL     | CREATE, REL |  &ni_prefs  |     USE     |  YES   |
+       // +====================+=============+=============+=============+=============+========+
+       // | PreferencesMonitor |   &prefs    |     USE     |    NULL     |  NO UPDATE  |  YES   |
+       // +====================+=============+=============+=============+=============+========+
+       // | scutil             |   &prefs    |     USE     |  &ni_prefs  | USE/CREATE  |   NO   |
+       // +====================+=============+=============+=============+=============+========+
+       //
+       // For InterfaceNamer, we are passed a reference to the SCPreferences[Ref] for the
+       // NetworkInterfaces.plist.  During the upgrade process we create (and then release)
+       // the companion preferences.plist.  Any needed changes will be committed to both
+       // plists.
+       //
+       // For PreferencesMonitor, we are passed a reference to the SCPreferences[Ref] for
+       // the preferences.plist.  Any needed changes to the plist will be committed.  The
+       // companion NetworkInterfaces.plist is not passed nor is it referenced/modified.
+       //
+       // For scutil, we are passed references to the SCPreferences[Ref] for both the
+       // preferences.plist and NetworkInterfaces.plist.  The NetworkInterfaces.plist
+       // reference will be used, if already open.  Else, the companion will be created
+       // and returned.  Regardless, any changes made will not be committed (we expect
+       // one to use scutil's "commit" command).
+       //
+
+       if (prefs_p != NULL) {
+               prefs = *prefs_p;
+       }
+
+       if (ni_prefs_p != NULL) {
+               ni_prefs = *ni_prefs_p;
+       }
+
+       if ((prefs_p == NULL) && (ni_prefs_p != NULL) && (ni_prefs != NULL)) {
+               // Here, we have been called by InterfaceNamer and need to get the [companion]
+               // preferences.plist (we need to update both)
+               prefs = SCPreferencesCreateCompanion(ni_prefs, NULL);
+               if (prefs == NULL) {
+                       SC_log(LOG_ERR,
+                              "__SCNetworkConfigurationUpgrade(): could not open [preferences.plist]: %s",
+                              SCErrorString(SCError()));
+                       return FALSE;
+               }
+               prefs_added = TRUE;
+       }
+
+       if ((prefs_p != NULL) && (prefs != NULL) && (ni_prefs_p != NULL) && (ni_prefs == NULL)) {
+               // Here, we have been called by scutil with the [companion] NetworkInterfaces.plist
+               // not yet open.  Open the companion so that we can update both.
+               ni_prefs = SCPreferencesCreateCompanion(prefs, INTERFACES_DEFAULT_CONFIG);
+               if (ni_prefs == NULL) {
+                       SC_log(LOG_ERR,
+                              "__SCNetworkConfigurationUpgrade(): could not open [NetworkInterfaces.plist]: %s",
+                              SCErrorString(SCError()));
+                       return FALSE;
+               }
+               ni_prefs_added = TRUE;
+       }
+
+       if (!needsUpdate(prefs,    NETWORK_CONFIGURATION_VERSION) &&
+           !needsUpdate(ni_prefs, NETWORK_CONFIGURATION_VERSION)) {
+               goto done;
+       }
+
+       // lock [preferences.plist] changes while we are updating
+       ok = lockWithSync(prefs);
+       if (!ok) {
+               SC_log(LOG_ERR,
+                      "__SCNetworkConfigurationUpgrade(): could not lock [preferences.plist]: %s",
+                      SCErrorString(SCError()));
+               goto done;
+       }
+
+       if (ni_prefs != NULL) {
+               // lock [NetworkInterfaces.plist] changes while we are updating
+               ok = lockWithSync(ni_prefs);
+               if (!ok) {
+                       SC_log(LOG_ERR,
+                              "__SCNetworkConfigurationUpgrade(): could not lock [NetworkInterfaces.plist]: %s",
+                              SCErrorString(SCError()));
+                       SCPreferencesUnlock(prefs);
+                       goto done;
+               }
+       }
+
+       // first, cleanup any leftover cruft from the configuration
+       __SCNetworkConfigurationClean(prefs, ni_prefs);
+
+       // update the version(s)
+       num = CFNumberCreate(NULL, kCFNumberIntType, &new_version);
+       SCPreferencesSetValue(prefs, kSCPrefVersion, num);
+       CFRelease(num);
+       if (ni_prefs != NULL) {
+               num = CFNumberCreate(NULL, kCFNumberIntType, &new_version);
+               SCPreferencesSetValue(ni_prefs, kSCPrefVersion, num);
+               CFRelease(num);
+       }
+
+       if (commit) {
+               // commit the [preferences.plist] changes
+               ok = SCPreferencesCommitChanges(prefs);
+               if (!ok) {
+                       SC_log(LOG_ERR,
+                              "__SCNetworkConfigurationUpgrade(): update not saved [preferences.plist]: %s",
+                              SCErrorString(SCError()));
+               }
+               if (ok) {
+                       ok = SCPreferencesApplyChanges(prefs);
+                       if (!ok) {
+                               SC_log(LOG_ERR,
+                                      "__SCNetworkConfigurationUpgrade(): update not applied [preferences.plist]: %s",
+                                      SCErrorString(SCError()));
+                       }
+               }
+       }
+       SCPreferencesUnlock(prefs);
+
+       if (ni_prefs != NULL) {
+               if (commit) {
+                       // commit the [NetworkInterfaces.plist] changes
+                       if (ok) {
+                               ok = SCPreferencesCommitChanges(ni_prefs);
+                               if (!ok) {
+                                       SC_log(LOG_ERR,
+                                              "__SCNetworkConfigurationUpgrade(): update not saved [NetworkInterfaces.plist]: %s",
+                                              SCErrorString(SCError()));
+                               }
+                       }
+               }
+               SCPreferencesUnlock(ni_prefs);
+       }
+
+    done :
+
+       if (prefs_added) {
+//             if (ok && (prefs_p != NULL)) {
+//                     *prefs_p = CFRetain(prefs);
+//             }
+               CFRelease(prefs);
+       }
+
+       if (ni_prefs_added) {
+               if (ok && (ni_prefs_p != NULL)) {
+                       *ni_prefs_p = CFRetain(ni_prefs);
+               }
+               CFRelease(ni_prefs);
+       }
+
+       return ok;
+}
+
+
+#pragma mark -
+#pragma mark Remove "Hidden" Interface Configurations
+
+
+static Boolean
+isThin(CFArrayRef interfaces, CFStringRef bsdName)
+{
+       Boolean         thin;
+
+       thin = CFArrayContainsValue(interfaces,
+                                   CFRangeMake(0, CFArrayGetCount(interfaces)),
+                                   bsdName);
+       return thin;
+}
+
+
+static Boolean
+thinAdd(CFMutableArrayRef interfaces, CFStringRef bsdName)
+{
+       if (!CFArrayContainsValue(interfaces,
+                                 CFRangeMake(0, CFArrayGetCount(interfaces)),
+                                 bsdName)) {
+               CFArrayAppendValue(interfaces, bsdName);
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+
+static Boolean
+thinRemove(CFMutableArrayRef interfaces, CFStringRef bsdName)
+{
+       CFIndex         n;
+
+       n = CFArrayGetFirstIndexOfValue(interfaces,
+                                       CFRangeMake(0, CFArrayGetCount(interfaces)),
+                                       bsdName);
+       if (n != kCFNotFound) {
+               CFArrayRemoveValueAtIndex(interfaces, n);
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+
+static CF_RETURNS_RETAINED CFStringRef
+serviceMatchesTemplate(SCPreferencesRef prefs, SCNetworkServiceRef existingService)
+{
+       CFStringRef             conflict        = NULL;
+       SCNetworkInterfaceRef   existingInterface;
+       CFIndex                 n;
+       CFArrayRef              protocols;
+       CFMutableArrayRef       protocolTypes;
+       SCNetworkServiceRef     templateService;
+
+       // create a temporary network service (so that we can get the template configuration)
+       existingInterface = SCNetworkServiceGetInterface(existingService);
+       if (existingInterface == NULL) {
+               conflict = CFStringCreateCopy(NULL, CFSTR("could not get interface for service"));
+               return conflict;
+       }
+
+       templateService = SCNetworkServiceCreate(prefs, existingInterface);
+       if (templateService == NULL) {
+               conflict = CFStringCreateCopy(NULL, CFSTR("could not create service for interface"));
+               return conflict;
+       }
+
+       (void) SCNetworkServiceEstablishDefaultConfiguration(templateService);
+
+       protocolTypes = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
+       // get protocol types from the existing service
+       protocols = SCNetworkServiceCopyProtocols(existingService);
+       if (protocols != NULL) {
+               n = CFArrayGetCount(protocols);
+
+               for (CFIndex i = 0; i < n; i++) {
+                       SCNetworkProtocolRef    protocol;
+                       CFStringRef             protocolType;
+
+                       protocol = CFArrayGetValueAtIndex(protocols, i);
+                       protocolType = SCNetworkProtocolGetProtocolType(protocol);
+                       if (!CFArrayContainsValue(protocolTypes,
+                                                 CFRangeMake(0, CFArrayGetCount(protocolTypes)),
+                                                 protocolType)) {
+                               CFArrayAppendValue(protocolTypes, protocolType);
+                       }
+               }
+
+               CFRelease(protocols);
+       }
+
+       // get protocol types from the template service
+       protocols = SCNetworkServiceCopyProtocols(templateService);
+       if (protocols != NULL) {
+               n = CFArrayGetCount(protocols);
+
+               for (CFIndex i = 0; i < n; i++) {
+                       SCNetworkProtocolRef    protocol;
+                       CFStringRef             protocolType;
+
+                       protocol = CFArrayGetValueAtIndex(protocols, i);
+                       protocolType = SCNetworkProtocolGetProtocolType(protocol);
+                       if (!CFArrayContainsValue(protocolTypes,
+                                                 CFRangeMake(0, CFArrayGetCount(protocolTypes)),
+                                                 protocolType)) {
+                               CFArrayAppendValue(protocolTypes, protocolType);
+                       }
+               }
+
+               CFRelease(protocols);
+       }
+
+       // compare the existing protocols with the template
+       n = CFArrayGetCount(protocolTypes);
+       for (CFIndex i = 0; i < n; i++) {
+               CFDictionaryRef         existingConfiguration   = NULL;
+               SCNetworkProtocolRef    existingProtocol;
+               Boolean                 match;
+               CFStringRef             protocolType;
+               CFDictionaryRef         templateConfiguration   = NULL;
+               SCNetworkProtocolRef    templateProtocol;
+
+               protocolType = CFArrayGetValueAtIndex(protocolTypes, i);
+               existingProtocol = SCNetworkServiceCopyProtocol(existingService, protocolType);
+               templateProtocol = SCNetworkServiceCopyProtocol(templateService, protocolType);
+
+               do {
+                       // compare "enabled"
+                       match = ((existingProtocol != NULL) &&
+                                (templateProtocol != NULL) &&
+                                (SCNetworkProtocolGetEnabled(existingProtocol) == SCNetworkProtocolGetEnabled(templateProtocol)));
+                       if (!match) {
+                               conflict = CFStringCreateWithFormat(NULL, NULL,
+                                                                   CFSTR("conflicting %@ enable/disable"),
+                                                                   protocolType);
+                               break;          // if enable/disable conflict
+                       }
+
+                       if (existingProtocol != NULL) {
+                               existingConfiguration = SCNetworkProtocolGetConfiguration(existingProtocol);
+                       }
+                       if (templateProtocol != NULL) {
+                               templateConfiguration = SCNetworkProtocolGetConfiguration(templateProtocol);
+                       }
+                       match = _SC_CFEqual(existingConfiguration, templateConfiguration);
+                       if (!match) {
+                               conflict = CFStringCreateWithFormat(NULL, NULL,
+                                                                   CFSTR("conflicting %@ configuration"),
+                                                                   protocolType);
+                               break;          // if configuration conflict
+                       }
+               } while (FALSE);
+
+               if (existingProtocol != NULL) CFRelease(existingProtocol);
+               if (templateProtocol != NULL) CFRelease(templateProtocol);
+               if (!match) {
+                       break;
+               }
+       }
+
+       (void) SCNetworkServiceRemove(templateService);
+       CFRelease(templateService);
+       CFRelease(protocolTypes);
+       return conflict;
+}
+
+
+static Boolean
+effectivelyHiddenConfiguration(SCNetworkInterfaceRef interface)
+{
+       const CFStringRef       known[] = {
+               CFSTR("Apple TV"),
+               CFSTR("Watch"),
+               CFSTR("iPad"),
+               CFSTR("iPhone"),
+               CFSTR("iPod"),
+       };
+       CFStringRef             name;
+
+       name = SCNetworkInterfaceGetLocalizedDisplayName(interface);
+       for (int i = 0; i < (int)(sizeof(known) / sizeof(known[0])); i++) {
+               if (CFStringHasPrefix(name, known[i])) {
+                       return TRUE;
+               }
+       }
+
+       return FALSE;
+}
+
+
+static Boolean
+__SCNetworkConfigurationCleanHiddenInterfaces(SCPreferencesRef prefs, SCPreferencesRef ni_prefs)
+{
+#pragma unused(prefs)
+#pragma unused(ni_prefs)
+       CFStringRef             bsdName;
+       Boolean                 changed         = FALSE;
+       CFArrayRef              interfaces;
+       CFMutableArrayRef       interfaces_thin;
+       CFIndex                 n;
+       CFDictionaryRef         nat_config;
+       SCPreferencesRef        nat_prefs;
+       CFArrayRef              services;
+       int                     updated         = 0;
+
+       // build a list of interfaces we "could" remove
+
+       interfaces_thin = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
+       services = SCNetworkServiceCopyAll(prefs);
+       if (services != NULL) {
+               n = CFArrayGetCount(services);
+               for (CFIndex i = 0; i < n; i++) {
+                       CFStringRef             conflict;
+                       SCNetworkInterfaceRef   interface;
+                       SCNetworkServiceRef     service;
+                       const char              *thin   = NULL;
+
+                       service = CFArrayGetValueAtIndex(services, i);
+                       interface = SCNetworkServiceGetInterface(service);
+                       bsdName = SCNetworkInterfaceGetBSDName(interface);
+
+                       if (bsdName == NULL) {
+                               // if no interface name
+                               if ((_sc_log == 1) || _sc_debug) {
+                                       SC_log(LOG_INFO,
+                                              "skipping service : %@ : %@ (no interface)",
+                                              SCNetworkServiceGetServiceID(service),
+                                              SCNetworkServiceGetName(service));
+                               }
+                               continue;
+                       }
+
+                       if (_SCNetworkInterfaceIsHiddenConfiguration(interface)) {
+                               thin = "hidden";
+                       } else if (effectivelyHiddenConfiguration(interface)) {
+                               thin = "effectively hidden";
+                       } else {
+                               // if not HiddenConfiguration
+                               if ((_sc_log == 1) || _sc_debug) {
+                                       SC_log(LOG_INFO,
+                                              "skipping service : %@ : %@ : %@ (not hidden)",
+                                               SCNetworkServiceGetServiceID(service),
+                                               SCNetworkServiceGetName(service),
+                                               bsdName);
+                               }
+                               continue;
+                       }
+
+                       conflict = serviceMatchesTemplate(prefs, service);
+                       if (conflict != NULL) {
+                               // if any part of the service's configuration was changed
+                               if ((_sc_log == 1) || _sc_debug) {
+                                       SC_log(LOG_INFO,
+                                              "skipping service : %@ : %@ : %@ (%s, non-default, %@)",
+                                              SCNetworkServiceGetServiceID(service),
+                                              SCNetworkServiceGetName(service),
+                                              bsdName,
+                                              thin,
+                                              conflict);
+                               }
+                               CFRelease(conflict);
+                               continue;
+                       }
+
+                       if ((_sc_log == 1) || _sc_debug) {
+                               SC_log(LOG_INFO, "candidate interface : %@ (%s)", bsdName, thin);
+                       }
+
+                       thinAdd(interfaces_thin, bsdName);
+               }
+       }
+
+       // remove any virtual interfaces from the list
+
+#if    !TARGET_OS_IPHONE
+       interfaces = SCBondInterfaceCopyAll(prefs);
+       if (interfaces != NULL) {
+               CFIndex         n;
+
+               n = CFArrayGetCount(interfaces);
+               for (CFIndex i = 0; i < n; i++) {
+                       SCBondInterfaceRef      bondInterface;
+                       CFArrayRef              members;
+                       CFIndex                 nn;
+
+                       bondInterface = CFArrayGetValueAtIndex(interfaces, i);
+                       members = SCBondInterfaceGetMemberInterfaces(bondInterface);
+                       nn = (members != NULL) ? CFArrayGetCount(members) : 0;
+                       for (CFIndex ii = 0; ii < nn; ii++) {
+                               SCNetworkInterfaceRef   member;
+
+                               member = CFArrayGetValueAtIndex(members, ii);
+                               bsdName = SCNetworkInterfaceGetBSDName(member);
+                               if ((bsdName != NULL) &&
+                                   thinRemove(interfaces_thin, bsdName)) {
+                                       if ((_sc_log == 1) || _sc_debug) {
+                                               SC_log(LOG_INFO, "skipping interface : %@ (bond member)", bsdName);
+                                       }
+                               }
+                       }
+               }
+
+               CFRelease(interfaces);
+       }
+#endif // !TARGET_OS_IPHONE
+
+       interfaces = SCBridgeInterfaceCopyAll(prefs);
+       if (interfaces != NULL) {
+               CFIndex         n;
+
+               n = CFArrayGetCount(interfaces);
+               for (CFIndex i = 0; i < n; i++) {
+                       SCBridgeInterfaceRef    bridgeInterface;
+                       CFArrayRef              members;
+                       CFIndex                 nn;
+
+                       bridgeInterface = CFArrayGetValueAtIndex(interfaces, i);
+                       members = SCBridgeInterfaceGetMemberInterfaces(bridgeInterface);
+                       nn = (members != NULL) ? CFArrayGetCount(members) : 0;
+                       for (CFIndex ii = 0; ii < nn; ii++) {
+                               SCNetworkInterfaceRef   member;
+
+                               member = CFArrayGetValueAtIndex(members, ii);
+                               bsdName = SCNetworkInterfaceGetBSDName(member);
+                               if ((bsdName != NULL) &&
+                                   thinRemove(interfaces_thin, bsdName)) {
+                                       if ((_sc_log == 1) || _sc_debug) {
+                                               SC_log(LOG_INFO, "skipping interface : %@ (bridge member)", bsdName);
+                                       }
+                               }
+                       }
+               }
+
+               CFRelease(interfaces);
+       }
+
+       interfaces = SCVLANInterfaceCopyAll(prefs);
+       if (interfaces != NULL) {
+               CFIndex         n;
+
+               n = CFArrayGetCount(interfaces);
+               for (CFIndex i = 0; i < n; i++) {
+                       SCBridgeInterfaceRef    vlanInterface;
+                       SCNetworkInterfaceRef   physicalInterface;
+
+                       vlanInterface = CFArrayGetValueAtIndex(interfaces, i);
+                       physicalInterface = SCVLANInterfaceGetPhysicalInterface(vlanInterface);
+                       bsdName = SCNetworkInterfaceGetBSDName(physicalInterface);
+                       if ((bsdName != NULL) &&
+                           thinRemove(interfaces_thin, bsdName)) {
+                               if ((_sc_log == 1) || _sc_debug) {
+                                       SC_log(LOG_INFO, "skipping interface : %@ (vlan physical)", bsdName);
+                               }
+                       }
+               }
+
+               CFRelease(interfaces);
+       }
+
+       // remove any "shared" interfaces from the list
+
+       nat_prefs = SCPreferencesCreateCompanion(prefs, CFSTR("com.apple.nat.plist"));
+       nat_config = SCPreferencesGetValue(nat_prefs, CFSTR("NAT"));
+       if (isA_CFDictionary(nat_config)) {
+               CFStringRef     sharedFrom      = NULL;
+               CFArrayRef      sharedTo        = NULL;
+
+               if (CFDictionaryGetValueIfPresent(nat_config,
+                                                 CFSTR("PrimaryService"),
+                                                 (const void **)&sharedFrom) &&
+                       isA_CFString(sharedFrom)) {
+                       SCNetworkInterfaceRef   interface;
+                       SCNetworkServiceRef     service;
+
+                       // if "Share your connection from" service configured
+                       service = SCNetworkServiceCopy(prefs, sharedFrom);
+                       if (service != NULL) {
+                               interface = SCNetworkServiceGetInterface(service);
+                               bsdName = SCNetworkInterfaceGetBSDName(interface);
+                               if ((bsdName != NULL) &&
+                                   thinRemove(interfaces_thin, bsdName)) {
+                                       if ((_sc_log == 1) || _sc_debug) {
+                                               SC_log(LOG_INFO, "skipping interface : %@ (Share your connection from)", bsdName);
+                                       }
+                               }
+                               CFRelease(service);
+                       } else {
+                               SC_log(LOG_INFO, "keeping [not found] service : %@ (Share your connection from)", sharedFrom);
+                       }
+               }
+
+          if (CFDictionaryGetValueIfPresent(nat_config,
+                                            CFSTR("SharingDevices"),
+                                            (const void **)&sharedTo) &&
+                  isA_CFArray(sharedTo)) {
+                  // if "To computers using" interfaces configured
+                  n = CFArrayGetCount(sharedTo);
+                  for (CFIndex i = 0; i < n; i++) {
+                          bsdName = CFArrayGetValueAtIndex(sharedTo, i);
+                          if (thinRemove(interfaces_thin, bsdName)) {
+                                  if ((_sc_log == 1) || _sc_debug) {
+                                          SC_log(LOG_INFO, "skipping interface : %@ (To computers using)", bsdName);
+                                  }
+                          }
+                  }
+          }
+       }
+       CFRelease(nat_prefs);
+
+       // thin preferences.plist
+       n = (services != NULL) ? CFArrayGetCount(services) : 0;
+       if (n > 0) {
+               updated = 0;
+
+               for (CFIndex i = 0; i < n; i++) {
+                       SCNetworkInterfaceRef   interface;
+                       SCNetworkServiceRef     service;
+
+                       service = CFArrayGetValueAtIndex(services, i);
+                       interface = SCNetworkServiceGetInterface(service);
+                       bsdName = SCNetworkInterfaceGetBSDName(interface);
+                       if (bsdName == NULL) {
+                               // if no interface name
+                               continue;
+                       }
+
+                       if (!isThin(interfaces_thin, bsdName)) {
+                               // if not thinned
+                               continue;
+                       }
+
+                       // remove this service associated with a "thinned" interface
+                       if ((_sc_log == 1) || _sc_verbose) {
+                               SC_log(LOG_INFO,
+                                      "thinned network service : %@ : %@ : %@",
+                                      SCNetworkServiceGetServiceID(service),
+                                      SCNetworkServiceGetName(service),
+                                      bsdName);
+                       }
+                       SCNetworkServiceRemove(service);
+                       updated++;
+               }
+
+               if (updated > 0) {
+                       if ((_sc_log == 1) || _sc_debug) {
+                               SC_log(LOG_NOTICE,
+                                      "Updating \"preferences.plist\" (thinned %d service%s)",
+                                      updated,
+                                      (updated != 1) ? "s" : "");
+                       }
+                       changed = TRUE;
+               }
+       }
+
+       // thin NetworkInterfaces.plist
+       interfaces = SCPreferencesGetValue(ni_prefs, INTERFACES);
+       interfaces = isA_CFArray(interfaces);
+       n = (interfaces != NULL) ? CFArrayGetCount(interfaces) : 0;
+       if (n > 0) {
+               CFMutableArrayRef       interfaces_new;
+
+               updated = 0;
+
+               interfaces_new = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+               n = CFArrayGetCount(interfaces);
+               for (CFIndex i = 0; i < n; i++) {
+                       CFDictionaryRef if_dict;
+
+                       if_dict = CFArrayGetValueAtIndex(interfaces, i);
+                       bsdName = CFDictionaryGetValue(if_dict, CFSTR(kIOBSDNameKey));
+                       if (isThin(interfaces_thin, bsdName)) {
+                               // remove this "thinned" interface
+                               if ((_sc_log == 1) || _sc_verbose) {
+                                       SC_log(LOG_INFO, "thinned network interface : %@", bsdName);
+                               }
+                               updated++;
+                               continue;
+                       }
+
+                       CFArrayAppendValue(interfaces_new, if_dict);
+               }
+               SCPreferencesSetValue(ni_prefs, INTERFACES, interfaces_new);
+               CFRelease(interfaces_new);
+
+               if (updated > 0) {
+                       if ((_sc_log == 1) || _sc_debug) {
+                               SC_log(LOG_INFO,
+                                      "Updating \"NetworkInterfaces.plist\" (thinned %d interface%s)",
+                                      updated,
+                                      (updated != 1) ? "s" : "");
+                       }
+                       changed = TRUE;
+               }
+       }
+
+       if (services != NULL) CFRelease(services);
+       CFRelease(interfaces_thin);
+       return changed;
+}
+
+
+#pragma mark -
+#pragma mark Remove [SCNetworkMigration] Inline Backups
+
+
+static void
+thinInlineBackup(const void *value, void *context)
+{
+       CFStringRef             backup          = (CFStringRef)value;
+       char                    *backup_str;
+       SCPreferencesRef        prefs           = (SCPreferencesRef)context;
+       CFStringRef             save_prefix;
+       CFStringRef             save_prefsID    = NULL;
+
+       SC_log(LOG_NOTICE, "thinning [inline] backup: %@", backup);
+
+       save_prefix = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ : "), backup);
+       backup_str = _SC_cfstring_to_cstring(backup, NULL, 0, kCFStringEncodingASCII);
+       if (backup_str != NULL) {
+               struct tm       save_tm = { 0 };
+
+               if (strptime(backup_str, "%Y-%m-%d %H:%M:%S", &save_tm) != NULL) {
+                       save_prefsID = CFStringCreateWithFormat(NULL,
+                                                               NULL,
+                                                               CFSTR("preferences-%4d-%02d-%02d-%02d%02d%02d.plist"),
+                                                               save_tm.tm_year + 1900,
+                                                               save_tm.tm_mon + 1,
+                                                               save_tm.tm_mday,
+                                                               save_tm.tm_hour,
+                                                               save_tm.tm_min,
+                                                               save_tm.tm_sec);
+               }
+               CFAllocatorDeallocate(NULL, backup_str);
+       }
+       if (save_prefsID == NULL) {
+               save_prefsID = CFStringCreateWithFormat(NULL, NULL, CFSTR("preferences-%@.plist"), backup);
+       }
+       savePreferences(prefs, save_prefsID, save_prefix, TRUE, NULL, NULL);
+       CFRelease(save_prefsID);
+       CFRelease(save_prefix);
+       return;
+}
+
+
+static Boolean
+__SCNetworkConfigurationCleanInlineBackups(SCPreferencesRef prefs)
+{
+       CFMutableSetRef backups = NULL;
+       Boolean         cleaned = FALSE;
+       CFArrayRef      keys;
+       CFIndex         n;
+       CFStringRef     suffix;
+
+       keys = SCPreferencesCopyKeyList(prefs);
+       if (keys == NULL) {
+               return FALSE;
+       }
+
+       suffix = CFStringCreateWithFormat(NULL, NULL, CFSTR(" : %@"), kSCPrefSets);
+       n = CFArrayGetCount(keys);
+       for (CFIndex i = 0; i < n; i++) {
+               CFStringRef             key     = CFArrayGetValueAtIndex(keys, i);
+               CFMutableStringRef      str;
+
+               if (CFStringHasSuffix(key, suffix)) {
+                       // if "<backup-date> : Sets"
+                       if (backups == NULL) {
+                               backups = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
+                       }
+                       str = CFStringCreateMutableCopy(NULL, 0, key);
+                       CFStringTrim(str, suffix);
+                       CFSetAddValue(backups, str);
+                       CFRelease(str);
+                       continue;
+               }
+       }
+       CFRelease(suffix);
+       CFRelease(keys);
+
+       if (backups != NULL) {
+               CFSetApplyFunction(backups, thinInlineBackup, (void *)prefs);
+               CFRelease(backups);
+               cleaned = TRUE;
+       }
+
+       return cleaned;
+}
+
+
+#pragma mark -
+#pragma mark Remove [new device type] Inline Backups
+
+
+static void
+thinInlineModel(const void *value, void *context)
+{
+       CFStringRef             model   = (CFStringRef)value;
+       SCPreferencesRef        prefs   = (SCPreferencesRef)context;
+       CFStringRef             save_prefix;
+       CFStringRef             save_prefsID;
+
+       SC_log(LOG_NOTICE, "thinning [per-model] backup: %@", model);
+
+       save_prefix = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@:"), model);
+       save_prefsID = CFStringCreateWithFormat(NULL, NULL, CFSTR("preferences-%@.plist"), model);
+       savePreferences(prefs, save_prefsID, save_prefix, TRUE, MODEL, model);
+       CFRelease(save_prefsID);
+       CFRelease(save_prefix);
+       return;
+}
+
+
+static Boolean
+__SCNetworkConfigurationCleanInlineModels(SCPreferencesRef prefs)
+{
+       Boolean         cleaned = FALSE;
+       CFArrayRef      keys;
+       CFMutableSetRef models  = NULL;
+       CFIndex         n;
+       CFStringRef     suffix;
+
+       keys = SCPreferencesCopyKeyList(prefs);
+       if (keys == NULL) {
+               return FALSE;
+       }
+
+       suffix = CFStringCreateWithFormat(NULL, NULL, CFSTR(":%@"), kSCPrefSets);
+       n = CFArrayGetCount(keys);
+       for (CFIndex i = 0; i < n; i++) {
+               CFStringRef             key     = CFArrayGetValueAtIndex(keys, i);
+               CFMutableStringRef      str;
+
+               if (CFStringHasSuffix(key, suffix)) {
+                       // if "<backup-date> : Sets"
+                       if (models == NULL) {
+                               models = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
+                       }
+                       str = CFStringCreateMutableCopy(NULL, 0, key);
+                       CFStringTrim(str, suffix);
+                       CFSetAddValue(models, str);
+                       CFRelease(str);
+                       continue;
+               }
+       }
+       CFRelease(suffix);
+       CFRelease(keys);
+
+       if (models != NULL) {
+               CFSetApplyFunction(models, thinInlineModel, (void *)prefs);
+               CFRelease(models);
+               cleaned = TRUE;
+       }
+
+       return cleaned;
+}
+
+
+#pragma mark -
+#pragma mark Remove Orphaned Services
+
+
+/*
+static Boolean
+__SCNetworkConfigurationCleanOrphanedServices(SCPreferencesRef prefs)
+{
+#pragma unused(prefs)
+       return FALSE;
+}
+*/
+
+
+#pragma mark -
+#pragma mark Cleanup network service order issues
+
+
+static Boolean
+__SCNetworkConfigurationCleanServiceOrderIssues(SCPreferencesRef prefs)
+{
+#pragma unused(prefs)
+       Boolean         cleaned = FALSE;
+       CFIndex         nSets;
+       CFArrayRef      sets;
+
+       sets = SCNetworkSetCopyAll(prefs);
+       nSets = (sets != NULL) ? CFArrayGetCount(sets) : 0;
+       for (CFIndex iSets = 0; iSets < nSets; iSets++) {
+               CFIndex                 iServices;
+               CFMutableSetRef         known           = NULL;
+               CFIndex                 nServices;
+               SCNetworkSetRef         set             = CFArrayGetValueAtIndex(sets, iSets);
+               CFStringRef             setID           = SCNetworkSetGetSetID(set);
+               CFArrayRef              order           = SCNetworkSetGetServiceOrder(set);
+               CFMutableArrayRef       newOrder        = NULL;
+
+               iServices = 0;
+               nServices = (order != NULL) ? CFArrayGetCount(order) : 0;
+               if (nServices > 0) {
+                       known = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
+                       newOrder = CFArrayCreateMutableCopy(NULL, 0, order);
+               }
+
+               while (iServices < nServices) {
+                       SCNetworkServiceRef     service;
+                       CFStringRef             serviceID       = CFArrayGetValueAtIndex(newOrder, iServices);
+
+                       // check if serviceID already known/processed
+                       if (CFSetContainsValue(known, serviceID)) {
+                               // if duplicate/removed service, remove from serviceOrder
+                               if ((_sc_log == 1) || _sc_debug) {
+                                       SC_log(LOG_NOTICE,
+                                              "set: %@, removing serviceID %@ (duplicate/removed)",
+                                              setID,
+                                              serviceID);
+                               }
+                               CFArrayRemoveValueAtIndex(newOrder, iServices);
+                               nServices--;
+                               cleaned = TRUE;
+                               continue;
+                       }
+
+                       // track this serviceID as known, already removed, or removed below
+                       CFSetAddValue(known, serviceID);
+
+                       // validate serviceID
+                       service = SCNetworkServiceCopy(prefs, serviceID);
+                       if (service == NULL) {
+                               // if no service, remove from serviceOrder
+                               if ((_sc_log == 1) || _sc_debug) {
+                                       SC_log(LOG_NOTICE,
+                                              "set: %@, removing serviceID %@ (no service)",
+                                              setID,
+                                              serviceID);
+                               }
+                               CFArrayRemoveValueAtIndex(newOrder, iServices);
+                               nServices--;
+                               cleaned = TRUE;
+                               continue;
+                       }
+
+                       if (!__SCNetworkServiceExists(service)) {
+                               // if service already removed, remove from serviceOrder
+                               if ((_sc_log == 1) || _sc_debug) {
+                                       SC_log(LOG_NOTICE,
+                                              "set: %@, removing serviceID %@ (service already removed)",
+                                              setID,
+                                              serviceID);
+                               }
+                               CFArrayRemoveValueAtIndex(newOrder, iServices);
+                               nServices--;
+                               cleaned = TRUE;
+                               CFRelease(service);
+                               continue;
+                       }
+
+                       CFRelease(service);
+                       iServices++;
+               }
+
+               if (known != NULL) {
+                       CFRelease(known);
+               }
+
+               if (newOrder != NULL) {
+                       if (cleaned) {
+                               SCNetworkSetSetServiceOrder(set, newOrder);
+                       }
+                       CFRelease(newOrder);
+               }
+       }
+
+       if (sets != NULL) {
+               CFRelease(sets);
+       }
+
+       return cleaned;
+}
+
+
+#pragma mark -
+#pragma mark Cleanup Network Configuration(s)
+
+
+Boolean
+__SCNetworkConfigurationClean(SCPreferencesRef prefs, SCPreferencesRef ni_prefs)
+{
+       Boolean         changed;
+       Boolean         updated =       FALSE;
+
+       changed = __SCNetworkConfigurationCleanInlineBackups(prefs);
+       if (changed) {
+               SC_log(LOG_NOTICE, "network configuration: unwanted inline backups removed");
+               updated = TRUE;
+       }
+
+       changed = __SCNetworkConfigurationCleanInlineModels(prefs);
+       if (changed) {
+               SC_log(LOG_NOTICE, "network configuration: unwanted device backups removed");
+               updated = TRUE;
+       }
+
+       if (ni_prefs != NULL) {
+               changed = __SCNetworkConfigurationCleanHiddenInterfaces(prefs, ni_prefs);
+               if (changed) {
+                       SC_log(LOG_NOTICE, "network configuration: hidden interface configurations removed");
+                       updated = TRUE;
+               }
+       }
+
+       changed = __SCNetworkConfigurationCleanServiceOrderIssues(prefs);
+       if (changed) {
+               SC_log(LOG_NOTICE, "network configuration: ServiceOrder cleaned");
+               updated = TRUE;
+       }
+
+       return updated;
+}
index e1346b0424a48b460bc66339a0eb5c6ced225264..31295695716190846c9c1e87fd6d750a65b636d9 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2005-2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2005-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -88,6 +88,34 @@ typedef CF_ENUM(uint32_t, SCNetworkServicePrimaryRank) {
        kSCNetworkServicePrimaryRankScoped      = 4
 };
 
        kSCNetworkServicePrimaryRankScoped      = 4
 };
 
+#pragma mark -
+#pragma mark SCNetworkConfiguration (SPI)
+
+/*!
+       @group Configuration
+ */
+
+Boolean
+_SCNetworkConfigurationBypassSystemInterfaces          (SCPreferencesRef       prefs)          SPI_AVAILABLE(macos(10.15.4), ios(13.4), tvos(13.4), watchos(6.2), bridgeos(4.0));
+
+void
+_SCNetworkConfigurationSetBypassSystemInterfaces       (SCPreferencesRef       prefs,
+                                                        Boolean                shouldBypass)   SPI_AVAILABLE(macos(10.15.4), ios(13.4), tvos(13.4), watchos(6.2), bridgeos(4.0));
+
+Boolean
+__SCNetworkConfigurationClean                          (SCPreferencesRef       prefs,
+                                                        SCPreferencesRef       ni_prefs)       SPI_AVAILABLE(macos(10.15.4), ios(13.4), tvos(13.4), watchos(6.2), bridgeos(4.0));
+
+Boolean
+__SCNetworkConfigurationSaveModel                      (SCPreferencesRef       prefs,
+                                                        CFStringRef            model)          SPI_AVAILABLE(macos(10.15.4), ios(13.4), tvos(13.4), watchos(6.2), bridgeos(4.0));
+
+Boolean
+__SCNetworkConfigurationUpgrade                                (SCPreferencesRef       *prefs,
+                                                        SCPreferencesRef       *ni_prefs,
+                                                        Boolean                commit)         SPI_AVAILABLE(macos(10.15.4), ios(13.4), tvos(13.4), watchos(6.2), bridgeos(4.0));
+
+
 #pragma mark -
 #pragma mark SCNetworkInterface configuration (SPI)
 
 #pragma mark -
 #pragma mark SCNetworkInterface configuration (SPI)
 
@@ -211,6 +239,10 @@ _SCNetworkInterfaceCopyBTPANInterface                      (void)                                          API_AVAILABLE(macos(10.9)) A
 CFStringRef
 _SCNetworkInterfaceCopySlashDevPath                    (SCNetworkInterfaceRef          interface)      API_AVAILABLE(macos(10.6), ios(3.0));
 
 CFStringRef
 _SCNetworkInterfaceCopySlashDevPath                    (SCNetworkInterfaceRef          interface)      API_AVAILABLE(macos(10.6), ios(3.0));
 
+SCNetworkServiceRef
+_SCNetworkServiceCreatePreconfigured                   (SCPreferencesRef               prefs,
+                                                        SCNetworkInterfaceRef          interface)      SPI_AVAILABLE(macos(10.15.4), ios(13.4), tvos(13.4), watchos(6.2), bridgeos(4.0));
+
 #define kIncludeNoVirtualInterfaces    0x0
 #define kIncludeVLANInterfaces         0x1
 #define kIncludeBondInterfaces         0x2
 #define kIncludeNoVirtualInterfaces    0x0
 #define kIncludeVLANInterfaces         0x1
 #define kIncludeBondInterfaces         0x2
index 32c6c61f2441e9da698d9b9a79726a6a1cc18ff0..91795507d5e36841ddae5a3390f1e3da6d048504 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004-2019 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -272,18 +272,6 @@ static const struct {
 };
 
 
 };
 
 
-#define kSCNetworkInterfaceActive                      "Active"
-#define kSCNetworkInterfaceInfo                                "SCNetworkInterfaceInfo"
-#define kSCNetworkInterfaceType                                "SCNetworkInterfaceType"
-#define kSCNetworkInterfaceBSDName                     kIOBSDNameKey
-#define kSCNetworkInterfaceIOBuiltin                   kIOBuiltin
-#define kSCNetworkInterfaceIOInterfaceNamePrefix       kIOInterfaceNamePrefix
-#define kSCNetworkInterfaceIOInterfaceType             kIOInterfaceType
-#define kSCNetworkInterfaceIOInterfaceUnit             kIOInterfaceUnit
-#define kSCNetworkInterfaceIOMACAddress                        kIOMACAddress
-#define kSCNetworkInterfaceIOPathMatch                 kIOPathMatchKey
-
-
 #define        NETWORKINTERFACE_LOCALIZATIONS  CFSTR("NetworkInterface")
 static CFBundleRef bundle                      = NULL;
 
 #define        NETWORKINTERFACE_LOCALIZATIONS  CFSTR("NetworkInterface")
 static CFBundleRef bundle                      = NULL;
 
@@ -1604,7 +1592,7 @@ isBluetoothBuiltin(Boolean *haveController)
 
                        if (isA_CFNumber(idVendor) &&
                            CFNumberGetValue(idVendor, kCFNumberIntType, &idVendorVal) &&
 
                        if (isA_CFNumber(idVendor) &&
                            CFNumberGetValue(idVendor, kCFNumberIntType, &idVendorVal) &&
-                           (idVendorVal == kIOUSBVendorIDAppleComputer)) {
+                           (idVendorVal == kIOUSBAppleVendorID)) {
                                builtin = TRUE;
                        }
 
                                builtin = TRUE;
                        }
 
@@ -2016,7 +2004,8 @@ processNetworkInterface(SCNetworkInterfacePrivateRef      interfacePrivate,
 #if    !TARGET_OS_SIMULATOR
                                                        if (CFEqual(provider, CFSTR(kIOUSBDeviceClassName)) ||
                                                            CFEqual(provider, CFSTR(kIOUSBInterfaceClassName)) ||
 #if    !TARGET_OS_SIMULATOR
                                                        if (CFEqual(provider, CFSTR(kIOUSBDeviceClassName)) ||
                                                            CFEqual(provider, CFSTR(kIOUSBInterfaceClassName)) ||
-                                                           CFEqual(provider, CFSTR(kIOUSBHostInterfaceClassName))) {
+                                                           CFEqual(provider, CFSTR(kIOUSBHostInterfaceClassName)) ||
+                                                           (_SC_isAppleInternal() && IOObjectConformsTo(node, "IOUserEthernetController"))) {
                                                                // get USB info (if available)
                                                                processUSBInterface(interfacePrivate,
                                                                                    interface,
                                                                // get USB info (if available)
                                                                processUSBInterface(interfacePrivate,
                                                                                    interface,
@@ -3038,7 +3027,7 @@ extendedConfigurationTypes(SCNetworkInterfaceRef interface)
                                                                           SCNetworkSetGetSetID(set),           // set
                                                                           interfacePrivate->entity_device,     // service
                                                                           NULL);                               // entity
                                                                           SCNetworkSetGetSetID(set),           // set
                                                                           interfacePrivate->entity_device,     // service
                                                                           NULL);                               // entity
-               configs = __getPrefsConfiguration(interfacePrivate->prefs, path);
+               configs = __SCNetworkConfigurationGetValue(interfacePrivate->prefs, path);
                CFRelease(path);
                if (isA_CFDictionary(configs)) {
                        CFDictionaryApplyFunction(configs,
                CFRelease(path);
                if (isA_CFDictionary(configs)) {
                        CFDictionaryApplyFunction(configs,
@@ -3465,7 +3454,7 @@ _SCNetworkInterfaceCopyPrefixFromBSDName(CFStringRef bsdName)
        UniChar lastChar;
        CFIndex length = 0;
 
        UniChar lastChar;
        CFIndex length = 0;
 
-       if (isA_CFString(bsdName) == NULL) {
+       if (!isA_CFString(bsdName)) {
                SC_log(LOG_DEBUG, "no BSD name");
                goto done;
        }
                SC_log(LOG_DEBUG, "no BSD name");
                goto done;
        }
@@ -3500,7 +3489,7 @@ __SCNetworkInterfaceUpdateBSDName(SCNetworkInterfaceRef interface, CFStringRef c
        Boolean success = FALSE;
        SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
 
        Boolean success = FALSE;
        SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
 
-       if (isA_SCNetworkInterface(interface) == NULL) {
+       if (!isA_SCNetworkInterface(interface)) {
                SC_log(LOG_INFO, "No interface");
                goto done;
        }
                SC_log(LOG_INFO, "No interface");
                goto done;
        }
@@ -3530,7 +3519,7 @@ __SCNetworkInterfaceUpdateIOPath(SCNetworkInterfaceRef interface)
 
        // Using the BSD Name update the path
        oldPath = interfacePrivate->path;
 
        // Using the BSD Name update the path
        oldPath = interfacePrivate->path;
-       if (isA_CFString(oldPath) == NULL) {
+       if (!isA_CFString(oldPath)) {
                goto done;
        }
        newPath = CFStringCreateWithFormat(NULL, NULL, CFSTR("Migrated_From: %@"), oldPath);
                goto done;
        }
        newPath = CFStringCreateWithFormat(NULL, NULL, CFSTR("Migrated_From: %@"), oldPath);
@@ -3554,7 +3543,7 @@ __SCNetworkInterfaceSetIOInterfacePrefix (SCNetworkInterfaceRef interface,
 {
        SCNetworkInterfacePrivateRef interfacePrivate;
 
 {
        SCNetworkInterfacePrivateRef interfacePrivate;
 
-       if (isA_CFString(prefix) == NULL) {
+       if (!isA_CFString(prefix)) {
                return;
        }
 
                return;
        }
 
@@ -3580,7 +3569,7 @@ __SCNetworkInterfaceSetIOInterfaceUnit(SCNetworkInterfaceRef interface,
        CFStringRef newBSDName = NULL;
        CFStringRef oldBSDName = NULL;
 
        CFStringRef newBSDName = NULL;
        CFStringRef oldBSDName = NULL;
 
-       if (isA_CFNumber(unit) == NULL) {
+       if (!isA_CFNumber(unit)) {
                return;
        }
        interfacePrivate = (SCNetworkInterfacePrivateRef) interface;
                return;
        }
        interfacePrivate = (SCNetworkInterfacePrivateRef) interface;
@@ -3588,7 +3577,7 @@ __SCNetworkInterfaceSetIOInterfaceUnit(SCNetworkInterfaceRef interface,
        oldBSDName = SCNetworkInterfaceGetBSDName(interface);
 
        if (interfacePrivate->prefix == NULL) {
        oldBSDName = SCNetworkInterfaceGetBSDName(interface);
 
        if (interfacePrivate->prefix == NULL) {
-               if (isA_CFString(interfacePrivate->entity_device) != NULL) {
+               if (isA_CFString(interfacePrivate->entity_device)) {
                        CFStringRef interfaceNamePrefix = _SCNetworkInterfaceCopyPrefixFromBSDName(interfacePrivate->entity_device);
                        if (interfaceNamePrefix == NULL) {
                                SC_log(LOG_INFO, "interfaceNamePrefix is NULL");
                        CFStringRef interfaceNamePrefix = _SCNetworkInterfaceCopyPrefixFromBSDName(interfacePrivate->entity_device);
                        if (interfaceNamePrefix == NULL) {
                                SC_log(LOG_INFO, "interfaceNamePrefix is NULL");
@@ -3633,22 +3622,17 @@ __private_extern__
 CFDictionaryRef
 __SCNetworkInterfaceCopyStorageEntity(SCNetworkInterfaceRef interface)
 {
 CFDictionaryRef
 __SCNetworkInterfaceCopyStorageEntity(SCNetworkInterfaceRef interface)
 {
-       CFMutableDictionaryRef interface_entity = NULL;
-       SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
-       CFBooleanRef active = NULL;
-       CFStringRef bsdName = NULL;
-       CFBooleanRef builtin = NULL;
-       CFStringRef interfaceNamePrefix = NULL;
-       CFNumberRef interfaceType = NULL;
-       CFNumberRef interfaceUnit = NULL;
-       CFDataRef macAddress = NULL;
-       CFStringRef pathMatch = NULL;
-       CFDictionaryRef info = NULL;
-       CFStringRef type = NULL;
-
-       if (interfacePrivate->active) {
-               active = kCFBooleanTrue;
-       }
+       CFMutableDictionaryRef          interface_entity        = NULL;
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+       CFStringRef                     bsdName;
+       CFBooleanRef                    builtin;
+       CFStringRef                     interfaceNamePrefix;
+       CFNumberRef                     interfaceType;
+       CFNumberRef                     interfaceUnit;
+       CFDataRef                       macAddress;
+       CFStringRef                     pathMatch;
+       CFDictionaryRef                 info                    = NULL;
+       CFStringRef                     type;
 
        bsdName = SCNetworkInterfaceGetBSDName(interface);
        if (!isA_CFString(bsdName)) {
 
        bsdName = SCNetworkInterfaceGetBSDName(interface);
        if (!isA_CFString(bsdName)) {
@@ -3656,6 +3640,7 @@ __SCNetworkInterfaceCopyStorageEntity(SCNetworkInterfaceRef interface)
        }
 
        builtin = interfacePrivate->builtin ? kCFBooleanTrue : kCFBooleanFalse;
        }
 
        builtin = interfacePrivate->builtin ? kCFBooleanTrue : kCFBooleanFalse;
+
        interfaceNamePrefix = _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface);
        if (!isA_CFString(interfaceNamePrefix)) {
                goto done;
        interfaceNamePrefix = _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface);
        if (!isA_CFString(interfaceNamePrefix)) {
                goto done;
@@ -3694,12 +3679,13 @@ __SCNetworkInterfaceCopyStorageEntity(SCNetworkInterfaceRef interface)
        interface_entity = CFDictionaryCreateMutable(NULL, 0,
                                                     &kCFTypeDictionaryKeyCallBacks,
                                                     &kCFTypeDictionaryValueCallBacks);
        interface_entity = CFDictionaryCreateMutable(NULL, 0,
                                                     &kCFTypeDictionaryKeyCallBacks,
                                                     &kCFTypeDictionaryValueCallBacks);
-
-       if (isA_CFBoolean(active) != NULL) {
-               CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceActive), active);
+       if (interfacePrivate->active) {
+               CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceActive), kCFBooleanTrue);
        }
        }
-
        CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceBSDName), bsdName);
        CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceBSDName), bsdName);
+       if (interfacePrivate->hidden) {
+               CFDictionaryAddValue(interface_entity, kSCNetworkInterfaceHiddenConfigurationKey, kCFBooleanTrue);
+       }
        CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOBuiltin), builtin);
        CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix), interfaceNamePrefix);
        CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceType), interfaceType);
        CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOBuiltin), builtin);
        CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix), interfaceNamePrefix);
        CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceType), interfaceType);
@@ -3708,7 +3694,12 @@ __SCNetworkInterfaceCopyStorageEntity(SCNetworkInterfaceRef interface)
        CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOPathMatch), pathMatch);
        CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceInfo), info);
        CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceType), type);
        CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOPathMatch), pathMatch);
        CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceInfo), info);
        CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceType), type);
-done:
+       if (isA_CFArray(interfacePrivate->matchingMACs)) {
+               CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceMatchingMACs), interfacePrivate->matchingMACs);
+       }
+
+    done:
+
        if (info != NULL) {
                CFRelease(info);
        }
        if (info != NULL) {
                CFRelease(info);
        }
@@ -3791,50 +3782,57 @@ __SCNetworkInterfaceMatchesName(CFStringRef name, CFStringRef key)
 
 
 static SCNetworkInterfaceRef
 
 
 static SCNetworkInterfaceRef
-__SCNetworkInterfaceCreateWithStorageEntity(CFAllocatorRef     allocator,
-                                           CFDictionaryRef     interface_entity)
+__SCNetworkInterfaceCreateWithStorageEntity(CFDictionaryRef interface_entity)
 {
 {
-#pragma unused(allocator)
-       SCNetworkInterfacePrivateRef interfacePrivate = NULL;
-       CFBooleanRef    active = NULL;
-       CFStringRef     bsdName = NULL;
-       CFBooleanRef    ioBuiltin = NULL;
-       CFStringRef     ioInterfaceNamePrefix = NULL;
-       CFNumberRef     ioInterfaceType = NULL;
-       int             ioInterfaceTypeNum;
-       CFNumberRef     ioInterfaceUnit = NULL;
-       CFDataRef       ioMACAddress = NULL;
-       CFStringRef     ioPathMatch = NULL;
-       CFDictionaryRef SCNetworkInterfaceInfo = NULL;
-       CFStringRef     userDefinedName = NULL;
-       CFStringRef     usbProductName = NULL;
-       CFNumberRef     idProduct = NULL;
-       CFNumberRef     idVendor = NULL;
-       CFStringRef     type = NULL;
+       CFIndex                         interfaceIndex;
+       SCNetworkInterfacePrivateRef    interfacePrivate        = NULL;
+       CFBooleanRef                    active;
+       CFStringRef                     bsdName;
+       CFBooleanRef                    hidden;
+       CFDictionaryRef                 interfaceInfo;
+       CFBooleanRef                    ioBuiltin;
+       CFStringRef                     ioInterfaceNamePrefix   = NULL;
+       CFNumberRef                     ioInterfaceType;
+       int                             ioInterfaceTypeNum;
+       CFNumberRef                     ioInterfaceUnit;
+       CFDataRef                       ioMACAddress;
+       CFStringRef                     ioPathMatch;
+       CFArrayRef                      matchingMacs;
+       CFStringRef                     userDefinedName;
+#if    !TARGET_OS_SIMULATOR
+       CFStringRef                     usbProductName;
+       CFNumberRef                     idProduct;
+       CFNumberRef                     idVendor;
+#endif // !TARGET_OS_SIMULATOR
+       CFStringRef                     type;
 
        /* initialize runtime */
        pthread_once(&initialized, __SCNetworkInterfaceInitialize);
 
 
        /* initialize runtime */
        pthread_once(&initialized, __SCNetworkInterfaceInitialize);
 
-       if (isA_CFDictionary(interface_entity) == NULL) {
+       if (!isA_CFDictionary(interface_entity)) {
                SC_log(LOG_INFO, "No interface entity");
                goto done;
        }
        active = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceActive));
                SC_log(LOG_INFO, "No interface entity");
                goto done;
        }
        active = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceActive));
-       if (isA_CFBoolean(active) == NULL) {
+       if (!isA_CFBoolean(active)) {
                active = kCFBooleanFalse;
        }
        bsdName = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceBSDName));
                active = kCFBooleanFalse;
        }
        bsdName = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceBSDName));
-       if (isA_CFString(bsdName) == NULL) {
+       if (!isA_CFString(bsdName)) {
                SC_log(LOG_INFO, "No BSD name");
                goto done;
        }
                SC_log(LOG_INFO, "No BSD name");
                goto done;
        }
+       hidden = CFDictionaryGetValue(interface_entity, kSCNetworkInterfaceHiddenConfigurationKey);
+       if (!isA_CFBoolean(hidden)) {
+               hidden = kCFBooleanFalse;
+       }
        ioBuiltin = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOBuiltin));
        ioBuiltin = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOBuiltin));
-       if (isA_CFBoolean(ioBuiltin) == NULL) {
+       if (!isA_CFBoolean(ioBuiltin)) {
                SC_log(LOG_INFO, "No IOBuiltin property");
                goto done;
        }
        ioInterfaceNamePrefix = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix));
                SC_log(LOG_INFO, "No IOBuiltin property");
                goto done;
        }
        ioInterfaceNamePrefix = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix));
-       if (isA_CFString(ioInterfaceNamePrefix) == NULL) {
+       if (!isA_CFString(ioInterfaceNamePrefix)) {
                ioInterfaceNamePrefix = _SCNetworkInterfaceCopyPrefixFromBSDName(bsdName);
                if (ioInterfaceNamePrefix == NULL) {
                        SC_log(LOG_INFO, "No BSD interface name prefix");
                ioInterfaceNamePrefix = _SCNetworkInterfaceCopyPrefixFromBSDName(bsdName);
                if (ioInterfaceNamePrefix == NULL) {
                        SC_log(LOG_INFO, "No BSD interface name prefix");
@@ -3844,7 +3842,7 @@ __SCNetworkInterfaceCreateWithStorageEntity(CFAllocatorRef        allocator,
                CFRetain(ioInterfaceNamePrefix);
        }
        ioInterfaceType = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceType));
                CFRetain(ioInterfaceNamePrefix);
        }
        ioInterfaceType = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceType));
-       if (isA_CFNumber(ioInterfaceType) == NULL) {
+       if (!isA_CFNumber(ioInterfaceType)) {
                SC_log(LOG_INFO, "No IOInterfaceType");
                goto done;
        }
                SC_log(LOG_INFO, "No IOInterfaceType");
                goto done;
        }
@@ -3852,37 +3850,37 @@ __SCNetworkInterfaceCreateWithStorageEntity(CFAllocatorRef      allocator,
                SC_log(LOG_NOTICE, "Count not extract value from ioInterfaceType");
        }
        ioInterfaceUnit = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceUnit));
                SC_log(LOG_NOTICE, "Count not extract value from ioInterfaceType");
        }
        ioInterfaceUnit = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceUnit));
-       if (isA_CFNumber(ioInterfaceUnit) == NULL) {
+       if (!isA_CFNumber(ioInterfaceUnit)) {
                SC_log(LOG_INFO, "No IOInterfaceUnit");
                SC_log(LOG_INFO, "No IOInterfaceUnit");
-
                goto done;
        }
        ioMACAddress = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOMACAddress));
                goto done;
        }
        ioMACAddress = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOMACAddress));
-       if (isA_CFData(ioMACAddress) == NULL) {
+       if (!isA_CFData(ioMACAddress)) {
                SC_log(LOG_INFO, "No IOMACAddress");
                goto done;
        }
        ioPathMatch = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOPathMatch));
                SC_log(LOG_INFO, "No IOMACAddress");
                goto done;
        }
        ioPathMatch = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOPathMatch));
-       if (isA_CFString(ioPathMatch) == NULL) {
+       if (!isA_CFString(ioPathMatch)) {
                SC_log(LOG_INFO, "No IOPathMatch");
                goto done;
        } else {
                // Check if Path contains the BSD Name in the end
        }
                SC_log(LOG_INFO, "No IOPathMatch");
                goto done;
        } else {
                // Check if Path contains the BSD Name in the end
        }
-       SCNetworkInterfaceInfo = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceInfo));
-       if (isA_CFDictionary(SCNetworkInterfaceInfo) == NULL) {
+       interfaceInfo = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceInfo));
+       if (!isA_CFDictionary(interfaceInfo)) {
                SC_log(LOG_INFO, "No SCNetworkInterfaceInfo");
                goto done;
        }
                SC_log(LOG_INFO, "No SCNetworkInterfaceInfo");
                goto done;
        }
-       userDefinedName = CFDictionaryGetValue(SCNetworkInterfaceInfo, kSCPropUserDefinedName);
+       userDefinedName = CFDictionaryGetValue(interfaceInfo, kSCPropUserDefinedName);
 #if    !TARGET_OS_SIMULATOR
 #if    !TARGET_OS_SIMULATOR
-       usbProductName = CFDictionaryGetValue(SCNetworkInterfaceInfo, CFSTR(kUSBProductString));
-       idProduct = CFDictionaryGetValue(SCNetworkInterfaceInfo, CFSTR(kUSBProductID));
-       idVendor = CFDictionaryGetValue(SCNetworkInterfaceInfo, CFSTR(kUSBVendorID));
+       usbProductName = CFDictionaryGetValue(interfaceInfo, CFSTR(kUSBProductString));
+       idProduct = CFDictionaryGetValue(interfaceInfo, CFSTR(kUSBProductID));
+       idVendor = CFDictionaryGetValue(interfaceInfo, CFSTR(kUSBVendorID));
 #endif // !TARGET_OS_SIMULATOR
 #endif // !TARGET_OS_SIMULATOR
+       matchingMacs = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceMatchingMACs));
 
        type = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceType));
 
        type = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceType));
-       if (isA_CFString(type) == NULL) {
+       if (!isA_CFString(type)) {
                SC_log(LOG_INFO, "No SCNetworkInterfaceType");
                goto done;
        }
                SC_log(LOG_INFO, "No SCNetworkInterfaceType");
                goto done;
        }
@@ -3891,6 +3889,7 @@ __SCNetworkInterfaceCreateWithStorageEntity(CFAllocatorRef        allocator,
        interfacePrivate->active = CFBooleanGetValue(active);
        interfacePrivate->entity_device = CFRetain(bsdName);
        interfacePrivate->builtin = CFBooleanGetValue(ioBuiltin);
        interfacePrivate->active = CFBooleanGetValue(active);
        interfacePrivate->entity_device = CFRetain(bsdName);
        interfacePrivate->builtin = CFBooleanGetValue(ioBuiltin);
+       interfacePrivate->hidden = CFBooleanGetValue(hidden);
        interfacePrivate->prefix = CFRetain(ioInterfaceNamePrefix);
        interfacePrivate->type = CFRetain(ioInterfaceType);
        interfacePrivate->unit = CFRetain(ioInterfaceUnit);
        interfacePrivate->prefix = CFRetain(ioInterfaceNamePrefix);
        interfacePrivate->type = CFRetain(ioInterfaceType);
        interfacePrivate->unit = CFRetain(ioInterfaceUnit);
@@ -3898,13 +3897,14 @@ __SCNetworkInterfaceCreateWithStorageEntity(CFAllocatorRef      allocator,
        interfacePrivate->path = CFRetain(ioPathMatch);
        interfacePrivate->name = ((userDefinedName != NULL) ? CFRetain(userDefinedName) : NULL);
        interfacePrivate->localized_name = ((userDefinedName != NULL) ? CFRetain(userDefinedName) : NULL);
        interfacePrivate->path = CFRetain(ioPathMatch);
        interfacePrivate->name = ((userDefinedName != NULL) ? CFRetain(userDefinedName) : NULL);
        interfacePrivate->localized_name = ((userDefinedName != NULL) ? CFRetain(userDefinedName) : NULL);
+#if    !TARGET_OS_SIMULATOR
        interfacePrivate->usb.name = ((usbProductName != NULL) ? CFRetain(usbProductName) : NULL);
        interfacePrivate->usb.pid = ((idProduct != NULL) ? CFRetain(idProduct) : NULL);
        interfacePrivate->usb.vid = ((idVendor != NULL) ? CFRetain(idVendor) : NULL);
        interfacePrivate->usb.name = ((usbProductName != NULL) ? CFRetain(usbProductName) : NULL);
        interfacePrivate->usb.pid = ((idProduct != NULL) ? CFRetain(idProduct) : NULL);
        interfacePrivate->usb.vid = ((idVendor != NULL) ? CFRetain(idVendor) : NULL);
+#endif // !TARGET_OS_SIMULATOR
+       interfacePrivate->matchingMACs = ((matchingMacs != NULL) ? CFRetain(matchingMacs) : NULL);
 
        // Handling interface types to be seen in NetworkInterfaces.plist
 
        // Handling interface types to be seen in NetworkInterfaces.plist
-       CFIndex interfaceIndex;
-
        interfaceIndex = findConfiguration(type);
        if (interfaceIndex != kCFNotFound) {
                interfacePrivate->interface_type = *configurations[interfaceIndex].interface_type;
        interfaceIndex = findConfiguration(type);
        if (interfaceIndex != kCFNotFound) {
                interfacePrivate->interface_type = *configurations[interfaceIndex].interface_type;
@@ -3918,7 +3918,9 @@ __SCNetworkInterfaceCreateWithStorageEntity(CFAllocatorRef        allocator,
        } else if (ioInterfaceTypeNum == kInterfaceTypeFirewireValue) {
                interfacePrivate->entity_type = kSCValNetInterfaceTypeFireWire;
        }
        } else if (ioInterfaceTypeNum == kInterfaceTypeFirewireValue) {
                interfacePrivate->entity_type = kSCValNetInterfaceTypeFireWire;
        }
-done:
+
+    done:
+
        if (ioInterfaceNamePrefix != NULL) {
                CFRelease(ioInterfaceNamePrefix);
        }
        if (ioInterfaceNamePrefix != NULL) {
                CFRelease(ioInterfaceNamePrefix);
        }
@@ -4013,8 +4015,7 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef        allocator,
 
        if (service != NULL) {
                servicePref = ((SCNetworkServicePrivateRef)service)->prefs;
 
        if (service != NULL) {
                servicePref = ((SCNetworkServicePrivateRef)service)->prefs;
-               useSystemInterfaces = ((__SCPreferencesUsingDefaultPrefs(servicePref)) &&
-                                      (!__SCPreferencesGetLimitSCNetworkConfiguration(servicePref)));
+               useSystemInterfaces = !_SCNetworkConfigurationBypassSystemInterfaces(servicePref);
        }
 
        ifType = CFDictionaryGetValue(interface_entity, kSCPropNetInterfaceType);
        }
 
        ifType = CFDictionaryGetValue(interface_entity, kSCPropNetInterfaceType);
@@ -5145,7 +5146,7 @@ __SCNetworkInterfaceGetDefaultConfiguration(SCNetworkSetRef set, SCNetworkInterf
                                                                                   interfacePrivate->entity_device,     // interface
                                                                                   defaultType);                        // entity
                        if (path != NULL) {
                                                                                   interfacePrivate->entity_device,     // interface
                                                                                   defaultType);                        // entity
                        if (path != NULL) {
-                               config = __getPrefsConfiguration(interfacePrivate->prefs, path);
+                               config = __SCNetworkConfigurationGetValue(interfacePrivate->prefs, path);
                                CFRelease(path);
 
                                if (config == NULL) {
                                CFRelease(path);
 
                                if (config == NULL) {
@@ -5185,7 +5186,7 @@ __SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef        interface,
                CFStringRef                     path;
 
                path = CFArrayGetValueAtIndex(paths, 0);
                CFStringRef                     path;
 
                path = CFArrayGetValueAtIndex(paths, 0);
-               config = __getPrefsConfiguration(interfacePrivate->prefs, path);
+               config = __SCNetworkConfigurationGetValue(interfacePrivate->prefs, path);
 
                CFRelease(paths);
        } else {
 
                CFRelease(paths);
        } else {
@@ -5232,7 +5233,7 @@ SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface)
                        path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL,                             // allocator
                                                                              interfacePrivate->serviceID,      // service
                                                                              kSCEntNetAirPort);                // entity
                        path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL,                             // allocator
                                                                              interfacePrivate->serviceID,      // service
                                                                              kSCEntNetAirPort);                // entity
-                       config = __getPrefsConfiguration(interfacePrivate->prefs, path);
+                       config = __SCNetworkConfigurationGetValue(interfacePrivate->prefs, path);
                        CFRelease(path);
                }
        }
                        CFRelease(path);
                }
        }
@@ -5699,7 +5700,7 @@ __SCNetworkInterfaceSetDefaultConfiguration(SCNetworkSetRef               set,
                                                                           interfacePrivate->entity_device,     // interface
                                                                           defaultType);                        // entity
                if (path != NULL) {
                                                                           interfacePrivate->entity_device,     // interface
                                                                           defaultType);                        // entity
                if (path != NULL) {
-                       ok = __setPrefsConfiguration(interfacePrivate->prefs, path, config, FALSE);
+                       ok = __SCNetworkConfigurationSetValue(interfacePrivate->prefs, path, config, FALSE);
                        CFRelease(path);
                        if (ok) {
                                // if configuration has been saved
                        CFRelease(path);
                        if (ok) {
                                // if configuration has been saved
@@ -5771,7 +5772,7 @@ __SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef        interface,
                        CFStringRef     path;
 
                        path = CFArrayGetValueAtIndex(paths, i);
                        CFStringRef     path;
 
                        path = CFArrayGetValueAtIndex(paths, i);
-                       ok = __setPrefsConfiguration(interfacePrivate->prefs, path, config, FALSE);
+                       ok = __SCNetworkConfigurationSetValue(interfacePrivate->prefs, path, config, FALSE);
                        if (!ok) {
                                break;
                        }
                        if (!ok) {
                                break;
                        }
@@ -7571,20 +7572,8 @@ _SCNetworkInterfaceIsApplePreconfigured(SCNetworkInterfaceRef interface)
                return FALSE;
        }
 
                return FALSE;
        }
 
-       if ((interfacePrivate->overrides == NULL) ||
-           (!CFDictionaryContainsKey(interfacePrivate->overrides, kSCNetworkProtocolTypeIPv4) &&
-            !CFDictionaryContainsKey(interfacePrivate->overrides, kSCNetworkProtocolTypeIPv6))) {
-               // if no [IPv4/IPv6] configuration overrides
-               return FALSE;
-       }
-
        if (_SCNetworkInterfaceIsBuiltin(interface)) {
        if (_SCNetworkInterfaceIsBuiltin(interface)) {
-               // if built-in (and overrides are present)
-               return TRUE;
-       }
-
-       if (_SCNetworkInterfaceIsCarPlay(interface)) {
-               // if CarPlay (and overrides are present)
+               // if built-in
                return TRUE;
        }
 
                return TRUE;
        }
 
@@ -7592,8 +7581,18 @@ _SCNetworkInterfaceIsApplePreconfigured(SCNetworkInterfaceRef interface)
                int             vid;
 
                if (CFNumberGetValue(interfacePrivate->usb.vid, kCFNumberIntType, &vid) &&
                int             vid;
 
                if (CFNumberGetValue(interfacePrivate->usb.vid, kCFNumberIntType, &vid) &&
-                   (vid == kIOUSBVendorIDAppleComputer)) {
-                       // if Apple interface (and overrides are present)
+                   (vid == kIOUSBAppleVendorID)) {
+                       // if Apple interface
+                       return TRUE;
+               }
+       }
+
+       if (_SCNetworkInterfaceIsCarPlay(interface)) {
+               // if CarPlay
+               if ((interfacePrivate->overrides != NULL) &&
+                   (CFDictionaryContainsKey(interfacePrivate->overrides, kSCNetworkProtocolTypeIPv4) ||
+                    CFDictionaryContainsKey(interfacePrivate->overrides, kSCNetworkProtocolTypeIPv6))) {
+                       // and overrides are present
                        return TRUE;
                }
        }
                        return TRUE;
                }
        }
@@ -7994,7 +7993,9 @@ __SCNetworkInterfaceIsMember(SCPreferencesRef prefs, SCNetworkInterfaceRef inter
 
 __private_extern__
 void
 
 __private_extern__
 void
-__SCNetworkInterfaceSetDeepConfiguration(SCNetworkSetRef set, SCNetworkInterfaceRef interface, CFArrayRef configs)
+__SCNetworkInterfaceSetDeepConfiguration(SCNetworkSetRef       set,
+                                        SCNetworkInterfaceRef  interface,
+                                        CFArrayRef             configs)
 {
        CFIndex i;
 
 {
        CFIndex i;
 
@@ -8171,7 +8172,7 @@ SCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface)
                CFDictionaryRef config;
                CFStringRef     path = CFArrayGetValueAtIndex(path_list, 0);
 
                CFDictionaryRef config;
                CFStringRef     path = CFArrayGetValueAtIndex(path_list, 0);
 
-               config = __getPrefsConfiguration(interfacePrivate->prefs, path);
+               config = __SCNetworkConfigurationGetValue(interfacePrivate->prefs, path);
                CFRelease(path_list);
                if (config != NULL) {
                        int     disable = 0;
                CFRelease(path_list);
                if (config != NULL) {
                        int     disable = 0;
@@ -8232,7 +8233,7 @@ __SCNetworkInterfaceSetDisableUntilNeededValue(SCNetworkInterfaceRef interface,
                CFMutableDictionaryRef  new_config;
                CFStringRef             path = CFArrayGetValueAtIndex(path_list, i);
 
                CFMutableDictionaryRef  new_config;
                CFStringRef             path = CFArrayGetValueAtIndex(path_list, i);
 
-               config = __getPrefsConfiguration(interfacePrivate->prefs, path);
+               config = __SCNetworkConfigurationGetValue(interfacePrivate->prefs, path);
                if (config != NULL) {
                        new_config
                                = CFDictionaryCreateMutableCopy(NULL, 0, config);
                if (config != NULL) {
                        new_config
                                = CFDictionaryCreateMutableCopy(NULL, 0, config);
@@ -8247,10 +8248,10 @@ __SCNetworkInterfaceSetDisableUntilNeededValue(SCNetworkInterfaceRef interface,
                } else {
                        CFDictionaryRemoveValue(new_config, kSCPropDisableUntilNeeded);
                }
                } else {
                        CFDictionaryRemoveValue(new_config, kSCPropDisableUntilNeeded);
                }
-               ok = __setPrefsConfiguration(interfacePrivate->prefs,
-                                            path,
-                                            (CFDictionaryGetCount(new_config) > 0) ? new_config : NULL,
-                                            FALSE);
+               ok = __SCNetworkConfigurationSetValue(interfacePrivate->prefs,
+                                                     path,
+                                                     (CFDictionaryGetCount(new_config) > 0) ? new_config : NULL,
+                                                     FALSE);
                CFRelease(new_config);
                if (!ok) {
                        break;
                CFRelease(new_config);
                if (!ok) {
                        break;
@@ -8325,120 +8326,105 @@ __private_extern__
 CFArrayRef  // SCNetworkInterfaceRef
 __SCNetworkInterfaceCopyStoredWithPreferences(SCPreferencesRef ni_prefs)
 {
 CFArrayRef  // SCNetworkInterfaceRef
 __SCNetworkInterfaceCopyStoredWithPreferences(SCPreferencesRef ni_prefs)
 {
-       CFStringRef             defaultNetworkInterfacePath     = NULL;
        CFArrayRef              if_list;
        CFArrayRef              if_list;
-       CFMutableArrayRef       interfaceList                   = NULL;
-       SCNetworkInterfaceRef   interfaceNamer                  = NULL;
+       CFMutableArrayRef       interfaceList   = NULL;
 
        /* initialize runtime */
        pthread_once(&initialized, __SCNetworkInterfaceInitialize);
 
 
        /* initialize runtime */
        pthread_once(&initialized, __SCNetworkInterfaceInitialize);
 
-       if (ni_prefs == NULL) {
-               defaultNetworkInterfacePath = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@"), PREFS_DEFAULT_DIR, NETWORK_INTERFACES_PREFS);
-               assert(defaultNetworkInterfacePath != NULL);
-               ni_prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath);
+       if (ni_prefs != NULL) {
+               CFRetain(ni_prefs);
+       } else {
+               ni_prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterface"), INTERFACES_DEFAULT_CONFIG);
+               assert(ni_prefs);
        }
 
        if_list = SCPreferencesGetValue(ni_prefs, INTERFACES);
        if (isA_CFArray(if_list)) {
        }
 
        if_list = SCPreferencesGetValue(ni_prefs, INTERFACES);
        if (isA_CFArray(if_list)) {
-               CFIndex i;
                CFIndex n       = CFArrayGetCount(if_list);
 
                interfaceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
                CFIndex n       = CFArrayGetCount(if_list);
 
                interfaceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-               for (i = 0; i < n; i++) {
+               for (CFIndex i = 0; i < n; i++) {
                        CFDictionaryRef dict;
 
                        dict = CFArrayGetValueAtIndex(if_list, i);
                        if (isA_CFDictionary(dict) != NULL) {
                        CFDictionaryRef dict;
 
                        dict = CFArrayGetValueAtIndex(if_list, i);
                        if (isA_CFDictionary(dict) != NULL) {
-                               interfaceNamer = __SCNetworkInterfaceCreateWithStorageEntity(NULL, dict);
+                               SCNetworkInterfaceRef   interface;
 
 
-                               if (interfaceNamer != NULL) {
-                                       CFArrayAppendValue(interfaceList, interfaceNamer);
-                                       CFRelease(interfaceNamer);
+                               interface = __SCNetworkInterfaceCreateWithStorageEntity(dict);
+                               if (interface != NULL) {
+                                       CFArrayAppendValue(interfaceList, interface);
+                                       CFRelease(interface);
                                }
                        }
                }
        }
 
                                }
                        }
                }
        }
 
-       if (defaultNetworkInterfacePath != NULL) {
-               CFRelease(defaultNetworkInterfacePath);
-               // prefs were created in the function, and hence need to be released
-               CFRelease(ni_prefs);
-       }
+       CFRelease(ni_prefs);
        return interfaceList;
 }
 
 
 __private_extern__
 Boolean
        return interfaceList;
 }
 
 
 __private_extern__
 Boolean
-__SCNetworkInterfaceSaveStoredWithPreferences(SCPreferencesRef prefs, CFArrayRef interfacesToSave)
+__SCNetworkInterfaceSaveStoredWithPreferences(SCPreferencesRef ni_prefs, CFArrayRef interfacesToSave)
 {
 {
-       CFStringRef defaultNetworkInterfacePath = NULL;
-       Boolean success = FALSE;
+       Boolean ok;
 
 
-       if (prefs == NULL) {    // TODO: Get the default preferences on the system
-               defaultNetworkInterfacePath = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), PREFS_DEFAULT_DIR, NETWORK_INTERFACES_PREFS);
-               assert(defaultNetworkInterfacePath != NULL);
-               prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath);
+       if (!isA_CFArray(interfacesToSave)) {
+               return FALSE;
        }
 
        }
 
-       if (isA_CFArray(interfacesToSave) == NULL) {
-               SC_log(LOG_INFO, "No interfaces to save");
-               goto done;
-       }
-       SCPreferencesSetValue(prefs, INTERFACES, interfacesToSave);
-       success = TRUE;
-done:
-       if (defaultNetworkInterfacePath != NULL) {
-               CFRelease(defaultNetworkInterfacePath);
-               // prefs were created in the function, and hence need to be released
-               CFRelease(prefs);
+       if (ni_prefs != NULL) {
+               CFRetain(ni_prefs);
+       } else {
+               ni_prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterface"), INTERFACES_DEFAULT_CONFIG);
+               assert(ni_prefs);
        }
 
        }
 
-       return success;
+       ok = SCPreferencesSetValue(ni_prefs, INTERFACES, interfacesToSave);
+       CFRelease(ni_prefs);
+       return ok;
 }
 
 __private_extern__
 SCNetworkInterfaceRef
 __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(CFAllocatorRef allocator, SCPreferencesRef ni_prefs, CFStringRef bsdName)
 {
 }
 
 __private_extern__
 SCNetworkInterfaceRef
 __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(CFAllocatorRef allocator, SCPreferencesRef ni_prefs, CFStringRef bsdName)
 {
-       CFArrayRef if_list;
-       SCNetworkInterfaceRef interface = NULL;
-       CFStringRef defaultNetworkInterfacePath;
+#pragma unused(allocator)
+       CFArrayRef              if_list;
+       SCNetworkInterfaceRef   interface       = NULL;
 
        /* initialize runtime */
        pthread_once(&initialized, __SCNetworkInterfaceInitialize);
 
 
        /* initialize runtime */
        pthread_once(&initialized, __SCNetworkInterfaceInitialize);
 
-       if (ni_prefs == NULL) {
-               defaultNetworkInterfacePath = CFStringCreateWithFormat(allocator, NULL, CFSTR("%@/%@"), PREFS_DEFAULT_DIR, NETWORK_INTERFACES_PREFS);
-               ni_prefs = SCPreferencesCreate(allocator, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath);
-               CFRelease(defaultNetworkInterfacePath);
-       }
-       else {
+       if (ni_prefs != NULL) {
                CFRetain(ni_prefs);
                CFRetain(ni_prefs);
+       } else {
+               ni_prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterface"), INTERFACES_DEFAULT_CONFIG);
+               assert(ni_prefs);
        }
 
        if_list = SCPreferencesGetValue(ni_prefs, INTERFACES);
        }
 
        if_list = SCPreferencesGetValue(ni_prefs, INTERFACES);
+       if (isA_CFArray(if_list)) {
+               CFIndex n =     CFArrayGetCount(if_list);
 
 
-       if (isA_CFArray(if_list) != NULL) {
-               CFIndex idx;
-               CFIndex count = CFArrayGetCount(if_list);
-
-               for (idx = 0; idx < count; idx++) {
-                       CFDictionaryRef dict;
-                       CFStringRef tmp_bsdName;
+               for (CFIndex i = 0; i < n; i++) {
+                       CFDictionaryRef dict;
+                       CFStringRef     tmp_bsdName;
 
 
-                       dict = CFArrayGetValueAtIndex(if_list, idx);
-                       if (isA_CFDictionary(dict) == NULL) {
+                       dict = CFArrayGetValueAtIndex(if_list, i);
+                       if (!isA_CFDictionary(dict)) {
                                continue;
                        }
 
                        tmp_bsdName = CFDictionaryGetValue(dict, CFSTR(kSCNetworkInterfaceBSDName));
                                continue;
                        }
 
                        tmp_bsdName = CFDictionaryGetValue(dict, CFSTR(kSCNetworkInterfaceBSDName));
-                       if (tmp_bsdName == NULL) {
+                       if (!isA_CFString(tmp_bsdName)) {
                                continue;
                        }
                                continue;
                        }
+
                        if (CFEqual(bsdName, tmp_bsdName)) {
                        if (CFEqual(bsdName, tmp_bsdName)) {
-                               interface = __SCNetworkInterfaceCreateWithStorageEntity(allocator, dict);
+                               interface = __SCNetworkInterfaceCreateWithStorageEntity(dict);
                                break;
                        }
                }
                                break;
                        }
                }
@@ -8468,7 +8454,7 @@ __SCNetworkInterfaceCreateMappingUsingBSDName(CFArrayRef interfaces)
                interface = (SCNetworkInterfaceRef) CFArrayGetValueAtIndex(interfaces, idx);
 
                bsdName = SCNetworkInterfaceGetBSDName(interface);
                interface = (SCNetworkInterfaceRef) CFArrayGetValueAtIndex(interfaces, idx);
 
                bsdName = SCNetworkInterfaceGetBSDName(interface);
-               if (isA_CFString(bsdName) == NULL) {
+               if (!isA_CFString(bsdName)) {
                        SC_log(LOG_INFO, "No BSD name");
                        continue;
                }
                        SC_log(LOG_INFO, "No BSD name");
                        continue;
                }
index 27c7d8b37081eb4228fdb57c6ef5f8c17bc87091..f38e15cca4a793c8b3e372e85c755f2dfb51a2b9 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2014-2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2014-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 
 #define BACK_TO_MY_MAC                 CFSTR("BackToMyMac")
 #define BACK_TO_MY_MAC_DSIDS           CFSTR("BackToMyMacDSIDs")
 
 #define BACK_TO_MY_MAC                 CFSTR("BackToMyMac")
 #define BACK_TO_MY_MAC_DSIDS           CFSTR("BackToMyMacDSIDs")
-#define        PREFS_DEFAULT_DIR_PLIST         "/Library/Preferences/SystemConfiguration"
-#define PREFS_DEFAULT_DIR_RELATIVE     CFSTR("Library/Preferences/SystemConfiguration/")
-#define        PREFS_DEFAULT_CONFIG_PLIST      "preferences.plist"
-#define        NETWORK_INTERFACES_PREFS_PLIST  "NetworkInterfaces.plist"
 #define NUM_MIGRATION_PATHS            2
 #define PLUGIN_ID                      CFSTR("System Migration")
 #define PREFERENCES_PLIST_INDEX                0
 #define NUM_MIGRATION_PATHS            2
 #define PLUGIN_ID                      CFSTR("System Migration")
 #define PREFERENCES_PLIST_INDEX                0
@@ -82,8 +78,8 @@ _SCNetworkConfigurationCopyMigrationPathsWithBaseURL(CFURLRef baseURL, CFURLRef
                CFRetain(baseURL);
        } else {
                baseURL = CFURLCreateFromFileSystemRepresentation(NULL,
                CFRetain(baseURL);
        } else {
                baseURL = CFURLCreateFromFileSystemRepresentation(NULL,
-                                                                 (UInt8*)PREFS_DEFAULT_DIR_PLIST,
-                                                                 sizeof(PREFS_DEFAULT_DIR_PLIST) - 1,
+                                                                 (UInt8*)PREFS_DEFAULT_DIR_PATH,
+                                                                 sizeof(PREFS_DEFAULT_DIR_PATH) - 1,
                                                                  TRUE);
        }
 
                                                                  TRUE);
        }
 
@@ -94,8 +90,8 @@ _SCNetworkConfigurationCopyMigrationPathsWithBaseURL(CFURLRef baseURL, CFURLRef
                                                                       baseURL);
 
        *interfaces = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL,
                                                                       baseURL);
 
        *interfaces = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL,
-                                                                           (UInt8*)NETWORK_INTERFACES_PREFS_PLIST,
-                                                                           sizeof(NETWORK_INTERFACES_PREFS_PLIST) - 1,
+                                                                           (UInt8*)INTERFACES_DEFAULT_CONFIG_PLIST,
+                                                                           sizeof(INTERFACES_DEFAULT_CONFIG_PLIST) - 1,
                                                                            FALSE,
                                                                            baseURL);
        CFRelease(baseURL);
                                                                            FALSE,
                                                                            baseURL);
        CFRelease(baseURL);
@@ -350,31 +346,24 @@ __SCNetworkCreateDefaultPref(CFStringRef prefsID)
 }
 
 __private_extern__
 }
 
 __private_extern__
-SCPreferencesRef
-__SCNetworkCreateDefaultNIPrefs(CFStringRef prefsID)
+void
+__SCNetworkPopulateDefaultNIPrefs(SCPreferencesRef ni_prefs)
 {
        CFMutableArrayRef interfaces = NULL;
        CFStringRef model;
        CFArrayRef networkInterfaces;
 {
        CFMutableArrayRef interfaces = NULL;
        CFStringRef model;
        CFArrayRef networkInterfaces;
-       SCPreferencesRef ni_prefs;
        CFComparisonResult res;
 
        CFComparisonResult res;
 
+       interfaces = (CFMutableArrayRef)SCPreferencesGetValue(ni_prefs, INTERFACES);
+       if (isA_CFArray(interfaces)) {
+               // if already populated
+               return;
+       }
+
        networkInterfaces = __SCNetworkInterfaceCopyAll_IONetworkInterface(TRUE);
        if (networkInterfaces == NULL) {
                SC_log(LOG_NOTICE, "networkInterfaces is NULL");
        networkInterfaces = __SCNetworkInterfaceCopyAll_IONetworkInterface(TRUE);
        if (networkInterfaces == NULL) {
                SC_log(LOG_NOTICE, "networkInterfaces is NULL");
-               return NULL;
-       }
-
-       if (prefsID == NULL) {
-               prefsID = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@"), PREFS_DEFAULT_DIR, NETWORK_INTERFACES_PREFS);
-       } else {
-               CFRetain(prefsID);
-       }
-       ni_prefs = SCPreferencesCreate(NULL, PLUGIN_ID, prefsID);
-       CFRelease(prefsID);
-       if (ni_prefs == NULL) {
-               SC_log(LOG_NOTICE, "ni_prefs is NULL");
-               goto done;
+               return;
        }
 
        interfaces = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        }
 
        interfaces = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
@@ -384,15 +373,15 @@ __SCNetworkCreateDefaultNIPrefs(CFStringRef prefsID)
                CFNumberRef if_type;
                CFNumberRef if_unit;
                SCNetworkInterfaceRef interface = CFArrayGetValueAtIndex(networkInterfaces, idx);
                CFNumberRef if_type;
                CFNumberRef if_unit;
                SCNetworkInterfaceRef interface = CFArrayGetValueAtIndex(networkInterfaces, idx);
-               CFDictionaryRef interfaceEntity = __SCNetworkInterfaceCopyStorageEntity(interface);
+               CFDictionaryRef interfaceEntity;
 
 
+               interfaceEntity = __SCNetworkInterfaceCopyStorageEntity(interface);
                if (interfaceEntity == NULL) {
                        continue;
                }
 
                if_type = _SCNetworkInterfaceGetIOInterfaceType(interface);
                if_unit = _SCNetworkInterfaceGetIOInterfaceUnit(interface);
                if (interfaceEntity == NULL) {
                        continue;
                }
 
                if_type = _SCNetworkInterfaceGetIOInterfaceType(interface);
                if_unit = _SCNetworkInterfaceGetIOInterfaceUnit(interface);
-
                if ((if_type == NULL) || (if_unit == NULL)) {
                        CFRelease(interfaceEntity);
                        continue;
                if ((if_type == NULL) || (if_unit == NULL)) {
                        CFRelease(interfaceEntity);
                        continue;
@@ -417,22 +406,19 @@ __SCNetworkCreateDefaultNIPrefs(CFStringRef prefsID)
                CFRelease(interfaceEntity);
 
        }
                CFRelease(interfaceEntity);
 
        }
+
        SCPreferencesSetValue(ni_prefs, INTERFACES, interfaces);
        SCPreferencesSetValue(ni_prefs, INTERFACES, interfaces);
+       CFRelease(interfaces);
 
        model = SCPreferencesGetValue(ni_prefs, MODEL);
        if (model == NULL) {
                model = _SC_hw_model(FALSE);
                SCPreferencesSetValue(ni_prefs, MODEL, model);
        }
 
        model = SCPreferencesGetValue(ni_prefs, MODEL);
        if (model == NULL) {
                model = _SC_hw_model(FALSE);
                SCPreferencesSetValue(ni_prefs, MODEL, model);
        }
-done:
-       if (interfaces != NULL) {
-               CFRelease(interfaces);
-       }
-       if (networkInterfaces != NULL) {
-               CFRelease(networkInterfaces);
-       }
 
 
-       return ni_prefs;
+       CFRelease(networkInterfaces);
+
+       return;
 }
 
 
 }
 
 
@@ -485,17 +471,29 @@ _SCNetworkConfigurationPerformMigration(CFURLRef sourceDir, CFURLRef currentDir,
        if (sourceDir == NULL) {
                sourceDirConfig = CFRetain(currentSystemPath);
        } else {
        if (sourceDir == NULL) {
                sourceDirConfig = CFRetain(currentSystemPath);
        } else {
-               sourceDirConfig = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE, kCFURLPOSIXPathStyle, TRUE, sourceDir);
+               sourceDirConfig = CFURLCreateWithFileSystemPathRelativeToBase(NULL,
+                                                                             PREFS_DEFAULT_DIR_RELATIVE,
+                                                                             kCFURLPOSIXPathStyle,
+                                                                             TRUE,
+                                                                             sourceDir);
        }
 
        if (currentDir != NULL) {
        }
 
        if (currentDir != NULL) {
-               currentDirConfig = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE, kCFURLPOSIXPathStyle, TRUE, currentDir);
+               currentDirConfig = CFURLCreateWithFileSystemPathRelativeToBase(NULL,
+                                                                              PREFS_DEFAULT_DIR_RELATIVE,
+                                                                              kCFURLPOSIXPathStyle,
+                                                                              TRUE,
+                                                                              currentDir);
        }
        // If the targetDir is not provided then migration will take place in currentDir
        if (targetDir == NULL) {
                targetDirConfig = CFRetain(currentSystemPath);
        } else {
        }
        // If the targetDir is not provided then migration will take place in currentDir
        if (targetDir == NULL) {
                targetDirConfig = CFRetain(currentSystemPath);
        } else {
-               targetDirConfig = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE, kCFURLPOSIXPathStyle, TRUE, targetDir);
+               targetDirConfig = CFURLCreateWithFileSystemPathRelativeToBase(NULL,
+                                                                             PREFS_DEFAULT_DIR_RELATIVE,
+                                                                             kCFURLPOSIXPathStyle,
+                                                                             TRUE,
+                                                                             targetDir);
        }
        // Source directory cannot be the same as Target Directory
        if (CFEqual(sourceDirConfig, targetDirConfig)) {
        }
        // Source directory cannot be the same as Target Directory
        if (CFEqual(sourceDirConfig, targetDirConfig)) {
@@ -1291,52 +1289,6 @@ remove_service(const void *value, void *context)
        }
 }
 
        }
 }
 
-static void
-_SCNetworkConfigurationSaveOldConfiguration(SCPreferencesRef prefs)
-{
-       CFAbsoluteTime absoluteTime;
-       CFCalendarRef currentCalendar;
-       int day;
-       int hour;
-       CFStringRef keyList[] = {
-                       kSCPrefCurrentSet,
-                       MODEL,
-                       kSCPrefNetworkServices,
-                       kSCPrefSets,
-                       kSCPrefSystem,
-                       kSCPrefVirtualNetworkInterfaces
-       };
-       CFIndex keyListCount;
-       int minute;
-       int month;
-       int second;
-       int year;
-
-       currentCalendar = CFCalendarCopyCurrent();
-       absoluteTime = CFAbsoluteTimeGetCurrent();
-
-       if (!CFCalendarDecomposeAbsoluteTime(currentCalendar, absoluteTime, "yMdHms",
-                                            &year, &month, &day, &hour, &minute, &second)) {
-               SC_log(LOG_INFO, "CFCalendarDecomposeAbsoluteTime() failed");
-       }
-       keyListCount = (CFIndex)sizeof(keyList)/sizeof(CFStringRef);
-
-       for (CFIndex idx = 0; idx < keyListCount; idx++) {
-               CFStringRef newKey;
-               CFTypeRef value = SCPreferencesGetValue(prefs, keyList[idx]);
-
-               if (value != NULL) {
-                       newKey = CFStringCreateWithFormat(NULL, NULL,
-                                                         CFSTR("%d-%d-%d %d:%d:%d : %@"),
-                                                         year, month, day, hour,
-                                                         minute, second, keyList[idx]);
-                       SCPreferencesSetValue(prefs, newKey, value);
-                       CFRelease(newKey);
-               }
-       }
-       CFRelease(currentCalendar);
-}
-
 static Boolean
 _SCNetworkConfigurationRepairUsingPreferences(SCPreferencesRef prefs,
                                              SCNetworkConfigurationValidityContext *context)
 static Boolean
 _SCNetworkConfigurationRepairUsingPreferences(SCPreferencesRef prefs,
                                              SCNetworkConfigurationValidityContext *context)
@@ -1355,7 +1307,7 @@ _SCNetworkConfigurationRepairUsingPreferences(SCPreferencesRef prefs,
                return FALSE;
        }
        // Backup current preferences before making changes
                return FALSE;
        }
        // Backup current preferences before making changes
-       _SCNetworkConfigurationSaveOldConfiguration(prefs);
+       __SCNetworkConfigurationBackup(prefs);
 
        serviceList = SCNetworkServiceCopyAll(prefs);
        CFArrayApplyFunction(serviceList, CFRangeMake(0, CFArrayGetCount(serviceList)), create_bsd_name_service_protocol_mapping, context);
 
        serviceList = SCNetworkServiceCopyAll(prefs);
        CFArrayApplyFunction(serviceList, CFRangeMake(0, CFArrayGetCount(serviceList)), create_bsd_name_service_protocol_mapping, context);
@@ -1491,7 +1443,7 @@ _SCNetworkConfigurationCheckValidityWithPreferences(SCPreferencesRef prefs,
        CFStringRef  model = NULL;
        CFStringRef ni_model = NULL;
        Boolean repairConfiguration = FALSE;
        CFStringRef  model = NULL;
        CFStringRef ni_model = NULL;
        Boolean repairConfiguration = FALSE;
-       Boolean revertLimitNetworkConfiguration = FALSE;
+       Boolean revertBypassSystemInterfaces = FALSE;
        CFArrayRef setServiceOrder = NULL;
        CFArrayRef setServices = NULL;
 
        CFArrayRef setServiceOrder = NULL;
        CFArrayRef setServices = NULL;
 
@@ -1501,9 +1453,9 @@ _SCNetworkConfigurationCheckValidityWithPreferences(SCPreferencesRef prefs,
                        repairConfiguration = CFBooleanGetValue(repair);
                }
        }
                        repairConfiguration = CFBooleanGetValue(repair);
                }
        }
-       if (!__SCPreferencesGetLimitSCNetworkConfiguration(prefs)) {
-               __SCPreferencesSetLimitSCNetworkConfiguration(prefs, TRUE);
-               revertLimitNetworkConfiguration = TRUE;
+       if (!_SCNetworkConfigurationBypassSystemInterfaces(prefs)) {
+               _SCNetworkConfigurationSetBypassSystemInterfaces(prefs, TRUE);
+               revertBypassSystemInterfaces = TRUE;
        }
        /*
 
        }
        /*
 
@@ -1719,8 +1671,8 @@ done:
        if (bsdNameServiceProtocolPreserveMapping != NULL) {
                CFRelease(bsdNameServiceProtocolPreserveMapping);
        }
        if (bsdNameServiceProtocolPreserveMapping != NULL) {
                CFRelease(bsdNameServiceProtocolPreserveMapping);
        }
-       if (revertLimitNetworkConfiguration) {
-               __SCPreferencesSetLimitSCNetworkConfiguration(prefs, FALSE);
+       if (revertBypassSystemInterfaces) {
+               _SCNetworkConfigurationSetBypassSystemInterfaces(prefs, FALSE);
        }
        return isValid;
 }
        }
        return isValid;
 }
@@ -1744,11 +1696,22 @@ _SCNetworkConfigurationCheckValidity(CFURLRef configDir, CFDictionaryRef options
                       (configDir == NULL) ? CFSTR("NULL") : CFURLGetString(configDir));
                goto done;
        }
                       (configDir == NULL) ? CFSTR("NULL") : CFURLGetString(configDir));
                goto done;
        }
-       baseURL = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE,
-                                                             kCFURLPOSIXPathStyle, TRUE, configDir);
+       baseURL = CFURLCreateWithFileSystemPathRelativeToBase(NULL,
+                                                             PREFS_DEFAULT_DIR_RELATIVE,
+                                                             kCFURLPOSIXPathStyle,
+                                                             TRUE,
+                                                             configDir);
 
 
-       configPreferenceFile = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)PREFS_DEFAULT_CONFIG_PLIST, sizeof(PREFS_DEFAULT_CONFIG_PLIST), FALSE, baseURL);
-       configNetworkInterfaceFile = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)NETWORK_INTERFACES_PREFS_PLIST, sizeof(NETWORK_INTERFACES_PREFS_PLIST), FALSE, baseURL);
+       configPreferenceFile = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL,
+                                                                                    (const UInt8*)PREFS_DEFAULT_CONFIG_PLIST,
+                                                                                    sizeof(PREFS_DEFAULT_CONFIG_PLIST),
+                                                                                    FALSE,
+                                                                                    baseURL);
+       configNetworkInterfaceFile = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL,
+                                                                                          (const UInt8*)INTERFACES_DEFAULT_CONFIG_PLIST,
+                                                                                          sizeof(INTERFACES_DEFAULT_CONFIG_PLIST),
+                                                                                          FALSE,
+                                                                                          baseURL);
 
        if (!CFURLGetFileSystemRepresentation(configPreferenceFile, TRUE, (UInt8*)prefsStr, sizeof(prefsStr))) {
                SC_log(LOG_NOTICE, "Cannot get file system representation for url: %@", configPreferenceFile);
 
        if (!CFURLGetFileSystemRepresentation(configPreferenceFile, TRUE, (UInt8*)prefsStr, sizeof(prefsStr))) {
                SC_log(LOG_NOTICE, "Cannot get file system representation for url: %@", configPreferenceFile);
@@ -3195,7 +3158,7 @@ preserve_service_order(const void *key, const void *value, void *context)
        migrated_context.success = success;
 
        // Creating a list of service IDs which were migrated in the target set
        migrated_context.success = success;
 
        // Creating a list of service IDs which were migrated in the target set
-       // while maintaining the service order or the source set
+       // while maintaining the service order of the source set
        CFArrayApplyFunction(sourceServiceOrder, CFRangeMake(0, CFArrayGetCount(sourceServiceOrder)), create_migrated_order, &migrated_context);
        if (*success == FALSE) {
                goto done;
        CFArrayApplyFunction(sourceServiceOrder, CFRangeMake(0, CFArrayGetCount(sourceServiceOrder)), create_migrated_order, &migrated_context);
        if (*success == FALSE) {
                goto done;
@@ -3347,10 +3310,9 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD
                }
        } else {
                targetPrefs = __SCNetworkCreateDefaultPref(targetPreferencesFileString);
                }
        } else {
                targetPrefs = __SCNetworkCreateDefaultPref(targetPreferencesFileString);
-               targetNetworkInterfacePrefs = __SCNetworkCreateDefaultNIPrefs(targetNetworkInterfaceFileString);
+               targetNetworkInterfacePrefs =  __SCPreferencesCreateNIPrefsFromPrefs(targetPrefs);
 
 
-               if (targetPrefs == NULL ||
-                   targetNetworkInterfacePrefs == NULL) {
+               if ((targetPrefs == NULL) || (targetNetworkInterfacePrefs == NULL)) {
                        SC_log(LOG_DEBUG, "Could not create default configuration");
                        goto done;
                }
                        SC_log(LOG_DEBUG, "Could not create default configuration");
                        goto done;
                }
@@ -3370,8 +3332,8 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD
               targetNetworkInterfaceFileString);
 
        // Setting Bypass Interface to avoid looking at system interfaces
               targetNetworkInterfaceFileString);
 
        // Setting Bypass Interface to avoid looking at system interfaces
-       __SCPreferencesSetLimitSCNetworkConfiguration(sourcePrefs, TRUE);
-       __SCPreferencesSetLimitSCNetworkConfiguration(targetPrefs, TRUE);
+       _SCNetworkConfigurationSetBypassSystemInterfaces(sourcePrefs, TRUE);
+       _SCNetworkConfigurationSetBypassSystemInterfaces(targetPrefs, TRUE);
 
        sourceModel = SCPreferencesGetValue(sourcePrefs, MODEL);
        targetModel = SCPreferencesGetValue(targetPrefs, MODEL);
 
        sourceModel = SCPreferencesGetValue(sourcePrefs, MODEL);
        targetModel = SCPreferencesGetValue(targetPrefs, MODEL);
@@ -3773,15 +3735,27 @@ _SCNetworkMigrationAreConfigurationsIdentical (CFURLRef configurationURL,
            expectedConfigurationURL == NULL) {
                return FALSE;
        }
            expectedConfigurationURL == NULL) {
                return FALSE;
        }
-       baseConfigURL = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE, kCFURLPOSIXPathStyle, TRUE, configurationURL);
-       configPreferencesURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*) PREFS_DEFAULT_CONFIG_PLIST, sizeof(PREFS_DEFAULT_CONFIG_PLIST), FALSE, baseConfigURL);
+       baseConfigURL = CFURLCreateWithFileSystemPathRelativeToBase(NULL,
+                                                                   PREFS_DEFAULT_DIR_RELATIVE,
+                                                                   kCFURLPOSIXPathStyle,
+                                                                   TRUE,
+                                                                   configurationURL);
+       configPreferencesURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL,
+                                                                                    (const UInt8*)PREFS_DEFAULT_CONFIG_PLIST,
+                                                                                    sizeof(PREFS_DEFAULT_CONFIG_PLIST),
+                                                                                    FALSE,
+                                                                                    baseConfigURL);
 
        if (!CFURLResourceIsReachable(configPreferencesURL, NULL)) {
                SC_log(LOG_INFO, "No preferences.plist file");
                goto done;
        }
 
 
        if (!CFURLResourceIsReachable(configPreferencesURL, NULL)) {
                SC_log(LOG_INFO, "No preferences.plist file");
                goto done;
        }
 
-       configNetworkInterfacesURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)NETWORK_INTERFACES_PREFS_PLIST, sizeof(NETWORK_INTERFACES_PREFS_PLIST), FALSE, baseConfigURL);
+       configNetworkInterfacesURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL,
+                                                                                          (const UInt8*)INTERFACES_DEFAULT_CONFIG_PLIST,
+                                                                                          sizeof(INTERFACES_DEFAULT_CONFIG_PLIST),
+                                                                                          FALSE,
+                                                                                          baseConfigURL);
 
        if (!CFURLResourceIsReachable(configNetworkInterfacesURL, NULL)) {
                SC_log(LOG_INFO, "No NetworkInterfaces.plist file");
 
        if (!CFURLResourceIsReachable(configNetworkInterfacesURL, NULL)) {
                SC_log(LOG_INFO, "No NetworkInterfaces.plist file");
@@ -3797,15 +3771,27 @@ _SCNetworkMigrationAreConfigurationsIdentical (CFURLRef configurationURL,
                goto done;
        }
 
                goto done;
        }
 
-       baseExpectedConfigURL = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE, kCFURLPOSIXPathStyle, TRUE, expectedConfigurationURL);
-       expectedPreferencesURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)PREFS_DEFAULT_CONFIG_PLIST, sizeof(PREFS_DEFAULT_CONFIG_PLIST), FALSE, baseExpectedConfigURL);
+       baseExpectedConfigURL = CFURLCreateWithFileSystemPathRelativeToBase(NULL,
+                                                                           PREFS_DEFAULT_DIR_RELATIVE,
+                                                                           kCFURLPOSIXPathStyle,
+                                                                           TRUE,
+                                                                           expectedConfigurationURL);
+       expectedPreferencesURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL,
+                                                                                      (const UInt8*)PREFS_DEFAULT_CONFIG_PLIST,
+                                                                                      sizeof(PREFS_DEFAULT_CONFIG_PLIST),
+                                                                                      FALSE,
+                                                                                      baseExpectedConfigURL);
 
        if (!CFURLResourceIsReachable(expectedPreferencesURL, NULL)) {
                SC_log(LOG_INFO, "No expected preferences.plist file");
                goto done;
        }
 
 
        if (!CFURLResourceIsReachable(expectedPreferencesURL, NULL)) {
                SC_log(LOG_INFO, "No expected preferences.plist file");
                goto done;
        }
 
-       expectedNetworkInterfaceURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)NETWORK_INTERFACES_PREFS_PLIST, sizeof(NETWORK_INTERFACES_PREFS_PLIST), FALSE, baseExpectedConfigURL);
+       expectedNetworkInterfaceURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL,
+                                                                                           (const UInt8*)INTERFACES_DEFAULT_CONFIG_PLIST,
+                                                                                           sizeof(INTERFACES_DEFAULT_CONFIG_PLIST),
+                                                                                           FALSE,
+                                                                                           baseExpectedConfigURL);
 
        if (!CFURLResourceIsReachable(expectedNetworkInterfaceURL, NULL)) {
                SC_log(LOG_INFO, "No expected NetworkInterfaces.plist file");
 
        if (!CFURLResourceIsReachable(expectedNetworkInterfaceURL, NULL)) {
                SC_log(LOG_INFO, "No expected NetworkInterfaces.plist file");
@@ -3902,8 +3888,11 @@ _SCNetworkConfigurationCopyMigrationRemovePaths  (CFArrayRef     targetPaths,
                        SC_log(LOG_NOTICE, "Cannot get file system representation for url: %@", affectedURL);
                        continue;
                }
                        SC_log(LOG_NOTICE, "Cannot get file system representation for url: %@", affectedURL);
                        continue;
                }
-               targetFile = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)filePath,
-               strnlen(filePath, sizeof(filePath)), FALSE, targetDir);
+               targetFile = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL,
+                                                                                  (const UInt8*)filePath,
+                                                                                  strnlen(filePath, sizeof(filePath)),
+                                                                                  FALSE,
+                                                                                  targetDir);
 
                if (!CFURLResourceIsReachable(targetFile, NULL)) {
                        CFArrayAppendValue(toBeRemoved, affectedURL);
 
                if (!CFURLResourceIsReachable(targetFile, NULL)) {
                        CFArrayAppendValue(toBeRemoved, affectedURL);
index d0cd41ea214e662dac5fb60e54c5c5025f80d169..b09f20df5495ac44f774241323e773f0a2f3e556 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004-2008, 2016-2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2008, 2016-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -261,7 +261,7 @@ SCNetworkProtocolGetConfiguration(SCNetworkProtocolRef protocol)
 
        servicePrivate = (SCNetworkServicePrivateRef)protocolPrivate->service;
        path = copyProtocolConfigurationPath(protocolPrivate);
 
        servicePrivate = (SCNetworkServicePrivateRef)protocolPrivate->service;
        path = copyProtocolConfigurationPath(protocolPrivate);
-       config = __getPrefsConfiguration(servicePrivate->prefs, path);
+       config = __SCNetworkConfigurationGetValue(servicePrivate->prefs, path);
        CFRelease(path);
 
        return config;
        CFRelease(path);
 
        return config;
@@ -330,7 +330,7 @@ SCNetworkProtocolSetConfiguration(SCNetworkProtocolRef protocol, CFDictionaryRef
        }
 
        path = copyProtocolConfigurationPath(protocolPrivate);
        }
 
        path = copyProtocolConfigurationPath(protocolPrivate);
-       ok = __setPrefsConfiguration(servicePrivate->prefs, path, config, TRUE);
+       ok = __SCNetworkConfigurationSetValue(servicePrivate->prefs, path, config, TRUE);
        CFRelease(path);
 
        if (ok) {
        CFRelease(path);
 
        if (ok) {
index d9c8d4bed15e63048bfd5db122fb49c29fd26b34..c64311636eb85112175c2abc31f8ce657ff34ea3 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004-2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 #include "SCNetworkConfigurationInternal.h"
 #include "SCPreferencesInternal.h"
 
 #include "SCNetworkConfigurationInternal.h"
 #include "SCPreferencesInternal.h"
 
+#include <net/if.h>
 #include <pthread.h>
 
 #include <pthread.h>
 
+#include <CommonCrypto/CommonDigest.h>
+
 #define EXTERNAL_ID_DOMAIN_PREFIX      "_"
 
 static CFStringRef     __SCNetworkServiceCopyDescription       (CFTypeRef cf);
 #define EXTERNAL_ID_DOMAIN_PREFIX      "_"
 
 static CFStringRef     __SCNetworkServiceCopyDescription       (CFTypeRef cf);
@@ -424,7 +427,7 @@ SCNetworkServiceAddProtocolType(SCNetworkServiceRef service, CFStringRef protoco
 
        newEntity = _protocolTemplate(service, protocolType);
        assert(newEntity != NULL);
 
        newEntity = _protocolTemplate(service, protocolType);
        assert(newEntity != NULL);
-       
+
        ok = SCNetworkProtocolSetConfiguration(protocol, newEntity);
        if (!ok) {
                // could not set default configuration
        ok = SCNetworkProtocolSetConfiguration(protocol, newEntity);
        if (!ok) {
                // could not set default configuration
@@ -460,6 +463,7 @@ SCNetworkServiceCopyAll(SCPreferencesRef prefs)
        CFStringRef             path;
        CFDictionaryRef         services;
 
        CFStringRef             path;
        CFDictionaryRef         services;
 
+
        path = SCPreferencesPathKeyCreateNetworkServices(NULL);
        services = SCPreferencesPathGetValue(prefs, path);
        CFRelease(path);
        path = SCPreferencesPathKeyCreateNetworkServices(NULL);
        services = SCPreferencesPathGetValue(prefs, path);
        CFRelease(path);
@@ -977,6 +981,91 @@ SCNetworkServiceCreate(SCPreferencesRef prefs, SCNetworkInterfaceRef interface)
 }
 
 
 }
 
 
+static CF_RETURNS_RETAINED CFStringRef
+copyInterfaceUUID(CFStringRef bsdName)
+{
+       union {
+               unsigned char   sha256_bytes[CC_SHA256_DIGEST_LENGTH];
+               CFUUIDBytes     uuid_bytes;
+       } bytes;
+       CC_SHA256_CTX   ctx;
+       char            if_name[IF_NAMESIZE];
+       CFUUIDRef       uuid;
+       CFStringRef     uuid_str;
+
+       // start with interface name
+       memset(&if_name, 0, sizeof(if_name));
+       (void) _SC_cfstring_to_cstring(bsdName,
+                                      if_name,
+                                      sizeof(if_name),
+                                      kCFStringEncodingASCII);
+
+       // create SHA256 hash
+       memset(&bytes, 0, sizeof(bytes));
+       CC_SHA256_Init(&ctx);
+       CC_SHA256_Update(&ctx,
+                        if_name,
+                        sizeof(if_name));
+       CC_SHA256_Final(bytes.sha256_bytes, &ctx);
+
+       // create UUID string
+       uuid = CFUUIDCreateFromUUIDBytes(NULL, bytes.uuid_bytes);
+       uuid_str = CFUUIDCreateString(NULL, uuid);
+       CFRelease(uuid);
+
+       return uuid_str;
+}
+
+
+SCNetworkServiceRef
+_SCNetworkServiceCreatePreconfigured(SCPreferencesRef prefs, SCNetworkInterfaceRef interface)
+{
+       CFStringRef             bsdName;
+       Boolean                 ok;
+       SCNetworkServiceRef     service;
+       CFStringRef             serviceID;
+
+       bsdName = SCNetworkInterfaceGetBSDName(interface);
+
+       // create network service
+       service = SCNetworkServiceCreate(prefs, interface);
+       if (service == NULL) {
+               SC_log(LOG_ERR, "could not create network service for \"%@\": %s",
+                      bsdName,
+                      SCErrorString(SCError()));
+               return NULL;
+       }
+
+       // update network service to use a consistent 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
+       }
+
+       // establish [template] configuration
+       ok = SCNetworkServiceEstablishDefaultConfiguration(service);
+       if (!ok) {
+               SC_log(LOG_ERR, "could not establish network service for \"%@\": %s",
+                      bsdName,
+                      SCErrorString(SCError()));
+               SCNetworkServiceRemove(service);
+               CFRelease(service);
+               service = NULL;
+       }
+
+       return service;
+}
+
+
 Boolean
 SCNetworkServiceEstablishDefaultConfiguration(SCNetworkServiceRef service)
 {
 Boolean
 SCNetworkServiceEstablishDefaultConfiguration(SCNetworkServiceRef service)
 {
@@ -1115,8 +1204,7 @@ SCNetworkServiceGetName(SCNetworkServiceRef service)
        entity = SCPreferencesPathGetValue(servicePrivate->prefs, path);
        CFRelease(path);
 
        entity = SCPreferencesPathGetValue(servicePrivate->prefs, path);
        CFRelease(path);
 
-       useSystemInterfaces = ((__SCPreferencesUsingDefaultPrefs(servicePrivate->prefs)) &&
-                              !__SCPreferencesGetLimitSCNetworkConfiguration(servicePrivate->prefs));
+       useSystemInterfaces = !_SCNetworkConfigurationBypassSystemInterfaces(servicePrivate->prefs);
 
        if (isA_CFDictionary(entity)) {
                name = CFDictionaryGetValue(entity, kSCPropUserDefinedName);
 
        if (isA_CFDictionary(entity)) {
                name = CFDictionaryGetValue(entity, kSCPropUserDefinedName);
index 2e223eb830a16a70ccecad6d4c44ac00def3bb42..80181cf82274f59b8c8da01d8c617f003ebf48df 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000, 2001, 2003-2005, 2007-2009, 2011, 2014-2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003-2005, 2007-2009, 2011, 2014-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -61,6 +61,29 @@ __SCPSignatureFromStatbuf(const struct stat *statBuf)
 }
 
 
 }
 
 
+__private_extern__
+uint32_t
+__SCPreferencesGetNetworkConfigurationFlags(SCPreferencesRef prefs)
+{
+       SCPreferencesPrivateRef prefsPrivate    = (SCPreferencesPrivateRef)prefs;
+
+       return (prefs != NULL) ? prefsPrivate->nc_flags : 0;
+}
+
+__private_extern__
+void
+__SCPreferencesSetNetworkConfigurationFlags(SCPreferencesRef prefs, uint32_t nc_flags)
+{
+       SCPreferencesPrivateRef prefsPrivate    = (SCPreferencesPrivateRef)prefs;
+
+       if (prefs != NULL) {
+               prefsPrivate->nc_flags = nc_flags;
+       }
+
+       return;
+}
+
+
 __private_extern__ char *
 __SCPreferencesPath(CFAllocatorRef     allocator,
                    CFStringRef         prefsID,
 __private_extern__ char *
 __SCPreferencesPath(CFAllocatorRef     allocator,
                    CFStringRef         prefsID,
@@ -119,19 +142,6 @@ __SCPreferencesPath(CFAllocatorRef allocator,
 }
 
 
 }
 
 
-__private_extern__
-Boolean
-__SCPreferencesGetLimitSCNetworkConfiguration(SCPreferencesRef prefs)
-{
-       SCPreferencesPrivateRef prefsPrivate    = (SCPreferencesPrivateRef)prefs;
-
-       if (prefs == NULL) {
-               return FALSE;
-       }
-       return prefsPrivate->limit_SCNetworkConfiguration;
-}
-
-
 __private_extern__
 off_t
 __SCPreferencesPrefsSize(SCPreferencesRef prefs)
 __private_extern__
 off_t
 __SCPreferencesPrefsSize(SCPreferencesRef prefs)
@@ -179,31 +189,13 @@ __private_extern__
 SCPreferencesRef
 __SCPreferencesCreateNIPrefsFromPrefs(SCPreferencesRef prefs)
 {
 SCPreferencesRef
 __SCPreferencesCreateNIPrefsFromPrefs(SCPreferencesRef prefs)
 {
-       CFMutableStringRef newPath = NULL;
-       CFURLRef newURL = NULL;
-       SCPreferencesRef ni_prefs = NULL;
-       SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs;
-       char * prefsPath = __SCPreferencesPath(NULL, prefsPrivate->prefsID, FALSE);
-
-
-       newPath = CFStringCreateMutable(NULL, 0);
-       CFStringAppendFormat(newPath, NULL, CFSTR("%s"), prefsPath);
+       SCPreferencesRef        ni_prefs;
 
 
-       CFStringFindAndReplace(newPath,
-                              PREFS_DEFAULT_CONFIG,
-                              NETWORK_INTERFACES_PREFS,
-                              CFRangeMake(0, CFStringGetLength(newPath)),
-                              kCFCompareBackwards);
+       // open [companion] NetworkInterfaces.plist
+       ni_prefs = SCPreferencesCreateCompanion(prefs, INTERFACES_DEFAULT_CONFIG);
 
 
-       newURL = CFURLCreateWithFileSystemPath(NULL, newPath, kCFURLPOSIXPathStyle, FALSE);
-       if (!CFURLResourceIsReachable(newURL, NULL)) {
-               ni_prefs = __SCNetworkCreateDefaultNIPrefs(newPath);
-       } else {
-               ni_prefs = SCPreferencesCreate(NULL, prefsPrivate->name, newPath);
-       }
-       CFAllocatorDeallocate(NULL, prefsPath);
-       CFRelease(newPath);
-       CFRelease(newURL);
+       // if needed, populate
+       __SCNetworkPopulateDefaultNIPrefs(ni_prefs);
 
        return ni_prefs;
 }
 
        return ni_prefs;
 }
@@ -280,15 +272,3 @@ SCDynamicStoreKeyCreatePreferences(CFAllocatorRef  allocator,
        return _SCPNotificationKey(allocator, prefsID, keyType);
 }
 
        return _SCPNotificationKey(allocator, prefsID, keyType);
 }
 
-
-__private_extern__ void
-__SCPreferencesSetLimitSCNetworkConfiguration(SCPreferencesRef prefs,
-                                             Boolean           limit_SCNetworkConfiguration)
-{
-       SCPreferencesPrivateRef prefsPrivate    = (SCPreferencesPrivateRef)prefs;
-
-       if (prefs == NULL) {
-               return;
-       }
-       prefsPrivate->limit_SCNetworkConfiguration = limit_SCNetworkConfiguration;
-}
index 42b9890bb11b6f39ca6f23bed431562d16f6341a..fa358dfb24241255654023833662bac78ad21c83 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2008, 2010-2013, 2015-2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2008, 2010-2013, 2015-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -332,9 +332,14 @@ SCPreferencesCommitChanges(SCPreferencesRef prefs)
 
     committed :
 
 
     committed :
 
-       SC_log(LOG_INFO, "SCPreferences() commit: %s, size=%lld",
-              prefsPrivate->newPath ? prefsPrivate->newPath : prefsPrivate->path,
-              __SCPreferencesPrefsSize(prefs));
+       if (prefsPrivate->changed) {
+               SC_log(LOG_INFO, "SCPreferences() commit: %s, size=%lld",
+                      prefsPrivate->newPath ? prefsPrivate->newPath : prefsPrivate->path,
+                      __SCPreferencesPrefsSize(prefs));
+       } else {
+               SC_log(LOG_INFO, "SCPreferences() commit: %s, w/no changes",
+                      prefsPrivate->newPath ? prefsPrivate->newPath : prefsPrivate->path);
+       }
 
        /* post notification */
        ok = SCDynamicStoreNotifyValue(NULL, prefsPrivate->sessionKeyCommit);
 
        /* post notification */
        ok = SCDynamicStoreNotifyValue(NULL, prefsPrivate->sessionKeyCommit);
index 05ef3a3f105b0875b50407591a2ff347fc1b2aa5..ebaddebf122547f98274339a19a7687d72a469d7 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright(c) 2000-2019 Apple Inc. All rights reserved.
+ * Copyright(c) 2000-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -65,13 +65,6 @@ __log_SCPreferences(void)
 }
 
 
 }
 
 
-static __inline__ CFTypeRef
-isA_SCPreferences(CFTypeRef obj)
-{
-       return (isA_CFType(obj, SCPreferencesGetTypeID()));
-}
-
-
 static CFStringRef
 __SCPreferencesCopyDescription(CFTypeRef cf) {
        CFAllocatorRef          allocator       = CFGetAllocator(cf);
 static CFStringRef
 __SCPreferencesCopyDescription(CFTypeRef cf) {
        CFAllocatorRef          allocator       = CFGetAllocator(cf);
@@ -119,6 +112,19 @@ __SCPreferencesDeallocate(CFTypeRef cf)
 
        pthread_mutex_destroy(&prefsPrivate->lock);
 
 
        pthread_mutex_destroy(&prefsPrivate->lock);
 
+       if (prefsPrivate->parent != NULL) {
+               SCPreferencesPrivateRef parentPrivate   = (SCPreferencesPrivateRef)prefsPrivate->parent;
+
+               // remove [weak] reference from parent to this companion
+               pthread_mutex_lock(&parentPrivate->lock);
+               CFDictionaryRemoveValue(parentPrivate->companions, prefsPrivate->prefsID);
+               pthread_mutex_unlock(&parentPrivate->lock);
+
+               // remove [strong] reference from companion to parent
+               CFRelease(prefsPrivate->parent);
+       }
+       if (prefsPrivate->companions != NULL)   CFRelease(prefsPrivate->companions);
+
        if (prefsPrivate->name)                 CFRelease(prefsPrivate->name);
        if (prefsPrivate->prefsID)              CFRelease(prefsPrivate->prefsID);
        if (prefsPrivate->options)              CFRelease(prefsPrivate->options);
        if (prefsPrivate->name)                 CFRelease(prefsPrivate->name);
        if (prefsPrivate->prefsID)              CFRelease(prefsPrivate->prefsID);
        if (prefsPrivate->options)              CFRelease(prefsPrivate->options);
@@ -662,8 +668,7 @@ SCPreferencesCreateWithOptions(CFAllocatorRef       allocator,
 
        if (authorization != NULL) {
                CFMutableDictionaryRef  authorizationDict;
 
        if (authorization != NULL) {
                CFMutableDictionaryRef  authorizationDict;
-               CFBundleRef             bundle;
-               CFStringRef             bundleID        = NULL;
+               CFStringRef             bundleID;
 
                authorizationDict =  CFDictionaryCreateMutable(NULL,
                                                               0,
 
                authorizationDict =  CFDictionaryCreateMutable(NULL,
                                                               0,
@@ -691,36 +696,10 @@ SCPreferencesCreateWithOptions(CFAllocatorRef     allocator,
                }
 #endif // !TARGET_OS_IPHONE
 
                }
 #endif // !TARGET_OS_IPHONE
 
-               /* get the application/executable/bundle name */
-               bundle = CFBundleGetMainBundle();
-               if (bundle != NULL) {
-                       bundleID = CFBundleGetIdentifier(bundle);
-                       if (bundleID != NULL) {
-                               CFRetain(bundleID);
-                       } else {
-                               CFURLRef        url;
-
-                               url = CFBundleCopyExecutableURL(bundle);
-                               if (url != NULL) {
-                                       bundleID = CFURLCopyPath(url);
-                                       CFRelease(url);
-                               }
-                       }
-
-                       if (bundleID != NULL) {
-                               if (CFEqual(bundleID, CFSTR("/"))) {
-                                       CFRelease(bundleID);
-                                       bundleID = NULL;
-                               }
-                       }
-               }
-               if (bundleID == NULL) {
-                       bundleID = CFStringCreateWithFormat(NULL, NULL, CFSTR("Unknown(%d)"), getpid());
-               }
+               bundleID = _SC_getApplicationBundleID();
                CFDictionaryAddValue(authorizationDict,
                                     kSCHelperAuthCallerInfo,
                                     bundleID);
                CFDictionaryAddValue(authorizationDict,
                                     kSCHelperAuthCallerInfo,
                                     bundleID);
-               CFRelease(bundleID);
 
                if (authorizationDict != NULL) {
                        (void) _SCSerialize((CFPropertyListRef)authorizationDict,
 
                if (authorizationDict != NULL) {
                        (void) _SCSerialize((CFPropertyListRef)authorizationDict,
@@ -761,6 +740,119 @@ SCPreferencesCreateWithOptions(CFAllocatorRef     allocator,
 }
 
 
 }
 
 
+SCPreferencesRef
+SCPreferencesCreateCompanion(SCPreferencesRef prefs, CFStringRef companionPrefsID)
+{
+       CFAllocatorRef          allocator       = CFGetAllocator(prefs);
+       SCPreferencesPrivateRef companionPrefs  = NULL;
+       CFMutableStringRef      newPrefsID;
+       SCPreferencesPrivateRef prefsPrivate    = (SCPreferencesPrivateRef)prefs;
+
+       if (companionPrefsID == NULL) {
+               companionPrefsID = PREFS_DEFAULT_CONFIG;
+       } else {
+               if (CFStringFindWithOptions(companionPrefsID,
+                                           CFSTR("/"),
+                                           CFRangeMake(0, CFStringGetLength(companionPrefsID)),
+                                           kCFCompareBackwards,
+                                           NULL)) {
+                       // if companion prefsID contains a "/"
+                       _SCErrorSet(kSCStatusInvalidArgument);
+                       return NULL;
+               }
+       }
+
+       if (prefsPrivate->prefsID == NULL) {
+               if (CFEqual(companionPrefsID, PREFS_DEFAULT_CONFIG)) {
+                       // if prefsID and companionPrefsID match
+                       _SCErrorSet(kSCStatusInvalidArgument);
+                       return NULL;
+               }
+               newPrefsID = CFStringCreateMutableCopy(allocator, 0, companionPrefsID);
+       } else {
+               CFIndex prefsIDLen      = CFStringGetLength(prefsPrivate->prefsID);
+               CFRange range;
+
+               if (CFStringFindWithOptions(prefsPrivate->prefsID,
+                                           CFSTR("/"),
+                                           CFRangeMake(0, prefsIDLen),
+                                           kCFCompareBackwards,
+                                           &range)) {
+                       Boolean         match;
+                       CFStringRef     suffix;
+
+                       // if slash, check suffix
+                       range.location++;
+                       if (range.location >= prefsIDLen) {
+                               // if no suffix
+                               _SCErrorSet(kSCStatusInvalidArgument);
+                               return NULL;
+                       }
+                       range.length = prefsIDLen - range.location;
+                       suffix = CFStringCreateWithSubstring(allocator, prefsPrivate->prefsID, range);
+                       match = CFEqual(suffix, companionPrefsID);
+                       CFRelease(suffix);
+                       if (match) {
+                               // if prefsID [suffix] and companionPrefsID match
+                               _SCErrorSet(kSCStatusInvalidArgument);
+                               return NULL;
+                       }
+
+                       // replace the suffix
+                       newPrefsID = CFStringCreateMutableCopy(NULL, 0, prefsPrivate->prefsID);
+                       CFStringReplace(newPrefsID, range, companionPrefsID);
+               } else if (!CFEqual(prefsPrivate->prefsID, companionPrefsID)) {
+                       // if no slash, prefsID and companionPrefsID differ
+                       newPrefsID = CFStringCreateMutableCopy(NULL, 0, companionPrefsID);
+               } else {
+                       // if no slash, prefsID and companionPrefsID match
+                       _SCErrorSet(kSCStatusInvalidArgument);
+                       return NULL;
+               }
+       }
+       assert(newPrefsID != NULL);
+
+       pthread_mutex_lock(&prefsPrivate->lock);
+       if ((prefsPrivate->companions != NULL) &&
+           CFDictionaryGetValueIfPresent(prefsPrivate->companions,
+                                         newPrefsID,
+                                         (const void **)&companionPrefs) &&
+           (companionPrefs != NULL)) {
+               // if we already have a companion
+               SC_log(LOG_DEBUG, "create [companion] reference %@", companionPrefs);
+               CFRetain(companionPrefs);
+       } else {
+               companionPrefs = __SCPreferencesCreate(allocator,
+                                                      prefsPrivate->name,
+                                                      newPrefsID,
+                                                      prefsPrivate->authorizationData,
+                                                      prefsPrivate->options);
+               if (companionPrefs != NULL) {
+                       SCPreferencesPrivateRef companionPrefsPrivate   = (SCPreferencesPrivateRef)companionPrefs;
+
+                       SC_log(LOG_DEBUG, "create [companion] %@", companionPrefs);
+
+                       // add [strong] reference from companion to parent
+                       companionPrefsPrivate->parent = CFRetain(prefs);
+
+                       // add [weak] reference from parent to this companion
+                       if (prefsPrivate->companions == NULL) {
+                               prefsPrivate->companions = CFDictionaryCreateMutable(NULL,
+                                                                                    0,
+                                                                                    &kCFTypeDictionaryKeyCallBacks,
+                                                                                    NULL);
+                       }
+                       CFDictionarySetValue(prefsPrivate->companions, newPrefsID, companionPrefs);
+               }
+       }
+       pthread_mutex_unlock(&prefsPrivate->lock);
+
+       CFRelease(newPrefsID);
+
+       return (SCPreferencesRef)companionPrefs;
+}
+
+
 CFTypeID
 SCPreferencesGetTypeID(void) {
        pthread_once(&initialized, __SCPreferencesInitialize);  /* initialize runtime */
 CFTypeID
 SCPreferencesGetTypeID(void) {
        pthread_once(&initialized, __SCPreferencesInitialize);  /* initialize runtime */
index 4201dc4c1733874342af5e0d552511baaab57668..af9804389f3d76ad8690fed66431f3a203ff670f 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000, 2001, 2003-2005, 2007-2011, 2013-2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003-2005, 2007-2011, 2013-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 #include <SystemConfiguration/SCDynamicStore.h>
 
 
 #include <SystemConfiguration/SCDynamicStore.h>
 
 
-#define        PREFS_DEFAULT_DIR               CFSTR("/Library/Preferences/SystemConfiguration")
-#define        PREFS_DEFAULT_CONFIG            CFSTR("preferences.plist")
+#define PREFS_DEFAULT_DIR_PATH_RELATIVE        "Library/Preferences/SystemConfiguration"
+#define        PREFS_DEFAULT_DIR_RELATIVE      CFSTR(PREFS_DEFAULT_DIR_PATH_RELATIVE "/")
+
+#define        PREFS_DEFAULT_DIR_PATH          "/" PREFS_DEFAULT_DIR_PATH_RELATIVE
+#define        PREFS_DEFAULT_DIR               CFSTR(PREFS_DEFAULT_DIR_PATH)
+
+#define        PREFS_DEFAULT_CONFIG_PLIST      "preferences.plist"
+#define        PREFS_DEFAULT_CONFIG            CFSTR(PREFS_DEFAULT_CONFIG_PLIST)
 
 #define        PREFS_DEFAULT_DIR_OLD           CFSTR("/var/db/SystemConfiguration")
 #define        PREFS_DEFAULT_CONFIG_OLD        CFSTR("preferences.xml")
 
 #define        PREFS_DEFAULT_USER_DIR          CFSTR("Library/Preferences")
 
 
 #define        PREFS_DEFAULT_DIR_OLD           CFSTR("/var/db/SystemConfiguration")
 #define        PREFS_DEFAULT_CONFIG_OLD        CFSTR("preferences.xml")
 
 #define        PREFS_DEFAULT_USER_DIR          CFSTR("Library/Preferences")
 
-#define        NETWORK_INTERFACES_PREFS        CFSTR("NetworkInterfaces.plist")
+#define        INTERFACES_DEFAULT_CONFIG_PLIST "NetworkInterfaces.plist"
+#define        INTERFACES_DEFAULT_CONFIG       CFSTR(INTERFACES_DEFAULT_CONFIG_PLIST)
 #define        INTERFACES                      CFSTR("Interfaces")
 
 
 #define        INTERFACES                      CFSTR("Interfaces")
 
 
@@ -108,11 +115,15 @@ typedef struct {
        /* preferences */
        CFMutableDictionaryRef  prefs;
 
        /* preferences */
        CFMutableDictionaryRef  prefs;
 
+       /* companion preferences, manipulate under lock */
+       SCPreferencesRef        parent;         // [strong] reference from companion to parent
+       CFMutableDictionaryRef  companions;     // [weak] reference from parent to companions
+
        /* flags */
        Boolean                 accessed;
        Boolean                 changed;
        Boolean                 isRoot;
        /* flags */
        Boolean                 accessed;
        Boolean                 changed;
        Boolean                 isRoot;
-       Boolean                 limit_SCNetworkConfiguration;
+       uint32_t                nc_flags;       // SCNetworkConfiguration flags
 
        /* authorization, helper */
        CFDataRef               authorizationData;
 
        /* authorization, helper */
        CFDataRef               authorizationData;
@@ -133,6 +144,12 @@ typedef struct {
 
 __BEGIN_DECLS
 
 
 __BEGIN_DECLS
 
+static __inline__ CFTypeRef
+isA_SCPreferences(CFTypeRef obj)
+{
+       return (isA_CFType(obj, SCPreferencesGetTypeID()));
+}
+
 os_log_t
 __log_SCPreferences                    (void);
 
 os_log_t
 __log_SCPreferences                    (void);
 
@@ -172,16 +189,18 @@ CFStringRef
 _SCPNotificationKey                    (CFAllocatorRef         allocator,
                                         CFStringRef            prefsID,
                                         int                    keyType);
 _SCPNotificationKey                    (CFAllocatorRef         allocator,
                                         CFStringRef            prefsID,
                                         int                    keyType);
-Boolean
-__SCPreferencesGetLimitSCNetworkConfiguration  (SCPreferencesRef prefs);
+
+uint32_t
+__SCPreferencesGetNetworkConfigurationFlags
+                                       (SCPreferencesRef       prefs);
 
 void
 
 void
-__SCPreferencesSetLimitSCNetworkConfiguration
+__SCPreferencesSetNetworkConfigurationFlags
                                        (SCPreferencesRef       prefs,
                                        (SCPreferencesRef       prefs,
-                                        Boolean                limit_SCNetworkConfiguration);
+                                        uint32_t               nc_flags);
 
 Boolean
 
 Boolean
-__SCPreferencesUsingDefaultPrefs               (SCPreferencesRef       prefs);
+__SCPreferencesUsingDefaultPrefs       (SCPreferencesRef       prefs);
 
 SCPreferencesRef
 __SCPreferencesCreateNIPrefsFromPrefs  (SCPreferencesRef prefs);
 
 SCPreferencesRef
 __SCPreferencesCreateNIPrefsFromPrefs  (SCPreferencesRef prefs);
index eabdba3df7bf884ac310cc1b0620fdaf5b7d84e9..86230caf62b2e8b666dc5daa60328ad846e390ed 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2005, 2007-2009, 2011, 2012, 2017, 2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2005, 2007-2009, 2011, 2012, 2017-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -122,6 +122,22 @@ SCDynamicStoreKeyCreatePreferences (
                                        SCPreferencesKeyType    keyType
                                        )       API_DEPRECATED("No longer supported", macos(10.1,10.4), ios(2.0,2.0));
 
                                        SCPreferencesKeyType    keyType
                                        )       API_DEPRECATED("No longer supported", macos(10.1,10.4), ios(2.0,2.0));
 
+/*!
+       @function SCPreferencesCreateCompanion
+       @discussion Initiates access to a [companion] of the configuration
+              preferences.
+       @param prefs The base preferences session.
+       @param companionPrefsID  A string that identifies the companion name
+               of the group of preferences to be accessed or updated.
+       @result Returns a reference to the new SCPreferences.
+              You must release the returned value.
+*/
+SCPreferencesRef
+SCPreferencesCreateCompanion           (
+                                        SCPreferencesRef       prefs,
+                                        CFStringRef            companionPrefsID
+                                       )       SPI_AVAILABLE(macos(10.15.4), ios(13.4), tvos(13.4), watchos(6.2), bridgeos(4.0));
+
 /*!
        @function SCPreferencesCreateWithOptions
        @discussion Initiates access to the per-system set of configuration
 /*!
        @function SCPreferencesCreateWithOptions
        @discussion Initiates access to the per-system set of configuration
index f9bf278522bd5aeebb9103d744a1391121fa2874..b721acd795e5db8e34204d614abbdb0a3bc83ed0 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2019 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -106,7 +106,8 @@ extern int  _sc_debug;      /* non-zero if debugging enabled */
 extern int     _sc_verbose;    /* non-zero if verbose logging enabled */
 extern int     _sc_log;        /* 0 if SC messages should be written to stdout/stderr,
                                   1 if SC messages should be logged w/os_log(3),
 extern int     _sc_verbose;    /* non-zero if verbose logging enabled */
 extern int     _sc_log;        /* 0 if SC messages should be written to stdout/stderr,
                                   1 if SC messages should be logged w/os_log(3),
-                                  2 if SC messages should be written to stdout/stderr AND logged */
+                                  2 if SC messages should be logged AND written to stdout/stderr
+                                  3 if SC messages should be logged AND written to stdout/stderr (w/o timestamp) */
 
 
 /* notify(3) keys */
 
 
 /* notify(3) keys */
@@ -767,6 +768,9 @@ _SC_dos_encoding_and_codepage                       (CFStringEncoding       macEncoding,
 #pragma mark Bundle
 
 
 #pragma mark Bundle
 
 
+CFStringRef
+_SC_getApplicationBundleID                                     (void);
+
 /*
  * bundle access
  */
 /*
  * bundle access
  */
index ebb53abd50111825567404ae05c754c5d7adfd0c..3d3ee59a847b2c8f9263b4058c615f035d225b3b 100644 (file)
@@ -19,6 +19,7 @@ const CFStringRef kSCPrefCurrentSet                                = CFSTR("Curr
 const CFStringRef kSCPrefNetworkServices                           = CFSTR("NetworkServices");
 const CFStringRef kSCPrefSets                                      = CFSTR("Sets");
 const CFStringRef kSCPrefSystem                                    = CFSTR("System");
 const CFStringRef kSCPrefNetworkServices                           = CFSTR("NetworkServices");
 const CFStringRef kSCPrefSets                                      = CFSTR("Sets");
 const CFStringRef kSCPrefSystem                                    = CFSTR("System");
+const CFStringRef kSCPrefVersion                                   = CFSTR("__VERSION__");
 const CFStringRef kSCPrefVirtualNetworkInterfaces                  = CFSTR("VirtualNetworkInterfaces");
 const CFStringRef kSCCompNetwork                                   = CFSTR("Network");
 const CFStringRef kSCCompService                                   = CFSTR("Service");
 const CFStringRef kSCPrefVirtualNetworkInterfaces                  = CFSTR("VirtualNetworkInterfaces");
 const CFStringRef kSCCompNetwork                                   = CFSTR("Network");
 const CFStringRef kSCCompService                                   = CFSTR("Service");
index 94d61c985e110c8a5f713fb77fd354d11d440c43..012652a569f713e25dec163063b54dff4c51d58d 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2019 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
index 35b00fd02853e06c2c683abba585aa6cd93acfb2..ad84324bc137ddd6c05f8b9917b429ac8048120b 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2019 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -35,6 +35,7 @@
  *
  * Preference Keys
  *
  *
  * Preference Keys
  *
+ *   kSCPrefVersion                                     "__VERSION__"                  CFString
  *   kSCPrefVirtualNetworkInterfaces                    "VirtualNetworkInterfaces"     CFDictionary
  *
  * Network Entity Keys
  *   kSCPrefVirtualNetworkInterfaces                    "VirtualNetworkInterfaces"     CFDictionary
  *
  * Network Entity Keys
@@ -355,6 +356,13 @@ extern const CFStringRef kSCPropDisableUntilNeeded                          API_
   @group Preference Keys
  */
 
   @group Preference Keys
  */
 
+/*!
+  @const kSCPrefVersion
+  @discussion Value is a CFString
+ */
+extern const CFStringRef kSCPrefVersion                                     API_AVAILABLE(macos(10.15.4)) SPI_AVAILABLE(ios(13.4), tvos(13.4), watchos(6.2), bridgeos(4.0));
+#define kSCPrefVersion kSCPrefVersion
+
 /*!
   @const kSCPrefVirtualNetworkInterfaces
   @discussion Value is a CFDictionary
 /*!
   @const kSCPrefVirtualNetworkInterfaces
   @discussion Value is a CFDictionary
index 07ba69359172fa879ca098b7128d9ba22dad44fa..c9ed85fc9a657edf4e16b9df9bb6578b18d0ac54 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2019 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -62,7 +62,7 @@
 
 char copyright_string[] =
 "/*\n"
 
 char copyright_string[] =
 "/*\n"
-" * Copyright (c) 2000-2019 Apple Inc. All rights reserved.\n"
+" * Copyright (c) 2000-2020 Apple Inc. All rights reserved.\n"
 " *\n"
 " * @APPLE_LICENSE_HEADER_START@\n"
 " *\n"
 " *\n"
 " * @APPLE_LICENSE_HEADER_START@\n"
 " *\n"
@@ -129,6 +129,7 @@ typedef enum {
        SC_10_13_IPHONE_11_0_PRIVATE,
        SC_10_14_IPHONE_12_0_PRIVATE,
        SC_10_15_IPHONE_13_0_PRIVATE,
        SC_10_13_IPHONE_11_0_PRIVATE,
        SC_10_14_IPHONE_12_0_PRIVATE,
        SC_10_15_IPHONE_13_0_PRIVATE,
+       SC_10_15_4_IPHONE_13_4_PRIVATE,
        SC_IPHONE_2_0_PRIVATE,
        SC_IPHONE_7_0_PRIVATE,
        SC_IPHONE_8_0_PRIVATE,
        SC_IPHONE_2_0_PRIVATE,
        SC_IPHONE_7_0_PRIVATE,
        SC_IPHONE_8_0_PRIVATE,
@@ -563,6 +564,7 @@ static schemaDefinition names[] = {
 
   { GROUP_PRIVATE, PREF, "Preference Keys", NULL, NULL },
 
 
   { GROUP_PRIVATE, PREF, "Preference Keys", NULL, NULL },
 
+    { SC_10_15_4_IPHONE_13_4_PRIVATE, PREF, VERSION, "__VERSION__", CFSTRING },
     { SC_10_5_PRIVATE, PREF, VIRTUALNETWORKINTERFACES, NULL, CFDICTIONARY },
     { COMMENT_PRIVATE, "", NULL, NULL, NULL },
 
     { SC_10_5_PRIVATE, PREF, VIRTUALNETWORKINTERFACES, NULL, CFDICTIONARY },
     { COMMENT_PRIVATE, "", NULL, NULL, NULL },
 
@@ -1519,6 +1521,9 @@ print_headerdoc(schemaDefinition *def)
            case SC_10_15_IPHONE_13_0_PRIVATE:
                printf("  API_AVAILABLE(macos(10.15)) SPI_AVAILABLE(ios(13.0), tvos(13.0), watchos(6.0), bridgeos(4.0));\n");
                break;
            case SC_10_15_IPHONE_13_0_PRIVATE:
                printf("  API_AVAILABLE(macos(10.15)) SPI_AVAILABLE(ios(13.0), tvos(13.0), watchos(6.0), bridgeos(4.0));\n");
                break;
+           case SC_10_15_4_IPHONE_13_4_PRIVATE:
+               printf("  API_AVAILABLE(macos(10.15.4)) SPI_AVAILABLE(ios(13.4), tvos(13.4), watchos(6.2), bridgeos(4.0));\n");
+               break;
            case SC_IPHONE_2_0_PRIVATE:
                printf("  SPI_AVAILABLE(macos(10.6), ios(2.0), tvos(9.0), watchos(1.0), bridgeos(1.0));\n");
                break;
            case SC_IPHONE_2_0_PRIVATE:
                printf("  SPI_AVAILABLE(macos(10.6), ios(2.0), tvos(9.0), watchos(1.0), bridgeos(1.0));\n");
                break;
@@ -1707,6 +1712,7 @@ dump_names(int type)
                            case SC_10_13_IPHONE_11_0_PRIVATE:
                            case SC_10_14_IPHONE_12_0_PRIVATE:
                            case SC_10_15_IPHONE_13_0_PRIVATE:
                            case SC_10_13_IPHONE_11_0_PRIVATE:
                            case SC_10_14_IPHONE_12_0_PRIVATE:
                            case SC_10_15_IPHONE_13_0_PRIVATE:
+                           case SC_10_15_4_IPHONE_13_4_PRIVATE:
                            case SC_IPHONE_2_0_PRIVATE:
                            case SC_IPHONE_7_0_PRIVATE:
                            case SC_IPHONE_8_0_PRIVATE:
                            case SC_IPHONE_2_0_PRIVATE:
                            case SC_IPHONE_7_0_PRIVATE:
                            case SC_IPHONE_8_0_PRIVATE:
@@ -1746,6 +1752,7 @@ dump_names(int type)
                            case SC_10_13_IPHONE_11_0_PRIVATE:
                            case SC_10_14_IPHONE_12_0_PRIVATE:
                            case SC_10_15_IPHONE_13_0_PRIVATE:
                            case SC_10_13_IPHONE_11_0_PRIVATE:
                            case SC_10_14_IPHONE_12_0_PRIVATE:
                            case SC_10_15_IPHONE_13_0_PRIVATE:
+                           case SC_10_15_4_IPHONE_13_4_PRIVATE:
                            case SC_IPHONE_2_0_PRIVATE:
                            case SC_IPHONE_7_0_PRIVATE:
                            case SC_IPHONE_8_0_PRIVATE:
                            case SC_IPHONE_2_0_PRIVATE:
                            case SC_IPHONE_7_0_PRIVATE:
                            case SC_IPHONE_8_0_PRIVATE:
@@ -1776,6 +1783,7 @@ dump_names(int type)
                            case SC_10_13_IPHONE_11_0_PRIVATE:
                            case SC_10_14_IPHONE_12_0_PRIVATE:
                            case SC_10_15_IPHONE_13_0_PRIVATE:
                            case SC_10_13_IPHONE_11_0_PRIVATE:
                            case SC_10_14_IPHONE_12_0_PRIVATE:
                            case SC_10_15_IPHONE_13_0_PRIVATE:
+                           case SC_10_15_4_IPHONE_13_4_PRIVATE:
                            case SC_IPHONE_2_0_PRIVATE:
                            case SC_IPHONE_7_0_PRIVATE:
                            case SC_IPHONE_8_0_PRIVATE:
                            case SC_IPHONE_2_0_PRIVATE:
                            case SC_IPHONE_7_0_PRIVATE:
                            case SC_IPHONE_8_0_PRIVATE:
@@ -1804,6 +1812,7 @@ dump_names(int type)
                            case SC_10_13_IPHONE_11_0_PRIVATE:
                            case SC_10_14_IPHONE_12_0_PRIVATE:
                            case SC_10_15_IPHONE_13_0_PRIVATE:
                            case SC_10_13_IPHONE_11_0_PRIVATE:
                            case SC_10_14_IPHONE_12_0_PRIVATE:
                            case SC_10_15_IPHONE_13_0_PRIVATE:
+                           case SC_10_15_4_IPHONE_13_4_PRIVATE:
                            case SC_IPHONE_2_0_PRIVATE:
                            case SC_IPHONE_7_0_PRIVATE:
                            case SC_IPHONE_8_0_PRIVATE:
                            case SC_IPHONE_2_0_PRIVATE:
                            case SC_IPHONE_7_0_PRIVATE:
                            case SC_IPHONE_8_0_PRIVATE:
index 5cc8c6d17fab551dc9b9efd259bed94b49ecaf39..6d1d5045aa811c53d01544d5b3b3d703f80794c7 100644 (file)
                152439E8180399D800D91708 /* CoreWLAN.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 152439E7180399D800D91708 /* CoreWLAN.framework */; };
                152439E91805CC6C00D91708 /* ev_extra.h in Headers */ = {isa = PBXBuildFile; fileRef = 152439E318038E5B00D91708 /* ev_extra.h */; };
                152439EA1805CC8400D91708 /* ev_extra.m in Sources */ = {isa = PBXBuildFile; fileRef = 152439E418038E5B00D91708 /* ev_extra.m */; };
                152439E8180399D800D91708 /* CoreWLAN.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 152439E7180399D800D91708 /* CoreWLAN.framework */; };
                152439E91805CC6C00D91708 /* ev_extra.h in Headers */ = {isa = PBXBuildFile; fileRef = 152439E318038E5B00D91708 /* ev_extra.h */; };
                152439EA1805CC8400D91708 /* ev_extra.m in Sources */ = {isa = PBXBuildFile; fileRef = 152439E418038E5B00D91708 /* ev_extra.m */; };
+               15260A452272529F00AE1F72 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1547072E0D1F70C80075C28D /* SystemConfiguration.framework */; };
+               15260A462272533D00AE1F72 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1547072E0D1F70C80075C28D /* SystemConfiguration.framework */; };
+               15260A472272535F00AE1F72 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1559C4440D349A4E0098FD59 /* SystemConfiguration.framework */; };
                152691DB1129EEA6006BD2D5 /* BridgeConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FD7B3B101E439200C56621 /* BridgeConfiguration.c */; };
                152691DC1129EEAD006BD2D5 /* BridgeConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FD7B3B101E439200C56621 /* BridgeConfiguration.c */; };
                152691DE1129EEC2006BD2D5 /* VLANConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69B605C0722B0099E85F /* VLANConfiguration.c */; };
                152691DB1129EEA6006BD2D5 /* BridgeConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FD7B3B101E439200C56621 /* BridgeConfiguration.c */; };
                152691DC1129EEAD006BD2D5 /* BridgeConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FD7B3B101E439200C56621 /* BridgeConfiguration.c */; };
                152691DE1129EEC2006BD2D5 /* VLANConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69B605C0722B0099E85F /* VLANConfiguration.c */; };
                159A752C107FEAA400A57EAB /* VPNPrivate.c in Sources */ = {isa = PBXBuildFile; fileRef = 159A7517107FEAA400A57EAB /* VPNPrivate.c */; };
                159A752E107FEAA400A57EAB /* VPNConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 159A7519107FEAA400A57EAB /* VPNConfiguration.c */; };
                159C32B60F583724008A72EE /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1520A3DE0846B2DC0010B584 /* Security.framework */; };
                159A752C107FEAA400A57EAB /* VPNPrivate.c in Sources */ = {isa = PBXBuildFile; fileRef = 159A7517107FEAA400A57EAB /* VPNPrivate.c */; };
                159A752E107FEAA400A57EAB /* VPNConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 159A7519107FEAA400A57EAB /* VPNConfiguration.c */; };
                159C32B60F583724008A72EE /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1520A3DE0846B2DC0010B584 /* Security.framework */; };
+               159C80B0219378710004C3A6 /* SCNetworkConfigurationPrivate.c in Sources */ = {isa = PBXBuildFile; fileRef = 15D427212166F6F50082AA78 /* SCNetworkConfigurationPrivate.c */; };
+               159C80B1219378760004C3A6 /* SCNetworkConfigurationPrivate.c in Sources */ = {isa = PBXBuildFile; fileRef = 15D427212166F6F50082AA78 /* SCNetworkConfigurationPrivate.c */; };
+               159C80B2219378790004C3A6 /* SCNetworkConfigurationPrivate.c in Sources */ = {isa = PBXBuildFile; fileRef = 15D427212166F6F50082AA78 /* SCNetworkConfigurationPrivate.c */; };
                159D540D07528DAE004F8947 /* ev_dlil.c in Sources */ = {isa = PBXBuildFile; fileRef = 159D53B107528B36004F8947 /* ev_dlil.c */; };
                159D540E07528DAE004F8947 /* ev_dlil.h in Headers */ = {isa = PBXBuildFile; fileRef = 159D53B207528B36004F8947 /* ev_dlil.h */; };
                159D540F07528DB0004F8947 /* ev_ipv4.c in Sources */ = {isa = PBXBuildFile; fileRef = 159D53B307528B36004F8947 /* ev_ipv4.c */; };
                159D540D07528DAE004F8947 /* ev_dlil.c in Sources */ = {isa = PBXBuildFile; fileRef = 159D53B107528B36004F8947 /* ev_dlil.c */; };
                159D540E07528DAE004F8947 /* ev_dlil.h in Headers */ = {isa = PBXBuildFile; fileRef = 159D53B207528B36004F8947 /* ev_dlil.h */; };
                159D540F07528DB0004F8947 /* ev_ipv4.c in Sources */ = {isa = PBXBuildFile; fileRef = 159D53B307528B36004F8947 /* ev_ipv4.c */; };
                15C330D1134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */; };
                15C330D2134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */; };
                15C330D3134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */; };
                15C330D1134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */; };
                15C330D2134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */; };
                15C330D3134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */; };
+               15C7B7C7224D9A9A0040A8D0 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15C7B7C6224D9A9A0040A8D0 /* CoreFoundation.framework */; };
+               15C7B7C9224D9AA70040A8D0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15C7B7C8224D9AA70040A8D0 /* Foundation.framework */; };
+               15C7B7CB224D9AAE0040A8D0 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15C7B7CA224D9AAE0040A8D0 /* SystemConfiguration.framework */; };
                15CB8F701EE4DCFC00726685 /* network_state_information_logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 1528922C1EDE41ED00FCFE71 /* network_state_information_logging.h */; };
                15CB8F711EE4DCFF00726685 /* network_state_information_logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 1528922C1EDE41ED00FCFE71 /* network_state_information_logging.h */; };
                15CB8F721EE4DD0400726685 /* network_state_information_logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 1528922C1EDE41ED00FCFE71 /* network_state_information_logging.h */; };
                15CB8F701EE4DCFC00726685 /* network_state_information_logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 1528922C1EDE41ED00FCFE71 /* network_state_information_logging.h */; };
                15CB8F711EE4DCFF00726685 /* network_state_information_logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 1528922C1EDE41ED00FCFE71 /* network_state_information_logging.h */; };
                15CB8F721EE4DD0400726685 /* network_state_information_logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 1528922C1EDE41ED00FCFE71 /* network_state_information_logging.h */; };
                15E56C5B21939B7B00088C51 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15E56C5A21939B7B00088C51 /* Foundation.framework */; };
                15E56C5C21939B8E00088C51 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15E56C5A21939B7B00088C51 /* Foundation.framework */; };
                15E91DB721893E83001155DC /* test-objC.m in Sources */ = {isa = PBXBuildFile; fileRef = 72D3E66B1AE6EAF600DB4C69 /* test-objC.m */; };
                15E56C5B21939B7B00088C51 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15E56C5A21939B7B00088C51 /* Foundation.framework */; };
                15E56C5C21939B8E00088C51 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15E56C5A21939B7B00088C51 /* Foundation.framework */; };
                15E91DB721893E83001155DC /* test-objC.m in Sources */ = {isa = PBXBuildFile; fileRef = 72D3E66B1AE6EAF600DB4C69 /* test-objC.m */; };
-               15E91DB921893E83001155DC /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1547072E0D1F70C80075C28D /* SystemConfiguration.framework */; };
                15E91DD021893EE1001155DC /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72D3E6601AE6EA3A00DB4C69 /* main.swift */; };
                15EF899F21894452003B2C5C /* SCNetworkInterfaceProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = F90E43542012AD3900EF27C4 /* SCNetworkInterfaceProvider.h */; settings = {ATTRIBUTES = (Private, ); }; };
                15EF89A021894533003B2C5C /* SNHelperPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = B0C967F717441F0E00889853 /* SNHelperPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
                15E91DD021893EE1001155DC /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72D3E6601AE6EA3A00DB4C69 /* main.swift */; };
                15EF899F21894452003B2C5C /* SCNetworkInterfaceProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = F90E43542012AD3900EF27C4 /* SCNetworkInterfaceProvider.h */; settings = {ATTRIBUTES = (Private, ); }; };
                15EF89A021894533003B2C5C /* SNHelperPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = B0C967F717441F0E00889853 /* SNHelperPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
                15F742EA1EC638D100DA2E7A /* liblog_SystemConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 151D060D1EC14C6700E02E48 /* liblog_SystemConfiguration.m */; };
                15F742EC1EC638D100DA2E7A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 725CB7541BF439C6000C05A8 /* Foundation.framework */; };
                15F742ED1EC638D100DA2E7A /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72573D331D66800C004975AD /* SystemConfiguration.framework */; };
                15F742EA1EC638D100DA2E7A /* liblog_SystemConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 151D060D1EC14C6700E02E48 /* liblog_SystemConfiguration.m */; };
                15F742EC1EC638D100DA2E7A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 725CB7541BF439C6000C05A8 /* Foundation.framework */; };
                15F742ED1EC638D100DA2E7A /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72573D331D66800C004975AD /* SystemConfiguration.framework */; };
+               15FA163A23C6341100573B3C /* SCTestInterfaceNamer.m in Sources */ = {isa = PBXBuildFile; fileRef = 15FA163923C6341100573B3C /* SCTestInterfaceNamer.m */; };
+               15FA163D23C67A9800573B3C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15FA163C23C67A9800573B3C /* IOKit.framework */; };
+               15FA163F23C67AAF00573B3C /* Network.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15FA163E23C67AAF00573B3C /* Network.framework */; };
+               15FA164123C67AF100573B3C /* Network.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15FA163E23C67AAF00573B3C /* Network.framework */; };
                15FB1F8A1E27EA8700B4F809 /* InterfaceNamerControlPrefs.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FB1F881E27E9A000B4F809 /* InterfaceNamerControlPrefs.c */; };
                15FB1F8B1E27EA8900B4F809 /* InterfaceNamerControlPrefs.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FB1F881E27E9A000B4F809 /* InterfaceNamerControlPrefs.c */; };
                15FBB54C17D6834C0035D752 /* libCrashReporterClient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 15FBB54B17D6834C0035D752 /* libCrashReporterClient.a */; };
                15FB1F8A1E27EA8700B4F809 /* InterfaceNamerControlPrefs.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FB1F881E27E9A000B4F809 /* InterfaceNamerControlPrefs.c */; };
                15FB1F8B1E27EA8900B4F809 /* InterfaceNamerControlPrefs.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FB1F881E27E9A000B4F809 /* InterfaceNamerControlPrefs.c */; };
                15FBB54C17D6834C0035D752 /* libCrashReporterClient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 15FBB54B17D6834C0035D752 /* libCrashReporterClient.a */; };
                72573D3E1D669AA6004975AD /* SCTestPreferences.m in Sources */ = {isa = PBXBuildFile; fileRef = 72573D3D1D669AA6004975AD /* SCTestPreferences.m */; };
                72573D401D67B2BE004975AD /* SCTestUnitTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 72573D3F1D67B2BE004975AD /* SCTestUnitTest.m */; };
                72573D421D6B798A004975AD /* SCTestConfigAgents.m in Sources */ = {isa = PBXBuildFile; fileRef = 72573D411D6B7989004975AD /* SCTestConfigAgents.m */; };
                72573D3E1D669AA6004975AD /* SCTestPreferences.m in Sources */ = {isa = PBXBuildFile; fileRef = 72573D3D1D669AA6004975AD /* SCTestPreferences.m */; };
                72573D401D67B2BE004975AD /* SCTestUnitTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 72573D3F1D67B2BE004975AD /* SCTestUnitTest.m */; };
                72573D421D6B798A004975AD /* SCTestConfigAgents.m in Sources */ = {isa = PBXBuildFile; fileRef = 72573D411D6B7989004975AD /* SCTestConfigAgents.m */; };
-               72573D441D6BA051004975AD /* Network.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 728015951BE16B6C009F4F60 /* Network.framework */; };
                725CB7551BF439C6000C05A8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 725CB7541BF439C6000C05A8 /* Foundation.framework */; };
                725CB7561BF439D2000C05A8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 725CB7541BF439C6000C05A8 /* Foundation.framework */; };
                725CB7581BF514F2000C05A8 /* configAgentDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 725CB7571BF51476000C05A8 /* configAgentDefines.h */; };
                725CB7551BF439C6000C05A8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 725CB7541BF439C6000C05A8 /* Foundation.framework */; };
                725CB7561BF439D2000C05A8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 725CB7541BF439C6000C05A8 /* Foundation.framework */; };
                725CB7581BF514F2000C05A8 /* configAgentDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 725CB7571BF51476000C05A8 /* configAgentDefines.h */; };
                7271EA241D76600B0055B1AA /* SCTestConfigAgents.m in Sources */ = {isa = PBXBuildFile; fileRef = 72573D411D6B7989004975AD /* SCTestConfigAgents.m */; };
                7271EA251D76600B0055B1AA /* SCTestPreferences.m in Sources */ = {isa = PBXBuildFile; fileRef = 72573D3D1D669AA6004975AD /* SCTestPreferences.m */; };
                7271EA261D76600B0055B1AA /* SCTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 72573D2D1D6673B6004975AD /* SCTest.m */; };
                7271EA241D76600B0055B1AA /* SCTestConfigAgents.m in Sources */ = {isa = PBXBuildFile; fileRef = 72573D411D6B7989004975AD /* SCTestConfigAgents.m */; };
                7271EA251D76600B0055B1AA /* SCTestPreferences.m in Sources */ = {isa = PBXBuildFile; fileRef = 72573D3D1D669AA6004975AD /* SCTestPreferences.m */; };
                7271EA261D76600B0055B1AA /* SCTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 72573D2D1D6673B6004975AD /* SCTest.m */; };
-               7271EA291D76600B0055B1AA /* Network.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 728015951BE16B6C009F4F60 /* Network.framework */; };
                7271EA2A1D76600B0055B1AA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72573D331D66800C004975AD /* SystemConfiguration.framework */; };
                7271EA2B1D76600B0055B1AA /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 728015961BE16B6C009F4F60 /* NetworkExtension.framework */; };
                7271EA2D1D76600B0055B1AA /* npt_configd.plist in npt_configd.plist */ = {isa = PBXBuildFile; fileRef = 72C12CAA1D6E9ED4000EE61C /* npt_configd.plist */; };
                7271EA2A1D76600B0055B1AA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72573D331D66800C004975AD /* SystemConfiguration.framework */; };
                7271EA2B1D76600B0055B1AA /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 728015961BE16B6C009F4F60 /* NetworkExtension.framework */; };
                7271EA2D1D76600B0055B1AA /* npt_configd.plist in npt_configd.plist */ = {isa = PBXBuildFile; fileRef = 72C12CAA1D6E9ED4000EE61C /* npt_configd.plist */; };
                151D060D1EC14C6700E02E48 /* liblog_SystemConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = liblog_SystemConfiguration.m; path = logging/liblog_SystemConfiguration.m; sourceTree = SOURCE_ROOT; };
                151F5D9A0CCE98E50093AC3B /* SCMonitor.plugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SCMonitor.plugin; sourceTree = BUILT_PRODUCTS_DIR; };
                151F63EC09328A3C0096DCC9 /* genSCPreferences */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = genSCPreferences; sourceTree = BUILT_PRODUCTS_DIR; };
                151D060D1EC14C6700E02E48 /* liblog_SystemConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = liblog_SystemConfiguration.m; path = logging/liblog_SystemConfiguration.m; sourceTree = SOURCE_ROOT; };
                151F5D9A0CCE98E50093AC3B /* SCMonitor.plugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SCMonitor.plugin; sourceTree = BUILT_PRODUCTS_DIR; };
                151F63EC09328A3C0096DCC9 /* genSCPreferences */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = genSCPreferences; sourceTree = BUILT_PRODUCTS_DIR; };
-               1520A3DE0846B2DC0010B584 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = /System/Library/Frameworks/Security.framework; sourceTree = "<absolute>"; };
+               1520A3DE0846B2DC0010B584 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
                1521FC5C060F296A003B28F5 /* dnsinfo_create.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dnsinfo_create.c; path = dnsinfo/dnsinfo_create.c; sourceTree = SOURCE_ROOT; };
                1522FCE50FA7FD7000B24128 /* dnsinfo_flatfile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = dnsinfo_flatfile.c; path = dnsinfo/dnsinfo_flatfile.c; sourceTree = "<group>"; };
                152439E318038E5B00D91708 /* ev_extra.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ev_extra.h; sourceTree = "<group>"; };
                152439E418038E5B00D91708 /* ev_extra.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ev_extra.m; sourceTree = "<group>"; };
                1521FC5C060F296A003B28F5 /* dnsinfo_create.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dnsinfo_create.c; path = dnsinfo/dnsinfo_create.c; sourceTree = SOURCE_ROOT; };
                1522FCE50FA7FD7000B24128 /* dnsinfo_flatfile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = dnsinfo_flatfile.c; path = dnsinfo/dnsinfo_flatfile.c; sourceTree = "<group>"; };
                152439E318038E5B00D91708 /* ev_extra.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ev_extra.h; sourceTree = "<group>"; };
                152439E418038E5B00D91708 /* ev_extra.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ev_extra.m; sourceTree = "<group>"; };
-               152439E7180399D800D91708 /* CoreWLAN.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreWLAN.framework; path = /System/Library/Frameworks/CoreWLAN.framework; sourceTree = "<absolute>"; };
+               152439E7180399D800D91708 /* CoreWLAN.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreWLAN.framework; path = System/Library/Frameworks/CoreWLAN.framework; sourceTree = SDKROOT; };
                152439EB180716ED00D91708 /* MobileWiFi.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileWiFi.framework; path = System/Library/PrivateFrameworks/MobileWiFi.framework; sourceTree = SDKROOT; };
                1524FE1920619BAF0010091E /* Info-Embedded.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "Info-Embedded.plist"; path = "Plugins/QoSMarking/Info-Embedded.plist"; sourceTree = "<group>"; };
                1528922C1EDE41ED00FCFE71 /* network_state_information_logging.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = network_state_information_logging.h; path = nwi/network_state_information_logging.h; sourceTree = "<group>"; };
                152439EB180716ED00D91708 /* MobileWiFi.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileWiFi.framework; path = System/Library/PrivateFrameworks/MobileWiFi.framework; sourceTree = SDKROOT; };
                1524FE1920619BAF0010091E /* Info-Embedded.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "Info-Embedded.plist"; path = "Plugins/QoSMarking/Info-Embedded.plist"; sourceTree = "<group>"; };
                1528922C1EDE41ED00FCFE71 /* network_state_information_logging.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = network_state_information_logging.h; path = nwi/network_state_information_logging.h; sourceTree = "<group>"; };
                15436251218AA22800283462 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = SCMonitor/en.lproj/Localizable.strings; sourceTree = "<group>"; };
                15436253218AA26100283462 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
                15436255218AA27400283462 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/NetworkInterface.strings; sourceTree = "<group>"; };
                15436251218AA22800283462 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = SCMonitor/en.lproj/Localizable.strings; sourceTree = "<group>"; };
                15436253218AA26100283462 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
                15436255218AA27400283462 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/NetworkInterface.strings; sourceTree = "<group>"; };
-               1543636A0752D03C00A8EC6C /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = "<absolute>"; };
+               1543636A0752D03C00A8EC6C /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
                1547001D08455B98006787CE /* SCHelper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = SCHelper; sourceTree = BUILT_PRODUCTS_DIR; };
                1547072E0D1F70C80075C28D /* SystemConfiguration.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SystemConfiguration.framework; sourceTree = BUILT_PRODUCTS_DIR; };
                154CF3F307E1EA4D00D8302E /* SCPreferencesGetSpecificPrivate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCPreferencesGetSpecificPrivate.h; sourceTree = "<group>"; };
                1547001D08455B98006787CE /* SCHelper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = SCHelper; sourceTree = BUILT_PRODUCTS_DIR; };
                1547072E0D1F70C80075C28D /* SystemConfiguration.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SystemConfiguration.framework; sourceTree = BUILT_PRODUCTS_DIR; };
                154CF3F307E1EA4D00D8302E /* SCPreferencesGetSpecificPrivate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCPreferencesGetSpecificPrivate.h; sourceTree = "<group>"; };
                15B73F0C05FD1B670096477F /* dnsinfo_private.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dnsinfo_private.h; path = dnsinfo/dnsinfo_private.h; sourceTree = "<group>"; };
                15B73F0D05FD1B670096477F /* dnsinfo_server.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dnsinfo_server.c; path = dnsinfo/dnsinfo_server.c; sourceTree = "<group>"; };
                15B73F0E05FD1B670096477F /* dnsinfo_server.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dnsinfo_server.h; path = dnsinfo/dnsinfo_server.h; sourceTree = "<group>"; };
                15B73F0C05FD1B670096477F /* dnsinfo_private.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dnsinfo_private.h; path = dnsinfo/dnsinfo_private.h; sourceTree = "<group>"; };
                15B73F0D05FD1B670096477F /* dnsinfo_server.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dnsinfo_server.c; path = dnsinfo/dnsinfo_server.c; sourceTree = "<group>"; };
                15B73F0E05FD1B670096477F /* dnsinfo_server.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dnsinfo_server.h; path = dnsinfo/dnsinfo_server.h; sourceTree = "<group>"; };
+               15B9C0AF2232202200C8FF86 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
+               15B9C0B42232224A00C8FF86 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
                15BAA32207F0699A00D9EC95 /* libbsm.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbsm.dylib; path = /usr/lib/libbsm.dylib; sourceTree = "<absolute>"; };
                15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCNetworkReachabilityInternal.h; sourceTree = "<group>"; };
                15BAA32207F0699A00D9EC95 /* libbsm.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbsm.dylib; path = /usr/lib/libbsm.dylib; sourceTree = "<absolute>"; };
                15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCNetworkReachabilityInternal.h; sourceTree = "<group>"; };
+               15C7B7C6224D9A9A0040A8D0 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
+               15C7B7C8224D9AA70040A8D0 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+               15C7B7CA224D9AAE0040A8D0 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
                15CB691305C0722B0099E85F /* SystemConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SystemConfiguration.h; sourceTree = "<group>"; };
                15CB691505C0722B0099E85F /* SCPrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SCPrivate.h; sourceTree = "<group>"; };
                15CB691705C0722B0099E85F /* SCDPlugin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SCDPlugin.h; sourceTree = "<group>"; };
                15CB691305C0722B0099E85F /* SystemConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SystemConfiguration.h; sourceTree = "<group>"; };
                15CB691505C0722B0099E85F /* SCPrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SCPrivate.h; sourceTree = "<group>"; };
                15CB691705C0722B0099E85F /* SCDPlugin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SCDPlugin.h; sourceTree = "<group>"; };
                15CB6A6005C0722B0099E85F /* tests.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = tests.c; sourceTree = "<group>"; };
                15CB6A6205C0722B0099E85F /* prefs.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = prefs.c; sourceTree = "<group>"; };
                15CB6A6A05C0722B0099E85F /* scutil.8 */ = {isa = PBXFileReference; explicitFileType = text.man; path = scutil.8; sourceTree = "<group>"; };
                15CB6A6005C0722B0099E85F /* tests.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = tests.c; sourceTree = "<group>"; };
                15CB6A6205C0722B0099E85F /* prefs.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = prefs.c; sourceTree = "<group>"; };
                15CB6A6A05C0722B0099E85F /* scutil.8 */ = {isa = PBXFileReference; explicitFileType = text.man; path = scutil.8; sourceTree = "<group>"; };
-               15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
+               15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
                15CFC229068B222F00123568 /* get-mobility-info */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.sh; path = "get-mobility-info"; sourceTree = SOURCE_ROOT; };
                15D3082716F3E4DA00014F82 /* libSimulatorSupport_sim.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSimulatorSupport_sim.a; sourceTree = BUILT_PRODUCTS_DIR; };
                15D3082D16F3E4E100014F82 /* SimulatorSupport.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SimulatorSupport.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
                15D3083616F3EB7200014F82 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Plugins/SimulatorSupport/Info.plist; sourceTree = "<group>"; };
                15D3083816F3EB8600014F82 /* simulator_support.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = simulator_support.c; path = Plugins/SimulatorSupport/simulator_support.c; sourceTree = "<group>"; };
                15D3083A16F4E6D900014F82 /* com.apple.configd_sim.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.configd_sim.plist; sourceTree = "<group>"; };
                15CFC229068B222F00123568 /* get-mobility-info */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.sh; path = "get-mobility-info"; sourceTree = SOURCE_ROOT; };
                15D3082716F3E4DA00014F82 /* libSimulatorSupport_sim.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSimulatorSupport_sim.a; sourceTree = BUILT_PRODUCTS_DIR; };
                15D3082D16F3E4E100014F82 /* SimulatorSupport.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SimulatorSupport.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
                15D3083616F3EB7200014F82 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Plugins/SimulatorSupport/Info.plist; sourceTree = "<group>"; };
                15D3083816F3EB8600014F82 /* simulator_support.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = simulator_support.c; path = Plugins/SimulatorSupport/simulator_support.c; sourceTree = "<group>"; };
                15D3083A16F4E6D900014F82 /* com.apple.configd_sim.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.configd_sim.plist; sourceTree = "<group>"; };
+               15D427212166F6F50082AA78 /* SCNetworkConfigurationPrivate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SCNetworkConfigurationPrivate.c; sourceTree = "<group>"; };
                15D8B2291450D8450090CECF /* SCD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCD.h; sourceTree = "<group>"; };
                15D92B9A1FFC5FA500DF2632 /* libnetwork.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libnetwork.tbd; path = usr/lib/libnetwork.tbd; sourceTree = SDKROOT; };
                15D92B9D1FFC61F400DF2632 /* libnetwork.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libnetwork.tbd; path = usr/lib/libnetwork.tbd; sourceTree = SDKROOT; };
                15D8B2291450D8450090CECF /* SCD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCD.h; sourceTree = "<group>"; };
                15D92B9A1FFC5FA500DF2632 /* libnetwork.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libnetwork.tbd; path = usr/lib/libnetwork.tbd; sourceTree = SDKROOT; };
                15D92B9D1FFC61F400DF2632 /* libnetwork.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libnetwork.tbd; path = usr/lib/libnetwork.tbd; sourceTree = SDKROOT; };
                15DC346E0711D49400A3311C /* net_set.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = net_set.h; sourceTree = "<group>"; };
                15E1B05916EBAE3C00E5F06F /* libIPMonitor_sim.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libIPMonitor_sim.a; sourceTree = BUILT_PRODUCTS_DIR; };
                15E1B06116EBAE7800E5F06F /* IPMonitor.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IPMonitor.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
                15DC346E0711D49400A3311C /* net_set.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = net_set.h; sourceTree = "<group>"; };
                15E1B05916EBAE3C00E5F06F /* libIPMonitor_sim.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libIPMonitor_sim.a; sourceTree = BUILT_PRODUCTS_DIR; };
                15E1B06116EBAE7800E5F06F /* IPMonitor.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IPMonitor.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
-               15E56C5A21939B7B00088C51 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
+               15E56C5A21939B7B00088C51 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
                15E91DBE21893E83001155DC /* SCTest-ObjC-Embedded */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "SCTest-ObjC-Embedded"; sourceTree = BUILT_PRODUCTS_DIR; };
                15E91DD621893EE1001155DC /* SCTest-Swift-Embedded */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "SCTest-Swift-Embedded"; sourceTree = BUILT_PRODUCTS_DIR; };
                15EF89B121894636003B2C5C /* SCTest-ObjC-EmbeddedSimulator */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "SCTest-ObjC-EmbeddedSimulator"; sourceTree = BUILT_PRODUCTS_DIR; };
                15E91DBE21893E83001155DC /* SCTest-ObjC-Embedded */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "SCTest-ObjC-Embedded"; sourceTree = BUILT_PRODUCTS_DIR; };
                15E91DD621893EE1001155DC /* SCTest-Swift-Embedded */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "SCTest-Swift-Embedded"; sourceTree = BUILT_PRODUCTS_DIR; };
                15EF89B121894636003B2C5C /* SCTest-ObjC-EmbeddedSimulator */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "SCTest-ObjC-EmbeddedSimulator"; sourceTree = BUILT_PRODUCTS_DIR; };
                15F742F11EC638D100DA2E7A /* liblog_SystemConfiguration.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = liblog_SystemConfiguration.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
                15FA0F73203A379600C7702F /* EventFactory.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = EventFactory.framework; sourceTree = "<group>"; };
                15FA0F74203A390E00C7702F /* EventFactory.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = EventFactory.framework; path = System/Library/PrivateFrameworks/EventFactory.framework; sourceTree = SDKROOT; };
                15F742F11EC638D100DA2E7A /* liblog_SystemConfiguration.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = liblog_SystemConfiguration.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
                15FA0F73203A379600C7702F /* EventFactory.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = EventFactory.framework; sourceTree = "<group>"; };
                15FA0F74203A390E00C7702F /* EventFactory.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = EventFactory.framework; path = System/Library/PrivateFrameworks/EventFactory.framework; sourceTree = SDKROOT; };
+               15FA163923C6341100573B3C /* SCTestInterfaceNamer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCTestInterfaceNamer.m; sourceTree = "<group>"; };
+               15FA163C23C67A9800573B3C /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
+               15FA163E23C67AAF00573B3C /* Network.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Network.framework; path = System/Library/Frameworks/Network.framework; sourceTree = SDKROOT; };
                15FB1F881E27E9A000B4F809 /* InterfaceNamerControlPrefs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = InterfaceNamerControlPrefs.c; sourceTree = "<group>"; };
                15FB1F891E27E9A000B4F809 /* InterfaceNamerControlPrefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InterfaceNamerControlPrefs.h; sourceTree = "<group>"; };
                15FBB54B17D6834C0035D752 /* libCrashReporterClient.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libCrashReporterClient.a; path = /usr/local/lib/libCrashReporterClient.a; sourceTree = "<absolute>"; };
                15FB1F881E27E9A000B4F809 /* InterfaceNamerControlPrefs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = InterfaceNamerControlPrefs.c; sourceTree = "<group>"; };
                15FB1F891E27E9A000B4F809 /* InterfaceNamerControlPrefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InterfaceNamerControlPrefs.h; sourceTree = "<group>"; };
                15FBB54B17D6834C0035D752 /* libCrashReporterClient.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libCrashReporterClient.a; path = /usr/local/lib/libCrashReporterClient.a; sourceTree = "<absolute>"; };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               15703B2A22320A940018D2EE /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               15C7B7C7224D9A9A0040A8D0 /* CoreFoundation.framework in Frameworks */,
+                               15C7B7C9224D9AA70040A8D0 /* Foundation.framework in Frameworks */,
+                               15C7B7CB224D9AAE0040A8D0 /* SystemConfiguration.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                1572C5230CFB55B400E2776E /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                1572C5230CFB55B400E2776E /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
-                               15E91DB921893E83001155DC /* SystemConfiguration.framework in Frameworks */,
+                               15260A452272529F00AE1F72 /* SystemConfiguration.framework in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        buildActionMask = 2147483647;
                        files = (
                                15E56C5B21939B7B00088C51 /* Foundation.framework in Frameworks */,
                        buildActionMask = 2147483647;
                        files = (
                                15E56C5B21939B7B00088C51 /* Foundation.framework in Frameworks */,
+                               15260A462272533D00AE1F72 /* SystemConfiguration.framework in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
-                               72573D441D6BA051004975AD /* Network.framework in Frameworks */,
-                               72573D351D6680AA004975AD /* SystemConfiguration.framework in Frameworks */,
+                               15FA163D23C67A9800573B3C /* IOKit.framework in Frameworks */,
+                               15FA163F23C67AAF00573B3C /* Network.framework in Frameworks */,
                                728E0E971D70348D00E0613A /* NetworkExtension.framework in Frameworks */,
                                728E0E971D70348D00E0613A /* NetworkExtension.framework in Frameworks */,
+                               72573D351D6680AA004975AD /* SystemConfiguration.framework in Frameworks */,
                                15D92B9F1FFC640200DF2632 /* libnetwork.tbd in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                                15D92B9F1FFC640200DF2632 /* libnetwork.tbd in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
-                               7271EA291D76600B0055B1AA /* Network.framework in Frameworks */,
-                               7271EA2A1D76600B0055B1AA /* SystemConfiguration.framework in Frameworks */,
+                               15FA164123C67AF100573B3C /* Network.framework in Frameworks */,
                                7271EA2B1D76600B0055B1AA /* NetworkExtension.framework in Frameworks */,
                                7271EA2B1D76600B0055B1AA /* NetworkExtension.framework in Frameworks */,
+                               7271EA2A1D76600B0055B1AA /* SystemConfiguration.framework in Frameworks */,
                                15D92BA11FFC641500DF2632 /* libnetwork.tbd in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                                15D92BA11FFC641500DF2632 /* libnetwork.tbd in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        buildActionMask = 2147483647;
                        files = (
                                15E56C5921939B6400088C51 /* Foundation.framework in Frameworks */,
                        buildActionMask = 2147483647;
                        files = (
                                15E56C5921939B6400088C51 /* Foundation.framework in Frameworks */,
+                               15260A472272535F00AE1F72 /* SystemConfiguration.framework in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        isa = PBXGroup;
                        children = (
                                15AD7A380670A85900BFE03C /* SCNetworkConfiguration.h */,
                        isa = PBXGroup;
                        children = (
                                15AD7A380670A85900BFE03C /* SCNetworkConfiguration.h */,
-                               155A1E6B081079CC00F70D98 /* SCNetworkConfigurationPrivate.h */,
                                15AD7A3A0670A85900BFE03C /* SCNetworkConfigurationInternal.h */,
                                15AD7A3A0670A85900BFE03C /* SCNetworkConfigurationInternal.h */,
+                               155A1E6B081079CC00F70D98 /* SCNetworkConfigurationPrivate.h */,
                        );
                        name = Headers;
                        sourceTree = "<group>";
                        );
                        name = Headers;
                        sourceTree = "<group>";
                        isa = PBXGroup;
                        children = (
                                15AD7A390670A85900BFE03C /* SCNetworkConfigurationInternal.c */,
                        isa = PBXGroup;
                        children = (
                                15AD7A390670A85900BFE03C /* SCNetworkConfigurationInternal.c */,
+                               15D427212166F6F50082AA78 /* SCNetworkConfigurationPrivate.c */,
                                15AD7A3B0670A85900BFE03C /* SCNetworkInterface.c */,
                                15AD7A3C0670A85900BFE03C /* SCNetworkProtocol.c */,
                                15AD7A3D0670A85900BFE03C /* SCNetworkService.c */,
                                15AD7A3B0670A85900BFE03C /* SCNetworkInterface.c */,
                                15AD7A3C0670A85900BFE03C /* SCNetworkProtocol.c */,
                                15AD7A3D0670A85900BFE03C /* SCNetworkService.c */,
                                72573D3D1D669AA6004975AD /* SCTestPreferences.m */,
                                72573D411D6B7989004975AD /* SCTestConfigAgents.m */,
                                728E0E951D70229A00E0613A /* SCTestReachability.m */,
                                72573D3D1D669AA6004975AD /* SCTestPreferences.m */,
                                72573D411D6B7989004975AD /* SCTestConfigAgents.m */,
                                728E0E951D70229A00E0613A /* SCTestReachability.m */,
+                               15FA163923C6341100573B3C /* SCTestInterfaceNamer.m */,
                                72573D3F1D67B2BE004975AD /* SCTestUnitTest.m */,
                                72573D431D6B9E72004975AD /* sctest-entitlements.plist */,
                                72C12CAA1D6E9ED4000EE61C /* npt_configd.plist */,
                                72573D3F1D67B2BE004975AD /* SCTestUnitTest.m */,
                                72573D431D6B9E72004975AD /* sctest-entitlements.plist */,
                                72C12CAA1D6E9ED4000EE61C /* npt_configd.plist */,
                90507AAE1CE2F55B0067D16B /* Frameworks */ = {
                        isa = PBXGroup;
                        children = (
                90507AAE1CE2F55B0067D16B /* Frameworks */ = {
                        isa = PBXGroup;
                        children = (
+                               15FA163E23C67AAF00573B3C /* Network.framework */,
+                               15FA163C23C67A9800573B3C /* IOKit.framework */,
+                               15C7B7CA224D9AAE0040A8D0 /* SystemConfiguration.framework */,
+                               15C7B7C8224D9AA70040A8D0 /* Foundation.framework */,
+                               15C7B7C6224D9A9A0040A8D0 /* CoreFoundation.framework */,
+                               15B9C0B42232224A00C8FF86 /* Foundation.framework */,
+                               15B9C0AF2232202200C8FF86 /* SystemConfiguration.framework */,
                                15E56C5A21939B7B00088C51 /* Foundation.framework */,
                                F9D7305020E41DD500521181 /* WirelessDiagnostics.framework */,
                                F9D7304E20E41D9C00521181 /* ProtocolBuffer.framework */,
                                15E56C5A21939B7B00088C51 /* Foundation.framework */,
                                F9D7305020E41DD500521181 /* WirelessDiagnostics.framework */,
                                F9D7304E20E41D9C00521181 /* ProtocolBuffer.framework */,
                                B0C9689D174426D100889853 /* SNHelper.c in Sources */,
                                1572C4FC0CFB55B400E2776E /* SCPUnlock.c in Sources */,
                                1572C4FD0CFB55B400E2776E /* SCPList.c in Sources */,
                                B0C9689D174426D100889853 /* SNHelper.c in Sources */,
                                1572C4FC0CFB55B400E2776E /* SCPUnlock.c in Sources */,
                                1572C4FD0CFB55B400E2776E /* SCPList.c in Sources */,
+                               159C80B1219378760004C3A6 /* SCNetworkConfigurationPrivate.c in Sources */,
                                1572C4FE0CFB55B400E2776E /* SCPGet.c in Sources */,
                                1572C4FF0CFB55B400E2776E /* SCPAdd.c in Sources */,
                                1572C5000CFB55B400E2776E /* SCPSet.c in Sources */,
                                1572C4FE0CFB55B400E2776E /* SCPGet.c in Sources */,
                                1572C4FF0CFB55B400E2776E /* SCPAdd.c in Sources */,
                                1572C5000CFB55B400E2776E /* SCPSet.c in Sources */,
                                15A5A2390D5B94190087BDA0 /* SCPOpen.c in Sources */,
                                15A5A23A0D5B94190087BDA0 /* SCPLock.c in Sources */,
                                15A5A23B0D5B94190087BDA0 /* SCPUnlock.c in Sources */,
                                15A5A2390D5B94190087BDA0 /* SCPOpen.c in Sources */,
                                15A5A23A0D5B94190087BDA0 /* SCPLock.c in Sources */,
                                15A5A23B0D5B94190087BDA0 /* SCPUnlock.c in Sources */,
+                               159C80B2219378790004C3A6 /* SCNetworkConfigurationPrivate.c in Sources */,
                                15A5A23C0D5B94190087BDA0 /* SCPList.c in Sources */,
                                15A5A23D0D5B94190087BDA0 /* SCPGet.c in Sources */,
                                15A5A23E0D5B94190087BDA0 /* SCPAdd.c in Sources */,
                                15A5A23C0D5B94190087BDA0 /* SCPList.c in Sources */,
                                15A5A23D0D5B94190087BDA0 /* SCPGet.c in Sources */,
                                15A5A23E0D5B94190087BDA0 /* SCPAdd.c in Sources */,
                                15DAD67C07591A1A0084A6ED /* SCDNotifierAdd.c in Sources */,
                                15DAD67D07591A1A0084A6ED /* SCDNotifierRemove.c in Sources */,
                                F9B7AE641862119300C78D18 /* IPMonitorControl.c in Sources */,
                                15DAD67C07591A1A0084A6ED /* SCDNotifierAdd.c in Sources */,
                                15DAD67D07591A1A0084A6ED /* SCDNotifierRemove.c in Sources */,
                                F9B7AE641862119300C78D18 /* IPMonitorControl.c in Sources */,
+                               159C80B0219378710004C3A6 /* SCNetworkConfigurationPrivate.c in Sources */,
                                15DAD67E07591A1A0084A6ED /* SCDNotifierGetChanges.c in Sources */,
                                15DAD67F07591A1A0084A6ED /* SCDNotifierWait.c in Sources */,
                                15DAD68007591A1A0084A6ED /* SCDNotifierInformViaCallback.c in Sources */,
                                15DAD67E07591A1A0084A6ED /* SCDNotifierGetChanges.c in Sources */,
                                15DAD67F07591A1A0084A6ED /* SCDNotifierWait.c in Sources */,
                                15DAD68007591A1A0084A6ED /* SCDNotifierInformViaCallback.c in Sources */,
                                728E0E961D70229A00E0613A /* SCTestReachability.m in Sources */,
                                72573D291D667372004975AD /* main.m in Sources */,
                                72573D421D6B798A004975AD /* SCTestConfigAgents.m in Sources */,
                                728E0E961D70229A00E0613A /* SCTestReachability.m in Sources */,
                                72573D291D667372004975AD /* main.m in Sources */,
                                72573D421D6B798A004975AD /* SCTestConfigAgents.m in Sources */,
+                               15FA163A23C6341100573B3C /* SCTestInterfaceNamer.m in Sources */,
                                72573D3E1D669AA6004975AD /* SCTestPreferences.m in Sources */,
                                72573D2E1D6673B6004975AD /* SCTest.m in Sources */,
                        );
                                72573D3E1D669AA6004975AD /* SCTestPreferences.m in Sources */,
                                72573D2E1D6673B6004975AD /* SCTest.m in Sources */,
                        );
diff --git a/sctest/SCTestInterfaceNamer.m b/sctest/SCTestInterfaceNamer.m
new file mode 100644 (file)
index 0000000..bbf42ff
--- /dev/null
@@ -0,0 +1,556 @@
+/*
+ * Copyright (c) 2020 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,
+ * 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@
+ */
+
+#import "SCTest.h"
+#import "SCTestUtils.h"
+
+#include <net/ethernet.h>
+#include <IOKit/IOKitLib.h>
+#include <IOKit/IOBSD.h>
+#include <IOKit/network/IONetworkController.h>
+#include <IOKit/network/IOUserEthernetController.h>
+#include <IOKit/storage/IOStorageDeviceCharacteristics.h>
+#include <IOKit/usb/USB.h>
+
+#define        INTERFACES_KEY                  @"State:/Network/Interface"
+#define        PLUGIN_INTERFACE_NAMER_KEY      @"Plugin:InterfaceNamer"
+
+#define        WAIT_TIME                       (30 * NSEC_PER_SEC)
+
+
+@interface SCTestInterfaceNamer : SCTest
+@property NSArray              *interfaces_all;
+@property NSArray              *interfaces_preconfigured;
+@property dispatch_queue_t     queue;
+@property dispatch_semaphore_t sem_interfaces_all;
+@property dispatch_semaphore_t sem_interfaces_preconfigured;
+@property SCDynamicStoreRef    store;
+@end
+
+@implementation SCTestInterfaceNamer
+
++ (NSString *)command
+{
+       return @"InterfaceNamer";
+}
+
++ (NSString *)commandDescription
+{
+       return @"Tests the InterfaceNamer.bundle code paths";
+}
+
+static void
+storeCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info)
+{
+       @autoreleasepool {
+               NSDictionary            *dict;
+               NSArray                 *interfaces;
+               SCTestInterfaceNamer    *test   = (__bridge SCTestInterfaceNamer *)info;
+
+               if ([(__bridge NSArray *)changedKeys containsObject:INTERFACES_KEY]) {
+                       // copy list of interfaces
+                       dict = (__bridge_transfer NSDictionary *)SCDynamicStoreCopyValue(store, (CFStringRef)INTERFACES_KEY);
+                       interfaces = [dict objectForKey:(__bridge NSString *)kSCPropNetInterfaces];
+                       if (!_SC_CFEqual((__bridge CFArrayRef)interfaces, (__bridge CFArrayRef)test.interfaces_all)) {
+                               test.interfaces_all = interfaces;
+                               dispatch_semaphore_signal(test.sem_interfaces_all);
+                       }
+               }
+
+               if ([(__bridge NSArray *)changedKeys containsObject:PLUGIN_INTERFACE_NAMER_KEY]) {
+                       // copy list of [pre-configured] interfaces
+                       dict = (__bridge_transfer NSDictionary *)SCDynamicStoreCopyValue(store, (CFStringRef)PLUGIN_INTERFACE_NAMER_KEY);
+                       interfaces = [dict objectForKey:@"_PreConfigured_"];
+                       if (!_SC_CFEqual((__bridge CFArrayRef)interfaces, (__bridge CFArrayRef)test.interfaces_preconfigured)) {
+                               test.interfaces_preconfigured = interfaces;
+                               dispatch_semaphore_signal(test.sem_interfaces_preconfigured);
+                       }
+               }
+       }
+
+       return;
+}
+
+- (instancetype)initWithOptions:(NSDictionary *)options
+{
+       self = [super initWithOptions:options];
+//     if (self) {
+//     }
+       return self;
+}
+
+- (void)dealloc
+{
+       [self watchForChanges:FALSE];
+}
+
+- (void)start
+{
+       [self cleanupAndExitWithErrorCode:0];
+}
+
+- (void)cleanupAndExitWithErrorCode:(int)error
+{
+       [super cleanupAndExitWithErrorCode:error];
+}
+
+- (BOOL)setup
+{
+       return YES;
+}
+
+- (BOOL)unitTest
+{
+       if(![self setup]) {
+               return NO;
+       }
+
+       BOOL allUnitTestsPassed = YES;
+       allUnitTestsPassed &= [self unitTestInsertRemoveOneInterface];
+
+       if(![self tearDown]) {
+               return NO;
+       }
+
+       return allUnitTestsPassed;
+}
+
+- (BOOL)tearDown
+{
+       return YES;
+}
+
+- (void)watchForChanges:(BOOL)enable
+{
+       if (enable) {
+               SCDynamicStoreContext   context = {0, NULL, CFRetain, CFRelease, NULL};
+               Boolean                 ok;
+
+               self.queue = dispatch_queue_create("SCTestInterfaceNamer callback queue", NULL);
+
+               self.sem_interfaces_all = dispatch_semaphore_create(0);
+
+               self.sem_interfaces_preconfigured = dispatch_semaphore_create(0);
+
+               context.info = (__bridge void * _Nullable)self;
+               self.store = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("SCTest"), storeCallback, &context);
+
+               ok = SCDynamicStoreSetNotificationKeys(self.store,
+                                                      (__bridge CFArrayRef)@[INTERFACES_KEY,
+                                                                             PLUGIN_INTERFACE_NAMER_KEY],
+                                                      NULL);
+               assert(ok);
+
+               ok = SCDynamicStoreSetDispatchQueue(self.store, self.queue);
+               assert(ok);
+       } else {
+               if (self.store != NULL) {
+                       (void)SCDynamicStoreSetDispatchQueue(self.store, NULL);
+                       CFRelease(self.store);
+                       self.store = NULL;
+               }
+
+               self.queue = NULL;
+               self.sem_interfaces_all = NULL;
+               self.sem_interfaces_preconfigured = NULL;
+       }
+}
+
+- (BOOL)isPreconfiguredInterface:(NSString *)bsdName
+{
+       return [self.interfaces_preconfigured containsObject:bsdName];;
+}
+
+#pragma mark -
+#pragma mark IOEthernetController support
+
+static CFStringRef
+copy_interface_name(IOEthernetControllerRef controller)
+{
+       CFStringRef     bsdName;
+       io_object_t     interface;
+
+       interface = IOEthernetControllerGetIONetworkInterfaceObject(controller);
+       if (interface == MACH_PORT_NULL) {
+               SCTestLog("*** could not get interface for controller");
+               return NULL;
+       }
+
+       bsdName = IORegistryEntryCreateCFProperty(interface, CFSTR(kIOBSDNameKey), NULL, kNilOptions);
+       if (bsdName == NULL) {
+               SCTestLog("*** IOEthernetController with no BSD interface name");
+               return NULL;
+       }
+
+       return bsdName;
+}
+
+static CFDataRef
+copy_interface_mac(IOEthernetControllerRef controller)
+{
+       CFDataRef       macAddress;
+       io_object_t     interface;
+
+       interface = IOEthernetControllerGetIONetworkInterfaceObject(controller);
+       if (interface == MACH_PORT_NULL) {
+               SCTestLog("*** could not get interface for controller");
+               return NULL;
+       }
+
+       macAddress = IORegistryEntrySearchCFProperty(interface,
+                                                    kIOServicePlane,
+                                                    CFSTR(kIOMACAddress),
+                                                    NULL,
+                                                    kIORegistryIterateRecursively | kIORegistryIterateParents);
+       if (macAddress == NULL) {
+               SCTestLog("*** IOEthernetController with no BSD interface name");
+               return NULL;
+       }
+
+       return macAddress;
+}
+
+static IOEthernetControllerRef
+create_hidden_interface(u_char ea_unique)
+{
+       IOEthernetControllerRef controller;
+       CFDataRef               data;
+       struct ether_addr       ea      = { .octet = { 0x02, 'F', 'A', 'K', 'E', ea_unique } };
+       CFMutableDictionaryRef  merge;
+       CFNumberRef             num;
+       CFMutableDictionaryRef  props;
+       const int               usb_vid_apple   = kIOUSBAppleVendorID;
+
+       props = CFDictionaryCreateMutable(NULL, 0,
+                                         &kCFTypeDictionaryKeyCallBacks,
+                                         &kCFTypeDictionaryValueCallBacks);
+
+       data = CFDataCreate(NULL, ea.octet, ETHER_ADDR_LEN);
+       CFDictionarySetValue(props, kIOEthernetHardwareAddress, data);
+       CFRelease(data);
+
+       merge = CFDictionaryCreateMutable(NULL, 0,
+                                         &kCFTypeDictionaryKeyCallBacks,
+                                         &kCFTypeDictionaryValueCallBacks);
+       CFDictionarySetValue(merge, CFSTR(kIOPropertyProductNameKey),           CFSTR("Hidden Ethernet"));
+       CFDictionarySetValue(merge, kIOUserEthernetInterfaceRole,               CFSTR("hidden-ethernet"));
+       CFDictionarySetValue(merge, kSCNetworkInterfaceHiddenConfigurationKey,  kCFBooleanTrue);
+       num = CFNumberCreate(NULL, kCFNumberIntType, &usb_vid_apple);
+       CFDictionarySetValue(merge, CFSTR(kUSBVendorID),                        num);
+       CFRelease(num);
+       CFDictionarySetValue(props, kIOUserEthernetInterfaceMergeProperties,    merge);
+       CFRelease(merge);
+
+       controller = IOEthernetControllerCreate(NULL, props);
+       CFRelease(props);
+       if (controller == NULL) {
+               SCTestLog("*** could not create ethernet controller for \"%s\"", ether_ntoa(&ea));
+               return NULL;
+       }
+
+       return controller;
+}
+
+- (BOOL)interfaceAdd:(u_char)ea_unique controller:(IOEthernetControllerRef *)newController
+{
+       BOOL                    ok      = FALSE;
+
+       do {
+               NSString        *bsdName;
+               NSData          *macAddress;
+               long            status;
+
+               // add an interface
+               *newController = create_hidden_interface(ea_unique);
+               if (*newController == NULL) {
+                       SCTestLog("*** could not create controller");
+                       break;
+               }
+
+               // wait for the [BSD] interface to show up
+               status = dispatch_semaphore_wait(self.sem_interfaces_all, dispatch_time(DISPATCH_TIME_NOW, WAIT_TIME));
+               if (status != 0) {
+                       // if timeout
+                       SCTestLog("*** no KernelEventMonitor change posted, interface not? created");
+                       break;
+               }
+
+               bsdName = (__bridge_transfer NSString *)copy_interface_name(*newController);
+               if (bsdName == NULL) {
+                       break;
+               }
+
+               macAddress = (__bridge_transfer NSData *)copy_interface_mac(*newController);
+               if (macAddress == NULL) {
+                       break;
+               }
+
+               SCTestLog("  Interface \"%@\" added, mac=%s",
+                         bsdName,
+                         ether_ntoa((struct ether_addr *)macAddress.bytes));
+
+               // check if pre-configured
+               status = dispatch_semaphore_wait(self.sem_interfaces_preconfigured, dispatch_time(DISPATCH_TIME_NOW, WAIT_TIME));
+               if (status != 0) {
+                       // if timeout
+                       SCTestLog("*** no InterfaceNamer change posted, not? preconfigured");
+                       break;
+               }
+
+               if (![self isPreconfiguredInterface:bsdName]) {
+                       SCTestLog("*** Interface \"%@\" is not pre-configured", bsdName);
+                       break;
+               }
+
+               SCTestLog("  Interface \"%@\" is pre-configured", bsdName);
+
+               ok = TRUE;
+       } while (0);
+
+       if (!ok) {
+               if (*newController != NULL) {
+                       CFRelease(*newController);
+                       *newController = NULL;
+               }
+       }
+
+       return ok;
+}
+
+- (BOOL)interfaceRemove:(IOEthernetControllerRef)controller
+{
+       BOOL    ok      = FALSE;
+
+       do {
+               NSString        *bsdName        = (__bridge_transfer NSString *)copy_interface_name(controller);
+               long            status;
+
+               // remove the interface
+               CFRelease(controller);
+
+               // wait for the [BSD] interface to go away
+               status = dispatch_semaphore_wait(self.sem_interfaces_all, dispatch_time(DISPATCH_TIME_NOW, WAIT_TIME));
+               if (status != 0) {
+                       // if timeout
+                       SCTestLog("*** no KernelEventMonitor change posted, interface not? removed");
+                       break;
+               }
+
+               SCTestLog("  Interface \"%@\" removed", bsdName);
+
+               // check if [still] pre-configured
+               status = dispatch_semaphore_wait(self.sem_interfaces_preconfigured, dispatch_time(DISPATCH_TIME_NOW, WAIT_TIME));
+               if (status != 0) {
+                       // if timeout
+                       SCTestLog("*** no InterfaceNamer change posted, still? preconfigured");
+                       break;
+               }
+
+               if ([self isPreconfiguredInterface:bsdName]) {
+                       SCTestLog("*** interface \"%@\" is still pre-configured", bsdName);
+                       break;
+               }
+
+               ok = TRUE;
+       } while (0);
+
+       return ok;
+}
+
+#pragma mark -
+#pragma mark unitTestInsertRemoveOneInterface
+
+#define N_INTERFACES           5
+
+- (BOOL)unitTestInsertRemoveOneInterface
+{
+       NSString                *bsdName1       = nil;
+       BOOL                    ok;
+       SCTestInterfaceNamer    *test;
+
+       test = [[SCTestInterfaceNamer alloc] initWithOptions:self.options];
+       [test watchForChanges:TRUE];
+
+       for (size_t i = 0; i < N_INTERFACES; i++) {
+               NSString                *bsdName;
+               IOEthernetControllerRef controller;
+
+               SCTestLog("Interface #%zd", i + 1);
+
+               // add an interface
+               ok = [test interfaceAdd:i controller:&controller];
+               if (!ok) {
+                       break;
+               }
+
+               // check the assigned interface name
+               bsdName = (__bridge_transfer NSString *)copy_interface_name(controller);
+               if (i == 0) {
+                       bsdName1 = bsdName;
+               } else if ([bsdName isNotEqualTo:bsdName1]) {
+                       SCTestLog("*** interface name not re-assigned, expected \"%@\", assigned \"%@\"", bsdName1, bsdName);
+                       break;
+               }
+
+               // remove the interface
+               ok = [test interfaceRemove:controller];
+               if (!ok) {
+                       break;
+               }
+       };
+
+       if (ok) {
+               SCTestLog("Successfully completed unitTestInsertRemoveOneInterface unit test");
+       }
+
+       return ok;
+}
+
+#pragma mark -
+#pragma mark unitTestInsertRemoveMultipleInterfaces
+
+#define N_INTERFACES_SLOT_X    (N_INTERFACES / 2)
+
+- (BOOL)unitTestInsertRemoveMultipleInterfaces
+{
+       NSString                        *bsdName;
+       IOEthernetControllerRef         controller;
+       struct {
+               NSString                *bsdName;
+               IOEthernetControllerRef controller;
+       } interfaces[N_INTERFACES]                      = { { } };
+       BOOL                            ok;
+       SCTestInterfaceNamer            *test;
+
+       test = [[SCTestInterfaceNamer alloc] initWithOptions:self.options];
+       [test watchForChanges:TRUE];
+
+       SCTestLog("Adding %d interfaces", N_INTERFACES);
+
+       for (size_t i = 0; i < N_INTERFACES; i++) {
+               // add an interface
+               ok = [test interfaceAdd:i controller:&controller];
+               if (!ok) {
+                       break;
+               }
+
+               interfaces[i].controller = controller;
+               interfaces[i].bsdName = (__bridge_transfer NSString *)copy_interface_name(controller);
+       }
+
+       if (ok) {
+               SCTestLog("Removing interfaces");
+
+               for (size_t i = 0; i < N_INTERFACES; i++) {
+                       // remove the interface
+                       ok = [test interfaceRemove:interfaces[i].controller];
+                       interfaces[i].controller = NULL;
+                       if (!ok) {
+                               break;
+                       }
+               }
+       }
+
+       if (ok) {
+               SCTestLog("Re-adding %d interfaces", N_INTERFACES);
+
+               for (size_t i = 0; i < N_INTERFACES; i++) {
+                       // add an interface
+                       ok = [test interfaceAdd:i controller:&controller];
+                       if (!ok) {
+                               break;
+                       }
+
+                       interfaces[i].controller = controller;
+
+                       bsdName = (__bridge_transfer NSString *)copy_interface_name(controller);
+                       ok = [bsdName isEqualTo:interfaces[i].bsdName];
+                       if (!ok) {
+                               SCTestLog("*** interface %zd not assigned the same name, expected \"%@\", assigned \"%@\"",
+                                         i,
+                                         interfaces[i].bsdName,
+                                         bsdName);
+                               break;
+                       }
+
+                       interfaces[i].bsdName = bsdName;
+               }
+       }
+
+       if (ok) {
+               SCTestLog("Removing one interface");
+
+               ok = [test interfaceRemove:interfaces[N_INTERFACES_SLOT_X].controller];
+               interfaces[N_INTERFACES_SLOT_X].controller = NULL;
+       }
+
+       if (ok) {
+               SCTestLog("Adding a new interface");
+
+               do {
+                       // add a new interface (should re-use the first available name)
+                       ok = [test interfaceAdd:N_INTERFACES controller:&controller];
+                       if (!ok) {
+                               break;
+                       }
+
+                       interfaces[N_INTERFACES_SLOT_X].controller = controller;
+
+                       bsdName = (__bridge_transfer NSString *)copy_interface_name(controller);
+                       ok = [bsdName isEqualTo:interfaces[N_INTERFACES_SLOT_X].bsdName];
+                       if (!ok) {
+                               SCTestLog("*** interface %d not assigned an old name, expected \"%@\", assigned \"%@\"",
+                                         N_INTERFACES,
+                                         interfaces[N_INTERFACES_SLOT_X].bsdName,
+                                         bsdName);
+                               break;
+                       }
+
+                       interfaces[N_INTERFACES_SLOT_X].bsdName = bsdName;
+               } while (0);
+       }
+
+       if (ok) {
+               SCTestLog("Removing interfaces (again)");
+
+               for (size_t i = 0; i < N_INTERFACES; i++) {
+                       // remove the interface
+                       ok = [test interfaceRemove:interfaces[i].controller];
+                       interfaces[i].controller = NULL;
+                       if (!ok) {
+                               break;
+                       }
+               }
+       }
+
+       // cleanup
+       for (size_t i = 0; i < N_INTERFACES; i++) {
+               if (interfaces[i].controller != NULL) {
+                       CFRelease(interfaces[i].controller);
+               }
+       }
+
+       return ok;
+}
+
+@end
index 46be006e5647f41d877b7e71cc3bd8c15dc36b0e..cc8c2f35a0d21b63b1972fa3d862137c9712e7fc 100644 (file)
@@ -67,6 +67,7 @@ extern const NSString * const kSCTestUnitTestTestMethodList;
                {"list_tests", 0, NULL, 0}, \
                {"test_method", 1, NULL, 0}, \
                {"test_method_list", 0, NULL, 0}, \
                {"list_tests", 0, NULL, 0}, \
                {"test_method", 1, NULL, 0}, \
                {"test_method_list", 0, NULL, 0}, \
+               {NULL, 0, NULL, 0},
 
 #define kSCTestOptionHelp \
                "\n============== global options =============\n"\
 
 #define kSCTestOptionHelp \
                "\n============== global options =============\n"\
index 5b071455105ca89fd47b87ac7f9865a8a9813276..02622a8f9e82942feb3607a43eb384ff5d0de301 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2016, 2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2016, 2017, 2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -28,7 +28,8 @@
 #import <SystemConfiguration/SCPrivate.h>
 #import <objc/objc-runtime.h>
 
 #import <SystemConfiguration/SCPrivate.h>
 #import <objc/objc-runtime.h>
 
-#define SCTestLog(fmt, ...)    SCPrint(TRUE, stdout, CFSTR(fmt "\n"), ##__VA_ARGS__)
+#define SCTestLog(fmt, ...)    SCLog(TRUE, LOG_NOTICE, CFSTR(fmt), ##__VA_ARGS__)
+
 #define ERR_EXIT               exit(1)
 
 typedef struct {
 #define ERR_EXIT               exit(1)
 
 typedef struct {
index 4374622203f7445c3f2efc1ecb04dd6fed6fb003..b06d1357a50b82b97f9b5e9702995ea037f788f9 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2016, 2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2016, 2017, 2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -103,6 +103,7 @@ printOptionEntries()
                printf("\t\t{\"%s\", %d, NULL, 0}, \\", testOptions[i].optionString, testOptions[i].hasArg);
                printf("\n");
        }
                printf("\t\t{\"%s\", %d, NULL, 0}, \\", testOptions[i].optionString, testOptions[i].hasArg);
                printf("\n");
        }
+       printf("\t\t{NULL, 0, NULL, 0},\n");
 }
 
 void
 }
 
 void
index e86811005f8ba0763a5f126b7d825e836c88c478..ec71efc4956789cac3910342bfa8eb93d288c0de 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2016 Apple Inc. All rights reserved.
+ * Copyright (c) 2016, 2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -50,6 +50,8 @@ int main(int argc, const char * argv[]) {
                Class testClass;
                SCTest *testClassObject;
 
                Class testClass;
                SCTest *testClassObject;
 
+               _sc_log = 0;    // print (stdout)
+
                if (argc == 1) {
                        usage();
                }
                if (argc == 1) {
                        usage();
                }
@@ -86,6 +88,8 @@ int main(int argc, const char * argv[]) {
                        }
                }
 
                        }
                }
 
+               _sc_log = 3;    // log AND print (stdout w/o timestamp)
+
                testClassObject = [(SCTest *)[testClass alloc] initWithOptions:options];
                if (testClassObject.options[kSCTestGlobalOptionCPU] != nil) {
                        cpuStart(testClassObject.globalCPU);
                testClassObject = [(SCTest *)[testClass alloc] initWithOptions:options];
                if (testClassObject.options[kSCTestGlobalOptionCPU] != nil) {
                        cpuStart(testClassObject.globalCPU);
index aeab336d475c4bbcf171c5001cc5e997298ab59c..79a8358412d05ac8a7235672753b4c935988a291 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2011, 2013, 2014, 2017, 2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2011, 2013, 2014, 2017-2019 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -192,10 +192,6 @@ const cmdInfo commands_net[] = {
                " enable protocol  [ <protocolType> ]\n"
                " enable service   [ <serviceName> | <service#> ]"                              },
 
                " enable protocol  [ <protocolType> ]\n"
                " enable service   [ <serviceName> | <service#> ]"                              },
 
-       { "migrate",    2,      5,      do_net_migrate,         11,     0,
-               " migrate perform <old-configuration> <new-configuration> [<current-configuration>]\n"
-               " migrate validate <configuration> <expected-configuration>"},
-
        { "remove",     1,      2,      do_net_remove,          6,      0,
                " remove protocol  [ <protocolType> ]\n"
                " remove service   [ <serviceName> | <service#> ]\n"
        { "remove",     1,      2,      do_net_remove,          6,      0,
                " remove protocol  [ <protocolType> ]\n"
                " remove service   [ <serviceName> | <service#> ]\n"
@@ -223,9 +219,19 @@ const cmdInfo commands_net[] = {
                " show sets\n\n"
                " show set       [ <setName> | <set#> ]"                                        },
 
                " show sets\n\n"
                " show set       [ <setName> | <set#> ]"                                        },
 
-       { "update",     0,      1,      do_net_update,          10,     0,
+       { "migrate",    2,      5,      do_net_migrate,         10,     0,
+               " migrate perform <old-configuration> <new-configuration> [<current-configuration>]\n"
+               " migrate validate <configuration> <expected-configuration>"},
+
+       { "clean",      0,      0,      do_net_clean,           11,     0,
+               " clean                         : clean the network configuration"              },
+
+       { "update",     0,      0,      do_net_update,          11,     0,
                " update                        : update the network configuration"             },
 
                " update                        : update the network configuration"             },
 
+       { "upgrade",    0,      1,      do_net_upgrade,         11,     0,
+               " upgrade [ <plist-name> ]      : upgrade the network configuration"            },
+
        { "snapshot",   0,      0,      do_net_snapshot,        99,     2,
                " snapshot"                                                                     }
 
        { "snapshot",   0,      0,      do_net_snapshot,        99,     2,
                " snapshot"                                                                     }
 
index d793a7c59852b17394c873477a36ea5ebd4c3d83..3cee9395e5d1632f91cfce2b66da03b601f32269 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004-2007, 2009-2011, 2014, 2016, 2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2007, 2009-2011, 2014, 2016, 2017, 2019, 2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -38,6 +38,9 @@
 #include "net_service.h"
 #include "net_set.h"
 
 #include "net_service.h"
 #include "net_set.h"
 
+#include "SCNetworkConfigurationInternal.h"
+#include "SCPreferencesInternal.h"
+
 #include <unistd.h>
 
 
 #include <unistd.h>
 
 
@@ -541,7 +544,6 @@ void
 do_net_open(int argc, char **argv)
 {
        Boolean         ok;
 do_net_open(int argc, char **argv)
 {
        Boolean         ok;
-       CFStringRef     prefsID = NULL;
 
        if (prefs != NULL) {
                if (_prefs_commitRequired(argc, argv, "close")) {
 
        if (prefs != NULL) {
                if (_prefs_commitRequired(argc, argv, "close")) {
@@ -552,12 +554,7 @@ do_net_open(int argc, char **argv)
                _prefs_close();
        }
 
                _prefs_close();
        }
 
-       if (argc > 0) {
-               prefsID = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
-       }
-
-       ok = _prefs_open(CFSTR("scutil --net"), prefsID);
-       if (prefsID != NULL) CFRelease(prefsID);
+       ok = _prefs_open(CFSTR("scutil --net"), (argc > 0) ? argv[0] : NULL);
        if (!ok) {
                SCPrint(TRUE,
                        stdout,
        if (!ok) {
                SCPrint(TRUE,
                        stdout,
@@ -1010,6 +1007,47 @@ do_net_show(int argc, char **argv)
 }
 
 
 }
 
 
+__private_extern__
+void
+do_net_clean(int argc, char **argv)
+{
+#pragma unused(argc)
+#pragma unused(argv)
+       Boolean         updated;
+
+       if (prefs == NULL) {
+               SCPrint(TRUE, stdout, CFSTR("network configuration not open\n"));
+               return;
+       }
+
+       if (ni_prefs == NULL) {
+               ni_prefs = SCPreferencesCreateCompanion(prefs, INTERFACES_DEFAULT_CONFIG);
+               if (ni_prefs == NULL) {
+                       SC_log(LOG_NOTICE, "SCPreferencesCreate( <NetworkInterfaces.plist> ) failed: %s", SCErrorString(SCError()));
+               }
+       }
+
+       updated = __SCNetworkConfigurationClean(prefs, ni_prefs);
+
+       if (updated) {
+               SCPrint(TRUE, stdout,
+                       CFSTR("network configuration updated, use \"commit\" to save\n"));
+               if ((prefsPath == NULL) || (strcmp(prefsPath, PREFS_DEFAULT_CONFIG_PLIST) == 0)) {
+                       SCPrint(TRUE, stdout,
+                               CFSTR( "\n"
+                                     "NOTE: because you have modified the system's \"live\" network configuration,\n"
+                                     "      a <reboot> is also REQUIRED.\n"
+                                     "\n"));
+               }
+               _prefs_changed = TRUE;
+       } else {
+               SCPrint(TRUE, stdout, CFSTR("network configuration not updated\n"));
+       }
+
+       return;
+}
+
+
 __private_extern__
 void
 do_net_update(int argc, char **argv)
 __private_extern__
 void
 do_net_update(int argc, char **argv)
@@ -1071,6 +1109,7 @@ do_net_update(int argc, char **argv)
                                SCNetworkSetGetSetID(set),
                                setCreated ? "created, selected, and " : "");
                }
                                SCNetworkSetGetSetID(set),
                                setCreated ? "created, selected, and " : "");
                }
+               _prefs_changed = TRUE;
        }
 
        CFRelease(set);
        }
 
        CFRelease(set);
@@ -1078,6 +1117,85 @@ do_net_update(int argc, char **argv)
 }
 
 
 }
 
 
+__private_extern__
+void
+do_net_upgrade(int argc, char **argv)
+{
+       Boolean         do_commit       = FALSE;
+       Boolean         upgraded;
+
+       if (prefs == NULL) {
+               SCPrint(TRUE, stdout, CFSTR("network configuration not open\n"));
+               return;
+       }
+
+       if (prefsPath != NULL) {
+               const char      *prefs_plist;
+
+               prefs_plist = strrchr(prefsPath, '/');
+               if (prefs_plist != NULL) {
+                       prefs_plist++;
+               } else {
+                       prefs_plist = prefsPath;
+               }
+
+               if (strcmp(prefs_plist, PREFS_DEFAULT_CONFIG_PLIST) != 0) {
+                       SCPrint(TRUE, stdout, CFSTR("not updating a \"preferences.plist\" file\n"));
+                       return;
+               }
+       }
+
+       if (argc > 0) {
+               if (strcmp(argv[0], PREFS_DEFAULT_CONFIG_PLIST) == 0) {
+                       upgraded = __SCNetworkConfigurationUpgrade(&prefs, NULL, do_commit);
+               } else if (strcmp(argv[0], INTERFACES_DEFAULT_CONFIG_PLIST) == 0) {
+                       if (ni_prefs == NULL) {
+                               ni_prefs = SCPreferencesCreateCompanion(prefs, INTERFACES_DEFAULT_CONFIG);
+                               if (ni_prefs == NULL) {
+                                       SC_log(LOG_NOTICE, "SCPreferencesCreate( <NetworkInterfaces.plist> ) failed: %s", SCErrorString(SCError()));
+                               }
+                       }
+
+                       do_commit = TRUE;       // using alternate, created on-the-fly preferences.plist
+
+                       upgraded = __SCNetworkConfigurationUpgrade(NULL, &ni_prefs, do_commit);
+               } else {
+                       SCPrint(TRUE, stdout, CFSTR("invalid .plist (\"preferences.plist\", \"NetworkInterfaces.plist\"\n"));
+                       return;
+               }
+       } else {
+               upgraded = __SCNetworkConfigurationUpgrade(&prefs, &ni_prefs, do_commit);
+       }
+
+       if (upgraded) {
+               SCPrint(TRUE, stdout,
+                       do_commit ? CFSTR("network configuration upgraded/saved\n")
+                                 : CFSTR("network configuration upgraded, use \"commit\" to save\n"));
+               if ((prefsPath == NULL) || (strcmp(prefsPath, PREFS_DEFAULT_CONFIG_PLIST) == 0)) {
+                       SCPrint(TRUE, stdout,
+                               do_commit ? CFSTR("\n"
+                                                 "NOTE: because you have modified the system's \"live\" network configuration,\n"
+                                                 "      a <reboot> is also REQUIRED.\n"
+                                                 "\n")
+
+                                         : CFSTR("\n"
+                                                 "NOTE: because you are modifying the system's \"live\" network configuration,\n"
+                                                 "      a <reboot> will also be REQUIRED.\n"
+                                                 "\n")
+                               );
+               }
+
+               if (!do_commit) {
+                       _prefs_changed = TRUE;
+               }
+       } else {
+               SCPrint(TRUE, stdout, CFSTR("network configuration upgrade not needed\n"));
+       }
+
+       return;
+}
+
+
 #include "SCPreferencesInternal.h"
 #include <fcntl.h>
 #include <unistd.h>
 #include "SCPreferencesInternal.h"
 #include <fcntl.h>
 #include <unistd.h>
index 3386d786902c45c1a0f647441550136d7df14bdd..b8c78c80e56406af8cd578b99a63d7fb5a8878e2 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004, 2006, 2011, 2014, 2016 Apple Inc. All rights reserved.
+ * Copyright (c) 2004, 2006, 2011, 2014, 2016, 2019, 2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -118,6 +118,7 @@ void                do_net_commit   (int argc, char **argv);
 void           do_net_apply    (int argc, char **argv);
 void           do_net_close    (int argc, char **argv);
 
 void           do_net_apply    (int argc, char **argv);
 void           do_net_close    (int argc, char **argv);
 
+void           do_net_clean    (int argc, char **argv);
 void           do_net_create   (int argc, char **argv);
 void           do_net_disable  (int argc, char **argv);
 void           do_net_enable   (int argc, char **argv);
 void           do_net_create   (int argc, char **argv);
 void           do_net_disable  (int argc, char **argv);
 void           do_net_enable   (int argc, char **argv);
@@ -127,6 +128,7 @@ void                do_net_select   (int argc, char **argv);
 void           do_net_set      (int argc, char **argv);
 void           do_net_show     (int argc, char **argv);
 void           do_net_update   (int argc, char **argv);
 void           do_net_set      (int argc, char **argv);
 void           do_net_show     (int argc, char **argv);
 void           do_net_update   (int argc, char **argv);
+void           do_net_upgrade  (int argc, char **argv);
 
 void           do_net_snapshot (int argc, char **argv);
 
 
 void           do_net_snapshot (int argc, char **argv);
 
index a4df6a43cc3fda5d97125e6d8eb4abde599eac9b..a0bf1125e758db834adc7c0be649a9e1938163a4 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2003-2008, 2011-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2008, 2011-2017, 2019, 2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -144,10 +144,11 @@ __private_extern__ Boolean        _prefs_changed  = FALSE;
 
 __private_extern__
 Boolean
 
 __private_extern__
 Boolean
-_prefs_open(CFStringRef name, CFStringRef prefsID)
+_prefs_open(CFStringRef name, const char *path)
 {
        char                    *env            = NULL;
        CFMutableDictionaryRef  options         = NULL;
 {
        char                    *env            = NULL;
        CFMutableDictionaryRef  options         = NULL;
+       CFStringRef             prefsID         = NULL;
        Boolean                 useHelper       = FALSE;
        Boolean                 useOptions      = FALSE;
 
        Boolean                 useHelper       = FALSE;
        Boolean                 useOptions      = FALSE;
 
@@ -191,6 +192,11 @@ _prefs_open(CFStringRef name, CFStringRef prefsID)
                CFRelease(str);
        }
 
                CFRelease(str);
        }
 
+       if (path != NULL) {
+               prefsPath = strdup(path);
+               prefsID = CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8);
+       }
+
        if (!useHelper && !useOptions) {
                // if no helper/options needed
                prefs = SCPreferencesCreate(NULL, name, prefsID);
        if (!useHelper && !useOptions) {
                // if no helper/options needed
                prefs = SCPreferencesCreate(NULL, name, prefsID);
@@ -202,7 +208,10 @@ _prefs_open(CFStringRef name, CFStringRef prefsID)
                CFRelease(options);
        }
 
                CFRelease(options);
        }
 
+       if (prefsID != NULL) CFRelease(prefsID);
        if (prefs == NULL) {
        if (prefs == NULL) {
+               if (prefsPath != NULL) free(prefsPath);
+               prefsPath = NULL;
                return FALSE;
        }
 
                return FALSE;
        }
 
@@ -230,8 +239,6 @@ _prefs_save()
                exit (1);
        }
 
                exit (1);
        }
 
-       _prefs_changed = FALSE;
-
        if (!SCPreferencesApplyChanges(prefs)) {
                SCPrint(TRUE,
                        stdout,
        if (!SCPreferencesApplyChanges(prefs)) {
                SCPrint(TRUE,
                        stdout,
@@ -240,6 +247,33 @@ _prefs_save()
                exit (1);
        }
 
                exit (1);
        }
 
+       _prefs_changed = FALSE;
+
+       if (ni_prefs != NULL) {
+               if (!SCPreferencesCommitChanges(ni_prefs)) {
+                       switch (SCError()) {
+                               case kSCStatusAccessError :
+                                       SCPrint(TRUE, stderr, CFSTR("Permission denied.\n"));
+                                       break;
+                               default :
+                                       SCPrint(TRUE,
+                                               stdout,
+                                               CFSTR("SCPreferencesCommitChanges( <NetworkInterfaces.plist> ) failed: %s\n"),
+                                               SCErrorString(SCError()));
+                                       break;
+                       }
+                       exit (1);
+               }
+
+               if (!SCPreferencesApplyChanges(ni_prefs)) {
+                       SCPrint(TRUE,
+                               stdout,
+                               CFSTR("SCPreferencesApplyChanges( <NetworkInterfaces.plist> ) failed: %s\n"),
+                               SCErrorString(SCError()));
+                       exit (1);
+               }
+       }
+
        return;
 }
 
        return;
 }
 
@@ -248,12 +282,22 @@ __private_extern__
 void
 _prefs_close()
 {
 void
 _prefs_close()
 {
+       if (prefsPath != NULL) {
+               free(prefsPath);
+               prefsPath = NULL;
+       }
+
        if (prefs != NULL) {
                CFRelease(prefs);
                prefs = NULL;
                _prefs_changed = FALSE;
        }
 
        if (prefs != NULL) {
                CFRelease(prefs);
                prefs = NULL;
                _prefs_changed = FALSE;
        }
 
+       if (ni_prefs != NULL) {
+               CFRelease(ni_prefs);
+               ni_prefs = NULL;
+       }
+
        if (authorization != NULL) {
 #if    !TARGET_OS_IPHONE
                _prefs_AuthorizationFree(authorization);
        if (authorization != NULL) {
 #if    !TARGET_OS_IPHONE
                _prefs_AuthorizationFree(authorization);
@@ -644,7 +688,6 @@ void
 do_prefs_open(int argc, char **argv)
 {
        Boolean         ok;
 do_prefs_open(int argc, char **argv)
 {
        Boolean         ok;
-       CFStringRef     prefsID = NULL;
 
        if (prefs != NULL) {
                if (_prefs_commitRequired(argc, argv, "close")) {
 
        if (prefs != NULL) {
                if (_prefs_commitRequired(argc, argv, "close")) {
@@ -654,12 +697,7 @@ do_prefs_open(int argc, char **argv)
                do_prefs_close(0, NULL);
        }
 
                do_prefs_close(0, NULL);
        }
 
-       if (argc > 0) {
-               prefsID = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
-       }
-
-       ok = _prefs_open(CFSTR("scutil --prefs"), prefsID);
-       if (prefsID != NULL) CFRelease(prefsID);
+       ok = _prefs_open(CFSTR("scutil --prefs"), (argc > 0) ? argv[0] : NULL);
        if (!ok) {
                SCPrint(TRUE,
                        stdout,
        if (!ok) {
                SCPrint(TRUE,
                        stdout,
@@ -768,6 +806,10 @@ do_prefs_synchronize(int argc, char **argv)
 #pragma unused(argc)
 #pragma unused(argv)
        SCPreferencesSynchronize(prefs);
 #pragma unused(argc)
 #pragma unused(argv)
        SCPreferencesSynchronize(prefs);
+       if (ni_prefs != NULL) {
+               SCPreferencesSynchronize(ni_prefs);
+       }
+
        return;
 }
 
        return;
 }
 
index b4f397a8df4ce2bb346f6cb4d38f9c61572dd53b..af4d98aa5ce305921da17f4bb50aa5e8f09b3848 100644 (file)
@@ -1,15 +1,15 @@
 /*
 /*
- * Copyright (c) 2003, 2005-2007, 2012, 2013, 2015-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2003, 2005-2007, 2012, 2013, 2015-2017, 2019, 2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  * @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.
  * 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,
  * 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.
  * 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@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -44,7 +44,7 @@ __BEGIN_DECLS
 AuthorizationRef       _prefs_AuthorizationCreate      (void);
 void                   _prefs_AuthorizationFree        (AuthorizationRef authorization);
 
 AuthorizationRef       _prefs_AuthorizationCreate      (void);
 void                   _prefs_AuthorizationFree        (AuthorizationRef authorization);
 
-Boolean        _prefs_open             (CFStringRef name, CFStringRef prefsID);
+Boolean        _prefs_open             (CFStringRef name, const char *path);
 void   _prefs_save             (void);
 void   _prefs_close            (void);
 Boolean        _prefs_commitRequired   (int argc, char **argv, const char *command);
 void   _prefs_save             (void);
 void   _prefs_close            (void);
 Boolean        _prefs_commitRequired   (int argc, char **argv, const char *command);
index a897d81862c34aacb9b272be5509f78b08dc8c50..0d27a4afca1518d71b622069266d9bb4f886b464 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -75,9 +75,11 @@ __private_extern__ AuthorizationRef  authorization   = NULL;
 __private_extern__ InputRef            currentInput    = NULL;
 __private_extern__ Boolean             doDispatch      = FALSE;
 __private_extern__ int                 nesting         = 0;
 __private_extern__ InputRef            currentInput    = NULL;
 __private_extern__ Boolean             doDispatch      = FALSE;
 __private_extern__ int                 nesting         = 0;
+__private_extern__ SCPreferencesRef    ni_prefs        = NULL;
 __private_extern__ CFRunLoopRef                notifyRl        = NULL;
 __private_extern__ CFRunLoopSourceRef  notifyRls       = NULL;
 __private_extern__ SCPreferencesRef    prefs           = NULL;
 __private_extern__ CFRunLoopRef                notifyRl        = NULL;
 __private_extern__ CFRunLoopSourceRef  notifyRls       = NULL;
 __private_extern__ SCPreferencesRef    prefs           = NULL;
+__private_extern__ char                        *prefsPath      = NULL;
 __private_extern__ SCDynamicStoreRef   store           = NULL;
 __private_extern__ CFPropertyListRef   value           = NULL;
 __private_extern__ CFMutableArrayRef   watchedKeys     = NULL;
 __private_extern__ SCDynamicStoreRef   store           = NULL;
 __private_extern__ CFPropertyListRef   value           = NULL;
 __private_extern__ CFMutableArrayRef   watchedKeys     = NULL;
index b72f28022dbc0d0948cd6878ffdbdc28d4e24c5e..c44303f63a6896154fc107e1c8113b014ecf00bc 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2005, 2009, 2012, 2016, 2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2005, 2009, 2012, 2016, 2017, 2019, 2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -37,7 +37,9 @@
 #include <sys/cdefs.h>
 #include <histedit.h>
 
 #include <sys/cdefs.h>
 #include <histedit.h>
 
-#define SC_LOG_HANDLE  _SC_LOG_DEFAULT
+#define SC_LOG_HANDLE          _SC_LOG_DEFAULT
+#define USE_SC_LOG_OR_PRINT    1
+
 #include <SystemConfiguration/SystemConfiguration.h>
 #include <SystemConfiguration/SCPrivate.h>
 #include <SystemConfiguration/SCValidation.h>
 #include <SystemConfiguration/SystemConfiguration.h>
 #include <SystemConfiguration/SCPrivate.h>
 #include <SystemConfiguration/SCValidation.h>
@@ -54,9 +56,11 @@ extern AuthorizationRef              authorization;
 extern InputRef                        currentInput;
 extern Boolean                 doDispatch;
 extern int                     nesting;
 extern InputRef                        currentInput;
 extern Boolean                 doDispatch;
 extern int                     nesting;
+extern SCPreferencesRef                ni_prefs;
 extern CFRunLoopRef            notifyRl;
 extern CFRunLoopSourceRef      notifyRls;
 extern SCPreferencesRef                prefs;
 extern CFRunLoopRef            notifyRl;
 extern CFRunLoopSourceRef      notifyRls;
 extern SCPreferencesRef                prefs;
+extern char                    *prefsPath;
 extern SCDynamicStoreRef       store;
 extern CFPropertyListRef       value;
 extern CFMutableArrayRef       watchedKeys;
 extern SCDynamicStoreRef       store;
 extern CFPropertyListRef       value;
 extern CFMutableArrayRef       watchedKeys;