/*
- * Copyright (c) 2017-2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2017-2019 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 #import "PreferencesMonitorParser.h"
 #import "StateDumpParser.h"
 #import "IPConfigurationParser.h"
+#import "SCDynamicStoreParser.h"
+#import "SCPreferencesParser.h"
 
 #pragma mark -
 #pragma mark Logging
 #pragma mark -
 #pragma mark SystemConfiguratioin Network Event Factory
 
+typedef NS_ENUM(NSInteger, LogAccumulatingState) {
+       NOT_ACCUMULATING,
+       ACCUMULATING_DNS,
+       ACCUMULATING_NWIv4,
+       ACCUMULATING_NWIv6,
+};
+
 @interface EventFactory ()
 @property NSDictionary<NSString *, SCLogParser *> *parserMap;
+@property LogAccumulatingState accumulating;
+@property EFLogEvent *accumulatingEvent;
+@property NSString *accumulatingEventIdentifierString;
 @end
 
 @implementation EventFactory
        parser = [[StateDumpParser alloc] init];
        newParserMap[parser.category] = parser;
 
+       parser = [[SCDynamicStoreParser alloc] init];
+       newParserMap[parser.category] = parser;
+
+       parser = [[SCPreferencesParser alloc] init];
+       newParserMap[parser.category] = parser;
+
        _parserMap = [[NSDictionary alloc] initWithDictionary:newParserMap];
+
+       _accumulating = NOT_ACCUMULATING;
+}
+
+- (NSString *)logEventIdentifierString:(EFLogEvent *)logEvent
+{
+       NSString        *identifierString;
+
+       identifierString = [[NSString alloc] initWithFormat:@"%@[%d]:%@:%@",
+                                                       logEvent.process,
+                                                       logEvent.processIdentifier,
+                                                       logEvent.subsystem,
+                                                       logEvent.category];
+
+       return identifierString;
 }
 
 - (void)handleLogEvent:(EFLogEvent *)logEvent completionHandler:(void (^)(NSArray<EFEvent *> * _Nullable))completionHandler
 {
-       NSString *category = nil;
        if ([logEvent.eventType isEqualToString:@"stateEvent"]) {
-               category = @"StateDump";
                logEvent.subsystem = @"com.apple.SystemConfiguration";
-               logEvent.category = category;
+               logEvent.category = @"StateDump";
        } else if ([logEvent.subsystem isEqualToString:@"com.apple.IPConfiguration"]) {
                logEvent.category = @"IPConfiguration";
        }
                return;
        }
 
+       if ([logEvent.subsystem isEqualToString:@"com.apple.SystemConfiguration"] &&
+               [logEvent.category  isEqualToString:@"IPMonitor"]) {
+               BOOL            appendMessage   = YES;
+               BOOL            done                    = NO;
+
+               if (_accumulating != NOT_ACCUMULATING) {
+                       /*
+                        * if we are accumulating a block of log messages
+                        */
+                       NSString *logEventIdentifierString = [self logEventIdentifierString:logEvent];
+                       if ((_accumulating != NOT_ACCUMULATING) &&
+                               ![_accumulatingEventIdentifierString isEqualToString:logEventIdentifierString]) {
+                               // if the PID changed
+                               specs_log_debug("Dropped partial message block: %@", _accumulatingEvent.eventMessage);
+                               _accumulating = NOT_ACCUMULATING;
+                               _accumulatingEvent = nil;
+                               appendMessage = NO;
+                       }
+               }
+
+               switch (_accumulating) {
+                       case NOT_ACCUMULATING : {
+                               if ([logEvent.eventMessage isEqualToString:@"Updating DNS configuration"]) {
+                                       /*
+                                         2019-10-10 14:07:32.891719-0400 0x350      Info        0x0                  70     0    configd: [com.apple.SystemConfiguration:IPMonitor] Updating DNS configuration
+                                         2019-10-10 14:07:32.891722-0400 0x350      Info        0x0                  70     0    configd: [com.apple.SystemConfiguration:IPMonitor] DNS configuration
+                                         -->
+                                         2019-10-10 14:03:17.549361-0400 0x0        State       0x2ed40              70     14   configd: DNS Configuration
+                                         DNS configuration
+                                       */
+                                       _accumulating = ACCUMULATING_DNS;
+                                       logEvent.eventMessage = @"DNS Configuration";
+                               } else if ([logEvent.eventMessage isEqualToString:@"Updating network information"]) {
+                                       /*
+                                         2019-10-10 14:07:32.889595-0400 0x350      Info        0x0                  70     0    configd: [com.apple.SystemConfiguration:IPMonitor] Updating network information
+                                         2019-10-10 14:07:32.889596-0400 0x350      Info        0x0                  70     0    configd: [com.apple.SystemConfiguration:IPMonitor] Network information (generation 156994061625682 size=1180)
+                                         -->
+                                         2019-10-10 14:03:17.549364-0400 0x0        State       0x2ed40              70     14   configd: Network information
+                                         Network information (generation 55086114928 size=724)
+                                       */
+                                       _accumulating = ACCUMULATING_NWIv4;
+                                       logEvent.eventMessage = @"Network information";
+                               }
+
+                               if (_accumulating != NOT_ACCUMULATING) {
+                                       // if we are now accumulating a block of messages
+                                       _accumulatingEventIdentifierString = [self logEventIdentifierString:logEvent];
+                                       _accumulatingEvent = logEvent;
+                                       _accumulatingEvent.subsystem = @"com.apple.SystemConfiguration";
+                                       _accumulatingEvent.category = @"StateDump";
+                                       appendMessage = NO;
+                               }
+                               break;
+                       }
+
+                       case ACCUMULATING_DNS : {
+                               if ([logEvent.eventMessage hasPrefix:@"DNS configuration updated: "]) {
+                                       done = YES;
+                                       appendMessage = NO;
+                               }
+                               break;
+                       }
+
+                       case ACCUMULATING_NWIv4 : {
+                               if ([logEvent.eventMessage isEqualToString:@"IPv6 network interface information"]) {
+                                       _accumulating = ACCUMULATING_NWIv6;
+                               }
+                               break;
+                       }
+
+                       case ACCUMULATING_NWIv6 : {
+                               if ([logEvent.eventMessage hasPrefix:@"   REACH : "]) {
+                                       done = YES;
+                               }
+                               break;
+                       }
+               }
+
+               if (appendMessage) {
+                       _accumulatingEvent.eventMessage = [NSString stringWithFormat:@"%@\n%@",
+                                                                                                       _accumulatingEvent.eventMessage,
+                                                                                                       logEvent.eventMessage];
+               }
+
+               if (done) {
+                       // if we have all we need, pass the [accumulated] event
+                       logEvent = _accumulatingEvent;
+                       _accumulating = NOT_ACCUMULATING;
+                       _accumulatingEvent = nil;
+               } else if (_accumulating != NOT_ACCUMULATING) {
+                       // if we are still (or now) accumulating
+                       completionHandler(nil);
+                       return;
+               }
+       }
+
        SCLogParser *parser = _parserMap[logEvent.category];
        if (parser == nil) {
                specs_log_debug("Skipped message with an unknown category (%@): %@", logEvent.category, logEvent.eventMessage);
 
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.19</string>
+       <string>1.20</string>
        <key>CFBundleVersion</key>
        <string>1</string>
        <key>NSPrincipalClass</key>
 
--- /dev/null
+/*
+ * Copyright (c) 2019 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 "SCLogParser.h"
+
+@interface SCDynamicStoreParser: SCLogParser
+@end
 
--- /dev/null
+/*
+ * Copyright (c) 2019 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 <Foundation/Foundation.h>
+#import <EventFactory/EventFactory.h>
+
+#import "SCDynamicStoreParser.h"
+
+@implementation SCDynamicStoreParser
+
+- (instancetype)init
+{
+       NSArray<EFLogEventMatch *> *matches = @[];
+       EFLogEventParser *parser = [[EFLogEventParser alloc] initWithMatches:matches];
+       return [super initWithCategory:@"SCDynamicStore" eventParser:parser];
+}
+
+@end
 
--- /dev/null
+/*
+ * Copyright (c) 2019 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 "SCLogParser.h"
+
+@interface SCPreferencesParser: SCLogParser
+@end
 
--- /dev/null
+/*
+ * Copyright (c) 2019 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 <Foundation/Foundation.h>
+#import <EventFactory/EventFactory.h>
+
+#import "SCPreferencesParser.h"
+
+@implementation SCPreferencesParser
+
+- (instancetype)init
+{
+       NSArray<EFLogEventMatch *> *matches = @[];
+       EFLogEventParser *parser = [[EFLogEventParser alloc] initWithMatches:matches];
+       return [super initWithCategory:@"SCPreferences" eventParser:parser];
+}
+
+@end
 
 /*
- * Copyright (c) 2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2018, 2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 
 #endif /* TEST_IPMONITOR_AWD_REPORT || TEST_IPMONITOR_CONTROL */
 
-
 STATIC AWDServerConnection *
 IPMonitorAWDServerConnection(void)
 {
        metric.name = value;                                    \
     }
 
-void
+PRIVATE_EXTERN void
 InterfaceAdvisoryReportSetFlags(InterfaceAdvisoryReportRef report,
                                AWDIPMonitorInterfaceAdvisoryReport_Flags flags)
 {
     INTERFACE_ADVISORY_REPORT_SET_PROP(report, flags, flags);
 }
 
-void
+PRIVATE_EXTERN void
 InterfaceAdvisoryReportSetAdvisoryCount(InterfaceAdvisoryReportRef report,
                                        uint32_t count)
 {
 
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.19</string>
+       <string>1.20</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.19</string>
+       <string>1.20</string>
        <key>MachServices</key>
        <dict>
                <key>com.apple.SystemConfiguration.DNSConfiguration_sim</key>
 
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.19</string>
+       <string>1.20</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.19</string>
+       <string>1.20</string>
        <key>MachServices</key>
        <dict>
                <key>com.apple.SystemConfiguration.DNSConfiguration</key>
 
 # Mac OS X or iOS internal SDK
 SDK=$(PLATFORM).internal
 SYSROOT=$(shell xcodebuild -version -sdk $(SDK) Path)
-CC = xcrun -sdk $(SDK) cc
+CC = xcrun -sdk $(SDK) clang
 PF_INC = -F$(SYSROOT)/System/Library/PrivateFrameworks
 
 ARCH_FLAGS=$(foreach a,$(ARCHS),-arch $(a))
 
-EXTRA_CFLAGS=
+EXTRA_CFLAGS=-fsanitize=address
+#EXTRA_CFLAGS=
+
 TEST_INCLUDE=-I. -I../common -I../../dnsinfo -I../../nwi -I../../libSystemConfiguration -I../../SystemConfiguration.fproj -I../../IPMonitorControl -I../../IPMonitorControl/AWD -I$(SYSROOT)/System/Library/Frameworks/System.framework/PrivateHeaders
 
 REFERENCE_OUTPUT=../../common/reference_output.sh
 dns-configuration.o: dns-configuration.h dns-configuration.c dnsinfo_create.o
        $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) ${TEST_INCLUDE} ${EXTRA_CFLAGS} -Wall -O0 -g -c dns-configuration.c
 
+nat64-configuration.o: nat64-configuration.h nat64-configuration.c
+       $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) ${TEST_INCLUDE} ${EXTRA_CFLAGS} -Wall -O0 -g -c nat64-configuration.c
+
 network_state_information_priv.o: ../../nwi/network_state_information_priv.h ../../nwi/network_state_information_priv.c
        $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) ${TEST_INCLUDE} -Wall -O0 -g -c ../../nwi/network_state_information_priv.c
 
 dns-configurationX.o: Makefile dns-configuration.h dns-configuration.c dnsinfo_create.o
        $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -DMAIN ${TEST_INCLUDE} ${EXTRA_CFLAGS} -Wall -O0 -g -c -o dns-configurationX.o dns-configuration.c
 
-test_dns: ip_pluginX.o IPMonitorControlPrefs.o agent-monitor.o configAgent.o controller.o dnsAgent.o proxyAgent.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o network_state_information_priv.o network_information_server.o dns-configurationX.o proxy-configuration.o set-hostname.o smb-configuration.o IPMonitorControlServer.o libSystemConfiguration_client.o libSystemConfiguration_server.o
-       $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -Wall -O0 -g -o test_dns ip_pluginX.o IPMonitorControlPrefs.o agent-monitor.o configAgent.o controller.o dnsAgent.o proxyAgent.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o network_state_information_priv.o network_information_server.o dns-configurationX.o proxy-configuration.o set-hostname.o smb-configuration.o IPMonitorControlServer.o libSystemConfiguration_client.o libSystemConfiguration_server.o ${EXTRA_CFLAGS} -lnetwork -framework SystemConfiguration -framework CoreFoundation -framework Foundation -framework Network -framework NetworkExtension
+test_dns: ip_pluginX.o IPMonitorControlPrefs.o agent-monitor.o configAgent.o controller.o dnsAgent.o proxyAgent.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o dns-configurationX.o nat64-configuration.o proxy-configuration.o set-hostname.o smb-configuration.o libSystemConfiguration_client.o libSystemConfiguration_server.o
+       $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -Wall -O0 -g -o test_dns ip_pluginX.o IPMonitorControlPrefs.o agent-monitor.o configAgent.o controller.o dnsAgent.o proxyAgent.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o dns-configurationX.o nat64-configuration.o proxy-configuration.o set-hostname.o smb-configuration.o libSystemConfiguration_client.o libSystemConfiguration_server.o ${EXTRA_CFLAGS} -lnetwork -framework SystemConfiguration -framework CoreFoundation -framework CoreServices -framework Foundation -framework Network -framework NetworkExtension
 
 # ----------
 
 proxy-configurationX.o: Makefile proxy-configuration.h proxy-configuration.c
        $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -DMAIN ${TEST_INCLUDE} ${EXTRA_CFLAGS} -Wall -O0 -g -c -o proxy-configurationX.o proxy-configuration.c
 
-test_proxy: ip_pluginX.o IPMonitorControlPrefs.o agent-monitor.o configAgent.o controller.o dnsAgent.o proxyAgent.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o network_state_information_priv.o network_information_server.o dns-configuration.o proxy-configurationX.o set-hostname.o smb-configuration.o IPMonitorControlServer.o libSystemConfiguration_client.o libSystemConfiguration_server.o
-       $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -Wall -O0 -g -o test_proxy ip_pluginX.o IPMonitorControlPrefs.o agent-monitor.o configAgent.o controller.o dnsAgent.o proxyAgent.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o network_state_information_priv.o network_information_server.o dns-configuration.o proxy-configurationX.o set-hostname.o smb-configuration.o IPMonitorControlServer.o libSystemConfiguration_client.o libSystemConfiguration_server.o ${EXTRA_CFLAGS} -lnetwork -framework SystemConfiguration -framework CoreFoundation -framework Foundation -framework Network -framework NetworkExtension
+test_proxy: ip_pluginX.o IPMonitorControlPrefs.o agent-monitor.o configAgent.o controller.o dnsAgent.o proxyAgent.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o dns-configuration.o nat64-configuration.o proxy-configurationX.o set-hostname.o smb-configuration.o libSystemConfiguration_client.o libSystemConfiguration_server.o
+       $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -Wall -O0 -g -o test_proxy ip_pluginX.o IPMonitorControlPrefs.o agent-monitor.o configAgent.o controller.o dnsAgent.o proxyAgent.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o dns-configuration.o nat64-configuration.o proxy-configurationX.o set-hostname.o smb-configuration.o libSystemConfiguration_client.o libSystemConfiguration_server.o ${EXTRA_CFLAGS} -lnetwork -framework SystemConfiguration -framework CoreFoundation -framework CoreServices -framework Foundation -framework Network -framework NetworkExtension
 
 # ----------
 
 set-hostnameX.o: Makefile set-hostname.h set-hostname.c
        $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -DMAIN -DDEBUG ${TEST_INCLUDE} ${EXTRA_CFLAGS} -Wall -O0 -g -c -o set-hostnameX.o set-hostname.c
 
-test_hostname: ip_pluginX.o IPMonitorControlPrefs.o agent-monitor.o configAgent.o controller.o dnsAgent.o proxyAgent.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o network_state_information_priv.o network_information_server.o dns-configuration.o proxy-configuration.o set-hostnameX.o smb-configuration.o IPMonitorControlServer.o libSystemConfiguration_client.o libSystemConfiguration_server.o
-       $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -Wall -O0 -g -o test_hostname ip_pluginX.o IPMonitorControlPrefs.o agent-monitor.o configAgent.o controller.o dnsAgent.o proxyAgent.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o network_state_information_priv.o network_information_server.o dns-configuration.o proxy-configuration.o set-hostnameX.o smb-configuration.o IPMonitorControlServer.o libSystemConfiguration_client.o libSystemConfiguration_server.o ${EXTRA_CFLAGS} -lnetwork -framework SystemConfiguration -framework CoreFoundation -framework Foundation -framework Network -framework NetworkExtension
+test_hostname: ip_pluginX.o IPMonitorControlPrefs.o agent-monitor.o configAgent.o controller.o dnsAgent.o proxyAgent.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o dns-configuration.o nat64-configuration.o proxy-configuration.o set-hostnameX.o smb-configuration.o libSystemConfiguration_client.o libSystemConfiguration_server.o
+       $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -Wall -O0 -g -o test_hostname ip_pluginX.o IPMonitorControlPrefs.o agent-monitor.o configAgent.o controller.o dnsAgent.o proxyAgent.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o dns-configuration.o nat64-configuration.o proxy-configuration.o set-hostnameX.o smb-configuration.o libSystemConfiguration_client.o libSystemConfiguration_server.o ${EXTRA_CFLAGS} -lnetwork -framework SystemConfiguration -framework CoreFoundation -framework CoreServices -framework Foundation -framework Network -framework NetworkExtension
 
 # ----------
 
 smb-configurationX.o: smb-configuration.h smb-configuration.c
        $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -DMAIN -DDEBUG ${TEST_INCLUDE} ${EXTRA_CFLAGS} -Wall -O0 -g -c -o smb-configurationX.o smb-configuration.c
 
-test_smb: ip_pluginX.o IPMonitorControlPrefs.o agent-monitor.o configAgent.o controller.o dnsAgent.o proxyAgent.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o network_state_information_priv.o network_information_server.o dns-configuration.o proxy-configuration.o set-hostname.o smb-configurationX.o IPMonitorControlServer.o libSystemConfiguration_client.o libSystemConfiguration_server.o
-       $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -Wall -O0 -g -o test_smb ip_pluginX.o IPMonitorControlPrefs.o agent-monitor.o configAgent.o controller.o dnsAgent.o proxyAgent.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o network_state_information_priv.o network_information_server.o dns-configuration.o proxy-configuration.o set-hostname.o smb-configurationX.o IPMonitorControlServer.o libSystemConfiguration_client.o libSystemConfiguration_server.o ${EXTRA_CFLAGS} -lnetwork -framework SystemConfiguration -framework CoreFoundation -framework Foundation -framework Network -framework NetworkExtension
+test_smb: ip_pluginX.o IPMonitorControlPrefs.o agent-monitor.o configAgent.o controller.o dnsAgent.o proxyAgent.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o dns-configuration.o nat64-configuration.o proxy-configuration.o set-hostname.o smb-configurationX.o libSystemConfiguration_client.o libSystemConfiguration_server.o
+       $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -Wall -O0 -g -o test_smb ip_pluginX.o IPMonitorControlPrefs.o agent-monitor.o configAgent.o controller.o dnsAgent.o proxyAgent.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o dns-configuration.o nat64-configuration.o proxy-configuration.o set-hostname.o smb-configurationX.o libSystemConfiguration_client.o libSystemConfiguration_server.o ${EXTRA_CFLAGS} -lnetwork -framework SystemConfiguration -framework CoreFoundation -framework CoreServices -framework Foundation -framework Network -framework NetworkExtension
 
 # ----------
 
 test_dns_order.o: ip_plugin.c
        $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -DTEST_DNS_ORDER ${TEST_INCLUDE} ${EXTRA_CFLAGS} -Wall -O0 -g -c -o $@ $^
 
-test_dns_order: test_dns_order.o IPMonitorControlPrefs.o agent-monitor.o configAgent.o controller.o dnsAgent.o proxyAgent.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o network_state_information_priv.o network_information_server.o dns-configuration.o proxy-configuration.o set-hostname.o smb-configuration.o IPMonitorControlServer.o libSystemConfiguration_client.o libSystemConfiguration_server.o
-       $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -Wall -O0 -g -o test_dns_order test_dns_order.o IPMonitorControlPrefs.o agent-monitor.o configAgent.o controller.o dnsAgent.o proxyAgent.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o network_state_information_priv.o network_information_server.o dns-configuration.o proxy-configuration.o set-hostname.o smb-configuration.o IPMonitorControlServer.o libSystemConfiguration_client.o libSystemConfiguration_server.o ${EXTRA_CFLAGS} -lnetwork -framework SystemConfiguration -framework CoreFoundation -framework Foundation -framework Network -framework NetworkExtension
+test_dns_order: test_dns_order.o IPMonitorControlPrefs.o agent-monitor.o configAgent.o controller.o dnsAgent.o proxyAgent.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o dns-configuration.o proxy-configuration.o set-hostname.o smb-configuration.o libSystemConfiguration_client.o libSystemConfiguration_server.o nat64-configuration.o
+       $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -Wall -O0 -g -o $@ test_dns_order.o IPMonitorControlPrefs.o agent-monitor.o configAgent.o controller.o dnsAgent.o proxyAgent.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o dns-configuration.o proxy-configuration.o set-hostname.o smb-configuration.o libSystemConfiguration_client.o libSystemConfiguration_server.o nat64-configuration.o $(EXTRA_CFLAGS) -lnetwork -framework SystemConfiguration -framework CoreFoundation -framework Foundation -framework Network -framework NetworkExtension -framework CoreServices
 
 # ----------
+
 test_ipv4_routelist.o: ip_plugin.c
        $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -DTEST_IPV4_ROUTELIST ${TEST_INCLUDE} ${EXTRA_CFLAGS} -Wall -O0 -g -c -o $@ $^
 
 test_ipv4_routelist: test_ipv4_routelist.o IPMonitorControlPrefs.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o dns-configuration.o proxy-configuration.o set-hostname.o smb-configuration.o libSystemConfiguration_client.o libSystemConfiguration_server.o
-       $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -Wall -O0 -g -o test_ipv4_routelist $^ ${EXTRA_CFLAGS} -lnetwork -framework SystemConfiguration -framework CoreFoundation -framework Foundation -framework Network -framework NetworkExtension
+       $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -Wall -O0 -g -o test_ipv4_routelist $^ ${EXTRA_CFLAGS} -lnetwork -framework SystemConfiguration -framework CoreFoundation -framework Foundation -framework Network -framework NetworkExtension -framework CoreServices
 
 test_ipv4_routelist_reference.txt: test_ipv4_routelist
        sh $(REFERENCE_OUTPUT) create ./test_ipv4_routelist test_ipv4_routelist_reference.txt routelist_output_filter.sh
        $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -DTEST_IPV6_ROUTELIST=1 ${TEST_INCLUDE} ${EXTRA_CFLAGS} -Wall -O0 -g -c -o $@ $^
 
 test_ipv6_routelist: test_ipv6_routelist.o IPMonitorControlPrefs.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o dns-configuration.o proxy-configuration.o set-hostname.o smb-configuration.o libSystemConfiguration_client.o libSystemConfiguration_server.o
-       $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -Wall -O0 -g -o test_ipv6_routelist $^ ${EXTRA_CFLAGS} -lnetwork -framework SystemConfiguration -framework CoreFoundation -framework Foundation -framework Network -framework NetworkExtension
+       $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -Wall -O0 -g -o test_ipv6_routelist $^ ${EXTRA_CFLAGS} -lnetwork -framework SystemConfiguration -framework CoreFoundation -framework Foundation -framework Network -framework NetworkExtension -framework CoreServices
 
 test_ipv6_routelist_reference.txt: test_ipv6_routelist
        sh $(REFERENCE_OUTPUT) create ./test_ipv6_routelist test_ipv6_routelist_reference.txt routelist_output_filter.sh
 
        CFRelease(global_proxy);
 }
 
+- (void)applyPolicies
+{
+       if (self.controlPolicySession != nil && ![self.controlPolicySession apply]) {
+               SC_log(LOG_ERR, "Failed to apply control policies");
+       }
+       if (self.policySession != nil && ![self.policySession apply]) {
+               SC_log(LOG_ERR, "Failed to apply policies");
+       }
+}
+
 - (void)processProxyChanges
 {
        CFDictionaryRef                 proxies;
        if (proxies == NULL) {
                SC_log(LOG_INFO, "No proxy information");
 
+               BOOL destroyedAgent = NO;
                NSMutableDictionary *copy = [self.floatingProxyAgentList copy];
                for (NSString *entity in copy) {
                        id agent = [copy objectForKey:entity];
                        [self destroyFloatingAgent:agent];
+                       destroyedAgent = YES;
                }
 
+               if (destroyedAgent) {
+                       [self applyPolicies];
+               }
                return;
        }
 
        [self processSupplementalProxyChanges:proxies];
        [self processServiceSpecificProxyChanges:proxies];
 
+       [self applyPolicies];
+
        CFRelease(proxies);
 }
 
 done:
 
        [self processOnionResolver:dns_config];
+       [self applyPolicies];
+
        if (dns_config != NULL) {
                dns_configuration_free(dns_config);
        }
        NEPolicySession         *       session;
        uint32_t                        multiple_entity_offset;
        NEPolicy                *       newPolicy;
-       BOOL                            ok;
        uint32_t                        order;
        uint32_t                        orderForSkip;
        NSMutableArray          *       policyArray;
                return NO;
        }
 
-       ok = [session apply];
-       if (!ok) {
-               SC_log(LOG_NOTICE, "Could not apply policy for agent %@", [agent getAgentName]);
-               return NO;
-       }
-
        policyArray = [self.policyDB objectForKey:[agent getAgentName]];
        if (policyArray == nil) {
                policyArray = [NSMutableArray array];
        [policyArray addObject:numberToNSNumber(policyID2)];
        [self.policyDB setObject:policyArray forKey:[agent getAgentName]];
 
-       return ok;
+       return YES;
 }
 
 #pragma mark Agent manipulation functions
                                }
                        }
 
-                       result = [session apply];
-                       if (result == NO) {
-                               SC_log(LOG_NOTICE, "Could not apply removed policies for agent %@", [agent getAgentName]);
-                       }
-
                        [self.policyDB removeObjectForKey:[agent getAgentName]];
                }
 
                                        SC_log(LOG_ERR, "Could not remove policies for agent %@", [agent getAgentName]);
                                }
 
-                               ok = [self.controlPolicySession apply];
-                               if (!ok) {
-                                       SC_log(LOG_ERR, "Could not apply policy change for agent %@", [agent getAgentName]);
-                               }
-
                                self.controlPolicySession = nil;
                                SC_log(LOG_NOTICE, "Closed control policy session");
                        }
 
 #include <arpa/inet.h>
 #include <arpa/nameser.h>
 #include <resolv.h>
-#include <notify.h>
-#include <notify_private.h>
 #include <CommonCrypto/CommonDigest.h>
 
 #include <CoreFoundation/CoreFoundation.h>
 #include <dns_sd.h>
 #include <dns_sd_private.h>
 
+#if    !TARGET_OS_IPHONE
+#include <CoreServices/CoreServices.h>
+#else  // TARGET_OS_IPHONE
+#include <FSEvents/FSEvents.h>
+#endif // TARGET_OS_IPHONE
+
 #define DNS_CONFIGURATION_FLAGS_KEY    CFSTR("__FLAGS__")
 #define DNS_CONFIGURATION_IF_INDEX_KEY CFSTR("__IF_INDEX__")
 #define DNS_CONFIGURATION_ORDER_KEY    CFSTR("__ORDER__")
                      CFDictionaryRef   services,
                      CFArrayRef        serviceOrder,
                      CFArrayRef        multicastResolvers,
-                     CFArrayRef        privateResolvers)
+                     CFArrayRef        privateResolvers,
+                     CFDictionaryRef   *globalResolver)
 {
        dns_create_config_t     dns_create_config;
        Boolean                 changed                 = FALSE;
                                resolver = new_resolver;
                        }
 
+                       if (i == 0) {
+                               *globalResolver = CFRetain(resolver);
+                       }
+
                        _resolver = create_resolver(resolver);
                        _dns_configuration_add_resolver(&dns_create_config, _resolver);
                        _dns_resolver_free(&_resolver);
 static SCDynamicStoreCallBack  dns_configuration_callout;
 
 static void
-dns_configuration_changed(CFMachPortRef port, void *msg, CFIndex size, void *info)
+dns_configuration_changed(ConstFSEventStreamRef                streamRef,
+                         void                          *clientCallBackInfo,
+                         size_t                        numEvents,
+                         void                          *eventPaths,
+                         const FSEventStreamEventFlags *eventFlags,
+                         const FSEventStreamEventId    *eventIds)
 {
-#pragma unused(port)
-#pragma unused(msg)
-#pragma unused(size)
-#pragma unused(info)
+#pragma unused(streamRef)
+#pragma unused(clientCallBackInfo)
+#pragma unused(numEvents)
+#pragma unused(eventPaths)
+#pragma unused(eventFlags)
+#pragma unused(eventIds)
        static const CFStringRef        key     = CFSTR(_PATH_RESOLVER_DIR);
        CFArrayRef                      keys;
        Boolean                         resolvers_now;
 void
 dns_configuration_monitor(SCDynamicStoreRef store, SCDynamicStoreCallBack callout)
 {
-       CFMachPortRef           mp;
-       mach_port_t             notify_port;
-       int                     notify_token;
-       char                    resolver_directory_path[PATH_MAX];
-       CFRunLoopSourceRef      rls;
-       uint32_t                status;
+       FSEventStreamContext            context = { 0,          // version
+                                                   NULL,       // info
+                                                   NULL,       // retain
+                                                   NULL,       // release
+                                                   NULL };     // copyDescription
+       FSEventStreamCreateFlags        flags   = kFSEventStreamCreateFlagUseCFTypes
+                                                 | kFSEventStreamCreateFlagFileEvents
+                                                 | kFSEventStreamCreateFlagWatchRoot;
+       FSEventStreamRef                monitor;
+       CFStringRef                     path;
+       CFMutableArrayRef               paths;
+       char                            resolver_directory_path[PATH_MAX];
 
        if (!normalize_path(_PATH_RESOLVER_DIR, resolver_directory_path)) {
                my_log(LOG_ERR, "Not monitoring \"%s\", could not resolve directory path", _PATH_RESOLVER_DIR);
        dns_configuration_store   = store;
        dns_configuration_callout = callout;
 
-       status = notify_register_mach_port(_PATH_RESOLVER_DIR, ¬ify_port, 0, ¬ify_token);
-       if (status != NOTIFY_STATUS_OK) {
-               my_log(LOG_ERR, "notify_register_mach_port() failed");
-               return;
-       }
+       paths = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       path = CFStringCreateWithCString(NULL, resolver_directory_path, kCFStringEncodingUTF8);
+       CFArrayAppendValue(paths, path);
+       CFRelease(path);
 
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated"
-       status = notify_monitor_file(notify_token, resolver_directory_path, 0);
-#pragma GCC diagnostic pop
-       if (status != NOTIFY_STATUS_OK) {
-               my_log(LOG_ERR, "notify_monitor_file() failed");
-               (void)notify_cancel(notify_token);
-               return;
-       }
+       monitor = FSEventStreamCreate(NULL,                             // allocator
+                                     dns_configuration_changed,        // callback
+                                     &context,                         // context
+                                     paths,                            // pathsToWatch (CFArray)
+                                     kFSEventStreamEventIdSinceNow,    // sinceWhen
+                                     0.0,                              // latency
+                                     flags);                           // flags
 
-       mp = _SC_CFMachPortCreateWithPort("IPMonitor/dns_configuration",
-                                         notify_port,
-                                         dns_configuration_changed,
-                                         NULL);
+       CFRelease(paths);
 
-       rls = CFMachPortCreateRunLoopSource(NULL, mp, -1);
-       if (rls == NULL) {
-               my_log(LOG_ERR, "SCDynamicStoreCreateRunLoopSource() failed");
-               CFRelease(mp);
-               (void)notify_cancel(notify_token);
-               return;
-       }
-       CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
-       CFRelease(rls);
+       FSEventStreamScheduleWithRunLoop(monitor, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+       FSEventStreamStart(monitor);
 
-       CFRelease(mp);
        return;
 }
 
 main(int argc, char **argv)
 {
        CFDictionaryRef         entities;
+       CFDictionaryRef         globalResolver  = NULL;
        CFStringRef             key;
        CFArrayRef              multicast_resolvers;
        CFStringRef             pattern;
                                    service_state_dict,
                                    service_order,
                                    multicast_resolvers,
-                                   private_resolvers);
+                                   private_resolvers,
+                                   &globalResolver);
 
        // cleanup
        if (setup_global_ipv4 != NULL)  CFRelease(setup_global_ipv4);
        if (state_global_ipv4 != NULL)  CFRelease(state_global_ipv4);
        if (multicast_resolvers != NULL) CFRelease(multicast_resolvers);
        if (private_resolvers != NULL)  CFRelease(private_resolvers);
+       if (globalResolver != NULL)     CFRelease(globalResolver);
        CFRelease(service_state_dict);
        CFRelease(store);
 
 
 /*
- * Copyright (c) 2006, 2008, 2009, 2011, 2012, 2015, 2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2006, 2008, 2009, 2011, 2012, 2015, 2018, 2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
                                         CFDictionaryRef        services,
                                         CFArrayRef             serviceOrder,
                                         CFArrayRef             multicastResolvers,
-                                        CFArrayRef             privateResolvers);
+                                        CFArrayRef             privateResolvers,
+                                        CFDictionaryRef        *globalResolver);
 
 __END_DECLS
 
 
 
 static boolean_t               S_append_state = FALSE;
 
-static CFDictionaryRef         S_dns_dict = NULL;
+static CFDictionaryRef         S_dns_global_dict = NULL;
+
+static CFDictionaryRef         S_dns_primary_dict = NULL;
 
 static Boolean                 S_dnsinfo_synced = TRUE;
 
     else {
        /* make space at [where] */
        insert_route = RouteListGetRouteAtIndexSimple(info, routes, where);
-       memcpy((void *)insert_route + info->element_size,
-              insert_route,
-              info->element_size * (routes->count - where));
+       /* overlapping copy requires memmove */
+       memmove((void *)insert_route + info->element_size,
+               insert_route,
+               info->element_size * (routes->count - where));
     }
     /* copy the route */
     memcpy(insert_route, this_route, info->element_size);
        RouteRef        remove_route;
 
        remove_route = RouteListGetRouteAtIndexSimple(info, routes, where);
-       memcpy(remove_route,
-              (void *)remove_route + info->element_size,
-              info->element_size * (routes->count - where));
+       /* overlapping copy requires memmove */
+       memmove(remove_route,
+               (void *)remove_route + info->element_size,
+               info->element_size * (routes->count - where));
     }
     return;
 }
 
     if (val != NULL) {
        boolean_t       is_ipv4;
-       boolean_t       is_ipv6;
 
        if ((is_ipv4 = CFEqual(entity, kSCEntNetIPv4))
-           || (is_ipv6 = CFEqual(entity, kSCEntNetIPv6))) {
+           || CFEqual(entity, kSCEntNetIPv6)) {
            RouteListUnion      routes;
 
            routes.ptr = ipdict_get_routelist(val);
 __private_extern__ CFDictionaryRef
 ipv4_dict_create(CFDictionaryRef state_dict)
 {
-    return (IPDictCreate(AF_INET, state_dict, NULL, NULL, NULL));
+    return (IPDictCreate(AF_INET, state_dict, NULL, NULL));
 }
 
 __private_extern__ CFDictionaryRef
 ipv6_dict_create(CFDictionaryRef state_dict)
 {
-    return (IPDictCreate(AF_INET6, state_dict, NULL, NULL, NULL));
+    return (IPDictCreate(AF_INET6, state_dict, NULL, NULL));
 }
 
 #endif /* TEST_DNS */
 
 static void
 add_service_keys(CFStringRef           serviceID,
-                CFMutableArrayRef      keys,
-                CFMutableArrayRef      patterns)
+                CFMutableArrayRef      keys)
 {
     int                        i;
     CFStringRef                key;
 
-    if (CFEqual(serviceID, kSCCompAnyRegex)) {
-       keys = patterns;
-    }
-
     for (i = 0; i < ENTITY_TYPES_COUNT; i++) {
        CFStringRef     name    = *entityTypeNames[i];
 
 
 static void
 add_transient_status_keys(CFStringRef          serviceID,
-                         CFMutableArrayRef     keys,
-                         CFMutableArrayRef     patterns)
+                         CFMutableArrayRef     keys)
 {
-    if (CFEqual(serviceID, kSCCompAnyRegex)) {
-       keys = patterns;
-    }
-
     for (size_t i = 0; i < countof(transientServiceInfo); i++) {
        CFStringRef     key;
 
     for (CFIndex s = 0; s < count; s++) {
        CFStringRef     serviceID = CFArrayGetValueAtIndex(service_list, s);
 
-       add_service_keys(serviceID, keys, patterns);
-       add_transient_status_keys(serviceID, keys, patterns);
+       add_service_keys(serviceID, keys);
+       add_transient_status_keys(serviceID, keys);
     }
 
     add_reachability_patterns(patterns);
           keyChangeListRef     keys)
 {
 #pragma unused(services_info)
+#pragma unused(keys)
     Boolean            changed = FALSE;
     CFDictionaryRef    dict    = NULL;
 
        }
     }
 
-    if (!_SC_CFEqual(S_dns_dict, dict)) {
-       if (dict == NULL) {
+    if (!_SC_CFEqual(S_dns_primary_dict, dict)) {
+       changed = TRUE;
+    }
+
+    if (dict != NULL) CFRetain(dict);
+    if (S_dns_primary_dict != NULL) CFRelease(S_dns_primary_dict);
+    S_dns_primary_dict = dict;
+
+    return changed;
+}
+
+static Boolean
+update_dns_global_resolver(CFDictionaryRef     dict,
+                          keyChangeListRef     keys)
+{
+    if (_SC_CFEqual(S_dns_global_dict, dict)) {
+       // if no changes
+       return FALSE;
+    }
+
+    if (dict != NULL) CFRetain(dict);
+    if (S_dns_global_dict != NULL) CFRelease(S_dns_global_dict);
+    S_dns_global_dict = dict;
+
+    if (dict == NULL) {
 #if    !TARGET_OS_IPHONE
-           empty_dns();
+       /*
+        * remove /etc/resolv.conf
+        */
+       empty_dns();
 #endif /* !TARGET_OS_IPHONE */
-           keyChangeListRemoveValue(keys, S_state_global_dns);
-       } else {
-           CFMutableDictionaryRef      new_dict;
+       /*
+        * remove State:/Network/Global/DNS
+        */
+       keyChangeListRemoveValue(keys, S_state_global_dns);
+    } else {
+       CFMutableDictionaryRef  new_dict;
 
 #if    !TARGET_OS_IPHONE
-           set_dns(CFDictionaryGetValue(dict, kSCPropNetDNSSearchDomains),
-                   CFDictionaryGetValue(dict, kSCPropNetDNSDomainName),
-                   CFDictionaryGetValue(dict, kSCPropNetDNSServerAddresses),
-                   CFDictionaryGetValue(dict, kSCPropNetDNSSortList));
+       /*
+        * update /etc/resolv.conf
+        */
+       set_dns(CFDictionaryGetValue(dict, kSCPropNetDNSSearchDomains),
+               CFDictionaryGetValue(dict, kSCPropNetDNSDomainName),
+               CFDictionaryGetValue(dict, kSCPropNetDNSServerAddresses),
+               CFDictionaryGetValue(dict, kSCPropNetDNSSortList));
 #endif /* !TARGET_OS_IPHONE */
-           new_dict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
-           CFDictionaryRemoveValue(new_dict, kSCPropInterfaceName);
-           CFDictionaryRemoveValue(new_dict, kSCPropNetDNSSupplementalMatchDomains);
-           CFDictionaryRemoveValue(new_dict, kSCPropNetDNSSupplementalMatchOrders);
-           CFDictionaryRemoveValue(new_dict, DNS_CONFIGURATION_SCOPED_QUERY_KEY);
-           keyChangeListSetValue(keys, S_state_global_dns, new_dict);
-           CFRelease(new_dict);
-       }
-       changed = TRUE;
-    }
 
-    if (dict != NULL) CFRetain(dict);
-    if (S_dns_dict != NULL) CFRelease(S_dns_dict);
-    S_dns_dict = dict;
+       /*
+        * update State:/Network/Global/DNS
+        */
+       new_dict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
+       CFDictionaryRemoveValue(new_dict, kSCPropInterfaceName);
+       CFDictionaryRemoveValue(new_dict, kSCPropNetDNSSupplementalMatchDomains);
+       CFDictionaryRemoveValue(new_dict, kSCPropNetDNSSupplementalMatchOrders);
+       CFDictionaryRemoveValue(new_dict, DNS_CONFIGURATION_SCOPED_QUERY_KEY);
+       keyChangeListSetValue(keys, S_state_global_dns, new_dict);
+       CFRelease(new_dict);
+    }
 
-    return changed;
+    return TRUE;
 }
 
 static Boolean
               CFArrayRef       service_order)
 {
     Boolean            changed;
-    CFDictionaryRef    dict    = NULL;
+    CFDictionaryRef    dict            = NULL;
+    CFDictionaryRef    globalResolver  = NULL;
     CFArrayRef         multicastResolvers;
     CFArrayRef         privateResolvers;
 
                                    S_service_state_dict,
                                    service_order,
                                    multicastResolvers,
-                                   privateResolvers);
+                                   privateResolvers,
+                                   &globalResolver);
     if (changed) {
-       keyChangeListNotifyKey(keys, S_state_global_dns);
+       if (!update_dns_global_resolver(globalResolver, keys)) {
+           /*
+            * There was no change to the default/global resolver
+            * configuration.  Even so, we still want to strobe
+            * the State:/Network/Global/DNS key to indicate that
+            * "a" change had occured.
+            */
+           keyChangeListNotifyKey(keys, S_state_global_dns);
+       }
     }
+    if (globalResolver != NULL) CFRelease(globalResolver);
+
     return changed;
 }
 
     my_log(LOG_INFO, "Updating network information");
     _nwi_state_log(state, TRUE, NULL);
 
-#if !TEST_IPV4_ROUTELIST && !TEST_IPV6_ROUTELIST
+#if !TEST_IPV4_ROUTELIST && !TEST_IPV6_ROUTELIST && !TEST_DNS && !TEST_DNS_ORDER
     if (!_nwi_state_store(state)) {
        my_log(LOG_ERR, "Notifying nwi_state_store failed");
     }
-#endif /* !TEST_IPV4_ROUTELIST && !TEST_IPV6_ROUTELIST */
+#endif /* !TEST_IPV4_ROUTELIST && !TEST_IPV6_ROUTELIST && !TEST_DNS && !TEST_DNS_ORDER */
 
     return TRUE;
 }
 #endif /* !TARGET_OS_SIMULATOR */
 
 
+static CFArrayRef
+ip_plugin_copy_keys(void)
+{
+    const void *       values[]
+       = {
+          S_setup_global_ipv4, /* serviceOrder/PPPOverridePrimary */
+          S_private_resolvers, /* private DNS config (Back to My Mac) */
+          S_multicast_resolvers,/* multicast DNS config (Bonjour/.local) */
+    };
+    const CFIndex      values_count = sizeof(values) / sizeof(values[0]);
 
-static void
-ip_plugin_init()
+    return (CFArrayCreate(NULL, values, values_count,
+                         &kCFTypeArrayCallBacks));
+}
+
+static CFArrayRef
+ip_plugin_copy_patterns(void)
 {
-    CFMutableArrayRef  keys = NULL;
     CFStringRef                pattern;
-    CFMutableArrayRef  patterns = NULL;
-    CFRunLoopSourceRef rls = NULL;
+    CFMutableArrayRef  patterns;
 
+    patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
+    /* State: and Setup: per-service notifications */
+    add_service_keys(kSCCompAnyRegex, patterns);
+
+    pattern = setup_service_key(kSCCompAnyRegex, kSCEntNetPPP);
+    CFArrayAppendValue(patterns, pattern);
+    CFRelease(pattern);
+
+    pattern = setup_service_key(kSCCompAnyRegex, kSCEntNetVPN);
+    CFArrayAppendValue(patterns, pattern);
+    CFRelease(pattern);
+
+    pattern = setup_service_key(kSCCompAnyRegex, kSCEntNetInterface);
+    CFArrayAppendValue(patterns, pattern);
+    CFRelease(pattern);
+
+    /* State: per-service PPP/VPN/IPSec status notifications */
+    add_transient_status_keys(kSCCompAnyRegex, patterns);
+
+#if !TARGET_OS_SIMULATOR && !TEST_IPV4_ROUTELIST && !TEST_IPV6_ROUTELIST
+    /* NAT64 prefix request pattern */
+    nat64_prefix_request_add_pattern(patterns);
+#endif /* TARGET_OS_SIMULATOR && !TEST_IPV4_ROUTELIST && !TEST_IPV6_ROUTELIST */
+
+    /* interface delegation pattern */
+    pattern = interface_entity_key_copy(kSCCompAnyRegex,
+                                       kSCEntNetInterfaceDelegation);
+    CFArrayAppendValue(patterns, pattern);
+    CFRelease(pattern);
+    return (patterns);
+}
+
+static void
+ip_plugin_init()
+{
     if (S_is_network_boot() != 0) {
        S_netboot = TRUE;
     }
        flush_inet_routes();
     }
 
+    /*
+     * Initialize globals
+     */
     S_session = SCDynamicStoreCreate(NULL, CFSTR("IPMonitor"),
                                   IPMonitorNotify, NULL);
     if (S_session == NULL) {
     S_interface_delegation_prefix
        = SCDynamicStoreKeyCreateNetworkInterface(NULL,
                                                  kSCDynamicStoreDomainState);
-
     S_service_state_dict
        = CFDictionaryCreateMutable(NULL, 0,
                                    &kCFTypeDictionaryKeyCallBacks,
                                    &kCFTypeDictionaryValueCallBacks);
-
     S_ipv4_service_rank_dict
        = CFDictionaryCreateMutable(NULL, 0,
                                    &kCFTypeDictionaryKeyCallBacks,
                                    &kCFTypeDictionaryValueCallBacks);
-
     S_ipv6_service_rank_dict
        = CFDictionaryCreateMutable(NULL, 0,
                                    &kCFTypeDictionaryKeyCallBacks,
                                    &kCFTypeDictionaryValueCallBacks);
+    S_multicast_resolvers
+       = SCDynamicStoreKeyCreate(NULL, CFSTR("%@/%@/%@"),
+                                 kSCDynamicStoreDomainState,
+                                 kSCCompNetwork,
+                                 CFSTR(kDNSServiceCompMulticastDNS));
+    S_private_resolvers
+       = SCDynamicStoreKeyCreate(NULL, CFSTR("%@/%@/%@"),
+                                 kSCDynamicStoreDomainState,
+                                 kSCCompNetwork,
+                                 CFSTR(kDNSServiceCompPrivateDNS));
+    /* initialize dns configuration */
+    (void)dns_configuration_set(NULL, NULL, NULL, NULL, NULL, NULL);
+#if    !TARGET_OS_IPHONE
+    empty_dns();
+#endif /* !TARGET_OS_IPHONE */
+    (void)SCDynamicStoreRemoveValue(S_session, S_state_global_dns);
 
-    keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-    patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-
-    /* register for State: and Setup: per-service notifications */
-    add_service_keys(kSCCompAnyRegex, keys, patterns);
-
-    pattern = setup_service_key(kSCCompAnyRegex, kSCEntNetPPP);
-    CFArrayAppendValue(patterns, pattern);
-    CFRelease(pattern);
+#if    !TARGET_OS_IPHONE
+    /* initialize SMB configuration */
+    (void)SCDynamicStoreRemoveValue(S_session, S_state_global_smb);
+#endif /* !TARGET_OS_IPHONE */
 
-    pattern = setup_service_key(kSCCompAnyRegex, kSCEntNetVPN);
-    CFArrayAppendValue(patterns, pattern);
-    CFRelease(pattern);
+    watch_proxies();
 
-    pattern = setup_service_key(kSCCompAnyRegex, kSCEntNetInterface);
-    CFArrayAppendValue(patterns, pattern);
-    CFRelease(pattern);
+    return;
+}
 
-    /* register for State: per-service PPP/VPN/IPSec status notifications */
-    add_transient_status_keys(kSCCompAnyRegex, NULL, patterns);
+static CFArrayRef
+copy_dictionary_keys(CFDictionaryRef dict)
+{
+    CFIndex            count;
+    CFArrayRef         ret_keys;
 
-    /* add notifier for ServiceOrder/PPPOverridePrimary changes for IPv4 */
-    CFArrayAppendValue(keys, S_setup_global_ipv4);
+    count = CFDictionaryGetCount(dict);
+    if (count > 0) {
+       const void *    keys[count];
 
-    /* add notifier for multicast DNS configuration (Bonjour/.local) */
-    S_multicast_resolvers = SCDynamicStoreKeyCreate(NULL, CFSTR("%@/%@/%@"),
-                                                   kSCDynamicStoreDomainState,
-                                                   kSCCompNetwork,
-                                                   CFSTR(kDNSServiceCompMulticastDNS));
-    CFArrayAppendValue(keys, S_multicast_resolvers);
+       CFDictionaryGetKeysAndValues(dict, keys, NULL);
+       ret_keys = CFArrayCreate(NULL, keys, count, &kCFTypeArrayCallBacks);
+    }
+    else {
+       ret_keys = NULL;
+    }
+    return (ret_keys);
+}
 
-    /* add notifier for private DNS configuration (Back to My Mac) */
-    S_private_resolvers = SCDynamicStoreKeyCreate(NULL, CFSTR("%@/%@/%@"),
-                                                 kSCDynamicStoreDomainState,
-                                                 kSCCompNetwork,
-                                                 CFSTR(kDNSServiceCompPrivateDNS));
-    CFArrayAppendValue(keys, S_private_resolvers);
+static void
+prime_notifications(CFArrayRef keys, CFArrayRef patterns)
+{
+    CFArrayRef         changed_keys;
+    CFDictionaryRef    info;
 
-#if    !TARGET_OS_SIMULATOR && !TEST_IPV4_ROUTELIST && !TEST_IPV6_ROUTELIST
-    /* add NAT64 prefix request pattern */
-    nat64_prefix_request_add_pattern(patterns);
-#endif /* TARGET_OS_SIMULATOR && !TEST_IPV4_ROUTELIST && !TEST_IPV6_ROUTELIST */
+    info = SCDynamicStoreCopyMultiple(S_session, keys, patterns);
+    if (info == NULL) {
+       my_log(LOG_NOTICE, "%s: no content", __func__);
+       return;
+    }
+    changed_keys = copy_dictionary_keys(info);
+    CFRelease(info);
+    if (changed_keys == NULL) {
+       my_log(LOG_NOTICE, "%s: no keys", __func__);
+       return;
+    }
+    my_log(LOG_NOTICE,
+          "IPMonitor prime %ld keys %@",
+          (long)CFArrayGetCount(changed_keys), changed_keys);
+    IPMonitorProcessChanges(S_session, changed_keys, NULL);
+    CFRelease(changed_keys);
+    return;
+}
 
-    /* add interface delegation pattern */
-    pattern = interface_entity_key_copy(kSCCompAnyRegex, kSCEntNetInterfaceDelegation);
-    CFArrayAppendValue(patterns, pattern);
-    CFRelease(pattern);
+static void
+initialize_notifications(void)
+{
+    CFArrayRef         keys;
+    CFArrayRef         patterns;
+    Boolean            success;
 
-    if (!SCDynamicStoreSetNotificationKeys(S_session, keys, patterns)) {
+    /* register for notifications */
+    keys = ip_plugin_copy_keys();
+    patterns = ip_plugin_copy_patterns();
+    success = SCDynamicStoreSetNotificationKeys(S_session, keys, patterns);
+    if (!success) {
        my_log(LOG_ERR,
               "SCDynamicStoreSetNotificationKeys() failed: %s",
               SCErrorString(SCError()));
-       goto done;
-    }
-
-    rls = SCDynamicStoreCreateRunLoopSource(NULL, S_session, 0);
-    if (rls == NULL) {
-       my_log(LOG_ERR,
-              "SCDynamicStoreCreateRunLoopSource() failed: %s",
-              SCErrorString(SCError()));
-       goto done;
     }
+    else {
+       CFRunLoopSourceRef      rls;
 
-    CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
-    CFRelease(rls);
-
-    /* initialize dns configuration */
-    (void)dns_configuration_set(NULL, NULL, NULL, NULL, NULL);
-#if    !TARGET_OS_IPHONE
-    empty_dns();
-#endif /* !TARGET_OS_IPHONE */
-    (void)SCDynamicStoreRemoveValue(S_session, S_state_global_dns);
-
-#if    !TARGET_OS_IPHONE
-    /* initialize SMB configuration */
-    (void)SCDynamicStoreRemoveValue(S_session, S_state_global_smb);
-#endif /* !TARGET_OS_IPHONE */
-
-    watch_proxies();
+       rls = SCDynamicStoreCreateRunLoopSource(NULL, S_session, 0);
+       if (rls == NULL) {
+           my_log(LOG_ERR,
+                  "SCDynamicStoreCreateRunLoopSource() failed: %s",
+                  SCErrorString(SCError()));
+       }
+       else {
+           CFRunLoopAddSource(CFRunLoopGetCurrent(), rls,
+                              kCFRunLoopDefaultMode);
+           CFRelease(rls);
 
-  done:
-    my_CFRelease(&keys);
-    my_CFRelease(&patterns);
+           /* catch any changes that happened before registering */
+           prime_notifications(keys, patterns);
+       }
+    }
+    CFRelease(keys);
+    CFRelease(patterns);
     return;
 }
 
 __private_extern__
 void
-prime_IPMonitor()
+prime_IPMonitor(void)
 {
     /* initialize multicast route */
     update_ipv4(NULL, NULL, NULL);
 
+    if (S_session == NULL) {
+       return;
+    }
+
+    /* initialize notifications */
+    CFRunLoopPerformBlock(CFRunLoopGetCurrent(),
+                         kCFRunLoopDefaultMode,
+                         ^{ initialize_notifications(); });
+
 #if    !TARGET_OS_SIMULATOR && !TEST_IPV4_ROUTELIST && !TEST_IPV6_ROUTELIST
     process_AgentMonitor();
 #endif // !TARGET_OS_SIMULATOR
     return (ret);
 }
 
-#if    !TARGET_OS_SIMULATOR && !TEST_IPV4_ROUTELIST && !TEST_IPV6_ROUTELIST
+#if    !TARGET_OS_SIMULATOR && !TEST_IPV4_ROUTELIST && !TEST_IPV6_ROUTELIST && !TEST_DNS && !TEST_DNS_ORDER
 #include "IPMonitorControlServer.h"
 
 static void
     return;
 }
 
-#endif /* !TARGET_OS_SIMULATOR */
+#endif /* !TARGET_OS_SIMULATOR && !TEST_IPV4_ROUTELIST && !TEST_IPV6_ROUTELIST && !TEST_DNS && !TEST_DNS_ORDER */
 
 __private_extern__
 void
     /* register to receive changes to the "verbose" flag and read the initial setting  */
     prefs_changed_callback_init();
 
-#if !TEST_IPV4_ROUTELIST && !TEST_IPV6_ROUTELIST
+#if !TEST_IPV4_ROUTELIST && !TEST_IPV6_ROUTELIST && !TEST_DNS && !TEST_DNS_ORDER
     /* start DNS configuration (dnsinfo) server */
     load_DNSConfiguration(bundle,                      // bundle
                          ^(Boolean inSync) {           // syncHandler
                                    post_network_change_when_ready();
                                });
                            });
-#endif /* !TEST_IPV4_ROUTELIST && !TEST_IPV6_ROUTELIST */
+#endif /* !TEST_IPV4_ROUTELIST && !TEST_IPV6_ROUTELIST && !TEST_DNS && !TEST_DNS_ORDER */
 
-#if    !TARGET_OS_SIMULATOR && !TEST_IPV4_ROUTELIST && !TEST_IPV6_ROUTELIST
+#if    !TARGET_OS_SIMULATOR && !TEST_IPV4_ROUTELIST && !TEST_IPV6_ROUTELIST && !TEST_DNS && !TEST_DNS_ORDER
     /* start IPMonitor Control (InterfaceRank) server */
     StartIPMonitorControlServer();
-#endif /* !TARGET_OS_IPHONE */
+#endif /* !TARGET_OS_SIMULATOR && !TEST_IPV4_ROUTELIST && !TEST_IPV6_ROUTELIST && !TEST_DNS && !TEST_DNS_ORDER */
 
     /* initialize DNS configuration */
     dns_configuration_init(bundle);
 }
 #endif /* TEST_IPMONITOR */
 
-#ifdef TEST_ROUTELIST
+#if defined(TEST_ROUTELIST) || defined(TEST_DNS_ORDER)
+
+#if defined(__has_feature)
+#if __has_feature(address_sanitizer)
+#define TEST_ROUTELIST_RUN_LEAKS       FALSE
+#endif /* if __has_feature(address_sanitizer) */
+#endif /* if defined(__has_feature) */
+
+#ifndef TEST_ROUTELIST_RUN_LEAKS
+#define TEST_ROUTELIST_RUN_LEAKS       TRUE
+#endif
+
+static boolean_t       S_run_leaks = TEST_ROUTELIST_RUN_LEAKS;
+
+static void
+test_complete(void)
+{
+    printf("\nTest Complete\n");
+    if (S_run_leaks) {
+       char    cmd[128];
+
+       sprintf(cmd, "leaks %d 2>&1", getpid());
+       fflush(stdout);
+       (void)system(cmd);
+    }
+}
 
 struct route {
     const char *       dest;
            apply_test(*test2, *test);
        }
     }
-
-    {
-       char    cmd[128];
-
-       printf("\nChecking for leaks\n");
-       sprintf(cmd, "leaks %d 2>&1", getpid());
-       fflush(stdout);
-       (void)system(cmd);
-    }
+    test_complete();
     exit(0);
     return (0);
 }
            apply_test(*test2, *test);
        }
     }
-
-    {
-       char    cmd[128];
-
-       printf("\nChecking for leaks\n");
-       sprintf(cmd, "leaks %d 2>&1", getpid());
-       fflush(stdout);
-       (void)system(cmd);
-    }
+    test_complete();
     exit(0);
     return (0);
 }
 int
 main(int argc, char **argv)
 {
+
     _sc_log     = kSCLogDestinationFile;
     _sc_verbose = (argc > 1) ? TRUE : FALSE;
     S_IPMonitor_debug = kDebugFlag1 | kDebugFlag2 | kDebugFlag4;
     for (DNSOrderTestRef * test = dns_order_tests; *test != NULL; test++) {
        apply_test(*test);
     }
-
-    {
-       char    cmd[128];
-
-       printf("\nChecking for leaks\n");
-       sprintf(cmd, "leaks %d 2>&1", getpid());
-       fflush(stdout);
-       (void)system(cmd);
-    }
-
+    test_complete();
     exit(0);
     return (0);
 }
 
 #!/bin/sh
-sed -e 's/^\(Process:.*\[\)[0-9][0-9]*/\1XXXX/'                        \
-    -e 's/^\(Load Address:.*\)[0-9a-f][0-9a-f]*/\10xXXXX/'     \
-    -e '/^Version:.*/d'                                                \
-    -e '/^Analysis Tool:.*/d'                                  \
-    -e '/^----$/d'                                             \
-    -e 's/^\(Parent Process:.*\[\)[0-9][0-9]*/\1XXXX/'         \
-    -e 's/^\(Date\/Time: *\)[0-9].*/\1XXXX/'                   \
-    -e '/Process [0-9][0-9]*: [0-9][0-9]* nodes malloced/d'    \
-    -e 's/^\(Process \)[0-9][0-9]*:\(.*\)/\1XXXX\2/'           \
-    -e 's/^\(Path: \)\(.*$\)/\1XXXX/'                          \
-    -e 's/^\(OS Version: \)\(.*$\)/\1XXXX/'                    \
-    -e '/^Load Address:.*/d'                                   \
-    -e '/^Launch Time:.*/d'                                    \
-    -e '/^Parent Process:.*/d'                                 \
-    -e '/^Analysis Tool Version:.*/d'                          \
-    -e '/^Physical footprint:.*/d'                             \
-    -e '/^Physical footprint (peak):.*/d'
+while IFS="" read a
+do
+    if [ "${a}" = "Test Complete" ]; then
+       exit 0
+    fi
+    echo "${a}"
+done
 
 /*
- * Copyright (c) 2006-2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2006-2018, 2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 #include "ip_plugin.h"
 #endif // MAIN
 
-#define        HW_MODEL_LEN                    64                      // Note: must be >= NETBIOS_NAME_LEN (below)
-
 #define        NETBIOS_NAME_LEN                16
 
 #define        SMB_STARTUP_DELAY               60.0
        n = CFStringGetLength(str);
        if (n > (NETBIOS_NAME_LEN - 1)) {
                CFStringReplace(str,
-                               CFRangeMake(NETBIOS_NAME_LEN, n - (NETBIOS_NAME_LEN - 1)),
+                               CFRangeMake(NETBIOS_NAME_LEN - 1, n - (NETBIOS_NAME_LEN - 1)),
                                CFSTR(""));
                n = NETBIOS_NAME_LEN - 1;
        }
 
 Add new[9]: Net 255.255.255.255/32 Ifp en1 Ifa 192.168.2.50 [last] [SCOPED]
 =================> Apply 'test18', 'test17' End <=================
 
-Checking for leaks
-Process:         test_ipv4_routelist [XXXX]
-Path: XXXX
-Identifier:      test_ipv4_routelist
-Code Type:       X86-64
-
-Date/Time:       XXXX
-OS Version: XXXX
-Report Version:  7
-
-leaks Report Version: 4.0
-Process XXXX 0 leaks for 0 total leaked bytes.
-
 
 failed to add: Host 2620:149:4:f01:225:ff:fecc:89a1 Gate 2620:149:4:f01:225:ff:fecc:89a2 Ifp en0 Ifa 2001:470:1f05:3cb:cabc:c8ff:fe96:9601
 =================> Apply 'test5', 'test4' End <=================
 
-Checking for leaks
-Process:         test_ipv6_routelist [XXXX]
-Path: XXXX
-Identifier:      test_ipv6_routelist
-Code Type:       X86-64
-
-Date/Time:       XXXX
-OS Version: XXXX
-Report Version:  7
-
-leaks Report Version: 4.0
-Process XXXX 0 leaks for 0 total leaked bytes.
-
 
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.19</string>
+       <string>1.20</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.19</string>
+       <string>1.20</string>
 </dict>
 </plist>
 
  * ifnamer.c
  * - module that receives IOKit Network Interface messages
  *   and names any interface that currently does not have a name
- * - uses Interface Type and MACAddress as the unique identifying
+ * - uses InterfaceNamePrefix and MACAddress as the unique identifying
  *   keys; any interface that doesn't contain both of these properties
  *   is ignored and not processed
- * - stores the Interface Type, MACAddress, and Unit in permanent storage
+ * - stores the InterfaceNamePrefix, MACAddress, and Unit in permanent storage
  *   to give persistent interface names
  */
 
 if_unit_compare(const void *val1, const void *val2, void *context)
 {
 #pragma unused(context)
+    CFStringRef                prefix1;
+    CFStringRef                prefix2;
     CFComparisonResult res;
-    CFNumberRef                type1;
-    CFNumberRef                type2;
     CFNumberRef                unit1;
     CFNumberRef                unit2;
 
-    type1 = CFDictionaryGetValue((CFDictionaryRef)val1,
-                                CFSTR(kIOInterfaceType));
-    type2 = CFDictionaryGetValue((CFDictionaryRef)val2,
-                                CFSTR(kIOInterfaceType));
-    res = CFNumberCompare(type1, type2, NULL);
+    prefix1 = CFDictionaryGetValue((CFDictionaryRef)val1,
+                                  CFSTR(kIOInterfaceNamePrefix));
+    prefix2 = CFDictionaryGetValue((CFDictionaryRef)val2,
+                                  CFSTR(kIOInterfaceNamePrefix));
+    res = CFStringCompare(prefix1, prefix2, 0);
     if (res != kCFCompareEqualTo) {
        return (res);
     }
 
            dict = CFArrayGetValueAtIndex(if_list, i);
            if (isA_CFDictionary(dict) &&
-               CFDictionaryContainsKey(dict, CFSTR(kIOInterfaceType)) &&
+               CFDictionaryContainsKey(dict, CFSTR(kIOInterfaceNamePrefix)) &&
                CFDictionaryContainsKey(dict, CFSTR(kIOInterfaceUnit)) &&
                CFDictionaryContainsKey(dict, CFSTR(kIOMACAddress))) {
                    CFArrayAppendValue(db_list, dict);
        CFDictionarySetValue(new_if, kSCNetworkInterfaceHiddenConfigurationKey, kCFBooleanTrue);
     }
 
+    if (_SCNetworkInterfaceIsHiddenInterface(interface)) {
+       CFDictionarySetValue(new_if, kSCNetworkInterfaceHiddenInterfaceKey, kCFBooleanTrue);
+    }
+
     CFDictionarySetValue(new_if, CFSTR(kSCNetworkInterfaceActive), kCFBooleanTrue);
 
     if (matchingMACs != NULL) {
 {
     CFDataRef  addr;
     CFIndex    n;
-    CFNumberRef        type;
+    CFStringRef        prefix;
 
     if (db_list == NULL) {
        return (NULL);
     }
-    type = _SCNetworkInterfaceGetIOInterfaceType(interface);
+    prefix = _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface);
     addr = _SCNetworkInterfaceGetHardwareAddress(interface);
-    if (type == NULL || addr == NULL) {
+    if (prefix == NULL || addr == NULL) {
        return (NULL);
     }
 
     n = CFArrayGetCount(db_list);
     for (CFIndex i = 0; i < n; i++) {
-       CFDataRef       a;
        CFDictionaryRef dict = CFArrayGetValueAtIndex(db_list, i);
-       CFNumberRef     t;
+       CFDataRef       this_addr;
+       CFStringRef     this_prefix;
 
-       t = CFDictionaryGetValue(dict, CFSTR(kIOInterfaceType));
-       a = CFDictionaryGetValue(dict, CFSTR(kIOMACAddress));
-       if (t == NULL || a == NULL)
+       this_prefix = CFDictionaryGetValue(dict, CFSTR(kIOInterfaceNamePrefix));
+       this_addr = CFDictionaryGetValue(dict, CFSTR(kIOMACAddress));
+       if (this_prefix == NULL || this_addr == NULL)
            continue;
 
-       if (CFEqual(type, t) && CFEqual(addr, a)) {
-           if (where) {
+       if (CFEqual(prefix, this_prefix) && CFEqual(addr, this_addr)) {
+           if (where != NULL) {
                *where = i;
            }
            return (dict);
 
        name = CFDictionaryGetValue(dict, CFSTR(kIOBSDNameKey));
        if (_SC_CFEqual(name, bsdName)) {
-           if (where) {
+           if (where != NULL) {
                *where = i;
            }
            return (dict);
 lookupInterfaceByUnit(CFArrayRef db_list, SCNetworkInterfaceRef interface, CFIndex * where)
 {
     CFIndex    n;
-    CFNumberRef        type;
+    CFStringRef        prefix;
     CFNumberRef        unit;
 
     if (db_list == NULL) {
        return (NULL);
     }
-    type = _SCNetworkInterfaceGetIOInterfaceType(interface);
+    prefix = _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface);
     unit = _SCNetworkInterfaceGetIOInterfaceUnit(interface);
-    if (type == NULL || unit == NULL) {
+    if (prefix == NULL || unit == NULL) {
        return (NULL);
     }
 
     n = CFArrayGetCount(db_list);
     for (CFIndex i = 0; i < n; i++) {
        CFDictionaryRef dict = CFArrayGetValueAtIndex(db_list, i);
-       CFNumberRef     t;
-       CFNumberRef     u;
+       CFStringRef     this_prefix;
+       CFNumberRef     this_unit;
 
-       t = CFDictionaryGetValue(dict, CFSTR(kIOInterfaceType));
-       u = CFDictionaryGetValue(dict, CFSTR(kIOInterfaceUnit));
-       if (t == NULL || u == NULL) {
+       this_prefix = CFDictionaryGetValue(dict, CFSTR(kIOInterfaceNamePrefix));
+       this_unit = CFDictionaryGetValue(dict, CFSTR(kIOInterfaceUnit));
+       if (this_prefix == NULL || this_unit == NULL) {
            continue;
        }
 
-       if (CFEqual(type, t) && CFEqual(unit, u)) {
-           if (where)
+       if (CFEqual(prefix, this_prefix) && CFEqual(unit, this_unit)) {
+           if (where != NULL) {
                *where = i;
+           }
            return (dict);
        }
     }
 typedef struct {
     CFDictionaryRef        match_info;
     CFStringRef                    match_type;
+    CFStringRef                    match_prefix;
     CFBooleanRef           match_builtin;
     CFMutableArrayRef      matches;
 } matchContext, *matchContextRef;
     CFDictionaryRef    known_dict      = (CFDictionaryRef)value;
     matchContextRef    match_context   = (matchContextRef)context;
 
+    // match prefix
+    {
+       CFStringRef     known_prefix;
+
+       known_prefix
+           = CFDictionaryGetValue(known_dict,
+                                  CFSTR(kIOInterfaceNamePrefix));
+       if (!_SC_CFEqual(known_prefix, match_context->match_prefix)) {
+           return;
+       }
+    }
+
     // match interface type
     {
        CFStringRef     known_type;
                        CFBooleanRef            builtin)
 {
     CFStringRef            if_type;
+    CFStringRef            if_prefix;
     CFDictionaryRef match          = NULL;
     matchContext    match_context;
 
     if (if_type == NULL) {
        return NULL;
     }
+    if_prefix = _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface);
+    if (if_prefix == NULL) {
+       return NULL;
+    }
 
     match_context.match_type   = if_type;
+    match_context.match_prefix = if_prefix;
     match_context.match_info   = _SCNetworkInterfaceCopyInterfaceInfo(interface);
     match_context.match_builtin        = builtin;
     match_context.matches      = NULL;
     CFIndex            i;
     CFDictionaryRef    if_dict;
     CFStringRef                if_name;
-    CFNumberRef                if_type;
+    CFStringRef                if_prefix;
     CFNumberRef                if_unit;
     CFArrayRef         matchingMACs    = NULL;
     CFIndex            n               = CFArrayGetCount(db_list);
        CFRelease(matchingMACs);
     }
 
-    if_type = _SCNetworkInterfaceGetIOInterfaceType(interface);
+    if_prefix = _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface);
     if_unit = _SCNetworkInterfaceGetIOInterfaceUnit(interface);
-    if ((if_type == NULL) || (if_unit == NULL)) {
+    if ((if_prefix == NULL) || (if_unit == NULL)) {
        CFRelease(if_dict);
        return;
     }
 
     for (i = 0; i < n; i++) {
-       CFNumberRef     db_type;
+       CFStringRef     db_prefix;
        CFNumberRef     db_unit;
        CFDictionaryRef dict    = CFArrayGetValueAtIndex(db_list, i);
 
-       db_type = CFDictionaryGetValue(dict, CFSTR(kIOInterfaceType));
+       db_prefix = CFDictionaryGetValue(dict, CFSTR(kIOInterfaceNamePrefix));
        db_unit = CFDictionaryGetValue(dict, CFSTR(kIOInterfaceUnit));
-       res = CFNumberCompare(if_type, db_type, NULL);
+       res = CFStringCompare(if_prefix, db_prefix, 0);
        if (res == kCFCompareLessThan
            || (res == kCFCompareEqualTo
                && (CFNumberCompare(if_unit, db_unit, NULL)
     int                        n               = 0;
     CFIndex            where;
 
-    // remove any dict that has our type/addr
+    // remove any dict that has our prefix+addr
     while (TRUE) {
        db_dict = lookupInterfaceByAddress(db_list, interface, &where);
        if (db_dict == NULL) {
        n++;
     }
 
-    // remove any dict that has the same type/unit
+    // remove any dict that has the same prefix+unit
     while (TRUE) {
        db_dict = lookupInterfaceByUnit(db_list, interface, &where);
        if (db_dict == NULL) {
 }
 
 static int
-getNextUnitForType(CFNumberRef if_type, int requested)
+getNextUnitForPrefix(CFStringRef if_prefix, int requested)
 {
     CFIndex    n;
 
     n = CFArrayGetCount(S_dblist);
     for (CFIndex i = 0; i < n; i++) {
        CFDictionaryRef dict = CFArrayGetValueAtIndex(S_dblist, i);
-       CFNumberRef     type;
+       CFStringRef     prefix;
 
-       type = CFDictionaryGetValue(dict, CFSTR(kIOInterfaceType));
-       if (CFEqual(type, if_type)) {
+       prefix = CFDictionaryGetValue(dict, CFSTR(kIOInterfaceNamePrefix));
+       if (CFEqual(prefix, if_prefix)) {
            int         u;
            CFNumberRef unit;
 
 {
     CFStringRef                addr;
     CFStringRef                name;
-    CFNumberRef                type;
+    CFStringRef                prefix;
     CFNumberRef                unit;
 
     name = SCNetworkInterfaceGetBSDName(interface);
     unit = _SCNetworkInterfaceGetIOInterfaceUnit(interface);
-    type = _SCNetworkInterfaceGetIOInterfaceType(interface);
+    prefix = _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface);
     addr = SCNetworkInterfaceGetHardwareAddressString(interface);
 
-    SC_log(LOG_INFO, "  %s%@%sType: %@, %s%@%sMAC address: %@",
+    SC_log(LOG_INFO, "  %s%@%sPrefix: %@, %s%@%sMAC address: %@",
          (name != NULL) ? "BSD Name: " : "",
          (name != NULL) ? name : CFSTR(""),
          (name != NULL) ? ", " : "",
-         type,
+         prefix,
          (unit != NULL) ? "Unit: " : "",
          (unit != NULL) ? (CFTypeRef)unit : (CFTypeRef)CFSTR(""),
          (unit != NULL) ? ", " : "",
                 CFNumberRef            if_unit)        // desired unit
 {
     CFIndex    i;
-    CFNumberRef if_type        = _SCNetworkInterfaceGetIOInterfaceType(interface);
+    CFStringRef if_prefix = _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface);
     CFIndex    n;
 
     n = (S_dblist != NULL) ? CFArrayGetCount(S_dblist) : 0;
        CFStringRef         if_path;
        CFDictionaryRef     known_dict      = CFArrayGetValueAtIndex(S_dblist, i);
        CFStringRef         known_path;
-       CFNumberRef         known_type;
+       CFStringRef         known_prefix;
        CFNumberRef         known_unit;
 
-       known_type = CFDictionaryGetValue(known_dict, CFSTR(kIOInterfaceType));
-       if (!_SC_CFEqual(if_type, known_type)) {
-           continue;   // if not the same interface type
+       known_prefix = CFDictionaryGetValue(known_dict, CFSTR(kIOInterfaceNamePrefix));
+       if (!_SC_CFEqual(if_prefix, known_prefix)) {
+           continue;   // if not the same interface prefix
        }
 
        known_unit = CFDictionaryGetValue(known_dict, CFSTR(kIOInterfaceUnit));
            return FALSE;
        }
 
-       // if same type, same unit, same path
+       // if same prefix+unit+path
        return TRUE;
     }
 
-    // if interface type/unit not found
+    // if interface prefix+unit not found
     return TRUE;
 }
 
 static int
-builtinCount(CFArrayRef if_list, CFIndex last, CFNumberRef if_type)
+builtinCount(CFArrayRef if_list, CFIndex last, CFStringRef if_prefix)
 {
     CFIndex    i;
     int                n       = 0;
 
     for (i = 0; i < last; i++) {
        SCNetworkInterfaceRef   builtin_if;
-       CFNumberRef             builtin_type;
+       CFStringRef             builtin_prefix;
 
        builtin_if   = CFArrayGetValueAtIndex(if_list, i);
-       builtin_type = _SCNetworkInterfaceGetIOInterfaceType(builtin_if);
-       if (CFEqual(if_type, builtin_type)) {
+       builtin_prefix = _SCNetworkInterfaceGetIOInterfaceNamePrefix(builtin_if);
+       if (CFEqual(if_prefix, builtin_prefix)) {
            if (_SCNetworkInterfaceIsBuiltin(builtin_if)) {
                n++;    // if built-in interface
            }
        WatchedInfo             *watchedInfo    = (WatchedInfo *)(void *)CFDataGetBytePtr(watched);
 
        name = SCNetworkInterfaceGetLocalizedDisplayName(watchedInfo->interface);
-       str = CFStringCreateWithFormat(NULL, NULL, CFSTR("\r\t%@"), name);
+       str = CFStringCreateWithFormat(NULL, NULL, CFSTR("\n\t%@"), name);
        CFArrayAppendValue(message, str);
        CFRelease(str);
     }
            S_locked = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        }
        CFArrayAppendValue(S_locked, watched);
+       CFRelease(watched);
        updated = TRUE;
     }
 
                    S_trustRequired = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
                }
                CFArrayAppendValue(S_trustRequired, watched);
+               CFRelease(watched);
                updated = TRUE;
            }
        }
                    S_preconfigured = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
                }
                CFArrayAppendValue(S_preconfigured, watched);
+               CFRelease(watched);
                updated = TRUE;
            }
        }
        SCNetworkInterfaceRef   interface;
        SCNetworkInterfaceRef   new_interface;
        CFStringRef             path;
-       CFNumberRef             type;
+       CFStringRef             prefix;
        CFNumberRef             unit;
        CFIndex                 where;
 
        interface = CFArrayGetValueAtIndex(if_list, i);
        path = _SCNetworkInterfaceGetIOPath(interface);
-       type = _SCNetworkInterfaceGetIOInterfaceType(interface);
+       prefix = _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface);
        unit = _SCNetworkInterfaceGetIOInterfaceUnit(interface);
        entryID = _SCNetworkInterfaceGetIORegistryEntryID(interface);
 
 
                if (is_builtin) {
                    // built-in interface, try to use the reserved slots
-                   next_unit = builtinCount(if_list, i, type);
+                   next_unit = builtinCount(if_list, i, prefix);
 
                    // But, before claiming a reserved slot we check to see if the
                    // slot had previously been used.  If so, and if the slot had been
                if (unit == NULL) {
                    // not built-in (or built-in unit not available), allocate from
                    // the non-reserved slots
-                   next_unit = builtinCount(if_list, n, type);
-                   next_unit = getNextUnitForType(type, next_unit);
+                   next_unit = builtinCount(if_list, n, prefix);
+                   next_unit = getNextUnitForPrefix(prefix, next_unit);
                    unit = CFNumberCreate(NULL, kCFNumberIntType, &next_unit);
                }
 
 
                new_unit = _SCNetworkInterfaceGetIOInterfaceUnit(new_interface);
                if (!CFEqual(unit, new_unit)) {
-                   SC_log(LOG_INFO, "interface type %@ assigned unit %@ instead of %@",
-                          type, new_unit, unit);
+                   SC_log(LOG_INFO, "interface prefix %@ assigned unit %@ instead of %@",
+                          prefix, new_unit, unit);
                }
 
                displayInterface(new_interface);
     for (CFIndex i = 0; i < n; i++) {
        CFDictionaryRef         if_dict;
        CFStringRef             name;
-       CFNumberRef             type;
+       CFStringRef             prefix;
        CFNumberRef             unit;
 
        if_dict = CFArrayGetValueAtIndex(S_prev_active_list, i);
        name = CFDictionaryGetValue(if_dict, CFSTR(kIOBSDNameKey));
-       type = CFDictionaryGetValue(if_dict, CFSTR(kIOInterfaceType));
+       prefix = CFDictionaryGetValue(if_dict, CFSTR(kIOInterfaceNamePrefix));
        unit = CFDictionaryGetValue(if_dict, CFSTR(kIOInterfaceUnit));
-       SC_log(LOG_INFO, "  %s%@%sType: %@, Unit: %@",
+       SC_log(LOG_INFO, "  %s%@%sPrefix: %@, Unit: %@",
               (name != NULL) ? "BSD Name: " : "",
               (name != NULL) ? name : CFSTR(""),
               (name != NULL) ? ", " : "",
-              type,
+              prefix,
               unit);
     }
 
        SCNetworkInterfaceRef           interface               = CFArrayGetValueAtIndex(interfaces_all, i);
        SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
 
-       if (interfacePrivate->type == NULL) {
-           // skip interfaces with a kIOInterfaceType property
+       if (interfacePrivate->prefix == NULL) {
+           // skip interfaces with no kIOInterfaceNamePrefix property
            continue;
        }
 
 
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.19</string>
+       <string>1.20</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.19</string>
+       <string>1.20</string>
        <key>Requires</key>
        <array>
                <string>com.apple.SystemConfiguration.InterfaceNamer</string>
 
 /*
- * Copyright (c) 2002-2019 Apple Inc. All rights reserved.
+ * Copyright (c) 2002-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
                }
        } else {
                /* remove the value */
-               if (oldDict != NULL) {
+               if (!only_if_different
+                   || oldDict != NULL) {
                        SC_log(LOG_DEBUG, "Update interface link status: %s: <removed>", if_name);
+                       SCDynamicStoreRemoveValue(store, key);
                }
-               SCDynamicStoreRemoveValue(store, key);
        }
 
        CFRelease(key);
 
 /*
- * Copyright (c) 2013-2016, 2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2013-2016, 2018, 2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 static CFBooleanRef
 is_expensive(SCNetworkInterfaceRef _Nonnull interface)
 {
-       CFBooleanRef    expensive       = NULL;
+       CFBooleanRef    expensive;
        CFStringRef     interfaceType;
 
        while (interface != NULL) {
 
                interface = child;
        }
-
-       // assume NOT expensive
-       expensive = kCFBooleanFalse;
-
+       // by default, don't set/clear expensive
+       expensive = NULL;
        interfaceType = SCNetworkInterfaceGetInterfaceType(interface);
        if (_SCNetworkInterfaceIsTethered(interface)) {
                // if tethered (to iOS) interface
 static int
 ifexpensive_set(int s, const char * name, uint32_t expensive)
 {
-#if    defined(SIOCSIFEXPENSIVE) && !defined(MAIN)
+#if    defined(SIOCGIFEXPENSIVE) && defined(SIOCSIFEXPENSIVE) && !defined(MAIN)
        struct ifreq    ifr;
        int             ret;
 
        memset(&ifr, 0, sizeof(ifr));
        strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+       ret = ioctl(s, SIOCGIFEXPENSIVE, &ifr);
+       if ((ret == -1) && (errno != EPERM)) {
+               SC_log(LOG_ERR, "%s: ioctl(SIOCGIFEXPENSIVE) failed: %s", name, strerror(errno));
+               return ret;
+       }
+
+       if (ifr.ifr_expensive == expensive) {
+               // if no change
+               return ret;
+       }
+
        ifr.ifr_expensive = expensive;
        ret = ioctl(s, SIOCSIFEXPENSIVE, &ifr);
        if ((ret == -1) && (errno != EPERM)) {
 CFBooleanRef
 interface_update_expensive(const char *if_name)
 {
-       CFBooleanRef            expensive       = NULL;
+       CFBooleanRef            expensive;
        SCNetworkInterfaceRef   interface;
        CFStringRef             interface_name;
        int                     s;
 
-       interface_name = CFStringCreateWithCString(NULL, if_name, kCFStringEncodingMacRoman);
+       interface_name = CFStringCreateWithCString(NULL, if_name, kCFStringEncodingUTF8);
        interface = _SCNetworkInterfaceCreateWithBSDName(NULL, interface_name, kIncludeNoVirtualInterfaces);
        CFRelease(interface_name);
-
-       if (interface != NULL) {
-               expensive = is_expensive(interface);
-               CFRelease(interface);
+       if (interface == NULL) {
+               return NULL;
+       }
+       expensive = is_expensive(interface);
+       CFRelease(interface);
+       if (expensive == NULL) {
+               return NULL;
        }
-
        // mark ... or clear ... the [if_name] interface as "expensive"
        s = dgram_socket(AF_INET);
        if (s != -1) {
                ifexpensive_set(s,
                                if_name,
-                               ((expensive != NULL) && CFBooleanGetValue(expensive)) ? 1 : 0);
+                               CFBooleanGetValue(expensive) ? 1 : 0);
                close(s);
        }
 
 
        expensive = interface_update_expensive(argv[1]);
        if (expensive != NULL) {
-               SCPrint(TRUE, stdout, CFSTR("interface \"%s\": %@\n"), argv[1], expensive);
+               SCPrint(TRUE, stdout, CFSTR("%s: set expensive to %@\n"), argv[1], expensive);
        } else {
-               SCPrint(TRUE, stdout, CFSTR("interface \"%s\": could not determine \"expensive\" status\n"), argv[1]);
+               SCPrint(TRUE, stdout, CFSTR("%s: not changing expensive\n"), argv[1]);
        }
 
        exit(0);
 
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.19</string>
+       <string>1.20</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.19</string>
+       <string>1.20</string>
        <key>Requires</key>
        <array>
                <string>com.apple.SystemConfiguration.InterfaceNamer</string>
 
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.19</string>
+       <string>1.20</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.19</string>
+       <string>1.20</string>
        <key>Builtin</key>
        <true/>
        <key>Requires</key>
 
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.19</string>
+       <string>1.20</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.19</string>
+       <string>1.20</string>
        <key>QoSMarking_AppleAudioVideoCalls_BundleIDs</key>
        <array>
                <string>com.apple.datausage.telephony.ims</string>
 
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.19</string>
+       <string>1.20</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.19</string>
+       <string>1.20</string>
        <key>QoSMarking_AppleAudioVideoCalls_BundleIDs</key>
        <array>
                <string>com.apple.datausage.telephony.ims</string>
 
 
 ifeq ($(PLATFORM),iphoneos)
 # iOS internal SDK
-ARCHS=armv7
+ARCHS=arm64
 endif
 
 ifeq ($(PLATFORM),macosx)
 endif
 
 # Mac OS X or iOS internal SDK
-SDK=$(PLATFORM).internal
+SDK=$(PLATFORM)internal
 SYSROOT=$(shell xcodebuild -version -sdk $(SDK) Path)
 CC = xcrun -sdk $(SDK) cc
 
 all : qos-marking
 
+# ---------- ---------- ---------- ---------- ----------
+
 qos-marking.o: qos-marking.m Makefile
-       $(CC) -DOS_ACTIVITY_OBJECT_API=1 -I../../SystemConfiguration.fproj -I${SYSROOT}/System/Library/Frameworks/System.framework/PrivateHeaders -Wall -g -DMAIN -O0 -c qos-marking.m
+       $(CC) -DOS_ACTIVITY_OBJECT_API=1 -I../../SystemConfiguration.fproj ${EXTRA} -I${SYSROOT}/System/Library/Frameworks/System.framework/PrivateHeaders -Wall -g -DMAIN -O0 -c qos-marking.m
 
 qos-marking: qos-marking.o Makefile
-       $(CC) -o qos-marking qos-marking.o -framework CoreFoundation -framework Foundation -framework SystemConfiguration -framework NetworkExtension
+       $(CC) -o qos-marking qos-marking.o ${EXTRA} -framework CoreFoundation -framework Foundation -framework SystemConfiguration -framework NetworkExtension
+
+# ---------- ---------- ---------- ---------- ----------
 
 clean:
        rm -rf *.o qos-marking qos-marking.dSYM
 
 /*
- * Copyright (c) 2016-2019 Apple Inc. All rights reserved.
+ * Copyright (c) 2016-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
        BOOL            reqEnabled      = false;
        BOOL            reqAppleAV      = false;
 
+       // overall policy change
+       BOOL            notify          = false;
+
        if (nowPolicy != nil) {
                if ([self qosMarkingIsEnabled:nowPolicy]) {
                        // if we have an enabled QoS marking policy
                } else {
                        SC_log(LOG_ERR, "socket() failed: %s", strerror(errno));
                }
+
+               notify = true;
        }
 
        if (reqEnabled) {
                qosMarkingSetRestrictAVApps(false);
                qosMarkingSetHavePolicies(false);
        }
+
+       if (notify) {
+               CFStringRef     key;
+
+               key = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
+                                                                   kSCDynamicStoreDomainState,
+                                                                   (__bridge CFStringRef)interface,
+                                                                   kSCEntNetQoSMarkingPolicy);
+               if (reqEnabled && (reqPolicy != nil)) {
+                       (void) SCDynamicStoreSetValue(NULL, key, (__bridge CFDictionaryRef)reqPolicy);
+               } else {
+                       (void) SCDynamicStoreRemoveValue(NULL, key);
+               }
+               CFRelease(key);
+       }
 }
 
 
 
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.19</string>
+       <string>1.20</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.19</string>
+       <string>1.20</string>
 </dict>
 </plist>
 
 #include <dns_sd.h>
 #include <dns_sd_private.h>
 
-#if    TARGET_OS_SIMULATOR && !TARGET_OS_IOSMAC
+#if    TARGET_OS_SIMULATOR && !TARGET_OS_MACCATALYST
 
 
 static CFMutableArrayRef       mirror_keys     = NULL;
 }
 #endif
 
-#endif // TARGET_OS_SIMULATOR && !TARGET_OS_IOSMAC
+#endif // TARGET_OS_SIMULATOR && !TARGET_OS_MACCATALYST
 
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.19</string>
+       <string>1.20</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.19</string>
+       <string>1.20</string>
        <key>CFPlugInDynamicRegistration</key>
        <string>NO</string>
        <key>CFPlugInFactories</key>
 
 /*
- * Copyright (c) 2007-2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2007-2018, 2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 #include <IOKit/IOKitLib.h>
 #include <IOKit/IOKitKeysPrivate.h>
 #include <IOKit/IOMessage.h>
-#include <ApplicationServices/ApplicationServices.h>
+#include <CoreServices/CoreServices.h>
 #include "UserEventAgentInterface.h"
 
 #define MY_BUNDLE_ID    "com.apple.SystemConfiguration.SCMonitor"
 
                        interface = CFArrayGetValueAtIndex(myInstance->interfaces_prompt, i);
                        name = SCNetworkInterfaceGetLocalizedDisplayName(interface);
-                       str = CFStringCreateWithFormat(NULL, NULL, CFSTR("\r\t%@"), name);
+                       str = CFStringCreateWithFormat(NULL, NULL, CFSTR("\n\t%@"), name);
                        CFArrayAppendValue(message, str);
                        CFRelease(str);
                }
 notify_configure(MyType *myInstance)
 {
        CFIndex                 i;
+       Boolean                 locked;
        CFIndex                 n               = CFArrayGetCount(myInstance->interfaces_configure);
        Boolean                 ok;
        SCPreferencesRef        prefs           = NULL;
                prefs = SCPreferencesCreateWithAuthorization(NULL, CFSTR("SCMonitor"), NULL, authorization);
        }
 
+       locked = SCPreferencesLock(prefs, TRUE);
+       if (!locked) {
+               SC_log(LOG_ERR,
+                      "SCPreferencesLock() failed: %s",
+                      SCErrorString(SCError()));
+               goto done;
+       }
+
        set = SCNetworkSetCopyCurrent(prefs);
        if (set == NULL) {
                // if no "current" set, create new/default ("Automatic") set
                set = NULL;
        }
 
-       if (prefs != NULL) {
-               CFRelease(prefs);
-               prefs = NULL;
+       if (locked) {
+               SCPreferencesUnlock(prefs);
        }
 
+       CFRelease(prefs);
+       prefs = NULL;
+
        CFRelease(myInstance->interfaces_configure);
        myInstance->interfaces_configure = NULL;
 
 
 /*
- * Copyright (c) 2009, 2010, 2012, 2013, 2015, 2018, 2019 Apple Inc. All rights reserved.
+ * Copyright (c) 2009, 2010, 2012, 2013, 2015, 2018, 2019, 2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 }
 
 CFDictionaryRef
-CNCopyCurrentNetworkInfo(CFStringRef   interfaceName)
+CNCopyCurrentNetworkInfo(CFStringRef interfaceName)
 {
-#if    TARGET_OS_IPHONE && !TARGET_OS_IOSMAC
        static typeof (CNCopyCurrentNetworkInfo) *dyfunc = NULL;
        if (!dyfunc) {
                void *image = __loadCaptiveNetwork();
                if (image) dyfunc = dlsym(image, "__CNCopyCurrentNetworkInfo");
        }
        return dyfunc ? dyfunc(interfaceName) : NULL;
-#else  // TARGET_OS_IPHONE && !TARGET_OS_IOSMAC
-#pragma unused(interfaceName)
-       return NULL;
-#endif // TARGET_OS_IPHONE && !TARGET_OS_IOSMAC
 }
 
 
 /*
- * Copyright (c) 2009-2016, 2018, 2019 Apple Inc. All rights reserved.
+ * Copyright (c) 2009-2016, 2018, 2019, 2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 
 /*!
  @function CNCopyCurrentNetworkInfo
- @discussion Returns the network information for the specified interface when the requesting application meets one of following 3 requirements -.
-       1. application is using CoreLocation API and has user's authorization to access location.
-       2. application has used NEHotspotConfiguration API to configure the current Wi-Fi network.
+ @discussion Returns the network information for the specified interface when the requesting application meets one of following 4 requirements -.
+       1. application is using CoreLocation API and has the user's authorization to access location.
+       2. application has used the NEHotspotConfiguration API to configure the current Wi-Fi network.
        3. application has active VPN configurations installed.
+       4. application has active NEDNSSettingsManager configurations installed.
 
        - An application that is linked against iOS 12.0 SDK and above must have the "com.apple.developer.networking.wifi-info" entitlement.
        - An application will receive a pseudo network information if it is linked against an SDK before iOS 13.0, and if it fails to meet any of the
-         above 3 requirements.
-       - An application will receive NULL if it is linked against iOS 13.0 SDK or above, and if it fails to meet any of the above 3 requirements..
+         above requirements.
+       - An application will receive NULL if it is linked against iOS 13.0 SDK (or newer), and if it fails to meet any of the above requirements.
+       - On Mac Catalyst platform, to receive current Wi-Fi network information, an application must have "com.apple.developer.networking.wifi-info"
+        entitlement and user's authorization to access location.
 
        Network Information dictionary will contain the following keys, and values:
        <pre>
  */
 CFDictionaryRef __nullable
 CNCopyCurrentNetworkInfo       (CFStringRef    interfaceName)
-    API_AVAILABLE(ios(4.1))
-    SPI_AVAILABLE(macos(10.6), tvos(9.0), watchos(1.0), bridgeos(1.0));
+API_DEPRECATED_WITH_REPLACEMENT("[NEHotspotNetwork fetchCurrentWithCompletionHandler:]", ios(4.1, API_TO_BE_DEPRECATED), macCatalyst(14.0, API_TO_BE_DEPRECATED))
+SPI_AVAILABLE(macos(10.6), tvos(9.0), watchos(1.0), bridgeos(1.0));
 
 __END_DECLS
 
 
        <key>CFBundleExecutable</key>
        <string>SystemConfiguration</string>
        <key>CFBundleGetInfoString</key>
-       <string>1.19</string>
+       <string>1.20</string>
        <key>CFBundleIdentifier</key>
        <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
        <key>CFBundleInfoDictionaryVersion</key>
        <key>CFBundlePackageType</key>
        <string>FMWK</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.19</string>
+       <string>1.20</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.19</string>
+       <string>1.20</string>
 </dict>
 </plist>
 
        <key>CFBundleExecutable</key>
        <string>SystemConfiguration</string>
        <key>CFBundleGetInfoString</key>
-       <string>1.19</string>
+       <string>1.20</string>
        <key>CFBundleIdentifier</key>
        <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
        <key>CFBundleInfoDictionaryVersion</key>
        <key>CFBundlePackageType</key>
        <string>FMWK</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.19</string>
+       <string>1.20</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.19</string>
+       <string>1.20</string>
 </dict>
 </plist>
 
 #include "dy_framework.h"
 
 
+#ifndef        __OPEN_SOURCE
+#pragma mark Support
+
+
+static Boolean
+keepPrivate(void)
+{
+       static Boolean          keepPrivate     = FALSE;
+       static dispatch_once_t  once;
+
+       dispatch_once(&once, ^{
+               SecTaskRef      current_task;
+
+               current_task = SecTaskCreateFromSelf(NULL);
+               if (current_task != NULL) {
+                       CFBooleanRef    entitlement;
+
+                       entitlement = SecTaskCopyValueForEntitlement(current_task,
+                                                                    CFSTR("com.apple.security.on-demand-install-capable"),
+                                                                    NULL);
+                       if (entitlement != NULL) {
+                               if (isA_CFBoolean(entitlement)) {
+                                       keepPrivate = CFBooleanGetValue(entitlement);
+                               }
+                               CFRelease(entitlement);
+                       }
+                       CFRelease(current_task);
+               }
+       });
+
+       return keepPrivate;
+}
+#endif // __OPEN_SOURCE
+
+
 #pragma mark ComputerName
 
 
        CFStringRef             key;
        CFStringRef             name            = NULL;
 
+#ifndef        __OPEN_SOURCE
+       if (keepPrivate()) {
+               return NULL;
+       }
+#endif // __OPEN_SOURCE
+
        key  = SCDynamicStoreKeyCreateComputerName(NULL);
        dict = SCDynamicStoreCopyValue(store, key);
        CFRelease(key);
        }
 
        ok = __SCNetworkConfigurationSetValue(prefs, path, newDict, FALSE);
-       if (ok) {
+       if (ok && __SCPreferencesUsingDefaultPrefs(prefs)) {
                if (name != NULL) {
                        SC_log(LOG_NOTICE, "attempting to set the computer name to \"%@\"", name);
                } else {
        CFStringRef     name;
        CFStringRef     path;
 
+#ifndef        __OPEN_SOURCE
+       if (keepPrivate()) {
+               return NULL;
+       }
+#endif // __OPEN_SOURCE
+
        path = CFStringCreateWithFormat(NULL,
                                        NULL,
                                        CFSTR("/%@/%@"),
        }
 
        ok = __SCNetworkConfigurationSetValue(prefs, path, newDict, FALSE);
-       if (ok) {
+       if (ok && __SCPreferencesUsingDefaultPrefs(prefs)) {
                if (name != NULL) {
                        SC_log(LOG_NOTICE, "attempting to set the host name to \"%@\"", name);
                } else {
        CFStringRef             key;
        CFStringRef             name            = NULL;
 
+#ifndef        __OPEN_SOURCE
+       if (keepPrivate()) {
+               return NULL;
+       }
+#endif // __OPEN_SOURCE
+
        key  = SCDynamicStoreKeyCreateHostNames(NULL);
        dict = SCDynamicStoreCopyValue(store, key);
        CFRelease(key);
        }
 
        ok = __SCNetworkConfigurationSetValue(prefs, path, newDict, FALSE);
-       if (ok) {
+       if (ok && __SCPreferencesUsingDefaultPrefs(prefs)) {
                if (name != NULL) {
                        SC_log(LOG_NOTICE, "attempting to set the local host name to \"%@\"", name);
                } else {
 
 #include <TargetConditionals.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <os/state_private.h>
 #include <sys/types.h>
 #include <mach/mach.h>
 #include <mach/mach_error.h>
 #include "config.h"            /* MiG generated file */
 #include "SCD.h"
 
-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 unsigned int            _sc_store_max   = 50;   /* complain if SCDynamicStore objects exceeds this [soft-]limit */
+#define        N_SESSIONS_WARN_DEFAULT 50      // complain if SCDynamicStore session count exceeds this [soft-]limit
+#define        N_SESSIONS_WARN_MAX     5000    // stop complaining when # sessions exceeds this [hard-]limit
 
+static pthread_mutex_t _sc_lock                = PTHREAD_MUTEX_INITIALIZER;
+static mach_port_t     _sc_server              = MACH_PORT_NULL;
+static CFIndex         _sc_store_advise        = N_SESSIONS_WARN_DEFAULT / 2;  // when snapshots should log
+static CFIndex         _sc_store_max           = N_SESSIONS_WARN_DEFAULT;
+static CFMutableSetRef _sc_store_sessions      = NULL; // sync w/storeQueue()
+
+static dispatch_queue_t
+storeQueue(void)
+{
+       static dispatch_once_t  once;
+       static dispatch_queue_t q;
+
+       dispatch_once(&once, ^{
+               // allocate mapping between [client] sessions and session info
+               _sc_store_sessions = CFSetCreateMutable(NULL, 0, NULL);
+
+               // and a queue to synchronize access to the mapping
+               q = dispatch_queue_create("SCDynamicStore/client sessions", NULL);
+       });
+
+       return q;
+}
 
 static const char      *notifyType[] = {
        "",
 };
 
 
+#pragma mark -
+#pragma mark SCDynamicStore state handler
+
+
+static void
+addSessionReference(const void *value, void *context)
+{
+       CFMutableDictionaryRef          dict            = (CFMutableDictionaryRef)context;
+       SCDynamicStorePrivateRef        storePrivate    = (SCDynamicStorePrivateRef)value;
+
+       if (!storePrivate->serverNullSession &&
+           (storePrivate->name != NULL)) {
+               int                     cnt;
+               CFMutableStringRef      key;
+               CFIndex                 n;
+               CFNumberRef             num;
+
+               // create [key] signature
+               key = CFStringCreateMutableCopy(NULL, 0, storePrivate->name);
+               n = (storePrivate->keys != NULL) ? CFArrayGetCount(storePrivate->keys) : 0;
+               if (n > 0) {
+                       CFStringAppendFormat(key, NULL, CFSTR(":k[0/%ld]=%@"),
+                                            n,
+                                            CFArrayGetValueAtIndex(storePrivate->keys, 0));
+               }
+               n = (storePrivate->patterns != NULL) ? CFArrayGetCount(storePrivate->patterns) : 0;
+               if (n > 0) {
+                       CFStringAppendFormat(key, NULL, CFSTR(":p[0/%ld]=%@"),
+                                            n,
+                                            CFArrayGetValueAtIndex(storePrivate->patterns, 0));
+               }
+
+               // bump [key] count
+               if (!CFDictionaryGetValueIfPresent(dict,
+                                                  key,
+                                                  (const void **)&num) ||
+                   !CFNumberGetValue(num, kCFNumberIntType, &cnt)) {
+                       // if first session
+                       cnt = 0;
+               }
+               cnt++;
+               num = CFNumberCreate(NULL, kCFNumberIntType, &cnt);
+               CFDictionarySetValue(dict, key, num);   // do we want to include name+keys[0]/patterns[0] ?
+               CFRelease(num);
+
+               CFRelease(key);
+       }
+
+       return;
+}
+
+
+static void
+add_state_handler()
+{
+       os_state_block_t        state_block;
+
+       state_block = ^os_state_data_t(os_state_hints_t hints) {
+#pragma unused(hints)
+               CFDataRef               data    = NULL;
+               CFMutableDictionaryRef  dict;
+               CFIndex                 n;
+               Boolean                 ok;
+               os_state_data_t         state_data;
+               size_t                  state_data_size;
+               CFIndex                 state_len;
+
+               n = CFSetGetCount(_sc_store_sessions);
+               if ((_sc_store_max <= 0) || (n == 0) || (n < _sc_store_advise)) {
+                       return NULL;
+               }
+
+               dict = CFDictionaryCreateMutable(NULL,
+                                                0,
+                                                &kCFTypeDictionaryKeyCallBacks,
+                                                &kCFTypeDictionaryValueCallBacks);
+               CFSetApplyFunction(_sc_store_sessions, addSessionReference, dict);
+               if (CFDictionaryGetCount(dict) == 0) {
+                       CFRelease(dict);
+                       return NULL;
+               }
+               ok = _SCSerialize(dict, &data, NULL, NULL);
+               CFRelease(dict);
+
+               state_len = (ok && (data != NULL)) ? CFDataGetLength(data) : 0;
+               state_data_size = OS_STATE_DATA_SIZE_NEEDED(state_len);
+               if (state_data_size > MAX_STATEDUMP_SIZE) {
+                       SC_log(LOG_ERR, "SCDynamicStore/client sessions : state data too large (%zd > %zd)",
+                              state_data_size,
+                              (size_t)MAX_STATEDUMP_SIZE);
+                       if (data != NULL) CFRelease(data);
+                       return NULL;
+               }
+
+               state_data = calloc(1, state_data_size);
+               if (state_data == NULL) {
+                       SC_log(LOG_ERR, "SCDynamicStore/client sessions: could not allocate state data");
+                       if (data != NULL) CFRelease(data);
+                       return NULL;
+               }
+
+               state_data->osd_type = OS_STATE_DATA_SERIALIZED_NSCF_OBJECT;
+               state_data->osd_data_size = (uint32_t)state_len;
+               strlcpy(state_data->osd_title, "SCDynamicStore/client sessions", sizeof(state_data->osd_title));
+               if (state_len > 0) {
+                       memcpy(state_data->osd_data, CFDataGetBytePtr(data), state_len);
+               }
+               if (data != NULL) CFRelease(data);
+
+               return state_data;
+       };
+
+       (void) os_state_add_handler(storeQueue(), state_block);
+       return;
+}
+
+
+#pragma mark -
+#pragma mark SCDynamicStore APIs
+
+
 void
 _SCDynamicStoreSetSessionWatchLimit(unsigned int limit)
 {
        _sc_store_max = limit;
+       _sc_store_advise = limit;
        return;
 }
 
 
        (void) pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldThreadState);
 
+       dispatch_sync(storeQueue(), ^{
+               // remove session tracking
+               CFSetRemoveValue(_sc_store_sessions, storePrivate);
+       });
+
        /* Remove/cancel any outstanding notification requests. */
        (void) SCDynamicStoreNotifyCancel(store);
 
                _SCDynamicStoreCacheClose(store);
        }
 
-       _SC_ATOMIC_DEC(&_sc_store_cnt);
-
        return;
 }
 
        /* add handler to cleanup after fork() */
        (void) pthread_atfork(NULL, NULL, childForkHandler);
 
+       add_state_handler();
+
        return;
 }
 
 }
 
 
+static void
+logSessionReference(const void *key, const void *value, void *context)
+{
+#pragma unused(context)
+       CFNumberRef     cnt     = (CFNumberRef)value;
+       CFStringRef     name    = (CFStringRef)key;
+
+       SC_log(LOG_ERR, "  %@ sessions w/name = \"%@\"", cnt, name);
+       return;
+}
+
+
 SCDynamicStorePrivateRef
 __SCDynamicStoreCreatePrivate(CFAllocatorRef           allocator,
                             const CFStringRef          name,
                             SCDynamicStoreCallBack     callout,
                             SCDynamicStoreContext      *context)
 {
-       unsigned int                    n;
        uint32_t                        size;
        SCDynamicStorePrivateRef        storePrivate;
+       __block Boolean                 tooManySessions = FALSE;
 
        /* initialize runtime */
        pthread_once(&initialized, __SCDynamicStoreInitialize);
        storePrivate->notifyFile                        = -1;
 
        /* watch for excessive SCDynamicStore usage */
-       n = _SC_ATOMIC_INC(&_sc_store_cnt);
-       if (n > _sc_store_max) {
-               if (_sc_store_max > 0) {
-                       SC_log(LOG_ERR, "SCDynamicStoreCreate(): number of SCDynamicStore objects now exceeds %u", n - 1);
-                       _sc_store_max = (_sc_store_max < 5000) ? (_sc_store_max * 2) : 0;
-                       _SC_crash_once("Excessive number of SCDynamicStore objects", NULL, NULL);
+       dispatch_sync(storeQueue(), ^{
+               CFIndex         n;
+
+               // track the session
+               CFSetAddValue(_sc_store_sessions, storePrivate);
+               n = CFSetGetCount(_sc_store_sessions);
+               if (n > _sc_store_max) {
+                       if (_sc_store_max > 0) {
+                               CFMutableDictionaryRef  dict;
+
+                               dict = CFDictionaryCreateMutable(NULL,
+                                                                0,
+                                                                &kCFTypeDictionaryKeyCallBacks,
+                                                                &kCFTypeDictionaryValueCallBacks);
+                               CFSetApplyFunction(_sc_store_sessions, addSessionReference, dict);
+                               SC_log(LOG_ERR,
+                                      "SCDynamicStoreCreate(): number of SCDynamicStore sessions %sexceeds %ld",
+                                      (n != N_SESSIONS_WARN_DEFAULT) ? "now " : "",
+                                      _sc_store_max);
+                               CFDictionaryApplyFunction(dict, logSessionReference, NULL);
+                               CFRelease(dict);
+
+                               // yes, we should complain
+                               tooManySessions = TRUE;
+
+                               // bump the threshold before we complain again
+                               _sc_store_max = (_sc_store_max < N_SESSIONS_WARN_MAX) ? (_sc_store_max * 2) : 0;
+                       }
                }
+       });
+
+       if (tooManySessions) {
+               _SC_crash_once("Excessive number of SCDynamicStore sessions", NULL, NULL);
        }
 
        return storePrivate;
 
 _SC_crash(const char *crash_info, CFStringRef notifyHeader, CFStringRef notifyMessage)
 {
        if (_SC_isAppleInternal()) {
-               if (crash_info != NULL) {
-                       CRSetCrashLogMessage(crash_info);
-                       SC_log(LOG_NOTICE, "%s", crash_info);
+               if (crash_info == NULL) {
+                       crash_info = "_SC_crash() called w/o \"crash_info\"";
                }
 
+               // augment the crash log message
+               CRSetCrashLogMessage(crash_info);
+
                // simulate a crash report
                os_log_with_type(SC_LOG_HANDLE(), OS_LOG_TYPE_FAULT, "%s", crash_info);
 
                        _SC_ReportCrash(notifyHeader, notifyMessage);
                }
 
-               if (crash_info != NULL) {
-                       CRSetCrashLogMessage(NULL);
-               }
+               // ... and cleanup after the crash report has been generated
+               CRSetCrashLogMessage(NULL);
        }
 
        return;
 
        CFStringRef             addressString;
        Boolean                 builtin;
        CFStringRef             configurationAction;
-       Boolean                 hidden;
+       Boolean                 hiddenConfiguration;
+       Boolean                 hiddenInterface;
        CFStringRef             location;
        CFStringRef             path;
        uint64_t                entryID;
 #pragma mark SCNetworkInterface configuration (internal)
 
 
+extern const SCNetworkServiceRef __kSCNetworkInterfaceSearchExternal;
+
+extern const SCNetworkServiceRef __kSCNetworkInterfaceSearchSystem;
+
 Boolean
 __SCNetworkInterfaceMatchesName                        (CFStringRef            name,
                                                 CFStringRef            key);
 __SCNetworkServiceIsPPTP                       (SCNetworkServiceRef    service);
 
 
-void
-__SCNetworkPopulateDefaultNIPrefs              (SCPreferencesRef       ni_prefs);
-
 /*!
  @function __SCNetworkServiceMigrateNew
  @discussion Adds network service to SCPreferencesRef if it doesn't exists
  @param prefs SCPreferencesRef
  @param service The network service
- @param bsdMapping Mapping of interface names between configurations
+ @param bsdNameMapping Mapping of interface names between configurations
  @result TRUE if add service to prefs is successful
  */
 Boolean
 __SCNetworkServiceMigrateNew                   (SCPreferencesRef       prefs,
                                                 SCNetworkServiceRef    service,
-                                                CFDictionaryRef        bsdMapping,
+                                                CFDictionaryRef        bsdNameMapping,
                                                 CFDictionaryRef        setMapping,
                                                 CFDictionaryRef        serviceSetMapping);
 
 
                       suffix);
        backup = SCPreferencesCreateCompanion(relativeTo, backupPrefsID);
        CFRelease(backupPrefsID);
-
-       SC_log(LOG_INFO,
-              "__SCNetworkConfigurationBackup()"
-              "\n  relativeTo = %@"
-              "\n  prefs      = %@"
-              "\n  backup     = %@",
-              relativeTo,
-              prefs,
-              backup);
-
        if (backup != NULL) {
                plist = SCPreferencesPathGetValue(prefs, CFSTR("/"));
                SCPreferencesPathSetValue(backup, CFSTR("/"), plist);
                                        }
                                        updated++;
                                        continue;
-                               }
+                               }
                        }
 
                        CFArrayAppendValue(interfaces_new, if_dict);
 
 Boolean
 _SCNetworkInterfaceIsHiddenConfiguration               (SCNetworkInterfaceRef          interface)      API_AVAILABLE(macos(10.7), ios(4.0));
 
+/*!
+       @function _SCNetworkInterfaceIsHiddenInterface
+       @discussion Identifies if this is a [fully] hidden network interface.
+       @param interface The network interface.
+       @result TRUE if this is a hidden interface.
+ */
+Boolean
+_SCNetworkInterfaceIsHiddenInterface                   (SCNetworkInterfaceRef          interface)      SPI_AVAILABLE(macos(10.16), ios(14.0), tvos(14.0), watchos(7.0));
+
+
+/*!
+       @function _SCNetworkInterfaceIsQoSMarkingProfileInstalled
+       @discussion Identifies if a network interface has a QoSMarking profile installed
+       @param interface The network interface.
+       @result TRUE if the interface is a tethered device.
+ */
+Boolean
+_SCNetworkInterfaceIsQoSMarkingProfileInstalled                (SCNetworkInterfaceRef          interface)      SPI_AVAILABLE(macos(10.16), ios(14.0), tvos(14.0), watchos(7.0));
+
 /*!
        @function _SCNetworkInterfaceIsTethered
        @discussion Identifies if a network interface is an Apple tethered device (e.g. an iPhone).
 
        const CFStringRef       *ppp_subtype;
        uint32_t                supported_protocols;
 } configurations[] = {
-       // interface type                         entity_hardware      if config? interface types PPP sub-type                          interface protocols
-       // =====================================  ==================== ========== =============== ======================================= =========================================
-       { &kSCNetworkInterfaceType6to4          , &kSCEntNet6to4      , FALSE,  doNone,         NULL,                                   doIPv6                                  },
-       { &kSCNetworkInterfaceTypeBluetooth     , &kSCEntNetModem     , FALSE,  doPPP,          &kSCValNetInterfaceSubTypePPPSerial,    doNone                                  },
-       { &kSCNetworkInterfaceTypeBond          , &kSCEntNetEthernet  , TRUE ,  doNone,         NULL,                                   doDNS|doIPv4|doIPv6|doProxies|doSMB     },
-       { &kSCNetworkInterfaceTypeBridge        , &kSCEntNetEthernet  , TRUE ,  doNone,         NULL,                                   doDNS|doIPv4|doIPv6|doProxies|doSMB     },
-       { &kSCNetworkInterfaceTypeEthernet      , &kSCEntNetEthernet  , TRUE ,  doPPP,          &kSCValNetInterfaceSubTypePPPoE,        doDNS|doIPv4|doIPv6|doProxies|doSMB     },
-       { &kSCNetworkInterfaceTypeFireWire      , &kSCEntNetFireWire  , TRUE ,  doNone,         NULL,                                   doDNS|doIPv4|doIPv6|doProxies|doSMB     },
-       { &kSCNetworkInterfaceTypeIEEE80211     , &kSCEntNetAirPort   , TRUE ,  doPPP,          &kSCValNetInterfaceSubTypePPPoE,        doDNS|doIPv4|doIPv6|doProxies|doSMB     },
-       { &kSCNetworkInterfaceTypeIPSec         , &kSCEntNetIPSec     , FALSE,  doNone,         NULL,                                   doDNS|doIPv4|doIPv6|doProxies|doSMB     },
-       { &kSCNetworkInterfaceTypeIrDA          , &kSCEntNetModem     , FALSE,  doPPP,          &kSCValNetInterfaceSubTypePPPSerial,    doNone                                  },
-       { &kSCNetworkInterfaceTypeL2TP          , NULL                , FALSE,  doPPP,          &kSCValNetInterfaceSubTypeL2TP,         doNone                                  },
-       { &kSCNetworkInterfaceTypeModem         , &kSCEntNetModem     , FALSE,  doPPP,          &kSCValNetInterfaceSubTypePPPSerial,    doNone                                  },
-       { &kSCNetworkInterfaceTypePPP           , &kSCEntNetPPP       , FALSE,  doNone,         NULL,                                   doDNS|doIPv4|doIPv6|doProxies|doSMB     },
+       // interface type                     entity_hardware      if config? interface types PPP sub-type                         interface protocols
+       // ================================== ==================== ========== =============== ==================================== ======================================
+       { &kSCNetworkInterfaceType6to4      , &kSCEntNet6to4      , FALSE,    doNone,         NULL,                                doIPv6                              },
+       { &kSCNetworkInterfaceTypeBluetooth , &kSCEntNetModem     , FALSE,    doPPP,          &kSCValNetInterfaceSubTypePPPSerial, doNone                              },
+       { &kSCNetworkInterfaceTypeBond      , &kSCEntNetEthernet  , TRUE ,    doNone,         NULL,                                doDNS|doIPv4|doIPv6|doProxies|doSMB },
+       { &kSCNetworkInterfaceTypeBridge    , &kSCEntNetEthernet  , TRUE ,    doNone,         NULL,                                doDNS|doIPv4|doIPv6|doProxies|doSMB },
+       { &kSCNetworkInterfaceTypeEthernet  , &kSCEntNetEthernet  , TRUE ,    doPPP,          &kSCValNetInterfaceSubTypePPPoE,     doDNS|doIPv4|doIPv6|doProxies|doSMB },
+       { &kSCNetworkInterfaceTypeFireWire  , &kSCEntNetFireWire  , TRUE ,    doNone,         NULL,                                doDNS|doIPv4|doIPv6|doProxies|doSMB },
+       { &kSCNetworkInterfaceTypeIEEE80211 , &kSCEntNetAirPort   , TRUE ,    doPPP,          &kSCValNetInterfaceSubTypePPPoE,     doDNS|doIPv4|doIPv6|doProxies|doSMB },
+       { &kSCNetworkInterfaceTypeIPSec     , &kSCEntNetIPSec     , FALSE,    doNone,         NULL,                                doDNS|doIPv4|doIPv6|doProxies|doSMB },
+       { &kSCNetworkInterfaceTypeL2TP      , NULL                , FALSE,    doPPP,          &kSCValNetInterfaceSubTypeL2TP,      doNone                              },
+       { &kSCNetworkInterfaceTypeModem     , &kSCEntNetModem     , FALSE,    doPPP,          &kSCValNetInterfaceSubTypePPPSerial, doNone                              },
+       { &kSCNetworkInterfaceTypePPP       , &kSCEntNetPPP       , FALSE,    doNone,         NULL,                                doDNS|doIPv4|doIPv6|doProxies|doSMB },
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wdeprecated"
-       { &kSCNetworkInterfaceTypePPTP          , NULL                , FALSE,  doPPP,          &kSCValNetInterfaceSubTypePPTP,         doNone                                  },
+       { &kSCNetworkInterfaceTypePPTP      , NULL                , FALSE,    doPPP,          &kSCValNetInterfaceSubTypePPTP,      doNone                              },
 #pragma GCC diagnostic pop
-       { &kSCNetworkInterfaceTypeSerial        , &kSCEntNetModem     , FALSE,  doPPP,          &kSCValNetInterfaceSubTypePPPSerial,    doNone                                  },
-       { &kSCNetworkInterfaceTypeVLAN          , &kSCEntNetEthernet  , TRUE ,  doNone,         &kSCValNetInterfaceSubTypePPPoE,        doDNS|doIPv4|doIPv6|doProxies|doSMB     },
-       { &kSCNetworkInterfaceTypeVPN           , &kSCEntNetVPN       , FALSE,  doNone,         NULL,                                   doDNS|doIPv4|doIPv6|doProxies|doSMB     },
-       { &kSCNetworkInterfaceTypeWWAN          , &kSCEntNetModem     , FALSE,  doPPP,          &kSCValNetInterfaceSubTypePPPSerial,    doNone                                  },
-       // =====================================  =================== ========== =============== ======================================= =========================================
-       { &kSCNetworkInterfaceTypeLoopback      , NULL                , TRUE ,  doNone,         NULL,                                   doIPv4|doIPv6                           },
-       // =====================================  =================== ========== =============== ======================================= =========================================
-       { &kSCNetworkInterfaceTypeIPv4          , NULL                , FALSE,  doOverIP,       NULL,                                   doNone                                  }
+       { &kSCNetworkInterfaceTypeSerial    , &kSCEntNetModem     , FALSE,    doPPP,          &kSCValNetInterfaceSubTypePPPSerial, doNone                              },
+       { &kSCNetworkInterfaceTypeVLAN      , &kSCEntNetEthernet  , TRUE ,    doNone,         &kSCValNetInterfaceSubTypePPPoE,     doDNS|doIPv4|doIPv6|doProxies|doSMB },
+       { &kSCNetworkInterfaceTypeVPN       , &kSCEntNetVPN       , FALSE,    doNone,         NULL,                                doDNS|doIPv4|doIPv6|doProxies|doSMB },
+       { &kSCNetworkInterfaceTypeWWAN      , &kSCEntNetModem     , FALSE,    doPPP,          &kSCValNetInterfaceSubTypePPPSerial, doNone                              },
+       // ================================== ==================== ========== =============== ==================================== ======================================
+       { &kSCNetworkInterfaceTypeLoopback  , NULL                , TRUE ,    doNone,         NULL,                                doIPv4|doIPv6                       },
+       // ================================== ==================== ========== =============== ==================================== ======================================
+       { &kSCNetworkInterfaceTypeIPv4      , NULL                , FALSE,    doOverIP,       NULL,                                doNone                              }
 };
 
 
                }
        }
        CFStringAppendFormat(result, NULL, CFSTR(", builtin = %s"), interfacePrivate->builtin ? "TRUE" : "FALSE");
-       if (interfacePrivate->hidden) {
+       if (interfacePrivate->hiddenConfiguration) {
                CFStringAppendFormat(result, NULL, CFSTR(", hidden = TRUE"));
        }
+       if (interfacePrivate->hiddenInterface) {
+               CFStringAppendFormat(result, NULL, CFSTR(", HIDDEN"));
+       }
 #if    TARGET_OS_IPHONE
        if (interfacePrivate->trustRequired) {
                CFStringAppendFormat(result, NULL, CFSTR(", trust required = TRUE"));
 __SCNetworkInterfaceOrder(SCNetworkInterfaceRef interface)
 {
        SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+       int                             order;
+
+       order = interfacePrivate->sort_order << 1;
+       if (!interfacePrivate->builtin) {
+               order |= 0x1;   // push non-builtin after built-in
+       }
 
-       return interfacePrivate->sort_order;
+       return order;
 }
 
 
 }
 
 
-static const struct {
-       const CFStringRef       name;
-       const CFStringRef       slot;
-} slot_mappings[] = {
-       // Beige G3
-       { CFSTR("A1") , CFSTR("1") },
-       { CFSTR("B1") , CFSTR("2") },
-       { CFSTR("C1") , CFSTR("3") },
-
-       // Blue&White G3, Yikes G4
-       { CFSTR("J12"), CFSTR("1") },
-       { CFSTR("J11"), CFSTR("2") },
-       { CFSTR("J10"), CFSTR("3") },
-       { CFSTR("J9"),  CFSTR("4") },
-
-       // AGP G4
-       { CFSTR("A")  , CFSTR("1") },
-       { CFSTR("B")  , CFSTR("2") },
-       { CFSTR("C")  , CFSTR("3") },
-       { CFSTR("D") ,  CFSTR("4") },
-
-       // Digital Audio G4 (and later models)
-       { CFSTR("1")  , CFSTR("1") },
-       { CFSTR("2")  , CFSTR("2") },
-       { CFSTR("3")  , CFSTR("3") },
-       { CFSTR("4") ,  CFSTR("4") },
-       { CFSTR("5") ,  CFSTR("5") }
-};
-
-
 static const CFStringRef       slot_prefixes[] = {
        CFSTR("thunderbolt slot "),
        CFSTR("pci slot "),
                        }
                }
 
-               for (size_t i = 0; i < sizeof(slot_mappings)/sizeof(slot_mappings[0]); i++) {
-                       if (CFStringCompare(slot,
-                                           slot_mappings[i].name,
-                                           kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
-                               CFRelease(slot);
-                               slot = (CFMutableStringRef)CFRetain(slot_mappings[i].slot);
-                               break;
-                       }
-               }
+               CFStringTrimWhitespace(slot);
 
                CFRelease(slot_name);
        }
                                if (pci_slot_name != NULL) {
                                        if (*pci_slot_name != NULL) CFRelease(*pci_slot_name);
                                        *pci_slot_name = parent_pci_slot_name;
-                               } else {
-                                       if (parent_pci_slot_name != NULL) CFRelease(parent_pci_slot_name);
+                                       if (*pci_slot_name != NULL) CFRetain(*pci_slot_name);
                                }
                        }
+                       if (parent_pci_slot_name != NULL) CFRelease(parent_pci_slot_name);
 
                        IOObjectRelease(parent);
                        break;
        if (*slot_name != NULL) {
                if (pci_slot_name != NULL) {
                        *port_name = pci_port(pci_slot_name, ift, bsd_name);
-                       CFRelease(pci_slot_name);
                }
                ok = TRUE;
        }
+       if (pci_slot_name != NULL) CFRelease(pci_slot_name);
 
        CFRelease(bsd_name);
        return ok;
                                interfacePrivate->supportsBond = TRUE;
                        }
 
-                       // enable Bridge support
-                       interfacePrivate->supportsBridge = TRUE;
+                       if (!CFEqual(interfacePrivate->interface_type, kSCNetworkInterfaceTypeIEEE80211)) {
+                               // if not Wi-Fi, enable Bridge support
+                               interfacePrivate->supportsBridge = TRUE;
+                       }
 
                        // built-in
                        val = isA_CFBoolean(CFDictionaryGetValue(interface_dict, CFSTR(kIOBuiltin)));
                                        interfacePrivate->localized_arg1 = CFRetain(interfacePrivate->location);
                                }
                        } else {
-                               CFStringRef     provider;
+                               io_registry_entry_t     node;
+                               CFStringRef             provider;
+
+                               // get provider
+                               node = interface;
+                               while (TRUE) {
+                                       io_registry_entry_t     parent;
+                                       IOReturn                status;
+
+                                       provider = IORegistryEntrySearchCFProperty(node,
+                                                                                  kIOServicePlane,
+                                                                                  CFSTR(kIOProviderClassKey),
+                                                                                  NULL,
+                                                                                  kIORegistryIterateRecursively | kIORegistryIterateParents);
+                                       if ((provider == NULL) ||
+                                           !CFEqual(provider, CFSTR("IOSkywalkEthernetInterface"))) {
+                                               // if not "IOSkywalkEthernetInterface" provider
+                                               break;
+                                       }
+
+                                       // skip over this node
+
+                                       CFRelease(provider);
+                                       provider = NULL;
+                                       status = IORegistryEntryGetParentEntry(node,
+                                                                              kIOServicePlane,
+                                                                              &parent);
+                                       if (status != kIOReturnSuccess) {
+                                               break;
+                                       }
+                                       node = parent;
+                               }
 
                                // check provider class
-                               provider = IORegistryEntrySearchCFProperty(interface,
-                                                                          kIOServicePlane,
-                                                                          CFSTR(kIOProviderClassKey),
-                                                                          NULL,
-                                                                          kIORegistryIterateRecursively | kIORegistryIterateParents);
                                if (provider != NULL) {
                                        if (CFEqual(provider, CFSTR("IOPCIDevice"))) {
                                                CFStringRef             port_name;
                                                                        interfacePrivate->localized_arg1 = slot_name;
                                                                        interfacePrivate->localized_arg2 = port_name;
                                                                }
-
                                                        } else {
                                                                if (port_name == NULL) {
                                                                        interfacePrivate->localized_key  = CFSTR("pci-ether");
        return reg_dict;
 }
 
+static Boolean
+isHidden(CFTypeRef hidden)
+{
+       int     val     = 0;
+
+       // looks at the [passed] value of the hidden property
+       if (hidden == NULL) {
+               return FALSE;
+       }
+
+       if (isA_CFBoolean(hidden)) {
+               return CFBooleanGetValue(hidden);
+       } else if (isA_CFNumber(hidden)) {
+               if (CFNumberGetValue(hidden, kCFNumberIntType, (void *)&val) &&
+                   (val == 0)) {
+                       return FALSE;
+               }
+       }
+
+       return TRUE;    // if not explicitly FALSE or 0
+}
+
 static SCNetworkInterfaceRef
-createInterface(io_registry_entry_t interface, processInterface func,
-               CFStringRef hidden_key)
+createInterface(io_registry_entry_t    interface,
+               processInterface        func,
+               CFStringRef             hidden_key,
+               Boolean                 keep_hidden)
 {
        io_registry_entry_t             bus                     = MACH_PORT_NULL;
        CFMutableDictionaryRef          bus_dict                = NULL;
        io_registry_entry_t             controller              = MACH_PORT_NULL;
        CFMutableDictionaryRef          controller_dict         = NULL;
        uint64_t                        entryID                 = 0;
+       Boolean                         hidden_interface        = FALSE;
        SCNetworkInterfacePrivateRef    interfacePrivate        = NULL;
        CFMutableDictionaryRef          interface_dict          = NULL;
        kern_return_t                   kr;
                                                      NULL,
                                                      kIORegistryIterateRecursively | kIORegistryIterateParents);
                if (val != NULL) {
+                       hidden_interface = isHidden(val);
                        CFRelease(val);
-                       goto done;      // if this interface should not be exposed
+                       if (hidden_interface && !keep_hidden) {
+                               goto done;      // if this interface should not be exposed
+                       }
                }
        }
 
-        interface_dict = copyIORegistryProperties(interface,
-                                                  interface_dict_keys,
-                                                  sizeof(interface_dict_keys)/sizeof(interface_dict_keys[0]));
+       interface_dict = copyIORegistryProperties(interface,
+                                                 interface_dict_keys,
+                                                 sizeof(interface_dict_keys)/sizeof(interface_dict_keys[0]));
 
        // get the controller node
        kr = IORegistryEntryGetParentEntry(interface, kIOServicePlane, &controller);
 
        interfacePrivate = __SCNetworkInterfaceCreatePrivate(NULL, NULL, NULL, NULL);
        assert(interfacePrivate != NULL);
+       interfacePrivate->hiddenInterface = hidden_interface;
        interfacePrivate->path = __SC_IORegistryEntryCopyPath(interface, kIOServicePlane);
        interfacePrivate->entryID = entryID;
 
                                                      NULL,
                                                      kIORegistryIterateRecursively | kIORegistryIterateParents);
                if (val != NULL) {
-                       interfacePrivate->hidden = TRUE;
+                       interfacePrivate->hiddenConfiguration = isHidden(val);
                        CFRelease(val);
                }
 
 findMatchingInterfaces(CFDictionaryRef matching,
                       processInterface func,
                       CFStringRef      hidden_key,
+                      Boolean          keep_hidden,
                       Boolean          keep_pre_configured)
 {
        CFMutableArrayRef       interfaces;
        while ((interface = IOIteratorNext(iterator)) != MACH_PORT_NULL) {
                SCNetworkInterfaceRef           match;
 
-               match = createInterface(interface, func, hidden_key);
+               match = createInterface(interface, func, hidden_key, keep_hidden);
                if (match != NULL) {
                        if (keep_pre_configured || !_SCNetworkInterfaceIsApplePreconfigured(match)) {
                                CFArrayAppendValue(interfaces, match);
 #pragma mark SCNetworkInterface <--> preferences entity
 
 
+static SCNetworkServicePrivate __SCNetworkInterfaceSearchExternal      = {
+       .cfBase         = INIT_CFRUNTIME_BASE(),        // cfBase
+};
+
+__private_extern__
+const SCNetworkServiceRef __kSCNetworkInterfaceSearchExternal  = (SCNetworkServiceRef)&__SCNetworkInterfaceSearchExternal;
+
+static SCNetworkServicePrivate __SCNetworkInterfaceSearchSystem        = {
+       .cfBase         = INIT_CFRUNTIME_BASE(),        // cfBase
+};
+
+__private_extern__
+const SCNetworkServiceRef __kSCNetworkInterfaceSearchSystem    = (SCNetworkServiceRef)&__SCNetworkInterfaceSearchSystem;
+
+
 __private_extern__
 CFDictionaryRef
 __SCNetworkInterfaceCopyInterfaceEntity(SCNetworkInterfaceRef interface)
                                     CFSTR("DeviceUniqueIdentifier"),
                                     interfacePrivate->entity_device_unique);
        }
-       if (interfacePrivate->hidden) {
+       if (interfacePrivate->hiddenConfiguration) {
                CFDictionarySetValue(entity,
                                     kSCNetworkInterfaceHiddenConfigurationKey,
                                     kCFBooleanTrue);
                CFDictionarySetValue(entity, CFSTR("_NO_VLAN_INTERFACES_"), kCFBooleanTrue);
        }
 
-       interface = _SCNetworkInterfaceCreateWithEntity(NULL, entity, NULL);
+       interface = _SCNetworkInterfaceCreateWithEntity(NULL, entity, __kSCNetworkInterfaceSearchSystem);
        CFRelease(entity);
 
        return interface;
                CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceActive), kCFBooleanTrue);
        }
        CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceBSDName), bsdName);
-       if (interfacePrivate->hidden) {
+       if (interfacePrivate->hiddenConfiguration) {
                CFDictionaryAddValue(interface_entity, kSCNetworkInterfaceHiddenConfigurationKey, kCFBooleanTrue);
        }
+       if (interfacePrivate->hiddenInterface) {
+               CFDictionaryAddValue(interface_entity, kSCNetworkInterfaceHiddenInterfaceKey, kCFBooleanTrue);
+       }
        CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOBuiltin), builtin);
        CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix), interfaceNamePrefix);
        CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceType), interfaceType);
 }
 
 
+static Boolean
+matchesName(CFBundleRef bundle, CFStringRef name, CFStringRef key, Boolean localized)
+{
+       Boolean         match   = FALSE;
+       CFStringRef     str;
+
+       str = copy_interface_string(bundle, key, localized);
+       if (str != NULL) {
+               match = CFEqual(name, str);
+               if (!match && CFStringHasSuffix(str, CFSTR(" %@"))) {
+                       CFMutableStringRef      str_multi;
+
+                       str_multi = CFStringCreateMutableCopy(NULL, 0, str);
+                       CFStringTrim(str_multi, CFSTR("%@"));
+                       match = CFStringHasPrefix(name, str_multi);
+                       CFRelease(str_multi);
+               }
+
+               CFRelease(str);
+       }
+
+       return match;
+}
+
+
 __private_extern__
 Boolean
 __SCNetworkInterfaceMatchesName(CFStringRef name, CFStringRef key)
 {
        Boolean         match;
-       CFStringRef     str;
 
        if (bundle == NULL) {
                SC_log(LOG_NOTICE, "no bundle information to compare interface names");
        }
 
        // check non-localized name for a match
-       str = copy_interface_string(bundle, key, FALSE);
-       if (str != NULL) {
-               match = CFEqual(name, str);
-               CFRelease(str);
-               if (match) {
-                       return TRUE;
-               }
-       }
+       match = matchesName(bundle, name, key, FALSE);
 
-       // check localized name for a match
-       str = copy_interface_string(bundle, key, TRUE);
-       if (str != NULL) {
-               match = CFEqual(name, str);
-               CFRelease(str);
-               if (match) {
-                       return TRUE;
-               }
+       if (!match) {
+               // check localized name for a match
+               match = matchesName(bundle, name, key, TRUE);
        }
 
-       return FALSE;
+       return match;
 }
 
 
-#define kInterfaceTypeEthernetValue 6
-#define kInterfaceTypeFirewireValue 144
-
-
 static SCNetworkInterfaceRef
-__SCNetworkInterfaceCreateWithStorageEntity(CFDictionaryRef interface_entity)
+__SCNetworkInterfaceCreateWithStorageEntity(CFDictionaryRef storage_entity)
 {
-       CFIndex                         interfaceIndex;
+       CFMutableDictionaryRef          interface_entity;
+       CFIndex                         interface_index;
+       CFStringRef                     interface_type;
        SCNetworkInterfacePrivateRef    interfacePrivate        = NULL;
        CFBooleanRef                    active;
        CFStringRef                     bsdName;
-       CFBooleanRef                    hidden;
+       CFBooleanRef                    hiddenConfiguration;
+       CFBooleanRef                    hiddenInterface;
+       CFStringRef                     ifType                  = kSCValNetInterfaceTypeEthernet;
        CFDictionaryRef                 interfaceInfo;
        CFBooleanRef                    ioBuiltin;
        CFStringRef                     ioInterfaceNamePrefix   = NULL;
        CFNumberRef                     idProduct;
        CFNumberRef                     idVendor;
 #endif // !TARGET_OS_SIMULATOR
-       CFStringRef                     type;
 
        /* initialize runtime */
        pthread_once(&initialized, __SCNetworkInterfaceInitialize);
 
-       if (!isA_CFDictionary(interface_entity)) {
+       if (!isA_CFDictionary(storage_entity)) {
                SC_log(LOG_INFO, "No interface entity");
                goto done;
        }
-       active = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceActive));
+       active = CFDictionaryGetValue(storage_entity, CFSTR(kSCNetworkInterfaceActive));
        if (!isA_CFBoolean(active)) {
                active = kCFBooleanFalse;
        }
-       bsdName = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceBSDName));
+       bsdName = CFDictionaryGetValue(storage_entity, CFSTR(kSCNetworkInterfaceBSDName));
        if (!isA_CFString(bsdName)) {
                SC_log(LOG_DEBUG, "No BSD name");
                goto done;
        }
-       hidden = CFDictionaryGetValue(interface_entity, kSCNetworkInterfaceHiddenConfigurationKey);
-       if (!isA_CFBoolean(hidden)) {
-               hidden = kCFBooleanFalse;
+       hiddenConfiguration = CFDictionaryGetValue(storage_entity, kSCNetworkInterfaceHiddenConfigurationKey);
+       if (!isA_CFBoolean(hiddenConfiguration)) {
+               hiddenConfiguration = kCFBooleanFalse;
+       }
+       hiddenInterface = CFDictionaryGetValue(storage_entity, kSCNetworkInterfaceHiddenInterfaceKey);
+       if (!isA_CFBoolean(hiddenInterface)) {
+               hiddenInterface = kCFBooleanFalse;
        }
-       ioBuiltin = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOBuiltin));
+       ioBuiltin = CFDictionaryGetValue(storage_entity, CFSTR(kSCNetworkInterfaceIOBuiltin));
        if (!isA_CFBoolean(ioBuiltin)) {
                SC_log(LOG_INFO, "No IOBuiltin property");
                goto done;
        }
-       ioInterfaceNamePrefix = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix));
+       ioInterfaceNamePrefix = CFDictionaryGetValue(storage_entity, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix));
        if (!isA_CFString(ioInterfaceNamePrefix)) {
                ioInterfaceNamePrefix = _SCNetworkInterfaceCopyPrefixFromBSDName(bsdName);
                if (ioInterfaceNamePrefix == NULL) {
        } else {
                CFRetain(ioInterfaceNamePrefix);
        }
-       ioInterfaceType = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceType));
+       ioInterfaceType = CFDictionaryGetValue(storage_entity, CFSTR(kSCNetworkInterfaceIOInterfaceType));
        if (!isA_CFNumber(ioInterfaceType)) {
                SC_log(LOG_INFO, "No IOInterfaceType");
                goto done;
        if (!CFNumberGetValue(ioInterfaceType, kCFNumberIntType, &ioInterfaceTypeNum)) {
                SC_log(LOG_NOTICE, "Count not extract value from ioInterfaceType");
        }
-       ioInterfaceUnit = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceUnit));
+       ioInterfaceUnit = CFDictionaryGetValue(storage_entity, CFSTR(kSCNetworkInterfaceIOInterfaceUnit));
        if (!isA_CFNumber(ioInterfaceUnit)) {
                SC_log(LOG_INFO, "No IOInterfaceUnit");
                goto done;
        }
-       ioMACAddress = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOMACAddress));
+       ioMACAddress = CFDictionaryGetValue(storage_entity, CFSTR(kSCNetworkInterfaceIOMACAddress));
        if (!isA_CFData(ioMACAddress)) {
                SC_log(LOG_INFO, "No IOMACAddress");
                goto done;
        }
-       ioPathMatch = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOPathMatch));
+       ioPathMatch = CFDictionaryGetValue(storage_entity, CFSTR(kSCNetworkInterfaceIOPathMatch));
        if (!isA_CFString(ioPathMatch)) {
                SC_log(LOG_INFO, "No IOPathMatch");
                goto done;
        } else {
                // Check if Path contains the BSD Name in the end
        }
-       interfaceInfo = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceInfo));
+       interfaceInfo = CFDictionaryGetValue(storage_entity, CFSTR(kSCNetworkInterfaceInfo));
        if (!isA_CFDictionary(interfaceInfo)) {
                SC_log(LOG_INFO, "No SCNetworkInterfaceInfo");
                goto done;
        }
        userDefinedName = CFDictionaryGetValue(interfaceInfo, kSCPropUserDefinedName);
+       userDefinedName = isA_CFString(userDefinedName);
 #if    !TARGET_OS_SIMULATOR
        usbProductName = CFDictionaryGetValue(interfaceInfo, CFSTR(kUSBProductString));
+       usbProductName = isA_CFString(usbProductName);
        idProduct = CFDictionaryGetValue(interfaceInfo, CFSTR(kUSBProductID));
+       idProduct = isA_CFNumber(idProduct);
        idVendor = CFDictionaryGetValue(interfaceInfo, CFSTR(kUSBVendorID));
+       idVendor = isA_CFNumber(idVendor);
 #endif // !TARGET_OS_SIMULATOR
-       matchingMacs = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceMatchingMACs));
+       matchingMacs = CFDictionaryGetValue(storage_entity, CFSTR(kSCNetworkInterfaceMatchingMACs));
+       matchingMacs = isA_CFArray(matchingMacs);
 
-       type = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceType));
-       if (!isA_CFString(type)) {
+       interface_type = CFDictionaryGetValue(storage_entity, CFSTR(kSCNetworkInterfaceType));
+       if (!isA_CFString(interface_type)) {
                SC_log(LOG_INFO, "No SCNetworkInterfaceType");
                goto done;
        }
 
-       interfacePrivate = __SCNetworkInterfaceCreatePrivate(NULL, NULL, NULL, NULL);
+       interface_entity = CFDictionaryCreateMutable(NULL,
+                                                   0,
+                                                   &kCFTypeDictionaryKeyCallBacks,
+                                                   &kCFTypeDictionaryValueCallBacks);
+       // set [entity] interface type
+       if (ioInterfaceTypeNum == IFT_ETHER) {
+               ifType = kSCValNetInterfaceTypeEthernet;
+       } else if (ioInterfaceTypeNum == IFT_IEEE1394) {
+               ifType = kSCValNetInterfaceTypeFireWire;
+       } else {
+               ifType = interface_type;
+       }
+       CFDictionarySetValue(interface_entity,
+                            kSCPropNetInterfaceType,
+                            ifType);
+       // set [entity] interface hardware
+       interface_index = findConfiguration(interface_type);
+       if (interface_index != kCFNotFound) {
+               // set interface type
+               if (configurations[interface_index].entity_hardware != NULL) {
+                       // set interface hardware
+                       CFDictionarySetValue(interface_entity,
+                                            kSCPropNetInterfaceHardware,
+                                            *configurations[interface_index].entity_hardware);
+               }
+       } else {
+               CFDictionarySetValue(interface_entity,
+                                    kSCPropNetInterfaceHardware,
+                                    interface_type);
+       }
+       // set [entity] BSD interface name
+       CFDictionarySetValue(interface_entity, kSCPropNetInterfaceDeviceName, bsdName);
+       // set [entity] hidden
+       if (CFBooleanGetValue(hiddenConfiguration)) {
+               CFDictionarySetValue(interface_entity, kSCNetworkInterfaceHiddenConfigurationKey, kCFBooleanTrue);
+       }
+       // set [entity] user defined name
+       if (userDefinedName != NULL) {
+               CFDictionarySetValue(interface_entity, kSCPropUserDefinedName, userDefinedName);
+       }
+
+       // create the interface
+       interfacePrivate = (SCNetworkInterfacePrivateRef)_SCNetworkInterfaceCreateWithEntity(NULL,
+                                                                                            interface_entity,
+                                                                                            __kSCNetworkInterfaceSearchExternal);
+       CFRelease(interface_entity);
+
+       // and fill in a few more of the [storage_entity] details
        interfacePrivate->active = CFBooleanGetValue(active);
-       interfacePrivate->entity_device = CFRetain(bsdName);
        interfacePrivate->builtin = CFBooleanGetValue(ioBuiltin);
-       interfacePrivate->hidden = CFBooleanGetValue(hidden);
+       interfacePrivate->hiddenInterface = CFBooleanGetValue(hiddenInterface);
        interfacePrivate->prefix = CFRetain(ioInterfaceNamePrefix);
        interfacePrivate->type = CFRetain(ioInterfaceType);
        interfacePrivate->unit = CFRetain(ioInterfaceUnit);
        interfacePrivate->address = CFRetain(ioMACAddress);
        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);
 #endif // !TARGET_OS_SIMULATOR
        interfacePrivate->matchingMACs = ((matchingMacs != NULL) ? CFRetain(matchingMacs) : NULL);
 
-       // Handling interface types to be seen in NetworkInterfaces.plist
-       interfaceIndex = findConfiguration(type);
-       if (interfaceIndex != kCFNotFound) {
-               interfacePrivate->interface_type = *configurations[interfaceIndex].interface_type;
-       } else {
-               interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet;
-       }
-
-       // Extracting entity type from value of interface type
-       if (ioInterfaceTypeNum == kInterfaceTypeEthernetValue) {
-               interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet; // kSCNetworkInterfaceTypeEthernet;
-       } else if (ioInterfaceTypeNum == kInterfaceTypeFirewireValue) {
-               interfacePrivate->entity_type = kSCValNetInterfaceTypeFireWire;
-       }
-
     done:
 
        if (ioInterfaceNamePrefix != NULL) {
                                    SCNetworkServiceRef service)
 {
 #pragma unused(allocator)
+       Boolean                         keepHidden              = FALSE;
        SCNetworkInterfacePrivateRef    interfacePrivate        = NULL;
        CFStringRef                     ifDevice;
        CFStringRef                     ifName                  = NULL;
        CFStringRef                     ifType;
        CFStringRef                     ifUnique;
        CFArrayRef                      matching_interfaces     = NULL;
-       SCPreferencesRef                servicePref             = NULL;
        Boolean                         useSystemInterfaces     = TRUE;
+       SCPreferencesRef                virtualPrefs            = NULL;
 
        /* initialize runtime (and kSCNetworkInterfaceIPv4) */
        pthread_once(&initialized, __SCNetworkInterfaceInitialize);
 
-       if (service != NULL) {
-               servicePref = ((SCNetworkServicePrivateRef)service)->prefs;
-               useSystemInterfaces = !_SCNetworkConfigurationBypassSystemInterfaces(servicePref);
+       if (service == __kSCNetworkInterfaceSearchExternal) {
+               // no service/prefs, ignore system interfaces
+               service = NULL;
+               useSystemInterfaces = FALSE;
+       } else if (service == __kSCNetworkInterfaceSearchSystem) {
+               // no service/prefs, include all system interfaces (including excluded)
+               keepHidden = TRUE;
+               service = NULL;
+               useSystemInterfaces = TRUE;
+       } else if (service != NULL) {
+               virtualPrefs = ((SCNetworkServicePrivateRef)service)->prefs;
+               useSystemInterfaces = !_SCNetworkConfigurationBypassSystemInterfaces(virtualPrefs);
        }
 
        ifType = CFDictionaryGetValue(interface_entity, kSCPropNetInterfaceType);
                                matching_interfaces = findMatchingInterfaces(matching,
                                                                             processNetworkInterface,
                                                                             kSCNetworkInterfaceHiddenInterfaceKey,
+                                                                            keepHidden,
                                                                             TRUE);
 
                                __SCNetworkInterfaceCacheAdd(ifDevice, matching_interfaces);
                                matching_interfaces = findMatchingInterfaces(matching,
                                                                             processSerialInterface,
                                                                             kSCNetworkInterfaceHiddenPortKey,
+                                                                            keepHidden,
                                                                             TRUE);
                                CFRelease(matching);
                        }
                                        matching_interfaces = findMatchingInterfaces(matching,
                                                                                     processSerialInterface,
                                                                                     kSCNetworkInterfaceHiddenPortKey,
+                                                                                    keepHidden,
                                                                                     TRUE);
                                        CFRelease(matching);
                                }
        }
 
        if (matching_interfaces != NULL) {
-               CFIndex                 n;
-               SCPreferencesRef        prefs;
-               Boolean                 temp_preferences        = FALSE;
+               CFIndex         n;
 
                n = CFArrayGetCount(matching_interfaces);
                switch (n) {
 
                                interfacePrivate = NULL;
                                // fall through
-                       case 0 :
+                       case 0 : {
+                               Boolean temp_preferences        = FALSE;
+
                                if (!CFEqual(ifType, kSCValNetInterfaceTypeEthernet)) {
                                        break;
                                }
                                        break;
                                }
 
-                               prefs = (service != NULL) ? ((SCNetworkServicePrivateRef)service)->prefs : NULL;
-                               if (prefs == NULL) {
-                                       prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterface"), NULL);
-                                       if (prefs != NULL) {
+                               if (virtualPrefs == NULL) {
+                                       virtualPrefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterface"), NULL);
+                                       if (virtualPrefs != NULL) {
                                                temp_preferences = TRUE;
                                        }
                                }
-                               if (prefs == NULL) {
+                               if (virtualPrefs == NULL) {
                                        break;
                                }
 #if    !TARGET_OS_IPHONE
                                if (!CFDictionaryContainsKey(interface_entity, CFSTR("_NO_BOND_INTERFACES_"))) {
-                                       interfacePrivate = (SCNetworkInterfacePrivateRef)findBondInterface(prefs, ifDevice);
+                                       interfacePrivate = (SCNetworkInterfacePrivateRef)findBondInterface(virtualPrefs, ifDevice);
                                }
 #endif // !TARGET_OS_IPHONE
                                if ((interfacePrivate == NULL)
                                    && !CFDictionaryContainsKey(interface_entity, CFSTR("_NO_BRIDGE_INTERFACES_"))) {
-                                       interfacePrivate = (SCNetworkInterfacePrivateRef)findBridgeInterface(prefs, ifDevice);
+                                       interfacePrivate = (SCNetworkInterfacePrivateRef)findBridgeInterface(virtualPrefs, ifDevice);
                                }
 
                                if ((interfacePrivate == NULL)
                                    && !CFDictionaryContainsKey(interface_entity, CFSTR("_NO_VLAN_INTERFACES_"))) {
-                                       interfacePrivate = (SCNetworkInterfacePrivateRef)findVLANInterface(prefs, ifDevice);
+                                       interfacePrivate = (SCNetworkInterfacePrivateRef)findVLANInterface(virtualPrefs, ifDevice);
+                               }
+                               if (temp_preferences) {
+                                       CFRelease(virtualPrefs);
+                                       virtualPrefs = NULL;
                                }
-                               if (temp_preferences) CFRelease(prefs);
                                break;
+                       }
                        default :
                                if (ifUnique != NULL) {
                                        CFIndex i;
     done :
 
        if ((interfacePrivate == NULL) || !useSystemInterfaces)  {
+               CFStringRef     userDefinedName;
+               CFBooleanRef    val;
+
                /*
                 * if device not present on this system
                 */
                interfacePrivate->entity_device        = (ifDevice != NULL) ? CFStringCreateCopy(NULL, ifDevice) : NULL;
                interfacePrivate->entity_device_unique = (ifUnique != NULL) ? CFStringCreateCopy(NULL, ifUnique) : NULL;
 
-               // Using UserDefinedName to check the validity of preferences file
-               // when useSystemInterfaces is FALSE
+               userDefinedName = CFDictionaryGetValue(interface_entity, kSCPropUserDefinedName);
+               userDefinedName = isA_CFString(userDefinedName);
+
+               // if not consulting the current systems interfaces, use the UserDefinedName
+               // to check the validity of preferences file
                if (!useSystemInterfaces) {
-                       CFStringRef userDefinedName = CFDictionaryGetValue(interface_entity, kSCPropUserDefinedName);
-                       if (isA_CFString(userDefinedName) != NULL) {
+                       if (userDefinedName != NULL) {
                                CFRetain(userDefinedName);
                                if (interfacePrivate->name != NULL) {
                                        CFRelease(interfacePrivate->name);
                }
 
                if (CFEqual(ifType, kSCValNetInterfaceTypeEthernet)) {
-                       CFStringRef     entity_hardware;
-                       SCNetworkInterfaceRef virtualInterface;
+                       CFStringRef             entity_hardware;
+                       SCNetworkInterfaceRef   virtualInterface;
 
                        if (!useSystemInterfaces &&
-                           (((virtualInterface = findBridgeInterface(servicePref, ifDevice)) != NULL) ||
+                           (((virtualInterface = findBridgeInterface(virtualPrefs, ifDevice)) != NULL) ||
 #if    !TARGET_OS_IPHONE
-                           ((virtualInterface = findBondInterface(servicePref,  ifDevice)) != NULL) ||
+                            ((virtualInterface = findBondInterface  (virtualPrefs, ifDevice)) != NULL) ||
 #endif // !TARGET_OS_IPHONE
-                           ((virtualInterface = findVLANInterface(servicePref, ifDevice)) != NULL))) {
+                            ((virtualInterface = findVLANInterface  (virtualPrefs, ifDevice)) != NULL))) {
                                CFRelease(interfacePrivate);
                                interfacePrivate = (SCNetworkInterfacePrivateRef)virtualInterface;
                        } else {
                                        interfacePrivate->interface_type = kSCNetworkInterfaceTypeIEEE80211;
                                        interfacePrivate->localized_key  = CFSTR("airport");
                                        interfacePrivate->sort_order     = kSortAirPort;
+                                       interfacePrivate->builtin        = TRUE;
                                } else {
-                                       CFStringRef     name;
-
                                        interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet;
-
-                                       name = CFDictionaryGetValue(interface_entity, kSCPropUserDefinedName);
-                                       if (__SCNetworkInterfaceMatchesName(name, CFSTR("iPhone"))) {
+                                       if (__SCNetworkInterfaceMatchesName(userDefinedName, CFSTR("ether")) ||
+                                           __SCNetworkInterfaceMatchesName(userDefinedName, CFSTR("multiether"))) {
+                                               interfacePrivate->sort_order    = kSortEthernet;
+                                               interfacePrivate->builtin       = TRUE;
+                                       } else if (__SCNetworkInterfaceMatchesName(userDefinedName, CFSTR("iPhone"))) {
                                                interfacePrivate->localized_key = CFSTR("iPhone");
                                                interfacePrivate->sort_order    = kSortTethered;
-                                       } else if (__SCNetworkInterfaceMatchesName(name, CFSTR("iPad"))) {
+                                       } else if (__SCNetworkInterfaceMatchesName(userDefinedName, CFSTR("iPad"))) {
                                                interfacePrivate->localized_key = CFSTR("iPad");
                                                interfacePrivate->sort_order    = kSortTethered;
-                                       } else if (__SCNetworkInterfaceMatchesName(name, CFSTR("thunderbolt"))) {
+                                       } else if (__SCNetworkInterfaceMatchesName(userDefinedName, CFSTR("thunderbolt")) ||
+                                                  __SCNetworkInterfaceMatchesName(userDefinedName, CFSTR("multithunderbolt"))) {
                                                interfacePrivate->localized_key = CFSTR("thunderbolt");
                                                interfacePrivate->sort_order    = kSortThunderbolt;
-                                       } else if (__SCNetworkInterfaceMatchesName(name, CFSTR("bluetooth-pan-gn"))) {
+                                               interfacePrivate->builtin       = TRUE;
+                                       } else if (__SCNetworkInterfaceMatchesName(userDefinedName, CFSTR("bluetooth-pan-gn"))) {
                                                interfacePrivate->localized_key = CFSTR("bluetooth-pan-gn");
                                                interfacePrivate->sort_order    = kSortBluetoothPAN_GN;
-                                       } else if (__SCNetworkInterfaceMatchesName(name, CFSTR("bluetooth-pan-nap"))) {
+                                       } else if (__SCNetworkInterfaceMatchesName(userDefinedName, CFSTR("bluetooth-pan-nap"))) {
                                                interfacePrivate->localized_key = CFSTR("bluetooth-pan-nap");
                                                interfacePrivate->sort_order    = kSortBluetoothPAN_NAP;
-                                       } else if (__SCNetworkInterfaceMatchesName(name, CFSTR("bluetooth-pan-u"))) {
+                                       } else if (__SCNetworkInterfaceMatchesName(userDefinedName, CFSTR("bluetooth-pan-u"))) {
                                                interfacePrivate->localized_key = CFSTR("bluetooth-pan-u");
                                                interfacePrivate->sort_order    = kSortBluetoothPAN_U;
                                        } else {
                } else if (CFEqual(ifType, kSCValNetInterfaceTypeFireWire)) {
                        interfacePrivate->interface_type = kSCNetworkInterfaceTypeFireWire;
                        interfacePrivate->sort_order     = kSortFireWire;
+                       if (__SCNetworkInterfaceMatchesName(userDefinedName, CFSTR("firewire"))) {
+                               interfacePrivate->builtin        = TRUE;
+                       }
                } else if (CFEqual(ifType, kSCValNetInterfaceTypePPP) && (ifSubType != NULL)) {
                        if (CFEqual(ifSubType, kSCValNetInterfaceSubTypePPPoE)) {
                                CFStringRef     entity_hardware;
                        }
                } else if (CFEqual(ifType, kSCValNetInterfaceTypeVPN) && (ifSubType != NULL)) {
                        SCNetworkInterfaceRef   child;
+
                        CFRelease(interfacePrivate);
                        child = SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4, ifSubType);
                        interfacePrivate = (SCNetworkInterfacePrivateRef)child;
                        return NULL;
                }
 
-               if (CFDictionaryContainsKey(interface_entity, kSCNetworkInterfaceHiddenConfigurationKey)) {
-                       interfacePrivate->hidden = TRUE;
-               }
+               val = CFDictionaryGetValue(interface_entity, kSCNetworkInterfaceHiddenConfigurationKey);
+               interfacePrivate->hiddenConfiguration = isHidden(val);
 #if    TARGET_OS_IPHONE
                if (CFDictionaryContainsKey(interface_entity, kSCNetworkInterfaceTrustRequiredKey)) {
                        interfacePrivate->trustRequired = TRUE;
        new_interfaces = findMatchingInterfaces(matching,
                                                processNetworkInterface,
                                                kSCNetworkInterfaceHiddenInterfaceKey,
+                                               FALSE,
                                                keep_pre_configured);
        CFRelease(matching);
 
        new_interfaces = findMatchingInterfaces(matching,
                                                processSerialInterface,
                                                kSCNetworkInterfaceHiddenPortKey,
+                                               FALSE,
                                                FALSE);
        CFRelease(matching);
 
        new_interfaces = findMatchingInterfaces(matching,
                                                processSerialInterface,
                                                kSCNetworkInterfaceHiddenPortKey,
+                                               FALSE,
                                                FALSE);
        CFRelease(matching);
 
 
 
 static void
-__waitForInterfaces()
+__wait_for_IOKit_to_quiesce(void)
 {
        CFStringRef             key     = NULL;
        CFArrayRef              keys;
        pthread_once(&initialized, __SCNetworkInterfaceInitialize);
 
        /* wait for IOKit to quiesce */
-       pthread_once(&iokit_quiet, __waitForInterfaces);
+       pthread_once(&iokit_quiet, __wait_for_IOKit_to_quiesce);
 
        all_interfaces = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
 
                goto fail;
        }
 
-       parentPrivate->hidden = childPrivate->hidden;
+       parentPrivate->hiddenConfiguration = childPrivate->hiddenConfiguration;
+
+       parentPrivate->hiddenInterface = childPrivate->hiddenInterface;
 
 #if    TARGET_OS_IPHONE
        parentPrivate->trustRequired = childPrivate->trustRequired;
        pthread_once(&initialized, __SCNetworkInterfaceInitialize);
 
        if (IOObjectConformsTo(if_obj, kIONetworkInterfaceClass)) {
-               interface = createInterface(if_obj, processNetworkInterface, NULL);
+               interface = createInterface(if_obj,
+                                           processNetworkInterface,
+                                           kSCNetworkInterfaceHiddenInterfaceKey,
+                                           TRUE);
        } else if (IOObjectConformsTo(if_obj, kIOSerialBSDServiceValue)) {
-               interface = createInterface(if_obj, processSerialInterface, kSCNetworkInterfaceHiddenPortKey);
+               interface = createInterface(if_obj,
+                                           processSerialInterface,
+                                           kSCNetworkInterfaceHiddenPortKey,
+                                           FALSE);
        }
 
        return interface;
 {
        SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
 
-       return interfacePrivate->hidden;
+       return interfacePrivate->hiddenConfiguration;
+}
+
+
+Boolean
+_SCNetworkInterfaceIsHiddenInterface(SCNetworkInterfaceRef interface)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+
+       return interfacePrivate->hiddenInterface;
+}
+
+
+Boolean
+_SCNetworkInterfaceIsQoSMarkingProfileInstalled(SCNetworkInterfaceRef interface)
+{
+       CFStringRef     bsdName;
+       CFStringRef     key;
+       Boolean         isInstalled             = FALSE;
+       CFDictionaryRef profile;
+
+       bsdName = SCNetworkInterfaceGetBSDName(interface);
+       if (bsdName == NULL) {
+               return FALSE;
+       }
+
+       key = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
+                                                           kSCDynamicStoreDomainState,
+                                                           bsdName,
+                                                           kSCEntNetQoSMarkingPolicy);
+       profile = SCDynamicStoreCopyValue(NULL, key);
+       CFRelease(key);
+       if (profile != NULL) {
+               CFRelease(profile);
+               isInstalled = TRUE;
+       }
+
+       return isInstalled;
 }
 
 
        if (oldPrivate->configurationAction != NULL) {
                newPrivate->configurationAction = CFRetain(oldPrivate->configurationAction);
        }
-       newPrivate->hidden                      = oldPrivate->hidden;
+       newPrivate->hiddenConfiguration         = oldPrivate->hiddenConfiguration;
+       newPrivate->hiddenInterface             = oldPrivate->hiddenInterface;
 #if    TARGET_OS_IPHONE
        newPrivate->trustRequired               = oldPrivate->trustRequired;
 #endif // TARGET_OS_IPHONE
 
 #include "SCPreferencesInternal.h"
 #include <IOKit/network/IONetworkInterface.h>
 #include <IOKit/network/IONetworkController.h>
+#if    !TARGET_OS_SIMULATOR
+#include <IOKit/usb/USB.h>
+#endif // !TARGET_OS_SIMULATOR
 #include <sys/stat.h>
 #include <copyfile.h>
 #include <sys/param.h>
        CFRelease(prefs);
        CFRelease(interfaces);
 
-       SC_log(LOG_INFO,
-              "_SCNetworkConfigurationCopyMigrationPaths() called%s"
-              "\n  options = %@"
-              "\n  paths   = %@",
-              _SC_isInstallEnvironment() ? " (INSTALLER ENVIRONMENT)" : "",
-              options,
-              migrationPaths);
-
        return migrationPaths;
 }
 
 static void
 __SCNetworkPopulateDefaultPrefs(SCPreferencesRef prefs)
 {
-       SCNetworkSetRef         currentSet;
-       CFStringRef             model;
-       CFNumberRef             version;
+       SCNetworkSetRef currentSet;
+       CFStringRef     model;
+       CFNumberRef     version;
 
        SC_log(LOG_INFO,
               "Populating preferences.plist"
 
        version = SCPreferencesGetValue(prefs, kSCPrefVersion);
        if (version == NULL) {
-               const int       new_version     = NETWORK_CONFIGURATION_VERSION;
+               const int       new_version     = NETWORK_CONFIGURATION_VERSION;
 
                version = CFNumberCreate(NULL, kCFNumberIntType, &new_version);
                SCPreferencesSetValue(prefs, kSCPrefVersion, version);
        return;
 }
 
-__private_extern__
-void
+static void
 __SCNetworkPopulateDefaultNIPrefs(SCPreferencesRef ni_prefs)
 {
        CFMutableArrayRef       interfaces      = NULL;
 _SCNetworkConfigurationPerformMigration(CFURLRef sourceDir, CFURLRef currentDir, CFURLRef targetDir, CFDictionaryRef options)
 {
 #pragma unused(options)
-       CFURLRef currentDirConfig = NULL;
-       CFURLRef currentSystemPath = NULL;
-       Boolean migrationComplete = FALSE;
-       CFArrayRef paths = NULL;
-       Boolean removeTargetOnFailure = FALSE;
-       CFURLRef sourceDirConfig = NULL;
-       CFURLRef targetDirConfig = NULL;
+       CFURLRef        currentDirConfig        = NULL;
+       CFURLRef        currentSystemPath       = NULL;
+       Boolean         migrationComplete       = FALSE;
+       CFArrayRef      paths                   = NULL;
+       Boolean         removeTargetOnFailure   = FALSE;
+       CFURLRef        sourceDirConfig         = NULL;
+       CFURLRef        targetDirConfig         = NULL;
 
        SC_log(LOG_INFO,
-              "_SCNetworkConfigurationPerformMigration() called%s"
+              "Perform Migration%s"
               "\n  sourceDir  = %@"
               "\n  currentDir = %@"
               "\n  targetDir  = %@"
               sourceDir,
               currentDir,
               targetDir,
-              options);
+              options != NULL ? options : (CFDictionaryRef)CFSTR("None"));
 
        if ((sourceDir != NULL) && !CFURLHasDirectoryPath(sourceDir)) {
                SC_log(LOG_NOTICE, "Migration source is not a directory: %@", sourceDir);
 static Boolean
 _SCNetworkConfigurationMigrateIsFilePresent(CFURLRef filePath)
 {
-       Boolean fileExists = false;
-       char filePathStr[PATH_MAX];
-       int statResult = 0;
-       struct stat statStruct = {0, };
+       Boolean         fileExists      = false;
+       char            filePathStr[PATH_MAX];
+       int             statResult      = 0;
+       struct stat     statStruct      = { 0, };
 
        if (filePath == NULL) {
                SC_log(LOG_NOTICE, "_SCNetworkConfigurationMigrateIsFilePresent: No path");
 static Boolean
 __SCNetworkConfigurationMigrateConfigurationFilesPresent(CFURLRef baseURL, CFArrayRef* migrationPaths, Boolean expected)
 {
-       Boolean configFilesPresent = FALSE;
-       CFIndex count;
-       CFURLRef filePath = NULL;
-       CFURLRef interfaces;
-       CFMutableArrayRef migrationPathsMutable = NULL;
-       CFURLRef prefs;
+       Boolean                 configFilesPresent      = FALSE;
+       CFIndex                 count;
+       CFURLRef                filePath                = NULL;
+       CFURLRef                interfaces;
+       CFMutableArrayRef       migrationPathsMutable   = NULL;
+       CFURLRef                prefs;
 
        if (baseURL == NULL) {
                SC_log(LOG_NOTICE, "No base migration URL");
 static CFMutableArrayRef
 _SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences(SCPreferencesRef ni_prefs, Boolean isBuiltin)
 {
-       CFIndex count = 0;
-       SCNetworkInterfaceRef interface;
-       CFArrayRef interfaceList = NULL;
-       CFMutableArrayRef resultInterfaceList = NULL;
+       CFIndex                 count                   = 0;
+       SCNetworkInterfaceRef   interface;
+       CFArrayRef              interfaceList           = NULL;
+       SCPreferencesRef        prefs                   = NULL;
+       CFMutableArrayRef       resultInterfaceList     = NULL;
 
        interfaceList = __SCNetworkInterfaceCopyStoredWithPreferences(ni_prefs);
        if (interfaceList == NULL) {
        count = CFArrayGetCount(interfaceList);
        if (count > 0) {
                resultInterfaceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+               prefs = SCPreferencesCreateCompanion(ni_prefs, NULL);
        }
 
        for (CFIndex i = 0; i < count; i++) {
                interface = CFArrayGetValueAtIndex(interfaceList, i);
-
                if (_SCNetworkInterfaceIsBuiltin(interface) == isBuiltin) {
-                       CFArrayAppendValue(resultInterfaceList, interface);
+                       SCNetworkInterfacePrivateRef    newInterface;
+
+                       newInterface = __SCNetworkInterfaceCreateCopy(NULL, interface, prefs, NULL);
+                       CFArrayAppendValue(resultInterfaceList, newInterface);
+                       CFRelease(newInterface);
                }
        }
 
        if (interfaceList != NULL) {
                CFRelease(interfaceList);
        }
+       if (prefs != NULL) {
+               CFRelease(prefs);
+       }
        return resultInterfaceList;
 }
 
 static CFMutableDictionaryRef
 _SCNetworkInterfaceStorageCopyMaxUnitPerInterfaceType(SCPreferencesRef ni_prefs)
 {
-       CFNumberRef cfMaxUnit;
-       CFIndex count = 0;
-       CFArrayRef ifList = NULL;
-       SCNetworkInterfaceRef interface;
-       CFMutableDictionaryRef interfaceTypeToMaxUnitMapping = NULL;
-       CFNumberRef type;
-       CFNumberRef unit;
+       CFNumberRef             cfMaxUnit;
+       CFIndex                 count                           = 0;
+       CFArrayRef              ifList                          = NULL;
+       SCNetworkInterfaceRef   interface;
+       CFMutableDictionaryRef  interfaceTypeToMaxUnitMapping   = NULL;
+       CFNumberRef             type;
+       CFNumberRef             unit;
 
        ifList = __SCNetworkInterfaceCopyStoredWithPreferences(ni_prefs);
        if (ifList == NULL) {
        }
 
        interfaceTypeToMaxUnitMapping = CFDictionaryCreateMutable(NULL, 0,
-                                                                   &kCFTypeDictionaryKeyCallBacks,
-                                                                   &kCFTypeDictionaryValueCallBacks);
+                                                                 &kCFTypeDictionaryKeyCallBacks,
+                                                                 &kCFTypeDictionaryValueCallBacks);
        count = CFArrayGetCount(ifList);
        for (CFIndex idx = 0; idx < count; idx++) {
                cfMaxUnit = NULL;
 static CFMutableDictionaryRef
 _SCNetworkConfigurationCopyBuiltinMapping (SCPreferencesRef sourcePrefs, SCPreferencesRef targetPrefs)
 {
-       CFMutableDictionaryRef builtinMapping = NULL;
-       CFIndex sourceBuiltinInterfaceCount = 0;
-       CFMutableArrayRef sourceBuiltinInterfaces = NULL;
-       SCNetworkInterfaceRef sourceInterface;
-       CFIndex targetBuiltinInterfaceCount = 0;
-       CFMutableArrayRef targetBuiltinInterfaces = NULL;
-       SCNetworkInterfaceRef targetInterface;
+       CFMutableDictionaryRef  builtinMapping                  = NULL;
+       CFIndex                 sourceBuiltinInterfaceCount     = 0;
+       CFMutableArrayRef       sourceBuiltinInterfaces         = NULL;
+       SCNetworkInterfaceRef   sourceInterface;
+       CFIndex                 targetBuiltinInterfaceCount     = 0;
+       CFMutableArrayRef       targetBuiltinInterfaces         = NULL;
+       SCNetworkInterfaceRef   targetInterface;
 
        sourceBuiltinInterfaces = _SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences(sourcePrefs, TRUE);
        if (!isA_CFArray(sourceBuiltinInterfaces)) {
        return builtinMapping;
 }
 
+static Boolean
+isExcludedExternalInterface(SCNetworkInterfaceRef interface)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+#if    !TARGET_OS_SIMULATOR
+       int                             vid;
+#endif // !TARGET_OS_SIMULATOR
+
+       if (_SCNetworkInterfaceIsHiddenInterface(interface)) {
+               return TRUE;
+       }
+
+#if    !TARGET_OS_SIMULATOR
+       if (!isA_CFNumber(interfacePrivate->usb.vid) ||
+           !CFNumberGetValue(interfacePrivate->usb.vid, kCFNumberIntType, &vid) ||
+           (vid != kIOUSBAppleVendorID)) {
+               // if not "Apple" interface
+               return FALSE;
+       }
+#endif // !TARGET_OS_SIMULATOR
+
+       if (_SC_CFEqual(interfacePrivate->name, CFSTR("iBridge"))) {
+               // exclude "Apple T2 Controller"
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
 static CFMutableDictionaryRef
-_SCNetworkConfigurationCopyExternalInterfaceMapping (SCPreferencesRef sourcePref, SCPreferencesRef targetPrefs)
+_SCNetworkConfigurationCopyExternalInterfaceMapping (SCPreferencesRef sourceNIPrefs, SCPreferencesRef targetNIPrefs)
 {
-       CFNumberRef cfMaxTargetUnit = NULL;
-       CFNumberRef currentInterfaceUnit = NULL;
-       CFMutableDictionaryRef externalMapping = NULL;
-       CFMutableDictionaryRef interfaceTypeToMaxUnitMapping = NULL;
-       int maxTargetUnit;
-       int newTargetUnit;
-       CFIndex sourceExternalInterfaceCount = 0;
-       CFMutableArrayRef sourceExternalInterfaces = NULL;
-       SCNetworkInterfaceRef sourceInterface = NULL;
-       CFIndex targetExternalInterfaceCount = 0;
-       CFMutableArrayRef targetExternalInterfaces = NULL;
-       SCNetworkInterfaceRef targetInterface = NULL;
-       CFNumberRef type;
-
-       sourceExternalInterfaces = _SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences(sourcePref, FALSE);
+       CFNumberRef             cfMaxTargetUnit                 = NULL;
+       CFNumberRef             currentInterfaceUnit            = NULL;
+       CFMutableDictionaryRef  externalMapping                 = NULL;
+       CFMutableDictionaryRef  interfaceTypeToMaxUnitMapping   = NULL;
+       int                     maxTargetUnit;
+       int                     newTargetUnit;
+       CFIndex                 sourceExternalInterfaceCount    = 0;
+       CFMutableArrayRef       sourceExternalInterfaces        = NULL;
+       SCNetworkInterfaceRef   sourceInterface                 = NULL;
+       CFIndex                 targetExternalInterfaceCount    = 0;
+       CFMutableArrayRef       targetExternalInterfaces        = NULL;
+       SCNetworkInterfaceRef   targetInterface                 = NULL;
+       SCPreferencesRef        targetPrefs                     = NULL;
+       CFNumberRef             type;
+
+       sourceExternalInterfaces = _SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences(sourceNIPrefs, FALSE);
        if (!isA_CFArray(sourceExternalInterfaces)) {
                SC_log(LOG_INFO, "No source external interfaces");
                goto done;
                goto done;
        }
 
-       targetExternalInterfaces = _SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences(targetPrefs, FALSE);
+       targetExternalInterfaces = _SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences(targetNIPrefs, FALSE);
        if (!isA_CFArray(targetExternalInterfaces)) {
                SC_log(LOG_INFO, "No target external interfaces");
                goto done;
        }
 
-       interfaceTypeToMaxUnitMapping = _SCNetworkInterfaceStorageCopyMaxUnitPerInterfaceType(targetPrefs);
+       interfaceTypeToMaxUnitMapping = _SCNetworkInterfaceStorageCopyMaxUnitPerInterfaceType(targetNIPrefs);
        externalMapping = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+       targetPrefs = SCPreferencesCreateCompanion(targetNIPrefs, NULL);
 
        // Map all external interfaces which exist in both source and target
        for (CFIndex idx = 0; idx < sourceExternalInterfaceCount; idx++) {
                        continue;
                }
 
+               // Before we create mapping for external source interfaces that do not exist
+               // in the target we need check for and handle some exclusions.
+               if (isExcludedExternalInterface(sourceInterface)) {
+                       // if excluded
+                       continue;
+               }
+
                // Create new mappings for external source interfaces which don't exist in the target
                type = _SCNetworkInterfaceGetIOInterfaceType(sourceInterface);
 
                cfMaxTargetUnit = CFNumberCreate(NULL, kCFNumberIntType, &newTargetUnit);
                CFDictionarySetValue(interfaceTypeToMaxUnitMapping, type, cfMaxTargetUnit);
 
-               targetInterface = (SCNetworkInterfaceRef)__SCNetworkInterfaceCreateCopy(NULL, sourceInterface, NULL, NULL);
-
-               SC_log(LOG_INFO, "sourceInterface: %p, target Interface: %p", sourceInterface, targetInterface);
+               targetInterface = (SCNetworkInterfaceRef)__SCNetworkInterfaceCreateCopy(NULL,
+                                                                                       sourceInterface,
+                                                                                       targetPrefs,
+                                                                                       NULL);
 
                currentInterfaceUnit = _SCNetworkInterfaceGetIOInterfaceUnit(targetInterface);
                if (!isA_CFNumber(currentInterfaceUnit) ||
        if (interfaceTypeToMaxUnitMapping != NULL) {
                CFRelease(interfaceTypeToMaxUnitMapping);
        }
+       if (targetPrefs != NULL) {
+               CFRelease(targetPrefs);
+       }
        return externalMapping;
 }
 static Boolean
 _SCNetworkConfigurationIsInterfaceNamerMappable(SCNetworkInterfaceRef interface1, SCNetworkInterfaceRef interface2, Boolean bypassActive)
 {
 #pragma unused(bypassActive)
-       Boolean interface1IsBuiltin;
-       CFStringRef interface1Prefix;
-       CFStringRef interface1Type;
-       CFStringRef interface1UserDefinedName;
-       Boolean interface2IsBuiltin;
-       CFStringRef interface2Prefix;
-       CFStringRef interface2Type;
-       CFStringRef interface2UserDefinedName;
+       Boolean         interface1IsBuiltin;
+       CFStringRef     interface1Prefix;
+       CFStringRef     interface1Type;
+       CFStringRef     interface1UserDefinedName;
+       Boolean         interface2IsBuiltin;
+       CFStringRef     interface2Prefix;
+       CFStringRef     interface2Type;
+       CFStringRef     interface2UserDefinedName;
 
        if (interface1 == interface2) {
                // No work needs to be done
 static Boolean
 __SCNetworkConfigurationInterfaceNameIsEquiv(CFStringRef interfaceName1, CFStringRef interfaceName2)
 {
-       CFStringRef interfaceArray[] = { CFSTR("iPhone"), CFSTR("iPad"), CFSTR("iPod"), CFSTR("AppleTV") };
-       const int interfaceCount = sizeof(interfaceArray) / sizeof(CFStringRef);
-       CFStringRef portSuffix = CFSTR(", Port 1");
+       CFStringRef     interfaceArray[]        = { CFSTR("iPhone"), CFSTR("iPad"), CFSTR("iPod"), CFSTR("AppleTV") };
+       const int       interfaceCount          = sizeof(interfaceArray) / sizeof(CFStringRef);
+       CFStringRef     portSuffix              = CFSTR(", Port 1");
 
-       if ((isA_CFString(interfaceName1) != NULL) &&
-           (isA_CFString(interfaceName2) != NULL)) {
+       if ((isA_CFString(interfaceName1)) && (isA_CFString(interfaceName2))) {
                if (!CFEqual(interfaceName1, interfaceName2)) {
                        // Check if we are looking at the WiFi interface
                        if ((CFEqual(interfaceName1, CFSTR("AirPort")) ||
 }
 
 typedef struct {
-       CFDictionaryRef interfaceMapping;
-       CFMutableArrayRef interfacesMissingServices;
-} SCNetworkConfigurationMissingServiceContext;
+       CFDictionaryRef         interfaceMapping;
+       CFMutableArrayRef       interfacesMissingServices;
+} missingServiceContext;
 
 typedef struct {
-       CFDictionaryRef bsdNameToBridgeServices;        // Mapping of BSD Name to SCBridgeInterfaceRef
-       CFDictionaryRef bsdNameToBondServices;          // Mapping of BSD Name to SCBondInterfaceRef
-       CFDictionaryRef bsdNameToVLANServices;          // Mapping of BSD Name to SCVLANInterfaceRef
-       CFDictionaryRef interfaceMapping;
-       Boolean* isValid;
-       CFMutableArrayRef interfaceToBeRemoved; // SCNetworkInterfaceRef. Services containing the interface will be removed
-       CFMutableArrayRef interfaceToBeReplaced;// SCNetworkInterfaceRef. Services containing the interface will be replaced with default service
-       CFMutableArrayRef interfacePreserveServiceInformation; // SCNetworkInterfaceRef. Services containing the interface will be replaced with new service which has same configuration as the current service with issue.
-       CFMutableDictionaryRef bsdNameServiceProtocolPreserveMapping;
-       SCPreferencesRef prefs;
-       Boolean repair;
-} SCNetworkConfigurationValidityContext;
+       CFDictionaryRef         bsdNameToBridgeServices;        // Mapping of BSD Name to SCBridgeInterfaceRef
+       CFDictionaryRef         bsdNameToBondServices;          // Mapping of BSD Name to SCBondInterfaceRef
+       CFDictionaryRef         bsdNameToVLANServices;          // Mapping of BSD Name to SCVLANInterfaceRef
+       CFDictionaryRef         interfaceMapping;
+       Boolean*                isValid;
+       CFMutableArrayRef       interfaceToBeRemoved;           // SCNetworkInterfaceRef. Services containing the interface will be removed
+       CFMutableArrayRef       interfaceToBeReplaced;          // SCNetworkInterfaceRef. Services containing the interface will be replaced with default service
+       CFMutableArrayRef       interfacePreserveServiceInformation; // SCNetworkInterfaceRef. Services containing the interface will be replaced with new service which has same configuration as the current service with issue.
+       CFMutableDictionaryRef  bsdNameServiceProtocolPreserveMapping;
+       SCPreferencesRef        prefs;
+       Boolean                 repair;
+} validityContext;
 
 static void
 _SCNetworkConfigurationValidateInterface (const void *key, const void *value, void *context)
 {
-       CFStringRef bsdName = (CFStringRef)key;
-       SCNetworkConfigurationValidityContext *ctx = (SCNetworkConfigurationValidityContext*)context;
-       CFDictionaryRef bsdNameToBridgeServices = ctx->bsdNameToBridgeServices;
-       CFDictionaryRef bsdNameToBondServices = ctx->bsdNameToBondServices;
-       CFDictionaryRef bsdNameToVLANServices = ctx->bsdNameToVLANServices;
-       SCNetworkInterfaceRef interface = NULL;
-       CFDictionaryRef interfaceMapping = ctx->interfaceMapping;
-       CFStringRef interfaceUserDefinedName = NULL;
-       Boolean repair = ctx->repair;
-       SCNetworkInterfaceRef serviceInterface = (SCNetworkInterfaceRef)value;
-       CFStringRef serviceInterfaceUserDefinedName = NULL;
-       CFMutableArrayRef interfaceToBeRemoved = ctx->interfaceToBeRemoved;
-       CFMutableArrayRef interfaceToBeReplaced = ctx->interfaceToBeReplaced;
-       CFMutableArrayRef interfacePreserveServiceInformation = ctx->interfacePreserveServiceInformation;
+       CFStringRef             bsdName                                 = (CFStringRef)key;
+       validityContext         *ctx                                    = (validityContext*)context;
+       CFDictionaryRef         bsdNameToBridgeServices                 = ctx->bsdNameToBridgeServices;
+       CFDictionaryRef         bsdNameToBondServices                   = ctx->bsdNameToBondServices;
+       CFDictionaryRef         bsdNameToVLANServices                   = ctx->bsdNameToVLANServices;
+       SCNetworkInterfaceRef   interface                               = NULL;
+       CFDictionaryRef         interfaceMapping                        = ctx->interfaceMapping;
+       CFStringRef             interfaceUserDefinedName                = NULL;
+       Boolean                 repair                                  = ctx->repair;
+       SCNetworkInterfaceRef   serviceInterface                        = (SCNetworkInterfaceRef)value;
+       CFStringRef             serviceInterfaceUserDefinedName         = NULL;
+       CFMutableArrayRef       interfaceToBeRemoved                    = ctx->interfaceToBeRemoved;
+       CFMutableArrayRef       interfaceToBeReplaced                   = ctx->interfaceToBeReplaced;
+       CFMutableArrayRef       interfacePreserveServiceInformation     = ctx->interfacePreserveServiceInformation;
 
        // No work needs to be done if we have already made determination that configuration somewhere is not valid,
        // or we don't intend to repair invalid configuration.
        // There is no interface present for the service
        interface = CFDictionaryGetValue(interfaceMapping, bsdName);
        if (interface == NULL) {
-               if ((((bsdNameToBridgeServices != NULL) && !CFDictionaryContainsKey(bsdNameToBridgeServices, bsdName))) &&
-                   (((bsdNameToBondServices != NULL) && !CFDictionaryContainsKey(bsdNameToBondServices, bsdName))) &&
-                   (((bsdNameToVLANServices != NULL) && !CFDictionaryContainsKey(bsdNameToVLANServices, bsdName)))) {
+               if (_SCNetworkInterfaceIsBluetoothPAN(serviceInterface)) {
+                       // interface not expected, BT-PAN
+                       return;
+               }
+
+               if (((bsdNameToBridgeServices != NULL) && !CFDictionaryContainsKey(bsdNameToBridgeServices, bsdName)) &&
+                   ((bsdNameToBondServices   != NULL) && !CFDictionaryContainsKey(bsdNameToBondServices  , bsdName)) &&
+                   ((bsdNameToVLANServices   != NULL) && !CFDictionaryContainsKey(bsdNameToVLANServices  , bsdName))) {
                        // Not a virtual interface
                        SC_log(LOG_NOTICE,
-                              "No real interface with BSD name (%@) for service",
+                              "No interface with BSD name (%@) present for service",
                               bsdName);
 
                        if (repair) {
 static void
 _SCNetworkConfigurationCollectMissingService(const void *key, const void *value, void *context)
 {
-       CFStringRef bsdName = (CFStringRef)key;
-       SCNetworkConfigurationMissingServiceContext *ctx = (SCNetworkConfigurationMissingServiceContext*)context;
-       SCNetworkInterfaceRef interface = (SCNetworkInterfaceRef)value;
-       CFMutableArrayRef interfacesMissingServices = ctx->interfacesMissingServices;
-       CFDictionaryRef serviceInterfaceMapping = ctx->interfaceMapping;
+       CFStringRef             bsdName                         = (CFStringRef)key;
+       missingServiceContext   *ctx                            = (missingServiceContext*)context;
+       SCNetworkInterfaceRef   interface                       = (SCNetworkInterfaceRef)value;
+       CFMutableArrayRef       interfacesMissingServices       = ctx->interfacesMissingServices;
+       CFDictionaryRef         serviceInterfaceMapping         = ctx->interfaceMapping;
 
        if (!isA_SCNetworkInterface(interface) ||
            !_SCNetworkInterfaceIsBuiltin(interface)) {
 _SCNetworkConfigurationCreateBuiltinInterfaceServices(SCPreferencesRef pref,
                                                      SCPreferencesRef ni_pref)
 {
-       SCNetworkConfigurationMissingServiceContext context;
-       SCNetworkInterfaceRef interface = NULL;
-       CFArrayRef interfaces = NULL;
-       CFMutableArrayRef interfacesWithoutService = NULL;
-       CFDictionaryRef mappingBSDNameToInterface = NULL;
-       CFDictionaryRef mappingServiceBSDNameToInterface = NULL;
-       CFIndex missingServiceCount = 0;
-       Boolean success = FALSE;
+       missingServiceContext   context;
+       SCNetworkInterfaceRef   interface                               = NULL;
+       CFArrayRef              interfaces                              = NULL;
+       CFMutableArrayRef       interfacesWithoutService                = NULL;
+       CFDictionaryRef         mappingBSDNameToInterface               = NULL;
+       CFDictionaryRef         mappingServiceBSDNameToInterface        = NULL;
+       CFIndex                 missingServiceCount                     = 0;
+       Boolean                 success                                 = FALSE;
 
        interfaces = __SCNetworkInterfaceCopyStoredWithPreferences(ni_pref);
        if (interfaces == NULL) {
        for (CFIndex idx = 0; idx < missingServiceCount; idx++) {
                interface = CFArrayGetValueAtIndex(interfacesWithoutService, idx);
 
+               if (__SCNetworkInterfaceIsMember(pref, interface)) {
+                       // if the interface is a member of a bond or bridge
+                       continue;
+               }
+
                if (!__SCNetworkServiceCreate(pref, interface, NULL)) {
                        SC_log(LOG_NOTICE, "Could not create service for interface: %@", interface);
                        success = FALSE;
 static void
 add_service(const void *value, void *context)
 {
-       SCNetworkConfigurationValidityContext *ctx = (SCNetworkConfigurationValidityContext *)context;
-       SCNetworkSetRef currentSet = NULL;
-       Boolean enabled;
-       SCNetworkInterfaceRef interface = (SCNetworkInterfaceRef)value;
-       CFDictionaryRef bsdNameServiceProtocolMapping = ctx->bsdNameServiceProtocolPreserveMapping;
-       SCPreferencesRef prefs = ctx->prefs;
-       SCNetworkServiceRef service;
-       CFStringRef bsdName = SCNetworkInterfaceGetBSDName(interface);
-       CFArrayRef protocolArray = NULL;
+       validityContext         *ctx                            = (validityContext *)context;
+       SCNetworkSetRef         currentSet                      = NULL;
+       Boolean                 enabled;
+       SCNetworkInterfaceRef   interface                       = (SCNetworkInterfaceRef)value;
+       CFDictionaryRef         bsdNameServiceProtocolMapping   = ctx->bsdNameServiceProtocolPreserveMapping;
+       SCPreferencesRef        prefs                           = ctx->prefs;
+       SCNetworkServiceRef     service;
+       CFStringRef             bsdName                         = SCNetworkInterfaceGetBSDName(interface);
+       CFArrayRef              protocolArray                   = NULL;
 
        if (isA_CFString(bsdName)) {
                protocolArray = CFDictionaryGetValue(bsdNameServiceProtocolMapping, bsdName);
 static void
 create_bsd_name_service_protocol_mapping(const void *value, void *context)
 {
-       SCNetworkConfigurationValidityContext *ctx = (SCNetworkConfigurationValidityContext *)context;
-       CFArrayRef interfacePreserveServiceInformation = ctx->interfacePreserveServiceInformation;
-       CFMutableDictionaryRef bsdNameServiceProtocolMapping = ctx->bsdNameServiceProtocolPreserveMapping;
-       SCNetworkInterfaceRef interface;
-       SCNetworkServiceRef service = (SCNetworkServiceRef)value;
+       validityContext         *ctx                                    = (validityContext *)context;
+       CFArrayRef              interfacePreserveServiceInformation     = ctx->interfacePreserveServiceInformation;
+       CFMutableDictionaryRef  bsdNameServiceProtocolMapping           = ctx->bsdNameServiceProtocolPreserveMapping;
+       SCNetworkInterfaceRef   interface;
+       SCNetworkServiceRef     service                                 = (SCNetworkServiceRef)value;
 
        interface = SCNetworkServiceGetInterface(service);
 
 static void
 remove_service(const void *value, void *context)
 {
-       SCNetworkConfigurationValidityContext *ctx = (SCNetworkConfigurationValidityContext *)context;
-       SCNetworkInterfaceRef interface;
-       SCNetworkServiceRef service = (SCNetworkServiceRef)value;
-       CFArrayRef toBeRemoved = ctx->interfaceToBeRemoved;
+       validityContext         *ctx            = (validityContext *)context;
+       SCNetworkInterfaceRef   interface;
+       SCNetworkServiceRef     service         = (SCNetworkServiceRef)value;
+       CFArrayRef              toBeRemoved     = ctx->interfaceToBeRemoved;
 
        interface = SCNetworkServiceGetInterface(service);
 
 }
 
 static Boolean
-_SCNetworkConfigurationRepairUsingPreferences(SCPreferencesRef prefs,
-                                             SCNetworkConfigurationValidityContext *context)
+_SCNetworkConfigurationRepairUsingPreferences(SCPreferencesRef prefs,
+                                             SCPreferencesRef  ni_prefs,
+                                             validityContext   *context)
 {
-       CFIndex removeCount;
-       CFIndex replaceCount;
-       CFArrayRef serviceList;
-       CFArrayRef interfaceToBeRemoved = context->interfaceToBeRemoved;
-       CFArrayRef interfaceToBeReplaced = context->interfaceToBeReplaced;
+       CFIndex         removeCount;
+       CFIndex         replaceCount;
+       CFArrayRef      serviceList;
+       CFArrayRef      interfaceToBeRemoved    = context->interfaceToBeRemoved;
+       CFArrayRef      interfaceToBeReplaced   = context->interfaceToBeReplaced;
 
        removeCount = CFArrayGetCount(interfaceToBeRemoved);
        replaceCount = CFArrayGetCount(interfaceToBeReplaced);
        }
        // Backup current preferences before making changes
        __SCNetworkConfigurationBackup(prefs, CFSTR("pre-repair"), prefs);
+       __SCNetworkConfigurationBackup(ni_prefs, CFSTR("pre-repair"), prefs);
 
        serviceList = SCNetworkServiceCopyAll(prefs);
        CFArrayApplyFunction(serviceList, CFRangeMake(0, CFArrayGetCount(serviceList)), create_bsd_name_service_protocol_mapping, context);
 static void
 validate_bridge(const void *value, void *context)
 {
-       SCBridgeInterfaceRef bridge = (SCBridgeInterfaceRef) value;
-       CFArrayRef memberInterfaces = SCBridgeInterfaceGetMemberInterfaces(bridge);
-       CFMutableArrayRef memberInterfacesMutable = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-       SCPreferencesRef ni_prefs = (SCPreferencesRef)context;
+       SCBridgeInterfaceRef    bridge                  = (SCBridgeInterfaceRef)value;
+       CFArrayRef              memberInterfaces        = SCBridgeInterfaceGetMemberInterfaces(bridge);
+       CFMutableArrayRef       memberInterfacesMutable = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       SCPreferencesRef        ni_prefs                = (SCPreferencesRef)context;
 
        for (CFIndex idx = 0; idx < CFArrayGetCount(memberInterfaces); idx++) {
-               CFStringRef bsdName;
-               SCNetworkInterfaceRef interface = (SCNetworkInterfaceRef)CFArrayGetValueAtIndex(memberInterfaces, idx);
-               SCNetworkInterfaceRef memberInterface;
+               CFStringRef             bsdName;
+               SCNetworkInterfaceRef   interface       = (SCNetworkInterfaceRef)CFArrayGetValueAtIndex(memberInterfaces, idx);
+               SCNetworkInterfaceRef   memberInterface;
 
                bsdName = SCNetworkInterfaceGetBSDName(interface);
                if (bsdName == NULL) {
        }
        CFRelease(memberInterfacesMutable);
 }
+
 #if    !TARGET_OS_IPHONE
 static void
 validate_bond(const void *value, void *context)
 {
-       SCBondInterfaceRef bond = (SCBondInterfaceRef)value;
-       CFArrayRef memberInterfaces = SCBondInterfaceGetMemberInterfaces(bond);
-       CFMutableArrayRef memberInterfacesMutable = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-       SCPreferencesRef ni_prefs = (SCPreferencesRef)context;
+       SCBondInterfaceRef      bond                    = (SCBondInterfaceRef)value;
+       CFArrayRef              memberInterfaces        = SCBondInterfaceGetMemberInterfaces(bond);
+       CFMutableArrayRef       memberInterfacesMutable = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       SCPreferencesRef        ni_prefs                = (SCPreferencesRef)context;
 
        for (CFIndex idx = 0; idx < CFArrayGetCount(memberInterfaces); idx++) {
-               CFStringRef bsdName;
-               SCNetworkInterfaceRef interface = (SCNetworkInterfaceRef)CFArrayGetValueAtIndex(memberInterfaces, idx);
-               SCNetworkInterfaceRef memberInterface;
+               CFStringRef             bsdName;
+               SCNetworkInterfaceRef   interface       = (SCNetworkInterfaceRef)CFArrayGetValueAtIndex(memberInterfaces, idx);
+               SCNetworkInterfaceRef   memberInterface;
 
                bsdName = SCNetworkInterfaceGetBSDName(interface);
                if (bsdName == NULL) {
 }
 #endif // !TARGET_OS_IPHONE
 
+typedef struct {
+       SCPreferencesRef        prefs;
+       SCPreferencesRef        ni_prefs;
+#if    !TARGET_OS_IPHONE
+       CFArrayRef              bondInterfaces;
+#endif // !TARGET_OS_IPHONE
+       CFArrayRef              bridgeInterfaces;
+} validate_prefs_context;
+
+static validate_prefs_context *
+validate_prefs_context_create(SCPreferencesRef prefs, SCPreferencesRef ni_prefs)
+{
+       validate_prefs_context  *context;
+
+       context = calloc(1, sizeof(validate_prefs_context));
+       context->prefs = prefs;
+       context->ni_prefs = ni_prefs;
+#if    !TARGET_OS_IPHONE
+       context->bondInterfaces = (CFArrayRef)kCFNull;
+#endif // !TARGET_OS_IPHONE
+       context->bridgeInterfaces = (CFArrayRef)kCFNull;
+       return context;
+}
+
+static void
+validate_prefs_context_release(validate_prefs_context *context)
+{
+#if    !TARGET_OS_IPHONE
+       if ((context->bondInterfaces != NULL) && (context->bondInterfaces != (CFArrayRef)kCFNull)) {
+               CFRelease(context->bondInterfaces);
+       }
+#endif // !TARGET_OS_IPHONE
+       if ((context->bridgeInterfaces != NULL) && (context->bridgeInterfaces != (CFArrayRef)kCFNull)) {
+               CFRelease(context->bridgeInterfaces);
+       }
+       free(context);
+}
+
+static Boolean
+interfaceArrayContainsBSDName(CFArrayRef interfaces, CFStringRef bsdName)
+{
+       Boolean match   = FALSE;
+       CFIndex n       = CFArrayGetCount(interfaces);
+
+       for (CFIndex i = 0; i < n; i++) {
+               SCNetworkInterfaceRef   interface;
+               CFStringRef             matchName;
+
+               interface = CFArrayGetValueAtIndex(interfaces, i);
+               matchName = SCNetworkInterfaceGetBSDName(interface);
+               if (_SC_CFEqual(bsdName, matchName)) {
+                       match = TRUE;
+                       break;
+               }
+       }
+
+       return match;
+}
+
 static void
 validate_vlan(const void *value, void *context)
 {
-       CFStringRef bsdName;
-       SCNetworkInterfaceRef interface;
-       Boolean isValid = TRUE;
-       SCPreferencesRef ni_prefs = (SCPreferencesRef)context;
-       SCNetworkInterfaceRef physicalInterface;
-       SCVLANInterfaceRef vlan = (SCVLANInterfaceRef)value;
+       CFStringRef             bsdName;
+       SCNetworkInterfaceRef   interface;
+       Boolean                 isValid                 = FALSE;
+       SCNetworkInterfaceRef   physicalInterface;
+       validate_prefs_context  *prefs                  = (validate_prefs_context *)context;
+       SCVLANInterfaceRef      vlan                    = (SCVLANInterfaceRef)value;
 
        physicalInterface = SCVLANInterfaceGetPhysicalInterface(vlan);
        bsdName = SCNetworkInterfaceGetBSDName(physicalInterface);
-
        if (bsdName == NULL) {
-               isValid = FALSE;
                goto done;
        }
 
        // Check if the physical interface is present
-       interface = __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(NULL, ni_prefs, bsdName);
-       if (interface == NULL) {
-               isValid = FALSE;
+       interface = __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(NULL, prefs->ni_prefs, bsdName);
+       if (interface != NULL) {
+               CFRelease(interface);
+               isValid = TRUE;
                goto done;
        }
-       CFRelease(interface);
 
-done:
+#if    !TARGET_OS_IPHONE
+       if (prefs->bondInterfaces == (CFArrayRef)kCFNull) {
+               prefs->bondInterfaces = SCBondInterfaceCopyAll(prefs->prefs);
+       }
+       if (prefs->bondInterfaces != NULL) {
+               isValid = interfaceArrayContainsBSDName(prefs->bondInterfaces, bsdName);
+               if (isValid) {
+                       goto done;
+               }
+       }
+#endif // !TARGET_OS_IPHONE
+
+       if (prefs->bridgeInterfaces == (CFArrayRef)kCFNull) {
+               prefs->bridgeInterfaces = SCBridgeInterfaceCopyAll(prefs->prefs);
+       }
+       if (prefs->bridgeInterfaces != NULL) {
+               isValid = interfaceArrayContainsBSDName(prefs->bridgeInterfaces, bsdName);
+               if (isValid) {
+                       goto done;
+               }
+       }
+
+    done:
        if (!isValid) {
                SC_log(LOG_NOTICE, "Removing VLAN w/no physical interface: %@", vlan);
                SCVLANInterfaceRemove(vlan);
 }
 
 Boolean
-_SCNetworkConfigurationCheckValidityWithPreferences(SCPreferencesRef prefs,
-                                                    SCPreferencesRef ni_prefs,
-                                                    CFDictionaryRef options)
+_SCNetworkConfigurationCheckValidityWithPreferences(SCPreferencesRef   prefs,
+                                                    SCPreferencesRef   ni_prefs,
+                                                    CFDictionaryRef    options)
 {
-       CFArrayRef allServices = NULL;
-       CFArrayRef allSets = NULL;
-       CFDictionaryRef bsdNameToBridgeServices = NULL;
-       CFDictionaryRef bsdNameToBondServices = NULL;
-       CFDictionaryRef bsdNameToVLANServices = NULL;
-       SCNetworkConfigurationValidityContext context;
-       CFArrayRef interfaces = NULL;
-       CFMutableArrayRef interfaceToBeRemoved = NULL;
-       CFMutableArrayRef interfaceToBeReplaced = NULL;
-       CFMutableArrayRef interfacePreserveServiceInformation = NULL;
-       CFMutableDictionaryRef bsdNameServiceProtocolPreserveMapping = NULL;
-       Boolean isValid = TRUE;
-       CFDictionaryRef mappingBSDNameToInterface = NULL;
-       CFDictionaryRef mappingServiceBSDNameToInterface = NULL;
-       CFStringRef  model = NULL;
-       CFStringRef ni_model = NULL;
-       Boolean repairConfiguration = FALSE;
-       Boolean revertBypassSystemInterfaces = FALSE;
-       CFArrayRef setServiceOrder = NULL;
-       CFArrayRef setServices = NULL;
+       CFArrayRef              allServices                             = NULL;
+       CFArrayRef              allSets                                 = NULL;
+       CFDictionaryRef         bsdNameToBridgeServices                 = NULL;
+       CFDictionaryRef         bsdNameToBondServices                   = NULL;
+       CFDictionaryRef         bsdNameToVLANServices                   = NULL;
+       validityContext         context;
+       CFArrayRef              interfaces                              = NULL;
+       CFMutableArrayRef       interfaceToBeRemoved                    = NULL;
+       CFMutableArrayRef       interfaceToBeReplaced                   = NULL;
+       CFMutableArrayRef       interfacePreserveServiceInformation     = NULL;
+       CFMutableDictionaryRef  bsdNameServiceProtocolPreserveMapping   = NULL;
+       Boolean                 isValid                                 = TRUE;
+       CFDictionaryRef         mappingBSDNameToInterface               = NULL;
+       CFDictionaryRef         mappingServiceBSDNameToInterface        = NULL;
+       CFStringRef             model                                   = NULL;
+       CFStringRef             ni_model                                = NULL;
+       Boolean                 repairConfiguration                     = FALSE;
+       Boolean                 revertBypassSystemInterfaces            = FALSE;
+       CFArrayRef              setServiceOrder                         = NULL;
+       CFArrayRef              setServices                             = NULL;
 
        if  ((isA_CFDictionary(options) != NULL)) {
                CFBooleanRef repair = CFDictionaryGetValue(options, kSCNetworkConfigurationRepair);
                       prefs,
                       ni_prefs);
                if (repairConfiguration) {
-                       isValid = _SCNetworkConfigurationRepairUsingPreferences(prefs, &context);
+                       isValid = _SCNetworkConfigurationRepairUsingPreferences(prefs, ni_prefs, &context);
                        if (!isValid) {
                                goto done;
                        }
 #endif // !TARGET_OS_IPHONE
        CFArrayRef vlans = SCVLANInterfaceCopyAll(prefs);
        if (vlans != NULL) {
-               CFArrayApplyFunction(vlans, CFRangeMake(0, CFArrayGetCount(vlans)), validate_vlan, (void*)ni_prefs);
+               validate_prefs_context  *validate_prefs;
+
+               validate_prefs = validate_prefs_context_create(prefs, ni_prefs);
+               CFArrayApplyFunction(vlans, CFRangeMake(0, CFArrayGetCount(vlans)), validate_vlan, (void*)validate_prefs);
+               validate_prefs_context_release(validate_prefs);
                CFRelease(vlans);
        }
 
 Boolean
 _SCNetworkConfigurationCheckValidity(CFURLRef configDir, CFDictionaryRef options)
 {
-       CFURLRef baseURL = NULL;
-       CFURLRef configNetworkInterfaceFile = NULL;
-       CFStringRef configNetworkInterfaceFileString = NULL;
-       SCPreferencesRef configNetworkInterfacePref = NULL;
-       SCPreferencesRef configPref = NULL;
-       CFURLRef configPreferenceFile = NULL;
-       CFStringRef configPreferencesFileString = NULL;
-       Boolean isValid = FALSE;
-       char networkInterfaceStr[PATH_MAX];
-       char prefsStr[PATH_MAX];
+       CFURLRef                baseURL                                 = NULL;
+       CFURLRef                configNetworkInterfaceFile              = NULL;
+       CFStringRef             configNetworkInterfaceFileString        = NULL;
+       SCPreferencesRef        configNetworkInterfacePref              = NULL;
+       SCPreferencesRef        configPref                              = NULL;
+       CFURLRef                configPreferenceFile                    = NULL;
+       CFStringRef             configPreferencesFileString             = NULL;
+       Boolean                 isValid                                 = FALSE;
+       char                    networkInterfaceStr[PATH_MAX];
+       char                    prefsStr[PATH_MAX];
 
        if (configDir == NULL) {
                SC_log(LOG_NOTICE, "Migration files not found in directory: %@",
        CFMutableArrayRef externalInterfaceList;
        CFMutableArrayRef networkInterfaceList;
        Boolean foundNewInterfaces;
-} SCExternalMappingContext;
+} externalMappingContext;
 
 static void
 _SCNetworkConfigurationCollectInterfaceStorageEntity(const void *key, const void *value, void *context)
 {
 #pragma unused(key)
-       SCExternalMappingContext* ctx = context;
-       CFDictionaryRef interface_entity = NULL;
-       SCNetworkInterfaceRef targetInterface = (SCNetworkInterfaceRef)value;
+       externalMappingContext  *ctx                    = context;
+       CFDictionaryRef         interface_entity        = NULL;
+       SCNetworkInterfaceRef   targetInterface         = (SCNetworkInterfaceRef)value;
 
        if (CFArrayContainsValue(ctx->externalInterfaceList, CFRangeMake(0, CFArrayGetCount(ctx->externalInterfaceList)), targetInterface)) {
                SC_log(LOG_NOTICE, "Target interface (%@) already exists, not adding to NetworkInterfaces.plist", targetInterface);
 static CFArrayRef   // CFDictionaryRef
 _SCNetworkMigrationCreateNetworkInterfaceArray(SCPreferencesRef ni_prefs, CFDictionaryRef externalMapping, Boolean *hasNewInterface)
 {
-       SCExternalMappingContext context;
-       CFIndex count = 0;
-       CFMutableArrayRef externalInterfaceList = NULL;
-       CFArrayRef if_list = NULL;
-       CFDictionaryRef interface_entity = NULL;
-       CFMutableArrayRef networkInterfaceList = NULL;
+       externalMappingContext  context;
+       CFIndex                 count                   = 0;
+       CFMutableArrayRef       externalInterfaceList   = NULL;
+       CFArrayRef              if_list                 = NULL;
+       CFDictionaryRef         interface_entity        = NULL;
+       CFMutableArrayRef       networkInterfaceList    = NULL;
 
        if (ni_prefs == NULL) {
                SC_log(LOG_NOTICE, "No NetworkInterfaces.plist");
 static void
 SCNetworkMigrationMapSourceToTargetName(const void *key, const void *value, void *context)
 {
-       SCNetworkInterfaceRef interfaceKey = (SCNetworkInterfaceRef)key;
-       SCNetworkInterfaceRef interfaceValue = (SCNetworkInterfaceRef)value;
-       CFMutableDictionaryRef mapping = (CFMutableDictionaryRef)context;
-       CFStringRef sourceBSDName = NULL;
-       CFStringRef targetBSDName = NULL;
+       SCNetworkInterfaceRef   interfaceKey    = (SCNetworkInterfaceRef)key;
+       SCNetworkInterfaceRef   interfaceValue  = (SCNetworkInterfaceRef)value;
+       CFMutableDictionaryRef  mapping         = (CFMutableDictionaryRef)context;
+       CFStringRef             sourceBSDName   = NULL;
+       CFStringRef             targetBSDName   = NULL;
 
        sourceBSDName = SCNetworkInterfaceGetBSDName(interfaceKey);
        if (!isA_CFString(sourceBSDName)) {
        return bsdNameMapping;
 }
 
-typedef struct {
-       CFMutableArrayRef mutableServiceArray;
-       SCPreferencesRef prefs;
-} SCNetworkServiceArrayCopyContext;
-
 static CFDictionaryRef
 _SCNetworkMigrationCreateServiceSetMapping(SCPreferencesRef prefs)
 {
-       CFMutableDictionaryRef serviceSetMapping = CFDictionaryCreateMutable(NULL, 0,
-                                                                            &kCFTypeDictionaryKeyCallBacks,
-                                                                            &kCFTypeDictionaryValueCallBacks);
-       SCNetworkServiceRef service = NULL;
-       CFArrayRef services = NULL;
-       CFMutableArrayRef setList = NULL;
-       CFArrayRef sets = NULL;
-
+       SCNetworkServiceRef     service;
+       CFMutableDictionaryRef  serviceSetMapping;
+       CFArrayRef              services        = NULL;
+       CFMutableArrayRef       setList         = NULL;
+       CFArrayRef              sets            = NULL;
+
+       serviceSetMapping = CFDictionaryCreateMutable(NULL, 0,
+                                                     &kCFTypeDictionaryKeyCallBacks,
+                                                     &kCFTypeDictionaryValueCallBacks);
        services = SCNetworkServiceCopyAll(prefs);
        if (services == NULL) {
                goto done;
        }
        for (CFIndex idx = 0; idx < CFArrayGetCount(services); idx++) {
                service = CFArrayGetValueAtIndex(services, idx);
-
                if (!CFDictionaryContainsKey(serviceSetMapping, service)) {
                        setList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
                        CFDictionaryAddValue(serviceSetMapping, service, setList);
        }
 
        for (CFIndex idx = 0; idx < CFArrayGetCount(sets); idx++) {
-               SCNetworkSetRef set = CFArrayGetValueAtIndex(sets, idx);
-               services = SCNetworkSetCopyServices(set);
+               SCNetworkSetRef set;
 
+               set = CFArrayGetValueAtIndex(sets, idx);
+               services = SCNetworkSetCopyServices(set);
                for (CFIndex idx2 = 0; idx2 < CFArrayGetCount(services); idx2++) {
                        service = CFArrayGetValueAtIndex(services, idx2);
                        setList = (CFMutableArrayRef)CFDictionaryGetValue(serviceSetMapping, service);
 _SCNetworkMigrationCreateSetMapping(SCPreferencesRef sourcePrefs,
                                    SCPreferencesRef targetPrefs)
 {
-       SCNetworkSetRef currentSourceSet = NULL;
-       CFMutableDictionaryRef setMapping = NULL;
-       CFStringRef setName;
-       CFArrayRef sourceSets = NULL;
-       CFIndex targetCount;
-       SCNetworkSetRef targetSet;
-       CFArrayRef targetSets = NULL;
-       CFMutableArrayRef targetSetsMutable = NULL;
+       SCNetworkSetRef         currentSourceSet        = NULL;
+       CFMutableDictionaryRef  setMapping              = NULL;
+       CFStringRef             setName;
+       CFArrayRef              sourceSets              = NULL;
+       CFIndex                 targetCount;
+       SCNetworkSetRef         targetSet;
+       CFArrayRef              targetSets              = NULL;
+       CFMutableArrayRef       targetSetsMutable       = NULL;
 
        sourceSets = SCNetworkSetCopyAll(sourcePrefs);
        targetSets = SCNetworkSetCopyAll(targetPrefs);
 // This function finds the mapping between source and target preferences (SCNetworkServicesRef -> SCNetworkServicesRef)
 // If there is no mapping found between source and target preferences, then the CFBooleanRef value indicating no value is found is stored (SCNetworkServicesRef -> kCFBooleanFalse)
 static CFDictionaryRef
-_SCNetworkMigrationCreateServiceMappingUsingBSDMapping(SCPreferencesRef sourcePrefs,
-                                                      SCPreferencesRef targetPrefs,
-                                                      CFDictionaryRef bsdNameMapping)
+_SCNetworkMigrationCreateServiceMappingUsingBSDNameMapping(SCPreferencesRef    sourcePrefs,
+                                                          SCPreferencesRef     targetPrefs,
+                                                          CFDictionaryRef      bsdNameMapping)
 {
-       CFStringRef bsdNameMapTarget = NULL;
-       CFMutableDictionaryRef serviceMapping = NULL;                               // Mapping of services between source and target configurations
-       CFStringRef sourceBSDName = NULL;
-       CFIndex sourceCount = 0;
-       SCNetworkInterfaceRef sourceInterface = NULL;
-       CFStringRef sourceInterfaceSubType = NULL;              // Check interface type and subtype to be able to transfer VPN
-       CFStringRef sourceInterfaceType = NULL;
-       CFArrayRef sourceSCNetworkServices = NULL;
-       CFMutableArrayRef sourceSCNetworkServicesMutable = NULL;                    // Source SCNetworkServiceRef mutable array
-       SCNetworkServiceRef sourceService = NULL;
-       CFStringRef targetBSDName = NULL;
-       CFIndex targetCount = 0;                                   // Count of Source and Target Services
-       SCNetworkInterfaceRef targetInterface = NULL;
-       CFStringRef targetInterfaceSubType = NULL;              // services during migration
-       CFStringRef targetInterfaceType = NULL;
-       CFArrayRef targetSCNetworkServices = NULL;
-       CFMutableArrayRef targetSCNetworkServicesMutable = NULL;                    // Target SCNetworkServiceRef mutable array
-       SCNetworkServiceRef targetService = NULL;
+       CFMutableDictionaryRef  serviceMapping                  = NULL; // Mapping of services between source and target configurations
+       CFStringRef             sourceBSDName                   = NULL;
+       CFIndex                 sourceCount                     = 0;
+       SCNetworkInterfaceRef   sourceInterface                 = NULL;
+       CFStringRef             sourceInterfaceSubType          = NULL; // Check interface type and subtype to be able to transfer VPN
+       CFStringRef             sourceInterfaceType             = NULL;
+       CFArrayRef              sourceSCNetworkServices         = NULL;
+       CFMutableArrayRef       sourceSCNetworkServicesMutable  = NULL; // Source SCNetworkServiceRef mutable array
+       SCNetworkServiceRef     sourceService                   = NULL;
+       CFStringRef             targetBSDName                   = NULL;
+       CFStringRef             targetBSDNameMapped             = NULL;
+       CFIndex                 targetCount                     = 0;    // Count of Source and Target Services
+       SCNetworkInterfaceRef   targetInterface                 = NULL;
+       CFStringRef             targetInterfaceSubType          = NULL; // services during migration
+       CFStringRef             targetInterfaceType             = NULL;
+       CFArrayRef              targetSCNetworkServices         = NULL;
+       CFMutableArrayRef       targetSCNetworkServicesMutable  = NULL; // Target SCNetworkServiceRef mutable array
+       SCNetworkServiceRef     targetService                   = NULL;
 
        // We need BSD Mapping to successfully create service mapping
        if (bsdNameMapping == NULL) {
-               SC_log(LOG_NOTICE, "No BSD name mapping");
+               SC_log(LOG_NOTICE, "No BSD name mappings");
                goto done;
        }
        sourceSCNetworkServices = SCNetworkServiceCopyAll(sourcePrefs);
                sourceInterface = NULL;
                sourceInterfaceType = NULL;
                sourceInterfaceSubType = NULL;
-               bsdNameMapTarget = NULL;
+               targetBSDNameMapped = NULL;
 
                targetCount = CFArrayGetCount(targetSCNetworkServicesMutable);
                sourceService = (SCNetworkServiceRef) CFArrayGetValueAtIndex(sourceSCNetworkServicesMutable, idx);
                         !isA_CFString(sourceInterfaceType)) {
                        sourceBSDName = SCNetworkInterfaceGetBSDName(sourceInterface);
                        if (!isA_CFString(sourceBSDName) ||
-                           !CFDictionaryContainsKey(bsdNameMapping, sourceBSDName)) {
-                               SC_log(LOG_NOTICE, "No BSD name mapping for %@",
-                                      (sourceBSDName == NULL) ? CFSTR("NULL") : sourceBSDName);
-                               continue;
-                       }
-
-                       bsdNameMapTarget = CFDictionaryGetValue(bsdNameMapping, sourceBSDName);
-                       if (!isA_CFString(bsdNameMapTarget)) {
-                               SC_log(LOG_NOTICE, "No BSD name mapping target");
+                           !CFDictionaryGetValueIfPresent(bsdNameMapping,
+                                                          sourceBSDName,
+                                                          (const void **)&targetBSDNameMapped) ||
+                           !isA_CFString(targetBSDNameMapped)) {
+                               SC_log(LOG_INFO, "No BSD name mapping for %@",
+                                      (sourceBSDName != NULL) ? sourceBSDName : CFSTR("NULL"));
                                continue;
                        }
                }
                                SC_log(LOG_NOTICE, "No target interface");
                                continue;
                        }
-                       SC_log(LOG_NOTICE, "targetInterface: %@", targetInterface);
                        if (sourceBSDName != NULL) {
                                targetBSDName = SCNetworkInterfaceGetBSDName(targetInterface);
                                if (!isA_CFString(targetBSDName)) {
-                                       SC_log(LOG_NOTICE, "No target BSD name");
+                                       SC_log(LOG_NOTICE, "No target BSD name: %@", targetInterface);
                                        continue;
                                }
 
-                               if (CFEqual(targetBSDName, bsdNameMapTarget)) {
-                                       SC_log(LOG_NOTICE, "Removing target BSD name: %@", targetBSDName);
+                               if (CFEqual(targetBSDName, targetBSDNameMapped)) {
                                        CFDictionaryAddValue(serviceMapping, sourceService, targetService);
                                        CFArrayRemoveValueAtIndex(targetSCNetworkServicesMutable, idx2);
                                        break;
                                if ((!isA_CFString(targetInterfaceType)) ||
                                    (!CFEqual(targetInterfaceType, kSCValNetInterfaceTypeVPN) &&
                                     !CFEqual(targetInterfaceType, kSCValNetInterfaceTypePPP))) {
-                                           SC_log(LOG_NOTICE, "Unexpected target interface type: %@",
-                                                  (targetInterfaceType != NULL) ? targetInterfaceType : CFSTR("NULL"));
-                                           continue;
+                                       SC_log(LOG_NOTICE, "Unexpected target interface type: %@", targetInterface);
+                                       continue;
                                    }
                                targetInterfaceSubType = __SCNetworkInterfaceGetEntitySubType(targetInterface);
                                if (!isA_CFString(targetInterfaceSubType)) {
-                                       SC_log(LOG_NOTICE, "No target interface SubType");
+                                       SC_log(LOG_NOTICE, "No target interface SubType: %@", targetInterface);
                                        continue;
                                }
 
                                // Check if the target interface type and the target interface sub type match
                                if (CFEqual(targetInterfaceType, sourceInterfaceType) &&
                                    CFEqual(targetInterfaceSubType, sourceInterfaceSubType)) {
-                                       SC_log(LOG_NOTICE, "Removing target BSD Name: %@ for VPN", targetBSDName);
                                        CFDictionaryAddValue(serviceMapping, sourceService, targetService);
                                        CFArrayRemoveValueAtIndex(targetSCNetworkServicesMutable, idx2);
                                        break;
                // Check if sourceService has found a mapping or not, if not the create a NULL mapping to indicate
                // the this service needs to be added and not replaced
                if (!CFDictionaryContainsKey(serviceMapping, sourceService)) {
-                       SC_log(LOG_NOTICE, "Service needs to be added: %@", sourceService);
                        CFDictionaryAddValue(serviceMapping, sourceService, kCFBooleanFalse);
                }
        }
 }
 
 typedef struct {
-       SCPreferencesRef targetPrefs;
-       CFDictionaryRef bsdMapping;
-       CFDictionaryRef setMapping;
-       CFDictionaryRef serviceSetMapping;
-} ServiceMigrationContext;
+       SCPreferencesRef        targetPrefs;
+       CFDictionaryRef         bsdNameMapping;
+       CFDictionaryRef         setMapping;
+       CFDictionaryRef         serviceSetMapping;
+} serviceMigrationContext;
 
 // value can be:
 //     SCNetworkServiceRef: if target service needs replacement
 static void
 ServiceMigrationAddOrReplace(const void *key, const void *value, void *context)
 {
-       CFDictionaryRef bsdMapping = NULL;
-       ServiceMigrationContext *ctx = (ServiceMigrationContext*)context;
-       CFDictionaryRef setMapping;
-       CFDictionaryRef sourceServiceSetMapping;
-       SCNetworkServiceRef sourceService = (SCNetworkServiceRef)key;
-       SCPreferencesRef targetPrefs = NULL;
-       SCNetworkServiceRef targetService = (SCNetworkServiceRef)value;
+       CFDictionaryRef         bsdNameMapping          = NULL;
+       serviceMigrationContext *ctx                    = (serviceMigrationContext*)context;
+       CFDictionaryRef         setMapping;
+       CFDictionaryRef         sourceServiceSetMapping;
+       SCNetworkServiceRef     sourceService           = (SCNetworkServiceRef)key;
+       SCPreferencesRef        targetPrefs             = NULL;
+       SCNetworkServiceRef     targetService           = (SCNetworkServiceRef)value;
 
        targetPrefs = ctx->targetPrefs;
-       bsdMapping = ctx->bsdMapping;
+       bsdNameMapping = ctx->bsdNameMapping;
        setMapping = ctx->setMapping;
        sourceServiceSetMapping = ctx->serviceSetMapping;
 
-       if ((setMapping != NULL || sourceServiceSetMapping != NULL)) {
+       if ((setMapping != NULL) || (sourceServiceSetMapping != NULL)) {
                if (isA_SCNetworkService(targetService)) {
-                       SC_log(LOG_INFO, "Removing target service: %@", targetService);
+                       (void)SCNetworkServiceGetName(targetService);   // ensures that the service name will be logged
                        SCNetworkServiceRemove(targetService);
                }
        }
-       SC_log(LOG_INFO, "Adding service: %@", sourceService);
-       if (__SCNetworkServiceMigrateNew(targetPrefs, sourceService, bsdMapping, setMapping, sourceServiceSetMapping) ==  FALSE) {
-               SC_log(LOG_INFO, "Could not add service: %@", sourceService);
+
+       if (!__SCNetworkServiceMigrateNew(targetPrefs, sourceService, bsdNameMapping, setMapping, sourceServiceSetMapping)) {
+               (void)SCNetworkServiceGetName(sourceService);   // ensures that the service name will be logged
+               SC_log(LOG_INFO, "*** [source] service add failed: %@", sourceService);
        }
 }
 
-static Boolean
-_SCNetworkMigrationDoServiceMigration(SCPreferencesRef sourcePrefs, SCPreferencesRef targetPrefs,
-                                     CFDictionaryRef serviceMapping, CFDictionaryRef bsdMapping,
-                                     CFDictionaryRef setMapping, CFDictionaryRef serviceSetMapping)
+static void
+logConfiguration(const char *description, SCPreferencesRef prefs)
 {
-       ServiceMigrationContext context;
-       Boolean success = FALSE;
+       CFArrayRef      sets;
 
-       SC_log(LOG_INFO,
-              "_SCNetworkMigrationDoServiceMigration() called"
-              "\n  sourcePrefs       = %@"
-              "\n  targetPrefs       = %@"
-              "\n  serviceMapping    = %@"
-              "\n  bsdMapping        = %@"
-              "\n  setMapping        = %@"
-              "\n  serviceSetMapping = %@",
-              sourcePrefs,
-              targetPrefs,
-              serviceMapping,
-              bsdMapping,
-              setMapping,
-              serviceSetMapping);
+       sets = SCNetworkSetCopyAll(prefs);
+       if (sets != NULL) {
+               CFIndex n       = CFArrayGetCount(sets);
+
+               SC_log(LOG_NOTICE, "%s configuration", description);
+               for (CFIndex i = 0; i < n; i++) {
+                       CFArrayRef      services;
+                       SCNetworkSetRef set;
+
+                       set = CFArrayGetValueAtIndex(sets, i);
+                       SC_log(LOG_NOTICE, "  Set %@ (%@)",
+                              SCNetworkSetGetSetID(set),
+                              SCNetworkSetGetName(set));
+
+                       services = SCNetworkSetCopyServices(set);
+                       if (services != NULL) {
+                               CFIndex         n;
+                               CFIndex         nOrder  = 0;
+                               CFArrayRef      order;
+
+                               order = SCNetworkSetGetServiceOrder(set);
+                               if (order != NULL) {
+                                       nOrder = CFArrayGetCount(order);
+                               }
+
+                               n = CFArrayGetCount(services);
+                               if (n > 1) {
+                                       CFMutableArrayRef       sorted;
+
+                                       sorted = CFArrayCreateMutableCopy(NULL, 0, services);
+                                       CFArraySortValues(sorted,
+                                                         CFRangeMake(0, CFArrayGetCount(sorted)),
+                                                         _SCNetworkServiceCompare,
+                                                         (void *)order);
+                                       CFRelease(services);
+                                       services = sorted;
+                               }
+
+                               for (CFIndex i = 0; i < n; i++) {
+                                       CFStringRef             bsdName;
+                                       SCNetworkInterfaceRef   interface;
+                                       CFIndex                 orderIndex      = kCFNotFound;
+                                       SCNetworkServiceRef     service;
+                                       CFStringRef             serviceName;
+                                       CFStringRef             serviceID;
+
+                                       service     = CFArrayGetValueAtIndex(services, i);
+                                       serviceID   = SCNetworkServiceGetServiceID(service);
+                                       serviceName = SCNetworkServiceGetName(service);
+                                       if (serviceName == NULL) serviceName = CFSTR("");
+
+                                       interface   = SCNetworkServiceGetInterface(service);
+                                       bsdName     = SCNetworkInterfaceGetBSDName(interface);
+
+                                       if (order != NULL) {
+                                               orderIndex  = CFArrayGetFirstIndexOfValue(order,
+                                                                                         CFRangeMake(0, nOrder),
+                                                                                         serviceID);
+                                       }
+                                       if (orderIndex != kCFNotFound) {
+                                               SC_log(LOG_NOTICE, "    Service %2ld : %@, %2d (%@%s%@)",
+                                                      orderIndex + 1,
+                                                      serviceID,
+                                                      __SCNetworkInterfaceOrder(SCNetworkServiceGetInterface(service)),        // temp?
+                                                      serviceName,
+                                                      bsdName != NULL ? ", " : "",
+                                                      bsdName != NULL ? bsdName : CFSTR(""));
+                                       } else {
+                                               SC_log(LOG_NOTICE, "    Service    : %@, %2d (%@%s%@)",
+                                                      serviceID,
+                                                      __SCNetworkInterfaceOrder(SCNetworkServiceGetInterface(service)),        // temp?
+                                                      serviceName,
+                                                      bsdName != NULL ? ", " : "",
+                                                      bsdName != NULL ? bsdName : CFSTR(""));
+                                       }
+                               }
+
+                               CFRelease(services);
+                       }
+               }
+
+               CFRelease(sets);
+       }
+
+       return;
+}
+
+static void
+logMapping(const void *key, const void *value, void *context)
+{
+#pragma unused(context)
+       CFTypeRef       mapping_key             = NULL;
+       const char      **mapping_name          = (const char **)context;
+       CFTypeRef       mapping_value           = NULL;
+       Boolean         mapping_value_new       = FALSE;
+
+       if (*mapping_name != NULL) {
+               SC_log(LOG_NOTICE, "%s =", *mapping_name);
+               *mapping_name = NULL;
+       }
+
+       if (isA_SCNetworkService(key)) {
+               mapping_key = SCNetworkServiceGetServiceID(key);
+       } else if (isA_SCNetworkSet(key)) {
+               mapping_key = SCNetworkSetGetSetID(key);
+       } else {
+               mapping_key = key;
+       }
+
+       if (isA_SCNetworkService(value)) {
+               mapping_value = SCNetworkServiceGetServiceID(value);
+       } else if (isA_SCNetworkSet(value)) {
+               mapping_value = SCNetworkSetGetSetID(value);
+       } else if (isA_CFBoolean(value)) {
+               mapping_value = CFSTR("None");
+       } else if (isA_CFArray(value)) {
+               CFIndex                 n       = CFArrayGetCount(value);
+               CFMutableStringRef      str     = CFStringCreateMutable(NULL, 0);
+
+               CFStringAppendFormat(str, NULL, CFSTR("( "));
+               for (CFIndex i = 0; i < n; i++) {
+                       CFTypeRef       val;
+
+                       val = CFArrayGetValueAtIndex(value, i);
+                       if (isA_SCNetworkSet(val)) {
+                               val = SCNetworkSetGetSetID(val);
+                       }
+                       CFStringAppendFormat(str, NULL, CFSTR("%s%@"),
+                                            i == 0 ? "" : ", ",
+                                            val);
+
+
+               }
+               CFStringAppendFormat(str, NULL, CFSTR(" )"));
+               mapping_value = str;
+               mapping_value_new = TRUE;
+       } else {
+               mapping_value = value;
+       }
+
+       SC_log(LOG_NOTICE, "  %@ --> %@", mapping_key, mapping_value);
+
+       if (mapping_value_new) {
+               CFRelease(mapping_value);
+       }
+       return;
+}
+
+static Boolean
+_SCNetworkMigrationDoServiceMigration(SCPreferencesRef sourcePrefs,
+                                     SCPreferencesRef  targetPrefs,
+                                     CFDictionaryRef   serviceMapping,
+                                     CFDictionaryRef   bsdNameMapping,
+                                     CFDictionaryRef   setMapping,
+                                     CFDictionaryRef   serviceSetMapping)
+{
+       serviceMigrationContext context;
+       const char              *mapping_name;
+       Boolean                 success = FALSE;
 
        if ((sourcePrefs == NULL) ||
            (targetPrefs == NULL) ||
            !isA_CFDictionary(serviceMapping) ||
-           !isA_CFDictionary(bsdMapping)) {
-               SC_log(LOG_INFO, "No sourcePrefs, targetPrefs, serviceMapping, or bsdMapping");
+           !isA_CFDictionary(bsdNameMapping)) {
+               SC_log(LOG_INFO, "No sourcePrefs, targetPrefs, serviceMapping, or bsdNameMapping");
                goto done;
        }
+
+       if (bsdNameMapping != NULL) {
+               mapping_name = "BSD name mapping";
+               CFDictionaryApplyFunction(bsdNameMapping, logMapping, &mapping_name);
+       }
+       if (serviceMapping != NULL) {
+               mapping_name = "SCNetworkService mapping";
+               CFDictionaryApplyFunction(serviceMapping, logMapping, &mapping_name);
+       }
+       if (setMapping != NULL) {
+               mapping_name = "SCNetworkSet mapping";
+               CFDictionaryApplyFunction(setMapping, logMapping, &mapping_name);
+       }
+       if (serviceSetMapping != NULL) {
+               mapping_name = "SCNetworkService/SCNetworkSet mapping";
+               CFDictionaryApplyFunction(serviceSetMapping, logMapping, &mapping_name);
+       }
+
        context.targetPrefs = targetPrefs;
-       context.bsdMapping = bsdMapping;
+       context.bsdNameMapping = bsdNameMapping;
        context.setMapping = setMapping;
        context.serviceSetMapping = serviceSetMapping;
-
        CFDictionaryApplyFunction(serviceMapping, ServiceMigrationAddOrReplace, &context);
 
        success = TRUE;
 static Boolean
 _SCNetworkMigrationDoSystemMigration(SCPreferencesRef sourcePrefs, SCPreferencesRef targetPrefs)
 {
-       CFStringEncoding nameEncoding;
-       CFStringRef computerName;
-       CFStringRef hostname;
-       CFStringRef localHostname;
-       CFDictionaryRef btmm = NULL;
-       CFDictionaryRef btmmDSID = NULL;
-       CFStringRef btmmDSIDPath;
-       CFStringRef btmmPath;
+       CFDictionaryRef         btmm;
+       CFDictionaryRef         btmmDSID;
+       CFStringRef             btmmDSIDPath;
+       CFStringRef             btmmPath;
+       CFStringRef             computerName;
+       CFStringRef             hostname;
+       CFStringRef             localHostname;
+       CFStringEncoding        nameEncoding;
 
-       SC_log(LOG_INFO,
-              "_SCNetworkMigrationDoSystemMigration() called"
-              "\n  sourcePrefs = %@"
-              "\n  targetPrefs = %@",
-              sourcePrefs,
-              targetPrefs);
+       SC_log(LOG_NOTICE, "Copying \"system\" settings");
 
        if ((sourcePrefs == NULL) ||
            (targetPrefs == NULL)) {
                                                kSCPrefSystem,
                                                kSCCompNetwork,
                                                BACK_TO_MY_MAC_DSIDS);
-
        btmmDSID = SCPreferencesPathGetValue(sourcePrefs, btmmDSIDPath);
        if (btmmDSID != NULL) {
                SCPreferencesPathSetValue(targetPrefs, btmmDSIDPath, btmmDSID);
 #if    !TARGET_OS_IPHONE
 
 typedef struct {
-       CFMutableArrayRef interfaceList;
-       SCPreferencesRef ni_prefs;
-       CFDictionaryRef bsdMapping;
-} SCVirtualInterfaceMemberListContext;
+       CFMutableArrayRef       interfaceList;
+       SCPreferencesRef        ni_prefs;
+       CFDictionaryRef         bsdNameMapping;
+} virtualInterfaceMemberListContext;
 
 typedef struct {
-       SCPreferencesRef prefs;
-       SCPreferencesRef ni_prefs;
-       CFDictionaryRef bsdMapping;
-       CFDictionaryRef virtualBSDMapping;
-       CFDictionaryRef mappingBSDNameToService;
-       CFDictionaryRef setMapping;
-       CFDictionaryRef serviceSetMapping;
-} SCVirtualInterfaceContext;
+       SCPreferencesRef        prefs;
+       SCPreferencesRef        ni_prefs;
+       CFDictionaryRef         bsdNameMapping;
+       CFDictionaryRef         virtualBSDNameMapping;
+       CFDictionaryRef         mappingBSDNameToService;
+       CFDictionaryRef         setMapping;
+       CFDictionaryRef         serviceSetMapping;
+} virtualInterfaceContext;
 
 static void
 add_virtual_interface(const void *value, void *context)
 {
-       SCVirtualInterfaceMemberListContext *ctx = (SCVirtualInterfaceMemberListContext*)context;
-       CFMutableArrayRef interfaceList = ctx->interfaceList;
-       CFDictionaryRef bsdMapping = ctx->bsdMapping;
-       CFStringRef oldInterfaceBSDName = (CFStringRef)value;
-       SCNetworkInterfaceRef newInterface;
-       CFStringRef newInterfaceBSDName;
+       virtualInterfaceMemberListContext       *ctx                    = (virtualInterfaceMemberListContext*)context;
+       CFDictionaryRef                         bsdNameMapping          = ctx->bsdNameMapping;
+       CFMutableArrayRef                       interfaceList           = ctx->interfaceList;
+       CFStringRef                             oldInterfaceBSDName     = (CFStringRef)value;
+       SCNetworkInterfaceRef                   newInterface;
+       CFStringRef                             newInterfaceBSDName;
 
        SC_log(LOG_INFO, "old BSD interface name: %@", oldInterfaceBSDName);
 
-       newInterfaceBSDName = CFDictionaryGetValue(bsdMapping, oldInterfaceBSDName);
+       newInterfaceBSDName = CFDictionaryGetValue(bsdNameMapping, oldInterfaceBSDName);
        if (newInterfaceBSDName == NULL) {
                return;
        }
 static void
 add_target_bridge(const void *key, const void *value, void *context)
 {
-       CFStringRef bridgeName;
-       CFDictionaryRef bridgeOptions;
-       SCVirtualInterfaceContext *ctx = (SCVirtualInterfaceContext*)context;
-       CFDictionaryRef bridgeBSDNameMapping = ctx->virtualBSDMapping;
-       CFDictionaryRef bsdNameToServiceMapping = ctx->mappingBSDNameToService;
-       SCVirtualInterfaceMemberListContext memberListContext;
-       CFMutableArrayRef newInterfaceList;
-       SCBridgeInterfaceRef newBridge;
-       SCBridgeInterfaceRef oldBridge = (SCBridgeInterfaceRef)key;
-       CFStringRef oldBSDName;
-       CFArrayRef oldInterfaceList = (CFArrayRef)value;
-       CFArrayRef oldServiceList;
-       SCPreferencesRef prefs = ctx->prefs;
-       CFDictionaryRef serviceSetMapping = ctx->serviceSetMapping;
-       CFDictionaryRef setMapping = ctx->setMapping;
+       CFStringRef                             bridgeName;
+       CFDictionaryRef                         bridgeOptions;
+       virtualInterfaceContext                 *ctx                    = (virtualInterfaceContext*)context;
+       CFDictionaryRef                         bridgeBSDNameMapping    = ctx->virtualBSDNameMapping;
+       CFDictionaryRef                         bsdNameToServiceMapping = ctx->mappingBSDNameToService;
+       virtualInterfaceMemberListContext       memberListContext;
+       CFMutableArrayRef                       newInterfaceList;
+       SCBridgeInterfaceRef                    newBridge;
+       SCBridgeInterfaceRef                    oldBridge               = (SCBridgeInterfaceRef)key;
+       CFStringRef                             oldBSDName;
+       CFArrayRef                              oldInterfaceList        = (CFArrayRef)value;
+       CFArrayRef                              oldServiceList;
+       SCPreferencesRef                        prefs                   = ctx->prefs;
+       CFDictionaryRef                         serviceSetMapping       = ctx->serviceSetMapping;
+       CFDictionaryRef                         setMapping              = ctx->setMapping;
 
        newInterfaceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
 
-       memberListContext.bsdMapping = ctx->bsdMapping;
+       memberListContext.bsdNameMapping = ctx->bsdNameMapping;
        memberListContext.interfaceList = newInterfaceList;
        memberListContext.ni_prefs = ctx->ni_prefs;
 
 static void
 _SCNetworkMigrationRemoveBridgeServices(SCPreferencesRef prefs)
 {
-       CFArrayRef services = SCNetworkServiceCopyAll(prefs);
+       CFArrayRef      services        = SCNetworkServiceCopyAll(prefs);
 
        for (CFIndex idx = 0; idx < CFArrayGetCount(services); idx++) {
                SCNetworkServiceRef service = CFArrayGetValueAtIndex(services, idx);
 static CFDictionaryRef
 _SCNetworkMigrationCopyMappingBSDNameToBridgeServices(SCPreferencesRef prefs)
 {
-       CFArrayRef services = SCNetworkServiceCopyAll(prefs);
-       CFMutableDictionaryRef bridgeServices = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+       CFArrayRef              services        = SCNetworkServiceCopyAll(prefs);
+       CFMutableDictionaryRef  bridgeServices  = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
 
        for (CFIndex idx = 0; idx < CFArrayGetCount(services); idx++) {
                SCNetworkServiceRef service = CFArrayGetValueAtIndex(services, idx);
 
 
 static Boolean
-_SCNetworkMigrationDoBridgeMigration (SCPreferencesRef sourcePrefs,
-                                     SCPreferencesRef sourceNIPrefs,
-                                     SCPreferencesRef targetPrefs,
-                                     SCPreferencesRef targetNIPrefs,
-                                     CFDictionaryRef bsdMapping,
-                                     CFDictionaryRef setMapping,
-                                     CFDictionaryRef serviceSetMapping)
+_SCNetworkMigrationDoBridgeMigration(SCPreferencesRef  sourcePrefs,
+                                    SCPreferencesRef   sourceNIPrefs,
+                                    SCPreferencesRef   targetPrefs,
+                                    SCPreferencesRef   targetNIPrefs,
+                                    CFDictionaryRef    bsdNameMapping,
+                                    CFDictionaryRef    setMapping,
+                                    CFDictionaryRef    serviceSetMapping)
 {
 #pragma unused(sourceNIPrefs)
-       CFArrayRef allSourceBridges;
-       CFArrayRef allTargetBridges;
-       SCBridgeInterfaceRef bridge;
-       CFMutableDictionaryRef bridgeInterfaceMapping = NULL;
-       CFMutableDictionaryRef bridgeMapping;
-       CFDictionaryRef bsdNameToBridgeServices;
-       SCVirtualInterfaceContext context;
-       CFIndex count = 0;
-       Boolean success = FALSE;
+       CFArrayRef              allSourceBridges;
+       CFArrayRef              allTargetBridges;
+       SCBridgeInterfaceRef    bridge;
+       CFMutableDictionaryRef  bridgeInterfaceMapping  = NULL;
+       CFMutableDictionaryRef  bridgeMapping;
+       CFDictionaryRef         bsdNameToBridgeServices;
+       virtualInterfaceContext context;
+       CFIndex                 count                   = 0;
+       Boolean                 success                 = FALSE;
 
        allSourceBridges = SCBridgeInterfaceCopyAll(sourcePrefs);
        allTargetBridges = SCBridgeInterfaceCopyAll(targetPrefs);
                        interface = CFArrayGetValueAtIndex(bridgeMembers, idx2);
                        interfaceName = SCNetworkInterfaceGetBSDName(interface);
 
-                       if (CFDictionaryContainsKey(bsdMapping, interfaceName)) {
+                       if (CFDictionaryContainsKey(bsdNameMapping, interfaceName)) {
                                CFStringRef bridgeNewName = CFStringCreateWithFormat(NULL, NULL, CFSTR("bridge%ld"), count);
                                CFDictionaryAddValue(bridgeMapping, interfaceName, bridgeNewName);
                                CFArrayAppendValue(interfaceList, interfaceName);
 
        context.prefs = targetPrefs;
        context.ni_prefs = targetNIPrefs;
-       context.bsdMapping = bsdMapping;
-       context.virtualBSDMapping = bridgeMapping;
+       context.bsdNameMapping = bsdNameMapping;
+       context.virtualBSDNameMapping = bridgeMapping;
        context.mappingBSDNameToService = bsdNameToBridgeServices;
        context.setMapping = setMapping;
        context.serviceSetMapping = serviceSetMapping;
 static void
 add_target_bond(const void *key, const void *value, void *context)
 {
-       CFNumberRef bondMode;
-       CFStringRef bondName;
-       CFDictionaryRef bondOptions;
-       SCVirtualInterfaceContext *ctx = (SCVirtualInterfaceContext*)context;
-       CFDictionaryRef bondBSDNameMapping = ctx->virtualBSDMapping;
-       CFDictionaryRef bsdNameToServiceMapping = ctx->mappingBSDNameToService;
-       SCVirtualInterfaceMemberListContext memberListContext;
-       CFMutableArrayRef newInterfaceList;
-       SCBondInterfaceRef newBond;
-       SCBondInterfaceRef oldBond = (SCBondInterfaceRef)key;
-       CFStringRef oldBSDName;
-       CFArrayRef oldInterfaceList = (CFArrayRef)value;
-       CFArrayRef oldServiceList;
-       SCPreferencesRef prefs = ctx->prefs;
-       CFDictionaryRef serviceSetMapping = ctx->serviceSetMapping;
-       CFDictionaryRef setMapping = ctx->setMapping;
+       CFNumberRef                             bondMode;
+       CFStringRef                             bondName;
+       CFDictionaryRef                         bondOptions;
+       virtualInterfaceContext                 *ctx                    = (virtualInterfaceContext*)context;
+       CFDictionaryRef                         bondBSDNameMapping      = ctx->virtualBSDNameMapping;
+       CFDictionaryRef                         bsdNameToServiceMapping = ctx->mappingBSDNameToService;
+       virtualInterfaceMemberListContext       memberListContext;
+       CFMutableArrayRef                       newInterfaceList;
+       SCBondInterfaceRef                      newBond;
+       SCBondInterfaceRef                      oldBond                 = (SCBondInterfaceRef)key;
+       CFStringRef                             oldBSDName;
+       CFArrayRef                              oldInterfaceList        = (CFArrayRef)value;
+       CFArrayRef                              oldServiceList;
+       SCPreferencesRef                        prefs                   = ctx->prefs;
+       CFDictionaryRef                         serviceSetMapping       = ctx->serviceSetMapping;
+       CFDictionaryRef                         setMapping              = ctx->setMapping;
 
        newInterfaceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
 
-       memberListContext.bsdMapping = ctx->bsdMapping;
+       memberListContext.bsdNameMapping = ctx->bsdNameMapping;
        memberListContext.interfaceList = newInterfaceList;
        memberListContext.ni_prefs = ctx->ni_prefs;
 
 static CFDictionaryRef
 _SCNetworkMigrationCopyMappingBSDNameToBondServices(SCPreferencesRef prefs)
 {
-       CFArrayRef services = SCNetworkServiceCopyAll(prefs);
-       CFMutableDictionaryRef bondServices = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+       CFArrayRef              services        = SCNetworkServiceCopyAll(prefs);
+       CFMutableDictionaryRef  bondServices    = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
 
        for (CFIndex idx = 0; idx < CFArrayGetCount(services); idx++) {
                SCNetworkServiceRef service = CFArrayGetValueAtIndex(services, idx);
 
 
 static Boolean
-_SCNetworkMigrationDoBondMigration (SCPreferencesRef sourcePrefs,
-                                   SCPreferencesRef sourceNIPrefs,
-                                   SCPreferencesRef targetPrefs,
-                                   SCPreferencesRef targetNIPrefs,
-                                   CFDictionaryRef bsdMapping,
-                                   CFDictionaryRef setMapping,
-                                   CFDictionaryRef serviceSetMapping)
+_SCNetworkMigrationDoBondMigration(SCPreferencesRef    sourcePrefs,
+                                  SCPreferencesRef     sourceNIPrefs,
+                                  SCPreferencesRef     targetPrefs,
+                                  SCPreferencesRef     targetNIPrefs,
+                                  CFDictionaryRef      bsdNameMapping,
+                                  CFDictionaryRef      setMapping,
+                                  CFDictionaryRef      serviceSetMapping)
 {
 #pragma unused(sourceNIPrefs)
-       CFArrayRef allSourceBonds;
-       CFArrayRef allTargetBonds;
-       SCBondInterfaceRef bond;
-       CFMutableDictionaryRef bondInterfaceMapping = NULL;
-       CFMutableDictionaryRef bondMapping;
-       CFDictionaryRef bsdNameToBondServices;
-       SCVirtualInterfaceContext context;
-       CFIndex count = 0;
-       Boolean success = FALSE;
+       CFArrayRef              allSourceBonds;
+       CFArrayRef              allTargetBonds;
+       SCBondInterfaceRef      bond;
+       CFMutableDictionaryRef  bondInterfaceMapping    = NULL;
+       CFMutableDictionaryRef  bondMapping;
+       CFDictionaryRef         bsdNameToBondServices;
+       virtualInterfaceContext context;
+       CFIndex                 count                   = 0;
+       Boolean                 success                 = FALSE;
 
        allSourceBonds = SCBondInterfaceCopyAll(sourcePrefs);
        allTargetBonds = SCBondInterfaceCopyAll(targetPrefs);
                        interface = CFArrayGetValueAtIndex(bondMembers, idx2);
                        interfaceName = SCNetworkInterfaceGetBSDName(interface);
 
-                       if (CFDictionaryContainsKey(bsdMapping, interfaceName)) {
+                       if (CFDictionaryContainsKey(bsdNameMapping, interfaceName)) {
                                CFStringRef bondNewName = CFStringCreateWithFormat(NULL, NULL, CFSTR("bond%ld"), count);
                                CFDictionaryAddValue(bondMapping, interfaceName, bondNewName);
                                CFArrayAppendValue(interfaceList, interfaceName);
 
        context.prefs = targetPrefs;
        context.ni_prefs = targetNIPrefs;
-       context.bsdMapping = bsdMapping;
-       context.virtualBSDMapping = bondMapping;
+       context.bsdNameMapping = bsdNameMapping;
+       context.virtualBSDNameMapping = bondMapping;
        context.mappingBSDNameToService = bsdNameToBondServices;
        context.setMapping = setMapping;
        context.serviceSetMapping = serviceSetMapping;
 static void
 add_target_vlan(const void *value, void *context)
 {
-       CFDictionaryRef bsdMapping;
-       SCVirtualInterfaceContext *ctx = (SCVirtualInterfaceContext*)context;
-       CFDictionaryRef bsdNameToServiceMapping = ctx->mappingBSDNameToService;
-       SCPreferencesRef prefs = ctx->prefs;
-       SCVLANInterfaceRef newVLAN = NULL;
-       SCNetworkInterfaceRef newPhysicalInterface = NULL;
-       CFStringRef newPhysicalInterfaceName;
-       SCVLANInterfaceRef oldVLAN = (SCVLANInterfaceRef)value;
-       CFStringRef oldBSDName;
-       SCNetworkInterfaceRef oldPhysicalInterface;
-       CFStringRef oldPhysicalInterfaceName;
-       SCNetworkServiceRef oldService;
-       CFArrayRef oldServiceList;
-       CFDictionaryRef serviceSetMapping = ctx->serviceSetMapping;
-       CFDictionaryRef setMapping = ctx->setMapping;
-       CFDictionaryRef vlanBSDMapping = ctx->virtualBSDMapping;
-       CFNumberRef vlanTag;
-       CFStringRef vlanName;
-       CFDictionaryRef vlanOptions;
-
-       bsdMapping = ctx->bsdMapping;
+       CFDictionaryRef         bsdNameMapping;
+       virtualInterfaceContext *ctx                    = (virtualInterfaceContext*)context;
+       CFDictionaryRef         bsdNameToServiceMapping = ctx->mappingBSDNameToService;
+       SCPreferencesRef        prefs                   = ctx->prefs;
+       SCVLANInterfaceRef      newVLAN                 = NULL;
+       SCNetworkInterfaceRef   newPhysicalInterface    = NULL;
+       CFStringRef             newPhysicalInterfaceName;
+       SCVLANInterfaceRef      oldVLAN                 = (SCVLANInterfaceRef)value;
+       CFStringRef             oldBSDName;
+       SCNetworkInterfaceRef   oldPhysicalInterface;
+       CFStringRef             oldPhysicalInterfaceName;
+       SCNetworkServiceRef     oldService;
+       CFArrayRef              oldServiceList;
+       CFDictionaryRef         serviceSetMapping       = ctx->serviceSetMapping;
+       CFDictionaryRef         setMapping              = ctx->setMapping;
+       CFDictionaryRef         vlanBSDNameMapping      = ctx->virtualBSDNameMapping;
+       CFNumberRef             vlanTag;
+       CFStringRef             vlanName;
+       CFDictionaryRef         vlanOptions;
+
+       bsdNameMapping = ctx->bsdNameMapping;
 
        oldPhysicalInterface = SCVLANInterfaceGetPhysicalInterface(oldVLAN);
        if (oldPhysicalInterface == NULL) {
                goto done;
        }
 
-       newPhysicalInterfaceName = CFDictionaryGetValue(bsdMapping, oldPhysicalInterfaceName);
+       newPhysicalInterfaceName = CFDictionaryGetValue(bsdNameMapping, oldPhysicalInterfaceName);
        if (newPhysicalInterfaceName == NULL) {
                SC_log(LOG_NOTICE, "No new VLAN physical interface name");
                goto done;
 
        for (CFIndex idx = 0; idx < CFArrayGetCount(oldServiceList); idx++) {
                oldService = CFArrayGetValueAtIndex(oldServiceList, idx);
-               if (!__SCNetworkServiceMigrateNew(prefs, oldService, vlanBSDMapping, setMapping, serviceSetMapping)) {
+               if (!__SCNetworkServiceMigrateNew(prefs, oldService, vlanBSDNameMapping, setMapping, serviceSetMapping)) {
                        SC_log(LOG_NOTICE, "Could not migrate VLAN service: %@", oldService);
                }
        }
 }
 
 static Boolean
-_SCNetworkMigrationDoVLANMigration (SCPreferencesRef sourcePrefs,
-                                   SCPreferencesRef sourceNIPrefs,
-                                   SCPreferencesRef targetPrefs,
-                                   SCPreferencesRef targetNIPrefs,
-                                   CFDictionaryRef bsdMapping,
-                                   CFDictionaryRef setMapping,
-                                   CFDictionaryRef serviceSetMapping)
+_SCNetworkMigrationDoVLANMigration(SCPreferencesRef    sourcePrefs,
+                                  SCPreferencesRef     sourceNIPrefs,
+                                  SCPreferencesRef     targetPrefs,
+                                  SCPreferencesRef     targetNIPrefs,
+                                  CFDictionaryRef      bsdNameMapping,
+                                  CFDictionaryRef      setMapping,
+                                  CFDictionaryRef      serviceSetMapping)
 {
 #pragma unused(sourceNIPrefs)
-       CFArrayRef allSourceVLAN;
-       CFArrayRef allTargetVLAN;
-       SCVirtualInterfaceContext context;
-       CFIndex count = 0;
-       Boolean success = FALSE;
-       SCVLANInterfaceRef vlan;
-       CFMutableArrayRef vlanList;
-       CFMutableDictionaryRef vlanMapping;
-       CFDictionaryRef bsdNameToVLANServices;
+       CFArrayRef              allSourceVLAN;
+       CFArrayRef              allTargetVLAN;
+       virtualInterfaceContext context;
+       CFIndex                 count           = 0;
+       Boolean                 success         = FALSE;
+       SCVLANInterfaceRef      vlan;
+       CFMutableArrayRef       vlanList;
+       CFMutableDictionaryRef  vlanMapping;
+       CFDictionaryRef         bsdNameToVLANServices;
 
        allSourceVLAN = SCVLANInterfaceCopyAll(sourcePrefs);
        allTargetVLAN = SCVLANInterfaceCopyAll(targetPrefs);
                CFStringRef physicalInterfaceName = SCNetworkInterfaceGetBSDName(physicalInterface);
 
                // Add VLAN to be migrated if the mapping between interfaces exists
-               if (CFDictionaryContainsKey(bsdMapping, physicalInterfaceName)) {
+               if (CFDictionaryContainsKey(bsdNameMapping, physicalInterfaceName)) {
                        CFStringRef vlanNewName = CFStringCreateWithFormat(NULL, NULL, CFSTR("vlan%ld"), count);
                        CFDictionaryAddValue(vlanMapping, vlanBSDName, vlanNewName);
                        CFArrayAppendValue(vlanList, vlan);
 
        context.prefs = targetPrefs;
        context.ni_prefs = targetNIPrefs;
-       context.bsdMapping = bsdMapping;
-       context.virtualBSDMapping = vlanMapping;
+       context.bsdNameMapping = bsdNameMapping;
+       context.virtualBSDNameMapping = vlanMapping;
        context.mappingBSDNameToService = bsdNameToVLANServices;
        context.setMapping = setMapping;
        context.serviceSetMapping = serviceSetMapping;
                                                      SCPreferencesRef sourceNIPrefs,
                                                      SCPreferencesRef targetPrefs,
                                                      SCPreferencesRef targetNIPrefs,
-                                                     CFDictionaryRef bsdMapping,
+                                                     CFDictionaryRef bsdNameMapping,
                                                      CFDictionaryRef setMapping,
                                                      CFDictionaryRef serviceSetMapping)
 {
        // Handle Bridges
        if (!_SCNetworkMigrationDoBridgeMigration(sourcePrefs, sourceNIPrefs,
                                                 targetPrefs, targetNIPrefs,
-                                                bsdMapping, setMapping, serviceSetMapping)) {
+                                                bsdNameMapping, setMapping, serviceSetMapping)) {
                SC_log(LOG_NOTICE, "Bridge migration failed");
        }
 
        // Handle Bonds
        if (!_SCNetworkMigrationDoBondMigration(sourcePrefs, sourceNIPrefs,
                                               targetPrefs, targetNIPrefs,
-                                              bsdMapping, setMapping, serviceSetMapping)) {
+                                              bsdNameMapping, setMapping, serviceSetMapping)) {
                SC_log(LOG_NOTICE, "Bond migration failed");
        }
 
        // Handle VLANs
        if (!_SCNetworkMigrationDoVLANMigration(sourcePrefs, sourceNIPrefs,
                                               targetPrefs, targetNIPrefs,
-                                              bsdMapping, setMapping, serviceSetMapping)) {
+                                              bsdNameMapping, setMapping, serviceSetMapping)) {
                SC_log(LOG_NOTICE, "VLAN migration failed");
        }
        return TRUE;
 #endif // !TARGET_OS_IPHONE
 
 typedef struct {
-       SCPreferencesRef prefs;
-       CFArrayRef serviceOrder;
-       CFMutableArrayRef serviceListMutable;
-       Boolean* success;
+       SCPreferencesRef        prefs;
+       CFArrayRef              serviceOrder;
+       CFMutableArrayRef       serviceOrderMutable;
+       Boolean                 *success;
 } migrated_service_context;
 
 static void
 create_migrated_order(const void *value, void *context)
 {
-       migrated_service_context *ctx = (migrated_service_context*)context;
-       CFMutableArrayRef migratedServiceOrder = ctx->serviceListMutable;
-       CFArrayRef targetServiceOrder = ctx->serviceOrder;
-       CFStringRef migratedServiceID = (CFStringRef)value;
-       Boolean *success = ctx->success;
+       migrated_service_context        *ctx                    = (migrated_service_context*)context;
+       CFMutableArrayRef               migratedServiceOrder    = ctx->serviceOrderMutable;
+       CFArrayRef                      targetServiceOrder      = ctx->serviceOrder;
+       CFStringRef                     migratedServiceID       = (CFStringRef)value;
+       Boolean                         *success                = ctx->success;
 
        if (*success == FALSE) {
                return;
        }
 }
 
+typedef struct {
+       SCPreferencesRef        prefs;
+       CFMutableArrayRef       serviceListMutable;
+       CFArrayRef              serviceOrder;
+       Boolean                 *success;
+} non_migrated_service_context;
+
 static void
 create_non_migrated_service_list(const void *value, void *context)
 {
-       migrated_service_context *ctx = (migrated_service_context*)context;
-       CFArrayRef migratedServiceOrder = ctx->serviceOrder;
-       CFMutableArrayRef nonMigratedService = ctx->serviceListMutable;
-       SCPreferencesRef prefs = ctx->prefs;
-       SCNetworkServiceRef service;
-       Boolean *success = ctx->success;
-       CFStringRef targetServiceID = (CFStringRef)value;
+       non_migrated_service_context    *ctx                    = (non_migrated_service_context*)context;
+       CFArrayRef                      migratedServiceOrder    = ctx->serviceOrder;
+       CFMutableArrayRef               nonMigratedService      = ctx->serviceListMutable;
+       SCPreferencesRef                prefs                   = ctx->prefs;
+       SCNetworkServiceRef             service;
+       Boolean                         *success                = ctx->success;
+       CFStringRef                     targetServiceID         = (CFStringRef)value;
 
        if (*success == FALSE) {
                return;
        // Adding all services not present in migratedServiceOrder into nonMigrated service
        if (CFArrayGetFirstIndexOfValue(migratedServiceOrder,
                                        CFRangeMake(0, CFArrayGetCount(migratedServiceOrder)),
-                                       targetServiceID)) {
+                                       targetServiceID) != kCFNotFound) {
                // if service already present
                return;
        }
 static void
 preserve_service_order(const void *key, const void *value, void *context)
 {
-       migrated_service_context migrated_context;
-       CFMutableArrayRef migratedServiceOrder;
-       migrated_service_context non_migrated_context;
-       CFMutableArrayRef nonMigratedServices;
-       SCNetworkSetRef sourceSet = (SCNetworkSetRef)key;
-       CFArrayRef sourceServiceOrder = NULL;
-       Boolean *success = (Boolean*)context;
-       SCNetworkSetRef targetSet = (SCNetworkSetRef)value;
-       SCNetworkSetPrivateRef targetPrivate = (SCNetworkSetPrivateRef)targetSet;
-       CFArrayRef targetServiceOrder = NULL;
+       migrated_service_context        migrated_context;
+       CFMutableArrayRef               migratedServiceOrder;
+       non_migrated_service_context    non_migrated_context;
+       CFMutableArrayRef               nonMigratedServices;
+       SCNetworkSetRef                 sourceSet               = (SCNetworkSetRef)key;
+       CFArrayRef                      sourceServiceOrder      = NULL;
+       Boolean                         *success                = (Boolean*)context;
+       SCNetworkSetRef                 targetSet               = (SCNetworkSetRef)value;
+       SCNetworkSetPrivateRef          targetPrivate           = (SCNetworkSetPrivateRef)targetSet;
+       CFArrayRef                      targetServiceOrder      = NULL;
 
        if (*success == FALSE) {
                return;
 
        migrated_context.prefs = NULL;
        migrated_context.serviceOrder = targetServiceOrder;
-       migrated_context.serviceListMutable = migratedServiceOrder;
+       migrated_context.serviceOrderMutable = migratedServiceOrder;
        migrated_context.success = success;
 
        // Creating a list of service IDs which were migrated in the target set
        non_migrated_context.serviceListMutable = nonMigratedServices;
        non_migrated_context.success = success;
 
-       // Creating a list of all the services which were not migrated from the source set to the
-       // target set
+       // Creating a list of all the services which were not migrated from the
+       // source set to the target set
        CFArrayApplyFunction(targetServiceOrder, CFRangeMake(0, CFArrayGetCount(targetServiceOrder)), create_non_migrated_service_list, &non_migrated_context);
 
        // Remove non migrated service
                SCNetworkServiceRef service = CFArrayGetValueAtIndex(nonMigratedServices, idx);
                SCNetworkSetRemoveService(targetSet, service);
        }
+
        // Set migrated service order
        SCNetworkSetSetServiceOrder(targetSet, migratedServiceOrder);
 
        // Add non migrated services
        for (CFIndex idx = 0; idx < CFArrayGetCount(nonMigratedServices); idx++) {
-               SCNetworkServiceRef service = CFArrayGetValueAtIndex(nonMigratedServices, idx);
-               (void)SCNetworkSetAddService(targetSet, service);
+               Boolean                 ok;
+               SCNetworkServiceRef     service;
+
+               service = CFArrayGetValueAtIndex(nonMigratedServices, idx);
+               ok = SCNetworkSetAddService(targetSet, service);
+               if (!ok) {
+                       CFStringRef             bsdName;
+                       SCNetworkInterfaceRef   interface;
+
+                       interface = SCNetworkServiceGetInterface(service);
+                       bsdName = SCNetworkInterfaceGetBSDName(interface);
+                       SC_log(LOG_NOTICE, "preserve_service_order():  could not add service: %s"
+                                          "\n  serviceID = %@, interface = %@",
+                              SCErrorString(SCError()),
+                              SCNetworkServiceGetServiceID(service),
+                              bsdName != NULL ? bsdName : CFSTR("?"));
+               }
        }
 
 done:
 }
 
 static Boolean
-_SCNetworkMigrationDoServiceOrderMigration(SCPreferencesRef sourcePrefs,
-                                          SCPreferencesRef targetPrefs,
-                                          CFDictionaryRef setMapping)
+_SCNetworkMigrationDoServiceOrderMigration(SCPreferencesRef    sourcePrefs,
+                                          SCPreferencesRef     targetPrefs,
+                                          CFDictionaryRef      setMapping)
 {
 #pragma unused(sourcePrefs)
 #pragma unused(targetPrefs)
        Boolean success = TRUE;
 
        if (!isA_CFDictionary(setMapping)) {
-               success = FALSE;
-               goto done;
+               return FALSE;
        }
 
        CFDictionaryApplyFunction(setMapping, preserve_service_order, &success);
-done:
        return success;
 }
 
 static Boolean
 _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetDir)
 {
-       CFDictionaryRef bsdNameMapping = NULL;                  // Mapping between BSD name and SCNetworkInterfaceRef to help with mapping services
-       CFMutableDictionaryRef builtinMapping = NULL;           // Mapping between builtin interfaces between source and target configurations: (SCNetworkInterfaceRef -> SCNetworkInterfaceRef)
-       CFMutableDictionaryRef externalMapping = NULL;          // Mapping between external interfaces between source and target configurations: (SCNetworkInterfaceRef -> SCNetworkInterfaceRef)
-       Boolean migrationSuccess = FALSE;
-       CFArrayRef newTargetNetworkInterfaceEntity = NULL;      // Array of Interface Entity which used to create new target interfaces created during migration
-       CFDictionaryRef serviceMapping = NULL;                  // Mapping between services of source to target. (SCNetworkServicesRef -> SCNetworkServicesRef)
-       CFDictionaryRef setMapping = NULL;
-       CFDictionaryRef sourceServiceSetMapping = NULL;
-       CFArrayRef sourceConfigurationFiles = NULL;             // Path to the source configuration files which need to be migrated
-       CFStringRef sourceModel = NULL;
-       CFURLRef sourceNetworkInterfaceFile = NULL;             // Source CFURLRef for preferences.plist and NetworkInterfaces.plist
-       char sourceNetworkInterfaceFileStr[PATH_MAX];
-       CFStringRef sourceNetworkInterfaceFileString = NULL;    // Source CFStringRef for preferences.plist and NetworkInterfaces.plist
-       SCPreferencesRef sourceNetworkInterfacePrefs = NULL;    // Source SCPreferencesRef for preferences.plist and NetworkInterfaces.plist
-       CFURLRef sourcePreferencesFile = NULL;
-       char sourcePreferencesFileStr[PATH_MAX];
-       CFStringRef sourcePreferencesFileString = NULL;
-       SCPreferencesRef sourcePrefs = NULL;
-       CFStringRef suffix;
-       CFArrayRef targetConfigurationFiles = NULL;             // Path to the target configuration files where migration will take place to
-       Boolean targetConfigurationFilesPresent;
-       CFStringRef targetModel = NULL;
-       CFURLRef targetNetworkInterfaceFile = NULL;             // Target CFURLRef for preferences.plist and NetworkInterfaces.plist
-       char targetNetworkInterfaceFileStr[PATH_MAX];
-       CFStringRef targetNetworkInterfaceFileString = NULL;    // Target CFStringRef for preferences.plist and NetworkInterfaces.plist
-       SCPreferencesRef targetNetworkInterfacePrefs = NULL;    // Target SCPreferencesRef for preferences.plist and NetworkInterfaces.plist
-       CFURLRef targetPreferencesFile = NULL;
-       char targetPreferencesFileStr[PATH_MAX];
-       CFStringRef targetPreferencesFileString = NULL;
-       SCPreferencesRef targetPrefs = NULL;
-       Boolean isUpgradeScenario = FALSE;
-       CFMutableDictionaryRef validityOptions = NULL;
-
-       SC_log(LOG_INFO,
-              "_SCNetworkConfigurationMigrateConfiguration() called"
-              "\n  sourceDir = %@"
-              "\n  targetDir = %@",
-              sourceDir,
-              targetDir);
+       CFDictionaryRef         bsdNameMapping                          = NULL; // Mapping between BSD name and SCNetworkInterfaceRef to help with mapping services
+       CFMutableDictionaryRef  builtinMapping                          = NULL; // Mapping between builtin interfaces between source and target configurations: (SCNetworkInterfaceRef -> SCNetworkInterfaceRef)
+       CFMutableDictionaryRef  externalMapping                         = NULL; // Mapping between external interfaces between source and target configurations: (SCNetworkInterfaceRef -> SCNetworkInterfaceRef)
+       Boolean                 migrationSuccess                        = FALSE;
+       CFArrayRef              newTargetNetworkInterfaceEntity         = NULL; // Array of Interface Entity which used to create new target interfaces created during migration
+       CFDictionaryRef         serviceMapping                          = NULL; // Mapping between services of source to target. (SCNetworkServicesRef -> SCNetworkServicesRef)
+       CFDictionaryRef         setMapping                              = NULL;
+       CFDictionaryRef         sourceServiceSetMapping                 = NULL;
+       CFArrayRef              sourceConfigurationFiles                = NULL; // Path to the source configuration files which need to be migrated
+       CFStringRef             sourceModel                             = NULL;
+       CFURLRef                sourceNetworkInterfaceFile              = NULL; // Source CFURLRef for preferences.plist and NetworkInterfaces.plist
+       char                    sourceNetworkInterfaceFileStr[PATH_MAX];
+       CFStringRef             sourceNetworkInterfaceFileString        = NULL; // Source CFStringRef for preferences.plist and NetworkInterfaces.plist
+       SCPreferencesRef        sourceNetworkInterfacePrefs             = NULL; // Source SCPreferencesRef for preferences.plist and NetworkInterfaces.plist
+       CFURLRef                sourcePreferencesFile                   = NULL;
+       char                    sourcePreferencesFileStr[PATH_MAX];
+       CFStringRef             sourcePreferencesFileString             = NULL;
+       SCPreferencesRef        sourcePrefs                             = NULL;
+       CFStringRef             suffix;
+       CFArrayRef              targetConfigurationFiles                = NULL; // Path to the target configuration files where migration will take place to
+       Boolean                 targetConfigurationFilesPresent;
+       CFStringRef             targetModel                             = NULL;
+       CFURLRef                targetNetworkInterfaceFile              = NULL; // Target CFURLRef for preferences.plist and NetworkInterfaces.plist
+       char                    targetNetworkInterfaceFileStr[PATH_MAX];
+       CFStringRef             targetNetworkInterfaceFileString        = NULL; // Target CFStringRef for preferences.plist and NetworkInterfaces.plist
+       SCPreferencesRef        targetNetworkInterfacePrefs             = NULL; // Target SCPreferencesRef for preferences.plist and NetworkInterfaces.plist
+       CFURLRef                targetPreferencesFile                   = NULL;
+       char                    targetPreferencesFileStr[PATH_MAX];
+       CFStringRef             targetPreferencesFileString             = NULL;
+       SCPreferencesRef        targetPrefs                             = NULL;
+       Boolean                 isUpgradeScenario                       = FALSE;
+       CFMutableDictionaryRef  validityOptions                         = NULL;
 
        // Check if configuration files exist in sourceDir
        if (!__SCNetworkConfigurationMigrateConfigurationFilesPresent(sourceDir, &sourceConfigurationFiles, TRUE)) {
        targetPreferencesFileString = CFStringCreateWithCString(NULL, targetPreferencesFileStr, kCFStringEncodingUTF8);
        targetNetworkInterfaceFileString = CFStringCreateWithCString(NULL, targetNetworkInterfaceFileStr, kCFStringEncodingUTF8);
 
-       SC_log(LOG_INFO,
-              "Migrating network configuration:"
-              "\n  target configuration files %s present"
-              "\n  target preferences.plist path       = %@"
-              "\n  target NetworkInterfaces.plist path = %@",
-              targetConfigurationFilesPresent ? "are" : "are not",
-              targetPreferencesFileString,
-              targetNetworkInterfaceFileString);
-
        if (targetConfigurationFilesPresent) {
                targetPrefs = SCPreferencesCreate(NULL, PLUGIN_ID, targetPreferencesFileString);
                targetNetworkInterfacePrefs = SCPreferencesCreate(NULL, PLUGIN_ID, targetNetworkInterfaceFileString);
                                                    &kCFTypeDictionaryValueCallBacks);
        CFDictionaryAddValue(validityOptions, kSCNetworkConfigurationRepair, kCFBooleanTrue);
 
-       SC_log(LOG_INFO,
-              "Migrating network configuration:"
-              "\n  sourcePrefs                 = %@"
-              "\n  sourceNetworkInterfacePrefs = %@"
-              "\n  targetPrefs                 = %@"
-              "\n  targetNetworkInterfacePrefs = %@",
-              sourcePrefs,
-              sourceNetworkInterfacePrefs,
-              targetPrefs,
-              targetNetworkInterfacePrefs);
-
        // Setting Bypass Interface to avoid looking at system interfaces
        _SCNetworkConfigurationSetBypassSystemInterfaces(sourcePrefs, TRUE);
        _SCNetworkConfigurationSetBypassSystemInterfaces(targetPrefs, TRUE);
 
        sourceModel = SCPreferencesGetValue(sourcePrefs, MODEL);
        targetModel = SCPreferencesGetValue(targetPrefs, MODEL);
-
-       isUpgradeScenario = (isA_CFString(sourceModel) && isA_CFString(targetModel) && CFStringCompare(sourceModel, targetModel, 0) == kCFCompareEqualTo);
+       isUpgradeScenario = (isA_CFString(sourceModel) && isA_CFString(targetModel) && CFEqual(sourceModel, targetModel));
        if (isUpgradeScenario) {
                SC_log(LOG_NOTICE, "Migrating network configuration: performing an \"upgrade\"");
        } else {
                SC_log(LOG_NOTICE, "Migrating network configuration: performing a \"migration\"");
        }
 
+       SC_log(LOG_INFO,
+                "  sourcePrefs                 = %@"
+              "\n  sourceNetworkInterfacePrefs = %@"
+              "\n  targetPrefs                 = %@%s"
+              "\n  targetNetworkInterfacePrefs = %@%s",
+              sourcePrefs,
+              sourceNetworkInterfacePrefs,
+              targetPrefs,
+              targetConfigurationFilesPresent ? "" : ", new",
+              targetNetworkInterfacePrefs,
+              targetConfigurationFilesPresent ? "" : ", new");
+
        // create backup of migration source
        suffix = CFStringCreateWithFormat(NULL, NULL,
                                          CFSTR("pre-%s-source"),
                        // create BSD name mapping to facilitate mapping of services
                        bsdNameMapping = _SCNetworkMigrationCreateBSDNameMapping(NULL, externalMapping);
 
-                       serviceMapping = _SCNetworkMigrationCreateServiceMappingUsingBSDMapping(upgradeSourcePrefs, targetPrefs, bsdNameMapping);
+                       serviceMapping = _SCNetworkMigrationCreateServiceMappingUsingBSDNameMapping(upgradeSourcePrefs, targetPrefs, bsdNameMapping);
 
+                       logConfiguration("Source", upgradeSourcePrefs);
+                       logConfiguration("Target", targetPrefs);
                        _SCNetworkMigrationDoServiceMigration(upgradeSourcePrefs,
                                                              targetPrefs,
                                                              serviceMapping,
                                                              bsdNameMapping,
                                                              NULL,
                                                              NULL);
+                       logConfiguration("Updated", targetPrefs);
                }
                CFRelease(upgradeSourcePrefs);
                CFRelease(upgradeSourceNIPrefs);
                builtinMapping = _SCNetworkConfigurationCopyBuiltinMapping(sourceNetworkInterfacePrefs, targetNetworkInterfacePrefs);
 
                externalMapping = _SCNetworkConfigurationCopyExternalInterfaceMapping(sourceNetworkInterfacePrefs, targetNetworkInterfacePrefs);
-               SC_log(LOG_INFO,
-                      "Migrating, external interface mapping: %@",
-                      externalMapping);
 
                newTargetNetworkInterfaceEntity = _SCNetworkMigrationCreateNetworkInterfaceArray(targetNetworkInterfacePrefs, externalMapping, NULL);
                if (newTargetNetworkInterfaceEntity == NULL) {
                // create BSD name mapping to facilitate mapping of services
                bsdNameMapping = _SCNetworkMigrationCreateBSDNameMapping(builtinMapping, externalMapping);
 
-               serviceMapping = _SCNetworkMigrationCreateServiceMappingUsingBSDMapping(sourcePrefs, targetPrefs, bsdNameMapping);
+               serviceMapping = _SCNetworkMigrationCreateServiceMappingUsingBSDNameMapping(sourcePrefs, targetPrefs, bsdNameMapping);
                if (serviceMapping == NULL) {
                        goto done;
                }
 
                sourceServiceSetMapping = _SCNetworkMigrationCreateServiceSetMapping(sourcePrefs);
 
-               // Perform the migration of services
-               if (!_SCNetworkMigrationDoServiceMigration(sourcePrefs, targetPrefs,
-                                                         serviceMapping, bsdNameMapping,
-                                                         setMapping, sourceServiceSetMapping)) {
+               logConfiguration("Source", sourcePrefs);
+               logConfiguration("Target", targetPrefs);
+               if (!_SCNetworkMigrationDoServiceMigration(sourcePrefs,
+                                                          targetPrefs,
+                                                          serviceMapping,
+                                                          bsdNameMapping,
+                                                          setMapping,
+                                                          sourceServiceSetMapping)) {
                        SC_log(LOG_NOTICE, "SCNetworkMigrationDoServiceMigration(): service migration failed");
                        goto done;
                }
-
 #if    !TARGET_OS_IPHONE
-               // Migrating Virtual Network Interface
+               // Migrating Virtual Network Interfaces
                if (!_SCNetworkMigrationDoVirtualNetworkInterfaceMigration(sourcePrefs, sourceNetworkInterfacePrefs,
                                                                          targetPrefs, targetNetworkInterfacePrefs,
                                                                          bsdNameMapping, setMapping, sourceServiceSetMapping)) {
                if (!_SCNetworkMigrationDoServiceOrderMigration(sourcePrefs, targetPrefs, setMapping)) {
                        SC_log(LOG_NOTICE, "SCNetworkMigrationDoServiceMigration(): service order migration failed");
                }
+               logConfiguration("Migrated", targetPrefs);
        }
 
 skipServiceMigration:
 
 /*
- * Copyright (c) 2003-2019 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 #include <net/if_dl.h>
 #include <net/if_types.h>
 #include <net/network_agent.h>
+#include <os/overflow.h>
 
 #include <CoreFoundation/CoreFoundation.h>
 #include <CoreFoundation/CFRuntime.h>
 static void            __SCNetworkReachabilityDeallocate       (CFTypeRef cf);
 
 static SCNetworkReachabilityFlags
-__SCNetworkReachabilityGetFlagsFromPath(nw_path_t                      path,
+__SCNetworkReachabilityGetFlagsFromPath(const char                     *prefix,
+                                       const char                      *caller,
+                                       nw_path_t                       path,
                                        ReachabilityAddressType         type,
                                        nw_resolver_status_t            resolverStatus,
                                        nw_array_t                      resolvedEndpoints,
 __SCNetworkReachabilityCopyTargetFlags(SCNetworkReachabilityRef target)
 {
        CFAllocatorRef                  allocator       = CFGetAllocator(target);
+       SCNetworkReachabilityFlags      flags;
+       unsigned int                    if_index;
        CFStringRef                     str;
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 
+       flags = __SCNetworkReachabilityGetFlagsFromPath(targetPrivate->log_prefix,
+                                                       "CopyTargetFlags",
+                                                       targetPrivate->lastPath,
+                                                       targetPrivate->type,
+                                                       targetPrivate->lastResolverStatus,
+                                                       targetPrivate->lastResolvedEndpoints,
+                                                       targetPrivate->lastResolvedEndpointHasFlags,
+                                                       targetPrivate->lastResolvedEndpointFlags);
+       if_index = targetPrivate->lastResolvedEndpointHasFlags ? targetPrivate->lastResolvedEndpointInterfaceIndex
+                                                              : nw_path_get_interface_index(targetPrivate->lastPath);
        str = CFStringCreateWithFormat(allocator,
                                       NULL,
                                       CFSTR("flags = 0x%08x, if_index = %u"),
-                                      __SCNetworkReachabilityGetFlagsFromPath(targetPrivate->lastPath,
-                                                                              targetPrivate->type,
-                                                                              targetPrivate->lastResolverStatus,
-                                                                              targetPrivate->lastResolvedEndpoints,
-                                                                              targetPrivate->lastResolvedEndpointHasFlags,
-                                                                              targetPrivate->lastResolvedEndpointFlags),
-                                      targetPrivate->lastResolvedEndpointHasFlags ? targetPrivate->lastResolvedEndpointInterfaceIndex
-                                                                                  : nw_path_get_interface_index(targetPrivate->lastPath));
+                                      flags,
+                                      if_index);
        return str;
 }
 
 __SCNetworkReachabilityGetAgentVPNFlags(xpc_object_t dictionary, Boolean *vpn, Boolean *onDemand)
 {
        const struct netagent *agent = NULL;
+       size_t expected = 0;
        size_t length = 0;
 
        if (dictionary == NULL || vpn == NULL || onDemand == NULL) {
        *onDemand = FALSE;
 
        agent = xpc_dictionary_get_data(dictionary, REACHABILITY_AGENT_DATA_KEY, &length);
-       if (agent == NULL || length < sizeof(struct netagent) || length != (sizeof(struct netagent) + agent->netagent_data_size)) {
+       if ((agent == NULL) ||
+           (length < sizeof(struct netagent)) ||
+           os_add_overflow(sizeof(struct netagent), agent->netagent_data_size, &expected) ||
+           (length != expected)) {
                return;
        }
 
 }
 
 static SCNetworkReachabilityFlags
-__SCNetworkReachabilityGetFlagsFromPath(nw_path_t                      path,
+__SCNetworkReachabilityGetFlagsFromPath(const char                     *log_prefix,
+                                       const char                      *caller,
+                                       nw_path_t                       path,
                                        ReachabilityAddressType         type,
                                        nw_resolver_status_t            resolverStatus,
                                        nw_array_t                      resolvedEndpoints,
 #endif // TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR
                }
        }
-       SC_log(LOG_DEBUG, "__SCNetworkReachabilityGetFlagsFromPath, flags = 0x%08x, %s", flags, why);
+
+       SC_log(LOG_DEBUG, "%s__SCNetworkReachabilityGetFlagsFromPath(%s), flags = 0x%08x, %s",
+              log_prefix,
+              caller,
+              flags,
+              why);
+
        return (flags & kSCNetworkReachabilityFlagsMask);
 }
 
 
        MUTEX_LOCK(&targetPrivate->lock);
 
-       flags = __SCNetworkReachabilityGetFlagsFromPath(targetPrivate->lastPath,
+       flags = __SCNetworkReachabilityGetFlagsFromPath(targetPrivate->log_prefix,
+                                                       "GetInterfaceIndex",
+                                                       targetPrivate->lastPath,
                                                        targetPrivate->type,
                                                        nw_resolver_status_invalid,
                                                        NULL,
        nw_path_t retPath = NULL;
        const struct sockaddr *sa;
 
-       if ((nw_path_get_status(path) != nw_path_status_unsatisfied) ||
+       if ((path == NULL) ||
+           (nw_path_get_status(path) != nw_path_status_unsatisfied) ||
            (NULL == endpoint) || (nw_endpoint_get_type(endpoint) != nw_endpoint_type_address)) {
                return NULL;
        }
 
        if (targetPrivate->scheduled) {
                // if being watched, return the last known (and what should be current) status
-               *flags = __SCNetworkReachabilityGetFlagsFromPath(targetPrivate->lastPath,
+               *flags = __SCNetworkReachabilityGetFlagsFromPath(targetPrivate->log_prefix,
+                                                                "GetFlags",
+                                                                targetPrivate->lastPath,
                                                                 targetPrivate->type,
                                                                 targetPrivate->lastResolverStatus,
                                                                 targetPrivate->lastResolvedEndpoints,
                }
        }
 
-       *flags = __SCNetworkReachabilityGetFlagsFromPath(path, 0, nw_resolver_status_invalid, NULL, FALSE, 0);
+       *flags = __SCNetworkReachabilityGetFlagsFromPath(targetPrivate->log_prefix,
+                                                        "GetFlags",
+                                                        path,
+                                                        0,
+                                                        nw_resolver_status_invalid,
+                                                        NULL,
+                                                        FALSE,
+                                                        0);
        nw_release(path);
        nw_release(pathEvaluator);
 
                context_release = NULL;
        }
 
-       flags = __SCNetworkReachabilityGetFlagsFromPath(targetPrivate->lastPath,
+       flags = __SCNetworkReachabilityGetFlagsFromPath(targetPrivate->log_prefix,
+                                                       "Perform",
+                                                       targetPrivate->lastPath,
                                                        targetPrivate->type,
                                                        targetPrivate->lastResolverStatus,
                                                        targetPrivate->lastResolvedEndpoints,
 }
 
 static __inline__ void
-__SCNetworkReachabilityCopyPathStatus(SCNetworkReachabilityPrivateRef targetPrivate, SCNetworkReachabilityFlags *flags, uint *ifIndex, size_t *endpointCount)
+__SCNetworkReachabilityCopyPathStatus(SCNetworkReachabilityPrivateRef  targetPrivate,
+                                     const char                        *caller,
+                                     SCNetworkReachabilityFlags        *flags,
+                                     uint                              *ifIndex,
+                                     size_t                            *endpointCount)
 {
        if (flags) {
-               *flags = __SCNetworkReachabilityGetFlagsFromPath(targetPrivate->lastPath,
+               *flags = __SCNetworkReachabilityGetFlagsFromPath(targetPrivate->log_prefix,
+                                                                caller,
+                                                                targetPrivate->lastPath,
                                                                 targetPrivate->type,
                                                                 targetPrivate->lastResolverStatus,
                                                                 targetPrivate->lastResolvedEndpoints,
 static __inline__ Boolean
 __SCNetworkReachabilityShouldUpdateClient(SCNetworkReachabilityPrivateRef targetPrivate, SCNetworkReachabilityFlags oldFlags, uint oldIFIndex, size_t oldEndpointCount)
 {
-       SCNetworkReachabilityFlags newFlags = 0;
-       uint newIFIndex = 0;
-       size_t newEndpointCount = 0;
-       __SCNetworkReachabilityCopyPathStatus(targetPrivate, &newFlags, &newIFIndex, &newEndpointCount);
+       SCNetworkReachabilityFlags      newFlags                = 0;
+       uint                            newIFIndex              = 0;
+       size_t                          newEndpointCount        = 0;
+
+       __SCNetworkReachabilityCopyPathStatus(targetPrivate,
+                                             "ShouldUpdateClient",
+                                             &newFlags,
+                                             &newIFIndex,
+                                             &newEndpointCount);
        return (!targetPrivate->sentFirstUpdate ||
                oldFlags != newFlags ||
                oldIFIndex != newIFIndex ||
 }
 
 static void
-__SCNetworkReachabilityRestartResolver(SCNetworkReachabilityPrivateRef targetPrivate)
+__SCNetworkReachabilityRestartResolver(SCNetworkReachabilityPrivateRef targetPrivate, const char *caller)
 {
        if (targetPrivate &&
            !targetPrivate->resolverBypass &&
                if (!nw_resolver_set_update_handler(resolver, targetPrivate->dispatchQueue, ^(nw_resolver_status_t status, nw_array_t resolved_endpoints) {
                        MUTEX_LOCK(&targetPrivate->lock);
                        if (targetPrivate->scheduled) {
-                               SCNetworkReachabilityFlags oldFlags = 0;
-                               uint oldIFIndex = 0;
-                               size_t oldEndpointCount = 0;
-                               __SCNetworkReachabilityCopyPathStatus(targetPrivate, &oldFlags, &oldIFIndex, &oldEndpointCount);
+                               SCNetworkReachabilityFlags      oldFlags                = 0;
+                               uint                            oldIFIndex              = 0;
+                               size_t                          oldEndpointCount        = 0;
+
+                               __SCNetworkReachabilityCopyPathStatus(targetPrivate,
+                                                                     caller,
+                                                                     &oldFlags,
+                                                                     &oldIFIndex,
+                                                                     &oldEndpointCount);
 
                                targetPrivate->lastResolverStatus = status;
                                nw_release(targetPrivate->lastResolvedEndpoints);
                                targetPrivate->lastResolvedEndpointFlags = 0;
                                targetPrivate->lastResolvedEndpointInterfaceIndex = 0;
                                nw_array_apply(targetPrivate->lastResolvedEndpoints, ^bool(size_t index, nw_object_t object) {
-#pragma unused(index)
-                                       SCNetworkReachabilityFlags flags = 0;
-                                       uint interfaceIndex = 0;
-                                       ReachabilityRankType rank;
-                                       nw_endpoint_t resolvedEndpoint = (nw_endpoint_t)object;
-                                       nw_path_evaluator_t pathEvaluator = nw_path_create_evaluator_for_endpoint(resolvedEndpoint, targetPrivate->lastPathParameters ? targetPrivate->lastPathParameters : targetPrivate->parameters);
-                                       nw_path_t path = nw_path_evaluator_copy_path(pathEvaluator);
+                                       SCNetworkReachabilityFlags      flags                   = 0;
+                                       unsigned int                    interfaceIndex          = 0;
+                                       ReachabilityRankType            rank;
+                                       nw_endpoint_t                   resolvedEndpoint        = (nw_endpoint_t)object;
+                                       nw_path_t                       path;
+                                       nw_path_evaluator_t             pathEvaluator;
+
+                                       pathEvaluator = nw_path_create_evaluator_for_endpoint(resolvedEndpoint,
+                                                                                             targetPrivate->lastPathParameters ? targetPrivate->lastPathParameters
+                                                                                                                               : targetPrivate->parameters);
+                                       path = nw_path_evaluator_copy_path(pathEvaluator);
                                        if (path != NULL) {
-                                               flags = __SCNetworkReachabilityGetFlagsFromPath(path, 0, nw_resolver_status_invalid, NULL, FALSE, 0);
+                                               char                    *e_caller       = NULL;
+                                               nw_endpoint_type_t      e_type;
+                                               int                     ret             = 0;
+
+                                               // Update the log prefix to note both the "target" [address] and the "endpoint"
+
+                                               e_type = nw_endpoint_get_type(resolvedEndpoint);
+                                               switch (e_type) {
+                                                       case nw_endpoint_type_host :
+                                                       case nw_endpoint_type_url : {
+                                                               const char      *hostname;
+
+                                                               hostname = nw_endpoint_get_hostname(resolvedEndpoint);
+                                                               if (hostname != NULL) {
+                                                                       ret = asprintf(&e_caller, "endpoint %zd, %s",
+                                                                                      index,
+                                                                                      hostname);
+                                                               }
+                                                               break;
+                                                       }
+                                                       case nw_endpoint_type_address : {
+                                                               const struct sockaddr   *addr;
+
+                                                               addr = nw_endpoint_get_address(resolvedEndpoint);
+                                                               if (addr != NULL) {
+                                                                       char    buf[128];
+
+                                                                       _SC_sockaddr_to_string(addr, buf, sizeof(buf));
+                                                                       ret = asprintf(&e_caller, "endpoint %zd, %s",
+                                                                                      index,
+                                                                                      buf);
+                                                               }
+                                                               break;
+                                                       }
+                                                       default : {
+                                                               ret = asprintf(&e_caller, "endpoint %zd, ?",
+                                                                              index);
+                                                               break;
+                                                       }
+                                               }
+                                               if ((ret < 0) && (e_caller != NULL)) {
+                                                       free(e_caller);
+                                                       e_caller = NULL;
+                                               }
+
+                                               flags = __SCNetworkReachabilityGetFlagsFromPath(targetPrivate->log_prefix,
+                                                                                               e_caller != NULL ? e_caller : "",
+                                                                                               path,
+                                                                                               0,
+                                                                                               nw_resolver_status_invalid,
+                                                                                               NULL,
+                                                                                               FALSE,
+                                                                                               0);
                                                hasFlags = TRUE;
+
+                                               if (e_caller != NULL) {
+                                                       free(e_caller);
+                                               }
                                        }
                                        interfaceIndex = nw_path_get_interface_index(path);
                                        nw_release(path);
                targetPrivate->lastResolverStatus = nw_resolver_status_invalid;
                nw_release(targetPrivate->lastResolvedEndpoints);
                targetPrivate->lastResolvedEndpoints = NULL;
-               __SCNetworkReachabilityRestartResolver(targetPrivate);
+               __SCNetworkReachabilityRestartResolver(targetPrivate, "Scheduled, start DNS");
 
                CFRetain(targetPrivate);
                nw_path_evaluator_set_cancel_handler(pathEvaluator, ^(void) {
                if (!nw_path_evaluator_set_update_handler(pathEvaluator, targetPrivate->dispatchQueue, ^(nw_path_t path) {
                        MUTEX_LOCK(&targetPrivate->lock);
                        if (targetPrivate->scheduled) {
-                               nw_path_t crazyIvanPath;
-                               SCNetworkReachabilityFlags oldFlags = 0;
-                               uint oldIFIndex = 0;
-                               size_t oldEndpointCount = 0;
-                               __SCNetworkReachabilityCopyPathStatus(targetPrivate, &oldFlags, &oldIFIndex, &oldEndpointCount);
+                               nw_path_t                       crazyIvanPath;
+                               SCNetworkReachabilityFlags      oldFlags                = 0;
+                               uint                            oldIFIndex              = 0;
+                               size_t                          oldEndpointCount        = 0;
+
+                               __SCNetworkReachabilityCopyPathStatus(targetPrivate,
+                                                                     "Path updated",
+                                                                     &oldFlags,
+                                                                     &oldIFIndex,
+                                                                     &oldEndpointCount);
 
                                nw_release(targetPrivate->lastPath);
                                targetPrivate->lastPath = nw_retain(path);
 
                                if (targetPrivate->lastResolverStatus == nw_resolver_status_complete) {
                                        targetPrivate->lastResolverStatus = nw_resolver_status_invalid;
-                                       __SCNetworkReachabilityRestartResolver(targetPrivate);
+                                       __SCNetworkReachabilityRestartResolver(targetPrivate, "Path updated, restart DNS");
                                }
 
                                if (__SCNetworkReachabilityShouldUpdateClient(targetPrivate, oldFlags, oldIFIndex, oldEndpointCount)) {
 
                service = CFArrayGetValueAtIndex(services, idx);
                interface = SCNetworkServiceGetInterface(service);
 
-               if (isA_SCNetworkInterface(interface) == NULL) {
+               if (!isA_SCNetworkInterface(interface)) {
                        continue;
                }
                CFArrayAppendValue(interfaces, interface);
 Boolean
 __SCNetworkServiceMigrateNew(SCPreferencesRef          prefs,
                             SCNetworkServiceRef        service,
-                            CFDictionaryRef            bsdMapping,
+                            CFDictionaryRef            bsdNameMapping,
                             CFDictionaryRef            setMapping,
                             CFDictionaryRef            serviceSetMapping)
 {
-       CFStringRef deviceName = NULL;
-       Boolean enabled;
-       SCNetworkInterfaceRef interface = NULL;
-       CFDictionaryRef interfaceEntity = NULL;
-       CFMutableDictionaryRef interfaceEntityMutable = NULL;
-       SCNetworkSetRef newSet = NULL;
-       SCPreferencesRef ni_prefs = NULL;
-       SCNetworkInterfaceRef ni_interface = NULL;
-       SCNetworkInterfaceRef oldInterface = NULL;
-       SCNetworkSetRef oldSet = NULL;
-       SCNetworkServiceRef newService = NULL;
-       CFStringRef serviceID = NULL;
-       SCNetworkServicePrivateRef servicePrivate = (SCNetworkServicePrivateRef) service;
-       CFArrayRef setList = NULL;
-       Boolean success = FALSE;
-       CFStringRef targetDeviceName = NULL;
-       CFStringRef userDefinedName = NULL;
-       CFStringRef userDefinedNameInterface = NULL;
-       CFArrayRef protocols = NULL;
-       CFStringRef subType;
-
-       if ((isA_SCNetworkService(service) == NULL) ||
-       (isA_SCNetworkInterface(servicePrivate->interface) == NULL) ||
-       (servicePrivate->prefs == NULL)) {
+       CFStringRef                     deviceName                      = NULL;
+       Boolean                         enabled;
+       SCNetworkInterfaceRef           interface                       = NULL;
+       CFDictionaryRef                 interfaceEntity                 = NULL;
+       CFMutableDictionaryRef          interfaceEntityMutable          = NULL;
+       SCNetworkSetRef                 newSet                          = NULL;
+       SCPreferencesRef                ni_prefs                        = NULL;
+       SCNetworkInterfaceRef           ni_interface                    = NULL;
+       SCNetworkInterfaceRef           newInterface                    = NULL;
+       SCNetworkServiceRef             newService                      = NULL;
+       SCNetworkSetRef                 oldSet                          = NULL;
+       CFStringRef                     serviceID                       = NULL;
+       SCNetworkServicePrivateRef      servicePrivate                  = (SCNetworkServicePrivateRef)service;
+       CFArrayRef                      setList                         = NULL;
+       Boolean                         success                         = FALSE;
+       CFStringRef                     targetDeviceName                = NULL;
+       CFStringRef                     userDefinedName                 = NULL;
+       CFStringRef                     userDefinedNameInterface        = NULL;
+       CFArrayRef                      protocols                       = NULL;
+       CFStringRef                     subType;
+
+       if (!isA_SCNetworkService(service) ||
+           !isA_SCNetworkInterface(servicePrivate->interface) ||
+           (servicePrivate->prefs == NULL)) {
                goto done;
        }
        serviceID = servicePrivate->serviceID;
                goto done;
        }
 
-       oldInterface = SCNetworkServiceGetInterface(service);
-       interfaceEntity = __SCNetworkInterfaceCopyInterfaceEntity(oldInterface);
+       interface = SCNetworkServiceGetInterface(service);
+       if (interface == NULL) {
+               SC_log(LOG_INFO, "No interface");
+               goto done;
+       }
+
+       interfaceEntity = __SCNetworkInterfaceCopyInterfaceEntity(interface);
        if (interfaceEntity == NULL) {
                SC_log(LOG_INFO, "No interface entity");
                goto done;
        }
        interfaceEntityMutable = CFDictionaryCreateMutableCopy(NULL, 0, interfaceEntity);
+       CFRelease(interfaceEntity);
 
-       if (isA_CFDictionary(bsdMapping) != NULL) {
+       if (isA_CFDictionary(bsdNameMapping) != NULL) {
                deviceName = CFDictionaryGetValue(interfaceEntityMutable, kSCPropNetInterfaceDeviceName);
                if (isA_CFString(deviceName) != NULL) {
-                       targetDeviceName = CFDictionaryGetValue(bsdMapping, deviceName);
+                       targetDeviceName = CFDictionaryGetValue(bsdNameMapping, deviceName);
                        if (targetDeviceName != NULL) {
                                // update mapping
                                CFDictionarySetValue(interfaceEntityMutable, kSCPropNetInterfaceDeviceName, targetDeviceName);
                        userDefinedNameInterface = CFDictionaryGetValue(interfaceEntityMutable, kSCPropUserDefinedName);
                }
        }
-       subType = CFDictionaryGetValue(interfaceEntityMutable, kSCPropNetInterfaceSubType);
-       interface = _SCNetworkInterfaceCreateWithEntity(NULL, interfaceEntityMutable, NULL);
+       newInterface = _SCNetworkInterfaceCreateWithEntity(NULL,
+                                                          interfaceEntityMutable,
+                                                          __kSCNetworkInterfaceSearchExternal);
        if (userDefinedNameInterface != NULL) {
-               __SCNetworkInterfaceSetUserDefinedName(interface, userDefinedNameInterface);
+               __SCNetworkInterfaceSetUserDefinedName(newInterface, userDefinedNameInterface);
        }
+
        // Supporting PPPoE subtype
+       subType = CFDictionaryGetValue(interfaceEntityMutable, kSCPropNetInterfaceSubType);
        if (subType != NULL &&
            CFEqual(subType, kSCValNetInterfaceSubTypePPPoE)) {
-               SCNetworkInterfaceRef childInterface = SCNetworkInterfaceGetInterface(interface);
+               SCNetworkInterfaceRef childInterface = SCNetworkInterfaceGetInterface(newInterface);
                if (childInterface != NULL) {
                        __SCNetworkInterfaceSetUserDefinedName(childInterface, userDefinedNameInterface);
                }
        }
-       newService = SCNetworkServiceCreate(prefs, interface);
+
+       newService = SCNetworkServiceCreate(prefs, newInterface);
        if (newService == NULL) {
                SC_log(LOG_INFO, "SCNetworkServiceCreate() failed");
                goto done;
        copyInterfaceConfiguration(service, newService);
 
        success = TRUE;
-done:
-       if (interface != NULL) {
-               CFRelease(interface);
-       }
-       if (interfaceEntity != NULL) {
-               CFRelease(interfaceEntity);
+
+    done:
+
+       if (newInterface != NULL) {
+               CFRelease(newInterface);
        }
        if (interfaceEntityMutable != NULL) {
                CFRelease(interfaceEntityMutable);
 
        if (setPrivate->name != NULL) {
                CFStringAppendFormat(result, NULL, CFSTR(", name = %@"), setPrivate->name);
        }
+       if (setPrivate->established) {
+               CFStringAppendFormat(result, NULL, CFSTR(", new"));
+       }
        if (!__SCNetworkSetExists(set)) {
                CFStringAppendFormat(result, NULL, CFSTR(", REMOVED"));
        }
 #pragma mark -
 
 
-static int
+static CFIndex
 _serviceOrder(SCNetworkServiceRef service)
 {
        SCNetworkInterfaceRef   interface;
 {
        CFIndex                 n;
        CFMutableArrayRef       newOrder;
+       CFIndex                 newSlot;
        CFArrayRef              order;
        CFStringRef             serviceID       = SCNetworkServiceGetServiceID(service);
        CFIndex                 serviceOrder    = _serviceOrder(service);
        SCNetworkSetPrivateRef  setPrivate      = (SCNetworkSetPrivateRef)set;
-       CFIndex                 slot;
 
        order = SCNetworkSetGetServiceOrder(set);
        if (order != NULL) {
                _SC_crash_once("SCNetworkSetAddService() w/service already in ServiceOrder", NULL, NULL);
        }
 
-       slot = 0;
+       newSlot = 0;
        n = CFArrayGetCount(newOrder);
        for (CFIndex i = 0; i < n; i++) {
-               int                     slotOrder;
+               CFIndex                 slotOrder;
                SCNetworkServiceRef     slotService;
                CFStringRef             slotServiceID;
 
                slotOrder = _serviceOrder(slotService);
                if (serviceOrder >= slotOrder) {
                        // add the service *after* this one
-                       slot = i + 1;
+                       newSlot = i + 1;
                }
 
                CFRelease(slotService);
        }
 
-       CFArrayInsertValueAtIndex(newOrder, slot, serviceID);
+       CFArrayInsertValueAtIndex(newOrder, newSlot, serviceID);
        (void) SCNetworkSetSetServiceOrder(set, newOrder);
        CFRelease(newOrder);
 
                       service);
                _SC_crash_once("SCNetworkSetAddService() w/removed set", NULL, NULL);
                _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
        }
 
        if (!__SCNetworkServiceExists(service)) {
        _serviceOrder_add(set, service);
 
        // mark set as no longer "new"
-       setPrivate->established = TRUE;
+       setPrivate->established = TRUE;
 
     done :
 
                SC_log(LOG_ERR, "SCNetworkSetRemove() w/removed set\n  set = %@", set);
                _SC_crash_once("SCNetworkSetRemove() w/removed set", NULL, NULL);
                _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
        }
 
 #if    TARGET_OS_IPHONE
                       service);
                _SC_crash_once("SCNetworkSetRemoveService() w/removed set", NULL, NULL);
                _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
        }
 
        if (!__SCNetworkServiceExists(service)) {
 
                                                             prefsNotify,
                                                             &context);
                if (prefsPrivate->session == NULL) {
-                       SC_log(LOG_INFO, "SCDynamicStoreCreate() failed");
+                       SC_log(LOG_ERR, "could not add SCDynamicStore session (for prefs): %s",
+                              SCErrorString(SCError()));
                        return FALSE;
                }
 
                keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
                CFArrayAppendValue(keys, prefsPrivate->sessionKeyCommit);
                CFArrayAppendValue(keys, prefsPrivate->sessionKeyApply);
-               (void) SCDynamicStoreSetNotificationKeys(prefsPrivate->session, keys, NULL);
+               ok = SCDynamicStoreSetNotificationKeys(prefsPrivate->session, keys, NULL);
                CFRelease(keys);
+               if (!ok) {
+                       SC_log(LOG_ERR, "could not set SCDynamicStore notification keys (for prefs): %s",
+                              SCErrorString(SCError()));
+                       goto done;
+               }
 
                if (runLoop != NULL) {
                        prefsPrivate->rls = SCDynamicStoreCreateRunLoopSource(NULL, prefsPrivate->session, 0);
+                       if (prefsPrivate->rls == NULL) {
+                               SC_log(LOG_ERR, "could not create SCDynamicStore runloop source (for prefs): %s",
+                                      SCErrorString(SCError()));
+                               ok = FALSE;
+                               goto done;
+                       }
                        prefsPrivate->rlList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
                }
 
 
 
 const CFStringRef kSCEntNet6to4                                    = CFSTR("6to4");
 const CFStringRef kSCEntNetAppLayer                                = CFSTR("AppLayer");
+const CFStringRef kSCEntNetCaptivePortal                           = CFSTR("CaptivePortal");
 
 
 const CFStringRef kSCEntNetEAPOL                                   = CFSTR("EAPOL");
 const CFStringRef kSCPropNetDNSConfirmedServiceID                  = CFSTR("ConfirmedServiceID");
 const CFStringRef kSCPropNetDNSServiceIdentifier                   = CFSTR("ServiceIdentifier");
 const CFStringRef kSCPropNetDNSSupplementalMatchDomainsNoSearch    = CFSTR("SupplementalMatchDomainsNoSearch");
+const CFStringRef kSCPropNetCaptivePortalURL                       = CFSTR("URL");
 const CFStringRef kSCPropNetEthernetMediaSubType                   = CFSTR("MediaSubType");
 const CFStringRef kSCPropNetEthernetMediaOptions                   = CFSTR("MediaOptions");
 const CFStringRef kSCPropNetEthernetMTU                            = CFSTR("MTU");
 const CFStringRef kSCValNetIPv4ConfigMethodManual                  = CFSTR("Manual");
 const CFStringRef kSCValNetIPv4ConfigMethodPPP                     = CFSTR("PPP");
 const CFStringRef kSCPropNetIPv4AdditionalRoutes                   = CFSTR("AdditionalRoutes");
+const CFStringRef kSCPropNetIPv4ARPResolvedHardwareAddress         = CFSTR("ARPResolvedHardwareAddress");
+const CFStringRef kSCPropNetIPv4ARPResolvedIPAddress               = CFSTR("ARPResolvedIPAddress");
 const CFStringRef kSCPropNetIPv4CLAT46                             = CFSTR("CLAT46");
 const CFStringRef kSCPropNetIPv4ExcludedRoutes                     = CFSTR("ExcludedRoutes");
 const CFStringRef kSCPropNetIPv4IncludedRoutes                     = CFSTR("IncludedRoutes");
 const CFStringRef kSCPropNetIPv4RouteSubnetMask                    = CFSTR("SubnetMask");
 const CFStringRef kSCPropNetIPv4RouteGatewayAddress                = CFSTR("GatewayAddress");
 const CFStringRef kSCPropNetIPv4RouteInterfaceName                 = CFSTR("InterfaceName");
-const CFStringRef kSCPropNetIPv4ARPResolvedHardwareAddress         = CFSTR("ARPResolvedHardwareAddress");
-const CFStringRef kSCPropNetIPv4ARPResolvedIPAddress               = CFSTR("ARPResolvedIPAddress");
 const CFStringRef kSCPropNetIPv6Addresses                          = CFSTR("Addresses");
 const CFStringRef kSCPropNetIPv6ConfigMethod                       = CFSTR("ConfigMethod");
 const CFStringRef kSCPropNetIPv6DestAddresses                      = CFSTR("DestAddresses");
 
  *   kSCPropNetIPv6Addresses                            "Addresses"                    CFArray[CFString]
  *   kSCPropNetIPv6ConfigMethod                         "ConfigMethod"                 CFString
  *   kSCPropNetIPv6DestAddresses                        "DestAddresses"                CFArray[CFString]
- *   kSCPropNetIPv6Flags                                "Flags"                        CFNumber
+ *   kSCPropNetIPv6Flags                                "Flags"                        CFArray[CFNumber]
  *   kSCPropNetIPv6PrefixLength                         "PrefixLength"                 CFArray[CFNumber]
  *   kSCPropNetIPv6Router                               "Router"                       CFString
  *
 
 /*!
   @const kSCPropNetIPv6Flags
-  @discussion Value is a CFNumber
+  @discussion Value is a CFArray[CFNumber]
  */
 extern const CFStringRef kSCPropNetIPv6Flags                                API_AVAILABLE(macos(10.3)) SPI_AVAILABLE(ios(2.0), tvos(9.0), watchos(1.0), bridgeos(1.0));
 #define kSCPropNetIPv6Flags kSCPropNetIPv6Flags
 
  * Network Entity Keys
  *
  *   kSCEntNetAppLayer                                  "AppLayer"                     CFDictionary
+ *   kSCEntNetCaptivePortal                             "CaptivePortal"                CFDictionary
  *   kSCEntNetCommCenter                                "com.apple.CommCenter"         CFDictionary
  *   kSCEntNetEAPOL                                     "EAPOL"                        CFDictionary
  *   kSCEntNetIdleRoute                                 "IdleRoute"
  *   kSCPropNetDNSServiceIdentifier                     "ServiceIdentifier"            CFNumber
  *   kSCPropNetDNSSupplementalMatchDomainsNoSearch      "SupplementalMatchDomainsNoSearch" CFNumber (0 or 1)
  *
+ * kSCEntNetCaptivePortal Entity Keys
+ *
+ *   kSCPropNetCaptivePortalURL                         "URL"                          CFString
+ *
  * kSCEntNetEthernet (Hardware) Entity Keys
  *
  *   kSCPropNetEthernetCapabilityAV                     "AV"                           CFNumber (0 or 1)
  * kSCEntNetIPv4 Entity Keys
  *
  *   kSCPropNetIPv4AdditionalRoutes                     "AdditionalRoutes"             CFArray[CFDictionary]
+ *   kSCPropNetIPv4ARPResolvedHardwareAddress           "ARPResolvedHardwareAddress"   CFString
+ *   kSCPropNetIPv4ARPResolvedIPAddress                 "ARPResolvedIPAddress"         CFString
  *   kSCPropNetIPv4CLAT46                               "CLAT46"                       CFBoolean
  *   kSCPropNetIPv4ExcludedRoutes                       "ExcludedRoutes"               CFArray[CFDictionary]
  *   kSCPropNetIPv4IncludedRoutes                       "IncludedRoutes"               CFArray[CFDictionary]
  *   kSCPropNetIPv4RouteGatewayAddress                  "GatewayAddress"               CFString
  *   kSCPropNetIPv4RouteInterfaceName                   "InterfaceName"                CFString
  *
- *   kSCPropNetIPv4ARPResolvedHardwareAddress           "ARPResolvedHardwareAddress"   CFString
- *   kSCPropNetIPv4ARPResolvedIPAddress                 "ARPResolvedIPAddress"         CFString
- *
  * kSCEntNetIPv6 Entity Keys
  *
  *   kSCPropNetIPv6AdditionalRoutes                     "AdditionalRoutes"             CFArray[CFDictionary]
 extern const CFStringRef kSCEntNetAppLayer                                  API_AVAILABLE(macos(10.9)) SPI_AVAILABLE(ios(7.0), tvos(9.0), watchos(1.0), bridgeos(1.0));
 #define kSCEntNetAppLayer kSCEntNetAppLayer
 
+/*!
+  @const kSCEntNetCaptivePortal
+  @discussion Value is a CFDictionary
+ */
+extern const CFStringRef kSCEntNetCaptivePortal                             SPI_AVAILABLE(macos(10.16), ios(14.0), tvos(14.0), watchos(7.0), bridgeos(5.0));
+#define kSCEntNetCaptivePortal kSCEntNetCaptivePortal
+
 /*!
   @const kSCEntNetCommCenter
   @discussion Value is a CFDictionary
 extern const CFStringRef kSCPropNetDNSSupplementalMatchDomainsNoSearch      API_AVAILABLE(macos(10.9)) SPI_AVAILABLE(ios(7.0), tvos(9.0), watchos(1.0), bridgeos(1.0));
 #define kSCPropNetDNSSupplementalMatchDomainsNoSearch kSCPropNetDNSSupplementalMatchDomainsNoSearch
 
+/*!
+  @group kSCEntNetCaptivePortal Entity Keys
+ */
+
+/*!
+  @const kSCPropNetCaptivePortalURL
+  @discussion Value is a CFString
+ */
+extern const CFStringRef kSCPropNetCaptivePortalURL                         SPI_AVAILABLE(macos(10.16), ios(14.0), tvos(14.0), watchos(7.0), bridgeos(5.0));
+#define kSCPropNetCaptivePortalURL kSCPropNetCaptivePortalURL
+
 /*!
   @group kSCEntNetEthernet (Hardware) Entity Keys
  */
 extern const CFStringRef kSCPropNetIPv4AdditionalRoutes                     API_AVAILABLE(macos(10.10)) SPI_AVAILABLE(ios(8.0), tvos(9.0), watchos(1.0), bridgeos(1.0));
 #define kSCPropNetIPv4AdditionalRoutes kSCPropNetIPv4AdditionalRoutes
 
+/*!
+  @const kSCPropNetIPv4ARPResolvedHardwareAddress
+  @discussion Value is a CFString
+ */
+extern const CFStringRef kSCPropNetIPv4ARPResolvedHardwareAddress           API_AVAILABLE(macos(10.7)) SPI_AVAILABLE(ios(5.0), tvos(9.0), watchos(1.0), bridgeos(1.0));
+#define kSCPropNetIPv4ARPResolvedHardwareAddress kSCPropNetIPv4ARPResolvedHardwareAddress
+
+/*!
+  @const kSCPropNetIPv4ARPResolvedIPAddress
+  @discussion Value is a CFString
+ */
+extern const CFStringRef kSCPropNetIPv4ARPResolvedIPAddress                 API_AVAILABLE(macos(10.7)) SPI_AVAILABLE(ios(5.0), tvos(9.0), watchos(1.0), bridgeos(1.0));
+#define kSCPropNetIPv4ARPResolvedIPAddress kSCPropNetIPv4ARPResolvedIPAddress
+
 /*!
   @const kSCPropNetIPv4CLAT46
   @discussion Value is a CFBoolean
 extern const CFStringRef kSCPropNetIPv4RouteInterfaceName                   API_AVAILABLE(macos(10.10)) SPI_AVAILABLE(ios(8.0), tvos(9.0), watchos(1.0), bridgeos(1.0));
 #define kSCPropNetIPv4RouteInterfaceName kSCPropNetIPv4RouteInterfaceName
 
-/*!
-  @const kSCPropNetIPv4ARPResolvedHardwareAddress
-  @discussion Value is a CFString
- */
-extern const CFStringRef kSCPropNetIPv4ARPResolvedHardwareAddress           API_AVAILABLE(macos(10.7)) SPI_AVAILABLE(ios(5.0), tvos(9.0), watchos(1.0), bridgeos(1.0));
-#define kSCPropNetIPv4ARPResolvedHardwareAddress kSCPropNetIPv4ARPResolvedHardwareAddress
-
-/*!
-  @const kSCPropNetIPv4ARPResolvedIPAddress
-  @discussion Value is a CFString
- */
-extern const CFStringRef kSCPropNetIPv4ARPResolvedIPAddress                 API_AVAILABLE(macos(10.7)) SPI_AVAILABLE(ios(5.0), tvos(9.0), watchos(1.0), bridgeos(1.0));
-#define kSCPropNetIPv4ARPResolvedIPAddress kSCPropNetIPv4ARPResolvedIPAddress
-
 /*!
   @group kSCEntNetIPv6 Entity Keys
  */
 
 /*
- * Copyright (c) 2000, 2001, 2003, 2005, 2007, 2013, 2015, 2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003, 2005, 2007, 2013, 2015, 2018-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 #ifndef _CONFIG_TYPES_H
 #define _CONFIG_TYPES_H
 
+#include <TargetConditionals.h>
+
 /*
  * Keep IPC functions private to the framework
  */
 /*
  * Mach server port name
  */
-#if    !TARGET_OS_SIMULATOR || TARGET_OS_IOSMAC
+#if    !TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
 #define SCD_SERVER     "com.apple.SystemConfiguration.configd"
-#else  // !TARGET_OS_SIMULATOR || TARGET_OS_IOSMAC
+#else  // !TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
 #define SCD_SERVER_HOST        "com.apple.SystemConfiguration.configd"
 #define SCD_SERVER     "com.apple.SystemConfiguration.configd_sim"
-#endif // !TARGET_OS_SIMULATOR || TARGET_OS_IOSMAC
+#endif // !TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
 
 /*
  * Input arguments: serialized key's, list delimiters, ...
 
        SC_IPHONE_2_0_PRIVATE,
        SC_IPHONE_7_0_PRIVATE,
        SC_IPHONE_8_0_PRIVATE,
+       SC_IPHONE_14_PRIVATE,
        COMMENT_DEPRECATED,
        GROUP_DEPRECATED,
        COMMENT_DEPRECATED_NO_HEADER,
 #define CALLWAITINGAUDIBLEALERT        "CallWaitingAudibleAlert"
 #define CAPABILITIES           "Capabilities"
 #define CAPABILITY             "Capability"
+#define CAPTIVEPORTAL          "CaptivePortal"
 #define CAUSE                  "Cause"
 #define CCP                    "CCP"
 #define CELLULAR               "Cellular"
 #define TYPE                   "Type"
 #define UID                    "UID"
 #define UPDATED                        "Updated"
+#define URL                    "URL"
 #define URLSTRING              "URLString"
 #define USE                    "Use"
 #define USERDEFINEDNAME                "UserDefinedName"
   { GROUP_PRIVATE, NETENT, "Network Entity Keys", NULL, NULL },
 
     { SC_10_9_IPHONE_7_0_PRIVATE, NETENT, APP LAYER, NULL, CFDICTIONARY},
+    { SC_IPHONE_14_PRIVATE, NETENT, CAPTIVEPORTAL, NULL, CFDICTIONARY },
     { SC_10_5_PRIVATE, NETENT, EAPOL, NULL, CFDICTIONARY },
     { SC_10_7_IPHONE_5_0_PRIVATE, NETENT, IDLE ROUTE, NULL, NULL},                     // notification
     { SC_10_10_IPHONE_7_0_PRIVATE, NETENT, INTERFACE ACTIVE DURINGSLEEP REQUESTED, ACTIVE DURINGSLEEP REQUESTED, CFDICTIONARY},
     { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP DNS, SUPPLEMENTAL MATCH DOMAINS NO SEARCH, NULL, CFNUMBER_BOOL},
     { COMMENT_PRIVATE, "", NULL, NULL, NULL },
 
+  { GROUP_PRIVATE, NETPROP CAPTIVEPORTAL, KEY_PREFIX NETENT CAPTIVEPORTAL " Entity Keys", NULL, NULL },
+
+    { SC_IPHONE_14_PRIVATE, NETPROP CAPTIVEPORTAL, URL, NULL, CFSTRING },
+    { COMMENT_PRIVATE, "", NULL, NULL, NULL },
+
   { GROUP, NETPROP ETHERNET, KEY_PREFIX NETENT ETHERNET " (Hardware) Entity Keys", NULL, NULL },
 
     { SC_10_2, NETPROP ETHERNET, MEDIA SUBTYPE, NULL, CFSTRING },
 
   { GROUP_PRIVATE, NETPROP IPV4, KEY_PREFIX NETENT IPV4 " Entity Keys", NULL, NULL },
     { SC_10_10_IPHONE_8_0_PRIVATE, NETPROP IPV4, ADDITIONAL ROUTES, NULL, CFARRAY_CFDICTIONARY },
+    { SC_10_7_IPHONE_5_0_PRIVATE, NETPROP IPV4, ARP RESOLVED HARDWARE ADDRESS, NULL, CFSTRING },
+    { SC_10_7_IPHONE_5_0_PRIVATE, NETPROP IPV4, ARP RESOLVED IP ADDRESS, NULL, CFSTRING },
     { SC_10_14_IPHONE_12_0_PRIVATE, NETPROP IPV4, CLAT46, NULL, CFBOOLEAN },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP IPV4, EXCLUDED ROUTES, NULL, CFARRAY_CFDICTIONARY },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP IPV4, INCLUDED ROUTES, NULL, CFARRAY_CFDICTIONARY },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP IPV4 ROUTE, GATEWAY ADDRESS, NULL, CFSTRING },
     { SC_10_10_IPHONE_8_0_PRIVATE, NETPROP IPV4 ROUTE, INTERFACENAME, NULL, CFSTRING },
     { COMMENT_PRIVATE, "", NULL, NULL, NULL },
-    { SC_10_7_IPHONE_5_0_PRIVATE, NETPROP IPV4, ARP RESOLVED HARDWARE ADDRESS, NULL, CFSTRING },
-    { SC_10_7_IPHONE_5_0_PRIVATE, NETPROP IPV4, ARP RESOLVED IP ADDRESS, NULL, CFSTRING },
-    { COMMENT_PRIVATE, "", NULL, NULL, NULL },
 
   { GROUP, NETPROP IPV6, KEY_PREFIX NETENT IPV6 " Entity Keys", NULL, NULL },
 
     { SC_10_1, NETPROP IPV6, ADDRESSES, NULL, CFARRAY_CFSTRING },
     { SC_10_1, NETPROP IPV6, CONFIGMETHOD, NULL, CFSTRING },
     { SC_10_3, NETPROP IPV6, DEST ADDRESSES, NULL, CFARRAY_CFSTRING },
-    { SC_10_3, NETPROP IPV6, FLAGS, NULL, CFNUMBER },
+    { SC_10_3, NETPROP IPV6, FLAGS, NULL, CFARRAY_CFNUMBER },
     { SC_10_3, NETPROP IPV6, PREFIXLENGTH, NULL, CFARRAY_CFNUMBER },
     { SC_10_3, NETPROP IPV6, ROUTER, NULL, CFSTRING },
     { COMMENT, "", NULL, NULL, NULL },
            case SC_IPHONE_8_0_PRIVATE:
                printf("  SPI_AVAILABLE(macos(10.0), ios(8.0), tvos(9.0), watchos(1.0), bridgeos(1.0));\n");
                break;
+           case SC_IPHONE_14_PRIVATE:
+               printf("  SPI_AVAILABLE(macos(10.16), ios(14.0), tvos(14.0), watchos(7.0), bridgeos(5.0));\n");
+               break;
            default:
                printf("\n");
                break;
                            case SC_IPHONE_2_0_PRIVATE:
                            case SC_IPHONE_7_0_PRIVATE:
                            case SC_IPHONE_8_0_PRIVATE:
+                           case SC_IPHONE_14_PRIVATE:
                                // don't report private definitions
                                break;
                            default:
                            case SC_IPHONE_2_0_PRIVATE:
                            case SC_IPHONE_7_0_PRIVATE:
                            case SC_IPHONE_8_0_PRIVATE:
+                           case SC_IPHONE_14_PRIVATE:
                                print_comment(&names[i]);
                                break;
                            default:
                            case SC_IPHONE_2_0_PRIVATE:
                            case SC_IPHONE_7_0_PRIVATE:
                            case SC_IPHONE_8_0_PRIVATE:
+                           case SC_IPHONE_14_PRIVATE:
                                // don't report private definitions
                                break;
                            default:
                            case SC_IPHONE_2_0_PRIVATE:
                            case SC_IPHONE_7_0_PRIVATE:
                            case SC_IPHONE_8_0_PRIVATE:
+                           case SC_IPHONE_14_PRIVATE:
                                print_headerdoc(&names[i]);
                                break;
                            default:
 
+++ /dev/null
-#!/bin/sh
-
-if [ $# -lt 1 ]; then
-       echo "Cannot update headers, private header directory not specified"
-       exit 1
-fi
-
-SPI_BASE="${1}"
-
-for H in                               \
-       DHCPClientPreferences.h         \
-       SCDynamicStore.h                \
-       SCDynamicStoreCopyDHCPInfo.h    \
-       SCDynamicStoreCopySpecific.h    \
-       SCDynamicStoreKey.h             \
-       SCNetworkConfiguration.h        \
-       SCNetworkConnection.h           \
-       SCPreferences.h                 \
-       SCPreferencesPath.h             \
-       SCPreferencesSetSpecific.h      \
-       SCSchemaDefinitions.h           \
-       SystemConfiguration.h           \
-
-do
-       HACK=$(echo "_DO_NOT_INCLUDE_${H}" | tr '[:lower:]' '[:upper:]' | sed -e 's/\./_/')
-       cat <<_END_OF_INPUT > "${SPI_BASE}/_${H}"
-#ifndef        ${HACK}
-#define        ${HACK}
-
-/*
- * WARNING WARNING WARNING WARNING WARNING
- *
- * This is a PRIVATE/INTERNAL header file that is on the to-be-removed soon
- * list.  Please update your project to use :
- *     #include <SystemConfiguration/${H}>
- * or :
- *     #include <SystemConfiguration/SystemConfiguration.h>
- *
- * WARNING WARNING WARNING WARNING WARNING
- */
-#ifndef        NO_TAPI_WARNINGS
-#warning "Please #include <SystemConfiguration/${H}>, NOT <SystemConfiguration/_${H}>. See rdar://41937689 for details"
-#endif // NO_TAPI_WARNINGS
-
-#endif // ${HACK}
-
-#include <SystemConfiguration/${H}>
-_END_OF_INPUT
-done
-
-exit
 
 /*
- * Copyright (c) 2012, 2013, 2015-2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2012, 2013, 2015-2019 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 #include <SystemConfiguration/SCPrivate.h>
 #include <SystemConfiguration/scprefs_observer.h>
 
-#define        MANAGED_PREFERENCES_PATH        "/Library/Managed Preferences"
-#if    TARGET_OS_IPHONE
-#define        MOBILE_PREFERENCES_PATH         "/var/mobile/Library/Preferences"
-#endif // TARGET_OS_IPHONE
-
 #if    !TARGET_OS_IPHONE
-#define        PREFS_OBSERVER_KEY              "com.apple.MCX._managementStatusChangedForDomains"
+#define        MANAGED_PREFERENCES_PATH        "/Library/Managed Preferences"
+#define        PREFS_OBSERVER_KEY              "com.apple.MCX._managementStatusChangedForDomains"      // posted by CF (OK for macOS, iOS)
 #else  // !TARGET_OS_IPHONE
-#define        PREFS_OBSERVER_KEY              "com.apple.ManagedConfiguration.profileListChanged"
+#define        MANAGED_PREFERENCES_MOBILE_PATH "/Library/Managed Preferences/mobile"
+#define        PREFS_OBSERVER_KEY              "com.apple.ManagedConfiguration.profileListChanged"     // posted by ManagedConfiguration
 #endif // !TARGET_OS_IPHONE
 
 #pragma mark -
 #pragma mark Utils
 
+#if    !TARGET_OS_IPHONE
 static void
 iterate_dir(const char *d_name, const char *f_name,
            CC_SHA256_CTX *ctxP, Boolean *found)
                                */
                                CC_SHA256_Update(ctxP, full_path, (CC_LONG)strlen(full_path));
                                CC_SHA256_Update(ctxP,
-                                              (void *)&s.st_mtimespec.tv_sec,
-                                              sizeof(s.st_mtimespec.tv_sec));
+                                                (void *)&s.st_mtimespec,
+                                                sizeof(s.st_mtimespec));
                                *found = TRUE;
                        }
                }
        closedir(dir);
        return;
 }
+#else  // !TARGET_OS_IPHONE
+static void
+observe_plist(const char *d_name, const char *f_name,
+             CC_SHA256_CTX *ctxP, Boolean *found)
+{
+       char            full_path[MAXPATHLEN];
+       struct stat     s;
+
+       snprintf(full_path, sizeof(full_path), "%s/%s", d_name, f_name);
+       if ((stat(full_path, &s) == 0) && S_ISREG(s.st_mode)) {
+               CC_SHA256_Update(ctxP, full_path, (CC_LONG)strlen(full_path));
+               CC_SHA256_Update(ctxP,
+                                (void *)&s.st_mtimespec,
+                                sizeof(s.st_mtimespec));
+               *found = TRUE;
+       }
+
+       return;
+}
+#endif // !TARGET_OS_IPHONE
 
 static CF_RETURNS_RETAINED CFDataRef
 build_digest(const char *top_dir, const char *file)
        Boolean         found = FALSE;
 
        CC_SHA256_Init(&ctx);
+#if    !TARGET_OS_IPHONE
        iterate_dir(top_dir, file, &ctx, &found);
+#else  // !TARGET_OS_IPHONE
+       observe_plist(top_dir, file, &ctx, &found);
+#endif // !TARGET_OS_IPHONE
        CC_SHA256_Final(bytes, &ctx);
        if (found) {
                digest = CFDataCreate(NULL, bytes, sizeof(bytes));
                return MANAGED_PREFERENCES_PATH;
 #else  // !TARGET_OS_IPHONE
        case scprefs_observer_type_global:
-               return MANAGED_PREFERENCES_PATH;
-       case scprefs_observer_type_profile:
-               return MOBILE_PREFERENCES_PATH;
+               return MANAGED_PREFERENCES_MOBILE_PATH;
 #endif // !TARGET_OS_IPHONE
        default:
                return (NULL);
 
 /*
- * Copyright (c) 2012-2014, 2017, 2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2012-2014, 2017-2019 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
                scprefs_observer_type_mcx       = 1,
 #else  // !TARGET_OS_IPHONE
                scprefs_observer_type_global    = 2,
-               scprefs_observer_type_profile   = 3,
 #endif // !TARGET_OS_IPHONE
 } _scprefs_observer_type;
 
 
 /*!
  @function prefs_observer_watch
- @discussion Cancells/deregisters the given preferences watcher.
+ @discussion Cancels/deregisters the given preferences watcher.
  @param observer the watcher to be cancelled.
  */
 void
 
        if (f == NULL) {
                return kSCStatusFailed;
        }
-       SCPrint(TRUE, f, CFSTR("Main thread :\n\n"));
+       SCPrint(TRUE, f, CFSTR("Main [plug-in] thread :\n\n"));
        SCPrint(TRUE, f, CFSTR("%@\n"), CFRunLoopGetCurrent());
-       if (plugin_runLoop != NULL) {
-               SCPrint(TRUE, f, CFSTR("Plug-in thread :\n\n"));
-               SCPrint(TRUE, f, CFSTR("%@\n"), plugin_runLoop);
-       }
        listSessions(f);
        (void) fclose(f);
 
 
 .\"
 .\"     @(#)configd.8
 .\"
-.Dd June 18, 2009
+.Dd April 14, 2020
 .Dt CONFIGD 8
 .Os "Mac OS X"
 .Sh NAME
 IOKit Registry for a list of network devices attached to the system and gives them BSD style names such as
 .Qq en0 .
 .Ss IPConfiguration
-This agent is responsible for establishing and maintaining IPv4 addresses on the system.  These addresses may be manually specified in the network preferences or acquired using DHCP (or BOOTP).
-.Ss IP6Configuration
-This agent is responsible for establishing and maintaining IPv6 addresses on the system.
+This agent is responsible for establishing and maintaining IPv4 and IPv6 addresses on the system.  These addresses may be manually specified in the network preferences or acquired using DHCP (or BOOTP), DHCPv6, and RTADV.
 .Ss IPMonitor
 This agent is responsible for establishing and maintaining the primary network service, the default route, the active DNS configuration, and the active network proxies on the system.
 .Ss LinkConfiguration
 bundles
 .It Pa /Library/Preferences/SystemConfiguration/
 Default directory for system configuration persistent store files.
-.Bl -tag -width .../VirtualNetworkInterfaces.plist
+.Bl -tag -width .../NetworkInterfaces.plist
 .It Pa .../preferences.plist
-System configuration
+Network configuration and computer/host names
 .It Pa .../NetworkInterfaces.plist
 Network interface --> BSD interface mappings
-.It Pa .../VirtualNetworkInterfaces.plist
-Virtual network interface (VLAN) configuration
 .El
 .El
 .Sh ERRORS
 
        CFRelease(rls);
 
        if (testBundle == NULL) {
-               /* don't complain about having  lots of SCDynamicStore objects */
+               /* don't complain about having  lots of SCDynamicStore sessions */
                _SCDynamicStoreSetSessionWatchLimit(0);
 
                /* initialize primary (store management) thread */
                        /* synchronize with parent process */
                        kill(getppid(), SIGTERM);
                }
+       }
 
-               /* load/initialize/start bundles into the secondary thread */
-               if (loadBundles) {
-                       /* start plug-in initialization */
-                       plugin_init();
-               }
-
-               /* start main thread */
-               CFRunLoopRun();
-       } else {
-               /* load/initialize/start specified plug-in */
+       if ((testBundle != NULL) || loadBundles) {
+               /* load/initialize/start [specified] plug-ins */
                plugin_exec((void *)testBundle);
        }
 
+       SC_log(LOG_DEBUG, "starting main/plugin CFRunLoop");
+       CFRunLoopRun();
+
        exit (EX_OK);   /* insure the process exit status is 0 */
        return 0;       /* ...and make main fit the ANSI spec. */
 }
 
        <true/>
        <key>com.apple.private.snhelper</key>
        <true/>
+       <key>com.apple.security.iokit-user-client-class</key>
+       <array>
+               <string>IONetworkStackUserClient</string>
+               <string>RootDomainUserClient</string>
+       </array>
        <key>com.apple.security.network.client</key>
        <true/>
        <key>com.apple.security.network.server</key>
 
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>com.apple.private.necp.match</key>
+       <true/>
+       <key>com.apple.private.necp.policies</key>
+       <true/>
+</dict>
+</plist>
 
 /*
- * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2019 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 // exiting bundles
 static CFMutableDictionaryRef  exiting                 = NULL;
 
-// plugin CFRunLoopRef
-__private_extern__
-CFRunLoopRef                   plugin_runLoop          = NULL;
-
 
 extern SCDynamicStoreBundleLoadFunction                load_IPMonitor;
 extern SCDynamicStoreBundlePrimeFunction       prime_IPMonitor;
 #pragma mark term
 
 
-static CFStringRef
-termRLSCopyDescription(const void *info)
-{
-#pragma unused(info)
-       return CFStringCreateWithFormat(NULL, NULL, CFSTR("<SIGTERM RLS>"));
-}
-
-
 __private_extern__
 Boolean
 plugin_term(int *status)
 {
-       CFRunLoopSourceContext  termContext = { 0                       // version
-                                             , (void *)1               // info
-                                             , NULL                    // retain
-                                             , NULL                    // release
-                                             , termRLSCopyDescription  // copyDescription
-                                             , NULL                    // equal
-                                             , NULL                    // hash
-                                             , NULL                    // schedule
-                                             , NULL                    // cancel
-                                             , stopBundles             // perform
-                                             };
-       CFRunLoopSourceRef      termRls;
-
-       if (plugin_runLoop == NULL) {
+       if (CFArrayGetCount(allBundles) == 0) {
                // if no plugins
                *status = EX_OK;
                return FALSE;   // don't delay shutdown
                                            &kCFTypeDictionaryKeyCallBacks,
                                            &kCFTypeDictionaryValueCallBacks);
 
-       termRls = CFRunLoopSourceCreate(NULL, 0, &termContext);
-       CFRunLoopAddSource(plugin_runLoop, termRls, kCFRunLoopDefaultMode);
-       CFRunLoopSourceSignal(termRls);
-       CFRelease(termRls);
-       CFRunLoopWakeUp(plugin_runLoop);
-
+       stopBundles();
        return TRUE;
 }
 
 
 
 __private_extern__
-void *
+void
 plugin_exec(void *arg)
 {
        CFIndex         nLoaded         = 0;
                        CFArrayRef      bundles;
                        CFURLRef        url;
 
-#if    TARGET_OS_SIMULATOR && !TARGET_OS_IOSMAC
+#if    TARGET_OS_SIMULATOR && !TARGET_OS_MACCATALYST
                        const char      *path_sim_prefix;
 
                        path_sim_prefix = getenv("IPHONE_SIMULATOR_ROOT");
                        } else {
                                path[0] = '\0';
                        }
-#endif // TARGET_OS_SIMULATOR && !TARGET_OS_IOSMAC
+#endif // TARGET_OS_SIMULATOR && !TARGET_OS_MACCATALYST
 
                        /* load any available bundle */
                        strlcat(path, BUNDLE_DIRECTORY, sizeof(path));
 
        if (nLoaded == 0) {
                // if no bundles loaded
-               goto done;
+               return;
        }
 
        /*
                             NULL);
 
        /*
-        * The assumption is that each loaded plugin will establish CFMachPortRef,
-        * CFSocketRef, and CFRunLoopTimerRef input sources to handle any events
-        * and register these sources with this threads run loop. If the plugin
-        * needs to wait and/or block at any time it should do so only in its a
-        * private thread.
+        * At this point, the assumption is that each loaded plugin will have
+        * established CFMachPort, CFSocket, and CFRunLoopTimer input sources
+        * to handle any events and registered these sources with this threads
+        * run loop and we're ready to go.
+        *
+        * Note: it is also assumed that any plugin needing to wait and/or block
+        * will do so only a private thread (or asynchronously on a non-main
+        * dispatch queue).
         */
-       SC_log(LOG_DEBUG, "starting plugin CFRunLoop");
-       plugin_runLoop = CFRunLoopGetCurrent();
-       pthread_setname_np("Main plugin thread");
-       CFRunLoopRun();
-
-    done :
-
-       SC_log(LOG_INFO, "No more work for the \"configd\" plugin thread");
-       plugin_runLoop = NULL;
-       return NULL;
-}
-
-
-__private_extern__
-void
-plugin_init()
-{
-       pthread_attr_t  tattr;
-       pthread_t       tid;
-
-       SC_log(LOG_DEBUG, "Starting \"configd\" plugin thread");
-       pthread_attr_init(&tattr);
-       pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM);
-       pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
-//      pthread_attr_setstacksize(&tattr, 96 * 1024); // each thread gets a 96K stack
-       pthread_create(&tid, &tattr, plugin_exec, NULL);
-       pthread_attr_destroy(&tattr);
-       SC_log(LOG_DEBUG, "  thread id=%p", tid);
 
        return;
 }
 
 /*
- * Copyright (c) 2000, 2001, 2005, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2005, 2006, 2019 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_LICENSE_HEADER_END@
  */
 
 
 #include <sys/cdefs.h>
 
-extern CFRunLoopRef    plugin_runLoop;
-
 __BEGIN_DECLS
 
-void   plugin_init     (void);
 void   plugin_exec     (void           *arg);
 Boolean        plugin_term     (int            *status);
 
 __END_DECLS
 
-#endif /* !_S_PLUGIN_SUPPORT_H */
+#endif /* !_S_PLUGIN_SUPPORT_H */
 
 /*
- * Copyright (c) 2000, 2001, 2003-2005, 2007-2019 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003-2005, 2007-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  * Note: sync w/sessionQueue()
  */
 static CFMutableDictionaryRef  client_sessions         = NULL;
+static CFIndex                 client_sessions_advise  = 250;          // when snapshot handler should detail sessions
 
 
 static dispatch_queue_t
                CFIndex                 state_len;
 
                n = CFDictionaryGetCount(client_sessions);
-               if (n < 500) {
+               if (n < client_sessions_advise) {
                        CFStringRef     str;
 
                        str = CFStringCreateWithFormat(NULL, NULL, CFSTR("n = %ld"), n);
 }
 
 
+#if __has_feature(ptrauth_intrinsics)
+extern const struct { char c; } objc_absolute_packed_isa_class_mask;
+#endif
+
+static void
+memcpy_objc_object(void* dst, const void* restrict src, size_t size)
+{
+       // first, we copy the object
+       memcpy(dst, src, size);
+
+       // then, if needed, fix the isa pointer
+  #if  __has_feature(ptrauth_intrinsics)
+       uintptr_t       flags;
+       uintptr_t       isa_mask;
+       void **         opaqueObject;
+       uintptr_t       raw_isa;
+       uintptr_t       real_isa;
+
+       opaqueObject = (void**)src;
+       isa_mask = (uintptr_t)&objc_absolute_packed_isa_class_mask;
+       flags = (uintptr_t)(*opaqueObject) & ~isa_mask;
+       real_isa = (uintptr_t)(*opaqueObject) & isa_mask;
+
+    #if                __has_feature(ptrauth_objc_isa)
+       raw_isa = (uintptr_t)ptrauth_auth_data((void *)real_isa,
+                                              ptrauth_key_process_independent_data,
+                                              ptrauth_blend_discriminator(opaqueObject, 0x6AE1));
+    #else      // __has_feature(ptrauth_objc_isa)
+       raw_isa = (uintptr_t)ptrauth_strip((void*)real_isa, ptrauth_key_process_independent_data);
+    #endif     // __has_feature(ptrauth_objc_isa)
+       ((CFRuntimeBase*)dst)->_cfisa = raw_isa;
+       ((uint64_t*)dst)[0] |= flags;
+  #endif       // __has_feature(ptrauth_intrinsics)
+}
+
+
 __private_extern__
 serverSessionRef
 tempSession(mach_port_t server, CFStringRef name, audit_token_t auditToken)
        static serverSession            temp_session;
 
        dispatch_once(&once, ^{
-               temp_session = *server_session;         /* use "server" session clone */
+               memcpy_objc_object(&temp_session,       /* use "server" session clone */
+                                  server_session,
+                                  sizeof(temp_session));
                (void) __SCDynamicStoreOpen(&temp_session.store, NULL);
        });
 
                                                        server_mach_channel_handler);
        if (!isMain) {
                // if not main SCDynamicStore port, watch for exit
-               dispatch_mach_request_no_senders(session->serverChannel);
+               dispatch_mach_notify_no_senders(session->serverChannel, FALSE);
        }
 #if    TARGET_OS_SIMULATOR
        // simulators don't support MiG QoS propagation yet
 
                        );
                        dependencies = (
                                15A5A2710D5B942D0087BDA0 /* PBXTargetDependency */,
-                               15E1B06416EBAF2A00E5F06F /* PBXTargetDependency */,
-                               15E1B06616EBAF2A00E5F06F /* PBXTargetDependency */,
-                               15D3083016F3EAD000014F82 /* PBXTargetDependency */,
-                               15D3083216F3EAD000014F82 /* PBXTargetDependency */,
-                               15E1B03E16EBAB8A00E5F06F /* PBXTargetDependency */,
-                               15E1B04016EBAB9400E5F06F /* PBXTargetDependency */,
                        );
                        name = "configd_base-EmbeddedSimulator";
                        productName = Frameworks;
                                15401C27219915C6006326B7 /* Create non-empty Root */,
                        );
                        dependencies = (
+                               156774A12466218800B0C1D6 /* PBXTargetDependency */,
+                               15677495246620C300B0C1D6 /* PBXTargetDependency */,
+                               15677497246620C300B0C1D6 /* PBXTargetDependency */,
+                               15677499246620D600B0C1D6 /* PBXTargetDependency */,
+                               1567749B246620D600B0C1D6 /* PBXTargetDependency */,
+                               1567749D246620E500B0C1D6 /* PBXTargetDependency */,
+                               1567749F246620F000B0C1D6 /* PBXTargetDependency */,
                        );
                        name = "configd_extras-EmbeddedSimulator";
                        productName = configd_extras;
                        isa = PBXAggregateTarget;
                        buildConfigurationList = 15631D231ECF98FB0088EEDD /* Build configuration list for PBXAggregateTarget "configd_executables-EmbeddedSimulator" */;
                        buildPhases = (
+                               156774A2246621C500B0C1D6 /* Create non-empty Root */,
                        );
                        dependencies = (
-                               15631D271ECF99800088EEDD /* PBXTargetDependency */,
-                               15631D291ECF99800088EEDD /* PBXTargetDependency */,
-                               15631D2B1ECF99800088EEDD /* PBXTargetDependency */,
                        );
                        name = "configd_executables-EmbeddedSimulator";
                        productName = configd_executables;
                        name = "configd_executables-Embedded";
                        productName = configd_executables;
                };
+               1584B5C32469B65A00AFF758 /* configd_plugins-EmbeddedSimulator */ = {
+                       isa = PBXAggregateTarget;
+                       buildConfigurationList = 1584B5DC2469B65A00AFF758 /* Build configuration list for PBXAggregateTarget "configd_plugins-EmbeddedSimulator" */;
+                       buildPhases = (
+                               1584B5DF2469B69A00AFF758 /* Create non-empty Root */,
+                       );
+                       dependencies = (
+                       );
+                       name = "configd_plugins-EmbeddedSimulator";
+                       productName = Plugins;
+               };
                159D542007528E7C004F8947 /* configd_plugins */ = {
                        isa = PBXAggregateTarget;
                        buildConfigurationList = 156EB61E0905594A00EEF749 /* Build configuration list for PBXAggregateTarget "configd_plugins" */;
                        dependencies = (
                                157FDE44164A079B0040D6A8 /* PBXTargetDependency */,
                                151FE37A0D5B713C000D6DB1 /* PBXTargetDependency */,
+                               1584B5E12469B6CE00AFF758 /* PBXTargetDependency */,
                                15631D2D1ECF99A00088EEDD /* PBXTargetDependency */,
                                15401C3021991B31006326B7 /* PBXTargetDependency */,
                                15EF89C62189484C003B2C5C /* PBXTargetDependency */,
                158337A00CFB6B9E0033AB93 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */; };
                158337A20CFB6B9E0033AB93 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1520A3DE0846B2DC0010B584 /* Security.framework */; };
                158337AD0CFB6BDC0033AB93 /* com.apple.SCHelper-embedded.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 151356AD0CE0CF2F0017E523 /* com.apple.SCHelper-embedded.plist */; };
+               1583DFBD2360D0E800AA397A /* SCPreferencesParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 1583DFB92360D0E700AA397A /* SCPreferencesParser.m */; };
+               1583DFBE2360D0E800AA397A /* SCDynamicStoreParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 1583DFBA2360D0E700AA397A /* SCDynamicStoreParser.m */; };
                158D6D891C974E9E00A08E78 /* com.apple.SystemConfiguration.plist in Logging Preferences */ = {isa = PBXBuildFile; fileRef = 158D6D871C974DBA00A08E78 /* com.apple.SystemConfiguration.plist */; };
                158D6D8B1C974F1800A08E78 /* com.apple.SystemConfiguration.plist in Logging Preferences */ = {isa = PBXBuildFile; fileRef = 158D6D871C974DBA00A08E78 /* com.apple.SystemConfiguration.plist */; };
                158D6D8D1C974F5800A08E78 /* com.apple.SystemConfiguration.plist in Logging Preferences */ = {isa = PBXBuildFile; fileRef = 158D6D871C974DBA00A08E78 /* com.apple.SystemConfiguration.plist */; };
                159D54D607529FFF004F8947 /* configd.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 15CB6A2005C0722B0099E85F /* configd.8 */; };
                159FFD5F2110EA44009311DD /* dnsinfo_flatfile.c in Sources */ = {isa = PBXBuildFile; fileRef = 1522FCE50FA7FD7000B24128 /* dnsinfo_flatfile.c */; };
                159FFD612110EA71009311DD /* dnsinfo_flatfile.c in Sources */ = {isa = PBXBuildFile; fileRef = 1522FCE50FA7FD7000B24128 /* dnsinfo_flatfile.c */; };
+               15A03BDE245B71C8003503BB /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15FEE80D0CCFD341001312F9 /* CoreServices.framework */; };
+               15A03BE0245B71F5003503BB /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15A03BDF245B71F5003503BB /* CoreServices.framework */; };
                15A1FF3210597F17004C9CC9 /* CaptiveNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = 15A1FF3010597F17004C9CC9 /* CaptiveNetwork.h */; settings = {ATTRIBUTES = (Public, ); }; };
                15A1FF3310597F17004C9CC9 /* CaptiveNetwork.c in Sources */ = {isa = PBXBuildFile; fileRef = 15A1FF3110597F17004C9CC9 /* CaptiveNetwork.c */; };
                15A1FF3410597F17004C9CC9 /* CaptiveNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = 15A1FF3010597F17004C9CC9 /* CaptiveNetwork.h */; settings = {ATTRIBUTES = (Public, ); }; };
                15CB8F881EE4DE3300726685 /* SCNetworkReachabilityLogging.h in Headers */ = {isa = PBXBuildFile; fileRef = 152EC34B1EE1B10200A1D27B /* SCNetworkReachabilityLogging.h */; };
                15CB8F891EE4DE3600726685 /* SCNetworkReachabilityLogging.h in Headers */ = {isa = PBXBuildFile; fileRef = 152EC34B1EE1B10200A1D27B /* SCNetworkReachabilityLogging.h */; };
                15CB8F8A1EE4DE3B00726685 /* SCNetworkReachabilityLogging.h in Headers */ = {isa = PBXBuildFile; fileRef = 152EC34B1EE1B10200A1D27B /* SCNetworkReachabilityLogging.h */; };
+               15D0E41F246776B5008DB9AA /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15A03BDF245B71F5003503BB /* CoreServices.framework */; };
                15D2E437167643460078F547 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1520A3DE0846B2DC0010B584 /* Security.framework */; };
                15D3083916F3EB8600014F82 /* simulator_support.c in Sources */ = {isa = PBXBuildFile; fileRef = 15D3083816F3EB8600014F82 /* simulator_support.c */; };
                15D3083B16F4E81C00014F82 /* com.apple.configd_sim.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 15D3083A16F4E6D900014F82 /* com.apple.configd_sim.plist */; };
                15FC130B0CCEA59E0013872C /* monitor.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FC130A0CCEA59E0013872C /* monitor.c */; };
                15FC13180CCF74740013872C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */; };
                15FD7B3C101E439200C56621 /* BridgeConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FD7B3B101E439200C56621 /* BridgeConfiguration.c */; };
-               15FEE80E0CCFD341001312F9 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15FEE80D0CCFD341001312F9 /* ApplicationServices.framework */; };
+               15FEE80E0CCFD341001312F9 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15FEE80D0CCFD341001312F9 /* CoreServices.framework */; };
                15FEE81F0CD03E75001312F9 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 15FEE8180CD03CBB001312F9 /* Localizable.strings */; };
                15FF5C370CDF776200EEC8AA /* com.apple.SCHelper.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 15FF5C290CDF770500EEC8AA /* com.apple.SCHelper.plist */; };
                55A3DB9E183C2AD900ED3DB7 /* SCNetworkMigration.c in Sources */ = {isa = PBXBuildFile; fileRef = 55A3DB9D183C2A8200ED3DB7 /* SCNetworkMigration.c */; };
                728015911BE1686C009F4F60 /* proxyAgent.m in Sources */ = {isa = PBXBuildFile; fileRef = 728015801BE16833009F4F60 /* proxyAgent.m */; };
                728015921BE1686F009F4F60 /* proxyAgent.m in Sources */ = {isa = PBXBuildFile; fileRef = 728015801BE16833009F4F60 /* proxyAgent.m */; };
                728015971BE16B6C009F4F60 /* Network.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 728015951BE16B6C009F4F60 /* Network.framework */; };
-               728015981BE16B6C009F4F60 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 728015961BE16B6C009F4F60 /* NetworkExtension.framework */; settings = {ATTRIBUTES = (Required, ); }; };
+               728015981BE16B6C009F4F60 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 728015961BE16B6C009F4F60 /* NetworkExtension.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
                728015991BE1812B009F4F60 /* agent-monitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 728015931BE1697E009F4F60 /* agent-monitor.h */; };
                7280159B1BE1812B009F4F60 /* configAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 728015781BE16833009F4F60 /* configAgent.h */; };
                7280159C1BE1812B009F4F60 /* controller.h in Headers */ = {isa = PBXBuildFile; fileRef = 7280157A1BE16833009F4F60 /* controller.h */; };
                        remoteGlobalIDString = 15F742DA1EC6370000DA2E7A;
                        remoteInfo = "liblog_SystemConfiguration-Embedded";
                };
-               15631D261ECF99800088EEDD /* PBXContainerItemProxy */ = {
+               15631D2C1ECF99A00088EEDD /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
-                       remoteGlobalIDString = 15F742E71EC638D100DA2E7A;
-                       remoteInfo = "liblog_SystemConfiguration-EmbeddedSimulator";
+                       remoteGlobalIDString = 15631D161ECF98FB0088EEDD;
+                       remoteInfo = "configd_executables-EmbeddedSimulator";
                };
-               15631D281ECF99800088EEDD /* PBXContainerItemProxy */ = {
+               15677494246620C300B0C1D6 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 15E1B04116EBAE3C00E5F06F;
+                       remoteInfo = "IPMonitor-EmbeddedSimulator";
+               };
+               15677496246620C300B0C1D6 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 15E1B05A16EBAE7800E5F06F;
+                       remoteInfo = "IPMonitor.bundle-EmbeddedSimulator";
+               };
+               15677498246620D600B0C1D6 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 15D3080F16F3E4DA00014F82;
+                       remoteInfo = "SimulatorSupport-EmbeddedSimulator";
+               };
+               1567749A246620D600B0C1D6 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 15D3082816F3E4E100014F82;
+                       remoteInfo = "SimulatorSupport.bundle-EmbeddedSimulator";
+               };
+               1567749C246620E500B0C1D6 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
                        remoteGlobalIDString = 15732A7616EA503200F3AC4C;
                        remoteInfo = "configd-EmbeddedSimulator";
                };
-               15631D2A1ECF99800088EEDD /* PBXContainerItemProxy */ = {
+               1567749E246620F000B0C1D6 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
                        remoteGlobalIDString = 15732AAD16EA511900F3AC4C;
                        remoteInfo = "scutil-EmbeddedSimulator";
                };
-               15631D2C1ECF99A00088EEDD /* PBXContainerItemProxy */ = {
+               156774A02466218800B0C1D6 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
-                       remoteGlobalIDString = 15631D161ECF98FB0088EEDD;
-                       remoteInfo = "configd_executables-EmbeddedSimulator";
+                       remoteGlobalIDString = 15F742E71EC638D100DA2E7A;
+                       remoteInfo = "liblog_SystemConfiguration-EmbeddedSimulator";
                };
                15732AE516EA6BCE00F3AC4C /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        remoteGlobalIDString = 1583177D0CFB85C8006F62B9;
                        remoteInfo = "IPMonitor.bundle-Embedded";
                };
+               1584B5E02469B6CE00AFF758 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 1584B5C32469B65A00AFF758;
+                       remoteInfo = "configd_plugins-EmbeddedSimulator";
+               };
                158AD9850754E72500124717 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        remoteGlobalIDString = 15A5A1E40D5B94190087BDA0;
                        remoteInfo = "SystemConfiguration.framework-EmbeddedSimulator";
                };
-               15AB752916EC254D00FAA8CE /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = 15E1B04116EBAE3C00E5F06F;
-                       remoteInfo = "IPMonitor-EmbeddedSimulator";
-               };
                15C64A210F684C4900D78394 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        remoteGlobalIDString = 157A84D80D56C63900B6F1A0;
                        remoteInfo = "DNSConfiguration-Embedded";
                };
-               15D3082F16F3EAD000014F82 /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = 15D3080F16F3E4DA00014F82;
-                       remoteInfo = "SimulatorSupport-EmbeddedSimulator";
-               };
-               15D3083116F3EAD000014F82 /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = 15D3082816F3E4E100014F82;
-                       remoteInfo = "SimulatorSupport.bundle-EmbeddedSimulator";
-               };
-               15D3083416F3EB2500014F82 /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = 15D3080F16F3E4DA00014F82;
-                       remoteInfo = "SimulatorSupport-EmbeddedSimulator";
-               };
-               15E1B03D16EBAB8A00E5F06F /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = 15732A7616EA503200F3AC4C;
-                       remoteInfo = "configd-EmbeddedSimulator";
-               };
-               15E1B03F16EBAB9400E5F06F /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = 15732AAD16EA511900F3AC4C;
-                       remoteInfo = "scutil-EmbeddedSimulator";
-               };
-               15E1B06316EBAF2A00E5F06F /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = 15E1B04116EBAE3C00E5F06F;
-                       remoteInfo = "IPMonitor-EmbeddedSimulator";
-               };
-               15E1B06516EBAF2A00E5F06F /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = 15E1B05A16EBAE7800E5F06F;
-                       remoteInfo = "IPMonitor.bundle-EmbeddedSimulator";
-               };
                15E83108167F9B0600FD51EC /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                1532629006281C9D00B1C10C /* dnsinfo_create.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dnsinfo_create.h; path = dnsinfo/dnsinfo_create.h; sourceTree = "<group>"; };
                153338BA14BE7978004FCE22 /* libSystemConfiguration_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libSystemConfiguration_client.c; path = libSystemConfiguration/libSystemConfiguration_client.c; sourceTree = "<group>"; };
                153338BB14BE7978004FCE22 /* libSystemConfiguration_client.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = libSystemConfiguration_client.h; path = libSystemConfiguration/libSystemConfiguration_client.h; sourceTree = "<group>"; };
-               153393E20D34994100FE74E7 /* restore-temporary-headers */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.perl; path = "restore-temporary-headers"; sourceTree = "<group>"; };
                153ACCA614E322D5005029A5 /* network_information_server.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; name = network_information_server.c; path = nwi/network_information_server.c; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.c; };
                153ACCA714E322D5005029A5 /* network_information_server.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = network_information_server.h; path = nwi/network_information_server.h; sourceTree = "<group>"; };
                1540E3600987DA9500157C07 /* com.apple.configd.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = com.apple.configd.plist; sourceTree = "<group>"; };
                15812A2D1EA5540B001CF384 /* nat64-configuration.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "nat64-configuration.c"; sourceTree = "<group>"; };
                15812A2E1EA5540B001CF384 /* nat64-configuration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "nat64-configuration.h"; sourceTree = "<group>"; };
                15828AE70753B5F900AD4710 /* KernelEventMonitor.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KernelEventMonitor.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
+               1583DFB92360D0E700AA397A /* SCPreferencesParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCPreferencesParser.m; sourceTree = "<group>"; };
+               1583DFBA2360D0E700AA397A /* SCDynamicStoreParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCDynamicStoreParser.m; sourceTree = "<group>"; };
+               1583DFBB2360D0E700AA397A /* SCDynamicStoreParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCDynamicStoreParser.h; sourceTree = "<group>"; };
+               1583DFBC2360D0E800AA397A /* SCPreferencesParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCPreferencesParser.h; sourceTree = "<group>"; };
                158AD8700754E3D400124717 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
                158AD8C00754E3EF00124717 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
                158AD9100754E40E00124717 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
                159D53F307528C79004F8947 /* libLinkConfiguration.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libLinkConfiguration.a; sourceTree = BUILT_PRODUCTS_DIR; };
                159D53FA07528C95004F8947 /* libPreferencesMonitor.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPreferencesMonitor.a; sourceTree = BUILT_PRODUCTS_DIR; };
                159D54D907529FFF004F8947 /* configd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = configd; sourceTree = BUILT_PRODUCTS_DIR; };
+               15A03BDF245B71F5003503BB /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.Internal.sdk/System/Library/Frameworks/CoreServices.framework; sourceTree = DEVELOPER_DIR; };
                15A1FF3010597F17004C9CC9 /* CaptiveNetwork.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CaptiveNetwork.h; sourceTree = "<group>"; };
                15A1FF3110597F17004C9CC9 /* CaptiveNetwork.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CaptiveNetwork.c; sourceTree = "<group>"; };
                15A2972D0A13C08C009879B3 /* SCNetworkConnectionPrivate.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = SCNetworkConnectionPrivate.c; sourceTree = "<group>"; };
                15FD73EE0754DE62001CC321 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
                15FD743E0754DE7A001CC321 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
                15FD7B3B101E439200C56621 /* BridgeConfiguration.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = BridgeConfiguration.c; sourceTree = "<group>"; };
-               15FEE80D0CCFD341001312F9 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; sourceTree = "<absolute>"; };
+               15FEE80D0CCFD341001312F9 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; };
                15FF5C290CDF770500EEC8AA /* com.apple.SCHelper.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = com.apple.SCHelper.plist; path = helper/com.apple.SCHelper.plist; sourceTree = "<group>"; };
                23C1E2B4062DD2C700835B54 /* pppcontroller_types.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 30; name = pppcontroller_types.h; path = usr/local/include/ppp/pppcontroller_types.h; sourceTree = SDKROOT; };
                23C1E2B8062DD45900835B54 /* pppcontroller.defs */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.mig; name = pppcontroller.defs; path = SystemConfiguration.fproj/pppcontroller.defs; sourceTree = "<group>"; };
                D6AEB89815AE4446009F2FAF /* ip_plugin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ip_plugin.h; sourceTree = "<group>"; };
                F90E43542012AD3900EF27C4 /* SCNetworkInterfaceProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCNetworkInterfaceProvider.h; sourceTree = "<group>"; };
                F90E43552012AD4500EF27C4 /* SCNetworkInterfaceProvider.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SCNetworkInterfaceProvider.c; sourceTree = "<group>"; };
+               F9292ACB24AEAB1C0039975D /* entitlements-macOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "entitlements-macOS.plist"; sourceTree = "<group>"; };
                F95B8A420B03E07A00993BA3 /* SCNetworkSignature.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = SCNetworkSignature.c; sourceTree = "<group>"; };
                F95B8A440B03E09300993BA3 /* SCNetworkSignature.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCNetworkSignature.h; sourceTree = "<group>"; };
                F95B8A450B03E09300993BA3 /* SCNetworkSignaturePrivate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCNetworkSignaturePrivate.h; sourceTree = "<group>"; };
                F9D7304820DD89C600521181 /* AWDMetricIds_IPMonitor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AWDMetricIds_IPMonitor.h; sourceTree = "<group>"; };
                F9D7304920DD89C600521181 /* AWDIPMonitorInterfaceAdvisoryReport.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AWDIPMonitorInterfaceAdvisoryReport.m; sourceTree = "<group>"; };
                F9D7304A20DDA59600521181 /* awdgen.yaml */ = {isa = PBXFileReference; lastKnownFileType = text; path = awdgen.yaml; sourceTree = "<group>"; };
-               F9D7304E20E41D9C00521181 /* ProtocolBuffer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ProtocolBuffer.framework; path = ../../../../../../../../SDKs/Peace16A315/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/PrivateFrameworks/ProtocolBuffer.framework; sourceTree = "<group>"; };
-               F9D7305020E41DD500521181 /* WirelessDiagnostics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WirelessDiagnostics.framework; path = ../../../../../../../../SDKs/Peace16A315/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/PrivateFrameworks/WirelessDiagnostics.framework; sourceTree = "<group>"; };
+               F9D7304E20E41D9C00521181 /* ProtocolBuffer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ProtocolBuffer.framework; path = System/Library/PrivateFrameworks/ProtocolBuffer.framework; sourceTree = SDKROOT; };
+               F9D7305020E41DD500521181 /* WirelessDiagnostics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WirelessDiagnostics.framework; path = System/Library/PrivateFrameworks/WirelessDiagnostics.framework; sourceTree = SDKROOT; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
                        buildActionMask = 2147483647;
                        files = (
                                15FC13180CCF74740013872C /* CoreFoundation.framework in Frameworks */,
-                               1559C4490D349A4E0098FD59 /* SystemConfiguration.framework in Frameworks */,
+                               15FEE80E0CCFD341001312F9 /* CoreServices.framework in Frameworks */,
                                15792B9B0DA2C190008DDED9 /* IOKit.framework in Frameworks */,
-                               15FEE80E0CCFD341001312F9 /* ApplicationServices.framework in Frameworks */,
                                150D7E1E0D16DC6C00AF4BED /* Security.framework in Frameworks */,
+                               1559C4490D349A4E0098FD59 /* SystemConfiguration.framework in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        buildActionMask = 2147483647;
                        files = (
                                1520A3870846829A0010B584 /* CoreFoundation.framework in Frameworks */,
-                               1559C4450D349A4E0098FD59 /* SystemConfiguration.framework in Frameworks */,
                                1520A3DF0846B2DD0010B584 /* Security.framework in Frameworks */,
+                               1559C4450D349A4E0098FD59 /* SystemConfiguration.framework in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        buildActionMask = 2147483647;
                        files = (
                                15732A9C16EA503200F3AC4C /* CoreFoundation.framework in Frameworks */,
+                               15D0E41F246776B5008DB9AA /* CoreServices.framework in Frameworks */,
                                15732A9D16EA503200F3AC4C /* SystemConfiguration.framework in Frameworks */,
                                15732A9E16EA503200F3AC4C /* IOKit.framework in Frameworks */,
                                15732A9F16EA503200F3AC4C /* Security.framework in Frameworks */,
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
-                               F9D7305120E41DD500521181 /* WirelessDiagnostics.framework in Frameworks */,
-                               F9D7304F20E41D9C00521181 /* ProtocolBuffer.framework in Frameworks */,
+                               1583174C0CFB80A1006F62B9 /* CoreFoundation.framework in Frameworks */,
+                               15A03BE0245B71F5003503BB /* CoreServices.framework in Frameworks */,
+                               1583174E0CFB80A1006F62B9 /* IOKit.framework in Frameworks */,
                                725CB7561BF439D2000C05A8 /* Foundation.framework in Frameworks */,
+                               15D92BA71FFC669100DF2632 /* MobileWiFi.framework in Frameworks */,
                                7214BCE31BEB392000A8F056 /* Network.framework in Frameworks */,
                                7214BCE41BEB392300A8F056 /* NetworkExtension.framework in Frameworks */,
-                               1583174C0CFB80A1006F62B9 /* CoreFoundation.framework in Frameworks */,
+                               F9D7304F20E41D9C00521181 /* ProtocolBuffer.framework in Frameworks */,
                                154707350D1F70C80075C28D /* SystemConfiguration.framework in Frameworks */,
-                               1583174E0CFB80A1006F62B9 /* IOKit.framework in Frameworks */,
-                               15D92BA71FFC669100DF2632 /* MobileWiFi.framework in Frameworks */,
                                159C32B60F583724008A72EE /* Security.framework in Frameworks */,
+                               F9D7305120E41DD500521181 /* WirelessDiagnostics.framework in Frameworks */,
                                158317500CFB80A1006F62B9 /* libbsm.dylib in Frameworks */,
                                1562569120856CCC00FCD61E /* liblockdown.dylib in Frameworks */,
                                15D92BA51FFC64DB00DF2632 /* libnetwork.tbd in Frameworks */,
                        buildActionMask = 2147483647;
                        files = (
                                158337A00CFB6B9E0033AB93 /* CoreFoundation.framework in Frameworks */,
-                               154707300D1F70C80075C28D /* SystemConfiguration.framework in Frameworks */,
                                158337A20CFB6B9E0033AB93 /* Security.framework in Frameworks */,
+                               154707300D1F70C80075C28D /* SystemConfiguration.framework in Frameworks */,
                                15F21618110F823500E89CF7 /* libbsm.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
-                               F9D7305520E4389700521181 /* WirelessDiagnostics.framework in Frameworks */,
-                               F9D7305420E4387A00521181 /* ProtocolBuffer.framework in Frameworks */,
-                               725CB7551BF439C6000C05A8 /* Foundation.framework in Frameworks */,
-                               728015971BE16B6C009F4F60 /* Network.framework in Frameworks */,
-                               728015981BE16B6C009F4F60 /* NetworkExtension.framework in Frameworks */,
                                159D54CC07529FFF004F8947 /* CoreFoundation.framework in Frameworks */,
-                               1559C44A0D349A4E0098FD59 /* SystemConfiguration.framework in Frameworks */,
+                               15A03BDE245B71C8003503BB /* CoreServices.framework in Frameworks */,
                                152439E8180399D800D91708 /* CoreWLAN.framework in Frameworks */,
+                               725CB7551BF439C6000C05A8 /* Foundation.framework in Frameworks */,
                                1543636B0752D03C00A8EC6C /* IOKit.framework in Frameworks */,
+                               728015971BE16B6C009F4F60 /* Network.framework in Frameworks */,
+                               728015981BE16B6C009F4F60 /* NetworkExtension.framework in Frameworks */,
+                               F9D7305420E4387A00521181 /* ProtocolBuffer.framework in Frameworks */,
                                D6623873120B2AA7007F8E95 /* Security.framework in Frameworks */,
+                               1559C44A0D349A4E0098FD59 /* SystemConfiguration.framework in Frameworks */,
+                               F9D7305520E4389700521181 /* WirelessDiagnostics.framework in Frameworks */,
                                15BAA32307F0699A00D9EC95 /* libbsm.dylib in Frameworks */,
                                78C951FE1F797B44000EA36B /* libnetwork.tbd in Frameworks */,
                        );
                                158D6D871C974DBA00A08E78 /* com.apple.SystemConfiguration.plist */,
                                15CFC229068B222F00123568 /* get-mobility-info */,
                                72499BA31AC9B7AB0090C49F /* get-network-info */,
-                               153393E20D34994100FE74E7 /* restore-temporary-headers */,
                        );
                        name = "Supporting Files";
                        sourceTree = "<group>";
                15CB6A1805C0722B0099E85F /* Supporting Files */ = {
                        isa = PBXGroup;
                        children = (
+                               F9292ACB24AEAB1C0039975D /* entitlements-macOS.plist */,
                                1540E3600987DA9500157C07 /* com.apple.configd.plist */,
                                15D3083A16F4E6D900014F82 /* com.apple.configd_sim.plist */,
                                15CB6A2005C0722B0099E85F /* configd.8 */,
                15CB6A6E05C0722B0099E85F /* External Frameworks and Libraries */ = {
                        isa = PBXGroup;
                        children = (
-                               725CB7541BF439C6000C05A8 /* Foundation.framework */,
-                               728015961BE16B6C009F4F60 /* NetworkExtension.framework */,
-                               728015951BE16B6C009F4F60 /* Network.framework */,
-                               15FEE80D0CCFD341001312F9 /* ApplicationServices.framework */,
                                15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */,
+                               15FEE80D0CCFD341001312F9 /* CoreServices.framework */,
                                152439E7180399D800D91708 /* CoreWLAN.framework */,
                                15FA0F73203A379600C7702F /* EventFactory.framework */,
+                               725CB7541BF439C6000C05A8 /* Foundation.framework */,
                                1543636A0752D03C00A8EC6C /* IOKit.framework */,
                                152439EB180716ED00D91708 /* MobileWiFi.framework */,
+                               728015951BE16B6C009F4F60 /* Network.framework */,
+                               728015961BE16B6C009F4F60 /* NetworkExtension.framework */,
                                1520A3DE0846B2DC0010B584 /* Security.framework */,
                                15BAA32207F0699A00D9EC95 /* libbsm.dylib */,
                                152CEED0070CF6640050F23C /* libedit.dylib */,
                90507AAE1CE2F55B0067D16B /* Frameworks */ = {
                        isa = PBXGroup;
                        children = (
-                               15FA163E23C67AAF00573B3C /* Network.framework */,
-                               15FA163C23C67A9800573B3C /* IOKit.framework */,
-                               15C7B7CA224D9AAE0040A8D0 /* SystemConfiguration.framework */,
-                               15C7B7C8224D9AA70040A8D0 /* Foundation.framework */,
                                15C7B7C6224D9A9A0040A8D0 /* CoreFoundation.framework */,
+                               15A03BDF245B71F5003503BB /* CoreServices.framework */,
+                               15FA0F74203A390E00C7702F /* EventFactory.framework */,
                                15B9C0B42232224A00C8FF86 /* Foundation.framework */,
-                               15B9C0AF2232202200C8FF86 /* SystemConfiguration.framework */,
+                               15C7B7C8224D9AA70040A8D0 /* Foundation.framework */,
                                15E56C5A21939B7B00088C51 /* Foundation.framework */,
-                               F9D7305020E41DD500521181 /* WirelessDiagnostics.framework */,
-                               F9D7304E20E41D9C00521181 /* ProtocolBuffer.framework */,
-                               1562569020856CCC00FCD61E /* liblockdown.dylib */,
-                               15FA0F74203A390E00C7702F /* EventFactory.framework */,
+                               15FA163C23C67A9800573B3C /* IOKit.framework */,
                                15D92BA61FFC669000DF2632 /* MobileWiFi.framework */,
+                               15FA163E23C67AAF00573B3C /* Network.framework */,
+                               F9D7304E20E41D9C00521181 /* ProtocolBuffer.framework */,
+                               15C7B7CA224D9AAE0040A8D0 /* SystemConfiguration.framework */,
+                               15B9C0AF2232202200C8FF86 /* SystemConfiguration.framework */,
                                72573D331D66800C004975AD /* SystemConfiguration.framework */,
-                               78C951FD1F797B43000EA36B /* libnetwork.tbd */,
+                               F9D7305020E41DD500521181 /* WirelessDiagnostics.framework */,
+                               1562569020856CCC00FCD61E /* liblockdown.dylib */,
                                15D92B9A1FFC5FA500DF2632 /* libnetwork.tbd */,
                                15D92B9D1FFC61F400DF2632 /* libnetwork.tbd */,
                                15D92BA01FFC641500DF2632 /* libnetwork.tbd */,
+                               78C951FD1F797B43000EA36B /* libnetwork.tbd */,
                        );
                        name = Frameworks;
                        sourceTree = "<group>";
                                C4C5FB0E20EAC05200F35614 /* PreferencesMonitorParser.m */,
                                C469CB2720EED63C00A7AD35 /* StateDumpParser.h */,
                                C469CB2820EED6C100A7AD35 /* StateDumpParser.m */,
+                               1583DFBB2360D0E700AA397A /* SCDynamicStoreParser.h */,
+                               1583DFBA2360D0E700AA397A /* SCDynamicStoreParser.m */,
+                               1583DFBC2360D0E800AA397A /* SCPreferencesParser.h */,
+                               1583DFB92360D0E700AA397A /* SCPreferencesParser.m */,
                                C4666C74206ED01800247AB6 /* Info.plist */,
                        );
                        path = EventFactory;
                        buildConfigurationList = 1572C5290CFB55B400E2776E /* Build configuration list for PBXNativeTarget "SystemConfiguration.framework-Embedded" */;
                        buildPhases = (
                                1572C4A80CFB55B400E2776E /* Headers */,
-                               153393E40D34999D00FE74E7 /* Restore temporary headers */,
                                1572C4DE0CFB55B400E2776E /* Sources */,
                                1572C5230CFB55B400E2776E /* Frameworks */,
                                1513C35C1F186BF90022398F /* Update "install_path" for address|thread sanitizers */,
                        buildRules = (
                        );
                        dependencies = (
-                               15AB752A16EC254D00FAA8CE /* PBXTargetDependency */,
-                               15D3083516F3EB2500014F82 /* PBXTargetDependency */,
                        );
                        name = "configd-EmbeddedSimulator";
                        productInstallPath = /usr/sbin;
                        buildConfigurationList = 15A5A2660D5B94190087BDA0 /* Build configuration list for PBXNativeTarget "SystemConfiguration.framework-EmbeddedSimulator" */;
                        buildPhases = (
                                15A5A1E60D5B94190087BDA0 /* Headers */,
-                               15A5A2170D5B94190087BDA0 /* Restore temporary headers */,
                                15A5A21D0D5B94190087BDA0 /* Sources */,
                                15A5A2620D5B94190087BDA0 /* Frameworks */,
                                15A5A2180D5B94190087BDA0 /* Resources */,
                                15732AD616EA6B6700F3AC4C /* libsystem_configuration-EmbeddedSimulator */,
                                151FE2DD0D5B7046000D6DB1 /* configd_base-EmbeddedSimulator */,
                                15A5A1E40D5B94190087BDA0 /* SystemConfiguration.framework-EmbeddedSimulator */,
+                               1584B5C32469B65A00AFF758 /* configd_plugins-EmbeddedSimulator */,
                                15E1B04116EBAE3C00E5F06F /* IPMonitor-EmbeddedSimulator */,
                                15E1B05A16EBAE7800E5F06F /* IPMonitor.bundle-EmbeddedSimulator */,
                                15D3080F16F3E4DA00014F82 /* SimulatorSupport-EmbeddedSimulator */,
                        shellPath = /bin/sh;
                        shellScript = "echo ${BUILT_PRODUCTS_DIR}\ncc -o ${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME} ${SRCROOT}/SystemConfiguration.fproj/genSCPreferences.c || exit 1\n${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME} header   > ${BUILT_PRODUCTS_DIR}/SCSchemaDefinitions.h        || exit 1\n${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME} private  > ${BUILT_PRODUCTS_DIR}/SCSchemaDefinitionsPrivate.h || exit 1\n${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME} cfile    > ${BUILT_PRODUCTS_DIR}/SCSchemaDefinitions.c        || exit 1\nexit 0";
                };
-               153393E40D34999D00FE74E7 /* Restore temporary headers */ = {
-                       isa = PBXShellScriptBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                       );
-                       inputPaths = (
-                               "$(SRCROOT)/SystemConfiguration.fproj/restore-temporary-headers",
-                       );
-                       name = "Restore temporary headers";
-                       outputPaths = (
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-                       shellPath = /bin/sh;
-                       shellScript = "if [ -x ${SCRIPT_INPUT_FILE_0} ]; then\n    ${SCRIPT_INPUT_FILE_0} \"${TARGET_BUILD_DIR}/${PRIVATE_HEADERS_FOLDER_PATH}\"\nfi\n";
-                       showEnvVarsInLog = 0;
-               };
                1535FEDC1B0FDDCD00B2A3AD /* Add framework symlink (TEMPORARY) */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
-                       shellScript = "if [ \"${USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK}\" = \"YES\" ]; then\n    mkdir -p ${DSTROOT}/System/Library/Frameworks\n    cd ${DSTROOT}/System/Library/Frameworks\n    rm -rf SystemConfiguration.framework\n    ln -s ../PrivateFrameworks/SystemConfiguration.framework .\nfi";
+                       shellScript = "if [ \"${USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK}\" = \"YES\" ]; then\n    mkdir -p ${DSTROOT}/System/Library/Frameworks\n    cd ${DSTROOT}/System/Library/Frameworks\n    rm -rf SystemConfiguration.framework\n    ln -s ../PrivateFrameworks/SystemConfiguration.framework .\nfi\n";
                        showEnvVarsInLog = 0;
                };
                15401C2021991549006326B7 /* Create non-empty Root */ = {
                        shellScript = "rm -rf \"${CLANG_MODULE_CACHE_PATH}\"\n";
                        showEnvVarsInLog = 0;
                };
+               156774A2246621C500B0C1D6 /* Create non-empty Root */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputFileListPaths = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "Create non-empty Root";
+                       outputFileListPaths = (
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "mkdir -p \"${DSTROOT}/AppleInternal\"\n";
+                       showEnvVarsInLog = 0;
+               };
                15703B2722320A940018D2EE /* Flush Module Cache */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 2147483647;
                        shellScript = "mkdir -p \"${DSTROOT}/usr/local/bin\"\nln -fs \"${INSTALL_PATH}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/get-mobility-info\" \"${DSTROOT}/usr/local/bin/\"\n";
                        showEnvVarsInLog = 0;
                };
-               1595B4B81B0C02FA0087944E /* Rename/update SCHelper launchd .plist */ = {
+               1584B5DF2469B69A00AFF758 /* Create non-empty Root */ = {
                        isa = PBXShellScriptBuildPhase;
-                       buildActionMask = 8;
+                       buildActionMask = 2147483647;
                        files = (
                        );
+                       inputFileListPaths = (
+                       );
                        inputPaths = (
                        );
-                       name = "Rename/update SCHelper launchd .plist";
+                       name = "Create non-empty Root";
+                       outputFileListPaths = (
+                       );
                        outputPaths = (
                        );
-                       runOnlyForDeploymentPostprocessing = 1;
+                       runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
-                       shellScript = "SCHELPER_LAUNCHD_PLIST_EMBEDDED=\"${DSTROOT}/System/Library/LaunchDaemons/com.apple.SCHelper-embedded.plist\"\nSCHELPER_LAUNCHD_PLIST=\"${DSTROOT}/System/Library/LaunchDaemons/com.apple.SCHelper.plist\"\n\nif [ -e \"${SCHELPER_LAUNCHD_PLIST_EMBEDDED}\" ]; then\n    mv \"${SCHELPER_LAUNCHD_PLIST_EMBEDDED}\" \"${SCHELPER_LAUNCHD_PLIST}\"\nfi\n\nif [ -e \"${SCHELPER_LAUNCHD_PLIST}\" ]; then\n    /usr/bin/plutil -replace Program -string \"${INSTALL_PATH}/SCHelper\" \"${SCHELPER_LAUNCHD_PLIST}\"\n    /usr/bin/plutil -convert binary1 \"${SCHELPER_LAUNCHD_PLIST}\"\nfi";
-                       showEnvVarsInLog = 0;
+                       shellScript = "mkdir -p \"${DSTROOT}/AppleInternal\"\n";
                };
-               15A5A2170D5B94190087BDA0 /* Restore temporary headers */ = {
+               1595B4B81B0C02FA0087944E /* Rename/update SCHelper launchd .plist */ = {
                        isa = PBXShellScriptBuildPhase;
-                       buildActionMask = 2147483647;
+                       buildActionMask = 8;
                        files = (
                        );
                        inputPaths = (
-                               "$(SRCROOT)/SystemConfiguration.fproj/restore-temporary-headers",
                        );
-                       name = "Restore temporary headers";
+                       name = "Rename/update SCHelper launchd .plist";
                        outputPaths = (
                        );
-                       runOnlyForDeploymentPostprocessing = 0;
+                       runOnlyForDeploymentPostprocessing = 1;
                        shellPath = /bin/sh;
-                       shellScript = "if [ -x ${SCRIPT_INPUT_FILE_0} ]; then\n${SCRIPT_INPUT_FILE_0} \"${TARGET_BUILD_DIR}/${PRIVATE_HEADERS_FOLDER_PATH}\"\nfi\n";
+                       shellScript = "SCHELPER_LAUNCHD_PLIST_EMBEDDED=\"${DSTROOT}/System/Library/LaunchDaemons/com.apple.SCHelper-embedded.plist\"\nSCHELPER_LAUNCHD_PLIST=\"${DSTROOT}/System/Library/LaunchDaemons/com.apple.SCHelper.plist\"\n\nif [ -e \"${SCHELPER_LAUNCHD_PLIST_EMBEDDED}\" ]; then\n    mv \"${SCHELPER_LAUNCHD_PLIST_EMBEDDED}\" \"${SCHELPER_LAUNCHD_PLIST}\"\nfi\n\nif [ -e \"${SCHELPER_LAUNCHD_PLIST}\" ]; then\n    /usr/bin/plutil -replace Program -string \"${INSTALL_PATH}/SCHelper\" \"${SCHELPER_LAUNCHD_PLIST}\"\n    /usr/bin/plutil -convert binary1 \"${SCHELPER_LAUNCHD_PLIST}\"\nfi";
                        showEnvVarsInLog = 0;
                };
                15A66BB11F18177100F7253B /* Update "install_path" for address|thread sanitizers */ = {
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
-                       shellScript = "if [ -x ${SCRIPT_INPUT_FILE_0} ]; then\n\t${SCRIPT_INPUT_FILE_0} com.apple.configd_sim.plist\nfi";
+                       shellScript = "if [ -x ${SCRIPT_INPUT_FILE_0} ]; then\n\t${SCRIPT_INPUT_FILE_0} com.apple.configd_sim.plist\nfi\n";
                        showEnvVarsInLog = 0;
                };
                7271EA2E1D76600B0055B1AA /* Fix plist ownership */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
-                               C496A09620F909FF0098B3E5 /* IPConfigurationParser.m in Sources */,
                                C4666C7A206ED27800247AB6 /* EventFactory.m in Sources */,
-                               C4C5FB0C20EABD9E00F35614 /* IPMonitorParser.m in Sources */,
                                C4C5FB0520EA9B6F00F35614 /* SCLogParser.m in Sources */,
                                C4C5FB0920EAB0DD00F35614 /* InterfaceNamerParser.m in Sources */,
-                               C469CB2920EED6C100A7AD35 /* StateDumpParser.m in Sources */,
-                               C4C5FB0F20EAC05200F35614 /* PreferencesMonitorParser.m in Sources */,
+                               C496A09620F909FF0098B3E5 /* IPConfigurationParser.m in Sources */,
+                               C4C5FB0C20EABD9E00F35614 /* IPMonitorParser.m in Sources */,
                                C4C5FB0620EA9C3200F35614 /* KernelEventMonitorParser.m in Sources */,
+                               C4C5FB0F20EAC05200F35614 /* PreferencesMonitorParser.m in Sources */,
+                               C469CB2920EED6C100A7AD35 /* StateDumpParser.m in Sources */,
+                               1583DFBE2360D0E800AA397A /* SCDynamicStoreParser.m in Sources */,
+                               1583DFBD2360D0E800AA397A /* SCPreferencesParser.m in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        target = 15F742DA1EC6370000DA2E7A /* liblog_SystemConfiguration-Embedded */;
                        targetProxy = 15631D121ECF93040088EEDD /* PBXContainerItemProxy */;
                };
-               15631D271ECF99800088EEDD /* PBXTargetDependency */ = {
+               15631D2D1ECF99A00088EEDD /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 15631D161ECF98FB0088EEDD /* configd_executables-EmbeddedSimulator */;
+                       targetProxy = 15631D2C1ECF99A00088EEDD /* PBXContainerItemProxy */;
+               };
+               15677495246620C300B0C1D6 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
-                       target = 15F742E71EC638D100DA2E7A /* liblog_SystemConfiguration-EmbeddedSimulator */;
-                       targetProxy = 15631D261ECF99800088EEDD /* PBXContainerItemProxy */;
+                       target = 15E1B04116EBAE3C00E5F06F /* IPMonitor-EmbeddedSimulator */;
+                       targetProxy = 15677494246620C300B0C1D6 /* PBXContainerItemProxy */;
+               };
+               15677497246620C300B0C1D6 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 15E1B05A16EBAE7800E5F06F /* IPMonitor.bundle-EmbeddedSimulator */;
+                       targetProxy = 15677496246620C300B0C1D6 /* PBXContainerItemProxy */;
                };
-               15631D291ECF99800088EEDD /* PBXTargetDependency */ = {
+               15677499246620D600B0C1D6 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 15D3080F16F3E4DA00014F82 /* SimulatorSupport-EmbeddedSimulator */;
+                       targetProxy = 15677498246620D600B0C1D6 /* PBXContainerItemProxy */;
+               };
+               1567749B246620D600B0C1D6 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 15D3082816F3E4E100014F82 /* SimulatorSupport.bundle-EmbeddedSimulator */;
+                       targetProxy = 1567749A246620D600B0C1D6 /* PBXContainerItemProxy */;
+               };
+               1567749D246620E500B0C1D6 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 15732A7616EA503200F3AC4C /* configd-EmbeddedSimulator */;
-                       targetProxy = 15631D281ECF99800088EEDD /* PBXContainerItemProxy */;
+                       targetProxy = 1567749C246620E500B0C1D6 /* PBXContainerItemProxy */;
                };
-               15631D2B1ECF99800088EEDD /* PBXTargetDependency */ = {
+               1567749F246620F000B0C1D6 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 15732AAD16EA511900F3AC4C /* scutil-EmbeddedSimulator */;
-                       targetProxy = 15631D2A1ECF99800088EEDD /* PBXContainerItemProxy */;
+                       targetProxy = 1567749E246620F000B0C1D6 /* PBXContainerItemProxy */;
                };
-               15631D2D1ECF99A00088EEDD /* PBXTargetDependency */ = {
+               156774A12466218800B0C1D6 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
-                       target = 15631D161ECF98FB0088EEDD /* configd_executables-EmbeddedSimulator */;
-                       targetProxy = 15631D2C1ECF99A00088EEDD /* PBXContainerItemProxy */;
+                       target = 15F742E71EC638D100DA2E7A /* liblog_SystemConfiguration-EmbeddedSimulator */;
+                       targetProxy = 156774A02466218800B0C1D6 /* PBXContainerItemProxy */;
                };
                15732AE616EA6BCE00F3AC4C /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 1583177D0CFB85C8006F62B9 /* IPMonitor.bundle-Embedded */;
                        targetProxy = 158317BA0CFB8660006F62B9 /* PBXContainerItemProxy */;
                };
+               1584B5E12469B6CE00AFF758 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 1584B5C32469B65A00AFF758 /* configd_plugins-EmbeddedSimulator */;
+                       targetProxy = 1584B5E02469B6CE00AFF758 /* PBXContainerItemProxy */;
+               };
                158AD9860754E72500124717 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 15FD72A10754DA4C001CC321 /* IPMonitor.bundle */;
                        target = 15A5A1E40D5B94190087BDA0 /* SystemConfiguration.framework-EmbeddedSimulator */;
                        targetProxy = 15A5A2700D5B942D0087BDA0 /* PBXContainerItemProxy */;
                };
-               15AB752A16EC254D00FAA8CE /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = 15E1B04116EBAE3C00E5F06F /* IPMonitor-EmbeddedSimulator */;
-                       targetProxy = 15AB752916EC254D00FAA8CE /* PBXContainerItemProxy */;
-               };
                15C64A220F684C4900D78394 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 15DAD5DF075913CE0084A6ED /* libsystem_configuration */;
                        target = 157A84D80D56C63900B6F1A0 /* libsystem_configuration-Embedded */;
                        targetProxy = 15C64A300F684C8F00D78394 /* PBXContainerItemProxy */;
                };
-               15D3083016F3EAD000014F82 /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = 15D3080F16F3E4DA00014F82 /* SimulatorSupport-EmbeddedSimulator */;
-                       targetProxy = 15D3082F16F3EAD000014F82 /* PBXContainerItemProxy */;
-               };
-               15D3083216F3EAD000014F82 /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = 15D3082816F3E4E100014F82 /* SimulatorSupport.bundle-EmbeddedSimulator */;
-                       targetProxy = 15D3083116F3EAD000014F82 /* PBXContainerItemProxy */;
-               };
-               15D3083516F3EB2500014F82 /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = 15D3080F16F3E4DA00014F82 /* SimulatorSupport-EmbeddedSimulator */;
-                       targetProxy = 15D3083416F3EB2500014F82 /* PBXContainerItemProxy */;
-               };
-               15E1B03E16EBAB8A00E5F06F /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = 15732A7616EA503200F3AC4C /* configd-EmbeddedSimulator */;
-                       targetProxy = 15E1B03D16EBAB8A00E5F06F /* PBXContainerItemProxy */;
-               };
-               15E1B04016EBAB9400E5F06F /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = 15732AAD16EA511900F3AC4C /* scutil-EmbeddedSimulator */;
-                       targetProxy = 15E1B03F16EBAB9400E5F06F /* PBXContainerItemProxy */;
-               };
-               15E1B06416EBAF2A00E5F06F /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = 15E1B04116EBAE3C00E5F06F /* IPMonitor-EmbeddedSimulator */;
-                       targetProxy = 15E1B06316EBAF2A00E5F06F /* PBXContainerItemProxy */;
-               };
-               15E1B06616EBAF2A00E5F06F /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = 15E1B05A16EBAE7800E5F06F /* IPMonitor.bundle-EmbeddedSimulator */;
-                       targetProxy = 15E1B06516EBAF2A00E5F06F /* PBXContainerItemProxy */;
-               };
                15E83109167F9B0600FD51EC /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 15CB690005C0722A0099E85F /* All */;
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                PRODUCT_NAME = "configd_base (EmbeddedSimulator)";
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                PRODUCT_NAME = "configd_base (EmbeddedSimulator)";
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Release;
                };
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                PRODUCT_NAME = "configd_extras (EmbeddedSimulator)";
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                PRODUCT_NAME = "configd_extras (EmbeddedSimulator)";
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Release;
                };
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                PRODUCT_NAME = "configd_executables (EmbeddedSimulator)";
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                PRODUCT_NAME = "configd_executables (EmbeddedSimulator)";
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Release;
                };
                                OTHER_LDFLAGS = (
                                        "-Wl,-umbrella,System",
                                        "-L/usr/lib/system",
-                                       "-lcompiler_rt",
                                        "-ldispatch",
-                                       "-ldyld",
                                        "-lsystem_asl",
                                        "-lsystem_blocks",
                                        "-lsystem_c",
-                                       "-lsystem$(INTERPOSITION_SIM_SUFFIX)_kernel",
                                        "-lsystem_malloc",
                                        "-lsystem_notify",
                                        "-lsystem$(INTERPOSITION_SIM_SUFFIX)_platform",
                                        "-lsystem_trace",
                                        "-lxpc",
                                );
+                               "OTHER_LDFLAGS[arch=x86_64]" = (
+                                       "$(inherited)",
+                                       "-ldyld",
+                               );
                                "OTHER_LDFLAGS_asan[arch=i386]" = "";
                                "OTHER_LDFLAGS_asan[sdk=macosx*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.asan_osx_dynamic";
                                "OTHER_LDFLAGS_tsan[arch=i386]" = "";
                                OTHER_LDFLAGS = (
                                        "-Wl,-umbrella,System",
                                        "-L/usr/lib/system",
-                                       "-lcompiler_rt",
                                        "-ldispatch",
-                                       "-ldyld",
                                        "-lsystem_asl",
                                        "-lsystem_blocks",
                                        "-lsystem_c",
-                                       "-lsystem$(INTERPOSITION_SIM_SUFFIX)_kernel",
                                        "-lsystem_malloc",
                                        "-lsystem_notify",
                                        "-lsystem$(INTERPOSITION_SIM_SUFFIX)_platform",
                                        "-lsystem_trace",
                                        "-lxpc",
                                );
+                               "OTHER_LDFLAGS[arch=x86_64]" = (
+                                       "$(inherited)",
+                                       "-ldyld",
+                               );
                                "OTHER_LDFLAGS_asan[arch=i386]" = "";
                                "OTHER_LDFLAGS_asan[sdk=macosx*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.asan_osx_dynamic";
                                "OTHER_LDFLAGS_tsan[arch=i386]" = "";
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                "ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD)";
+                               CODE_SIGN_ENTITLEMENTS = "configd.tproj/entitlements-macOS.plist";
                                FRAMEWORK_SEARCH_PATHS = (
                                        "$(SYMROOT)",
                                        "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
                156EB6240905594A00EEF749 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               CODE_SIGN_ENTITLEMENTS = "configd.tproj/entitlements-macOS.plist";
                                FRAMEWORK_SEARCH_PATHS = (
                                        "$(SYMROOT)",
                                        "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
                                GCC_WARN_UNINITIALIZED_AUTOS = YES;
                                GCC_WARN_UNUSED_FUNCTION = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
-                               INSTALL_PATH = /usr/sbin;
                                INTERPOSITION_SIM_SUFFIX = "";
-                               "INTERPOSITION_SIM_SUFFIX[sdk=bridgesimulator*]" = _sim;
+                               "INTERPOSITION_SIM_SUFFIX[sdk=appletvsimulator*]" = _sim;
                                "INTERPOSITION_SIM_SUFFIX[sdk=iphonesimulator*]" = _sim;
-                               "INTERPOSITION_SIM_SUFFIX[sdk=tvossimulator*]" = _sim;
                                "INTERPOSITION_SIM_SUFFIX[sdk=watchsimulator*]" = _sim;
                                OTHER_CFLAGS = (
                                        "$(inherited)",
                                GCC_WARN_UNINITIALIZED_AUTOS = YES;
                                GCC_WARN_UNUSED_FUNCTION = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
-                               INSTALL_PATH = /usr/sbin;
                                INTERPOSITION_SIM_SUFFIX = "";
-                               "INTERPOSITION_SIM_SUFFIX[sdk=bridgesimulator*]" = _sim;
+                               "INTERPOSITION_SIM_SUFFIX[sdk=appletvsimulator*]" = _sim;
                                "INTERPOSITION_SIM_SUFFIX[sdk=iphonesimulator*]" = _sim;
-                               "INTERPOSITION_SIM_SUFFIX[sdk=tvossimulator*]" = _sim;
                                "INTERPOSITION_SIM_SUFFIX[sdk=watchsimulator*]" = _sim;
                                OTHER_CFLAGS = (
                                        "$(inherited)",
                                );
                                INFOPLIST_FILE = "SystemConfiguration.fproj/Info-Embedded.plist";
                                INSTALLHDRS_SCRIPT_PHASE = YES;
-                               "INSTALL_PATH[sdk=appletv*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
-                               "INSTALL_PATH[sdk=iphone*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
-                               "INSTALL_PATH[sdk=watch*]" = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+                               "INSTALL_PATH[sdk=appletvos*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
+                               "INSTALL_PATH[sdk=bridgeos*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
+                               "INSTALL_PATH[sdk=iphoneos*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
+                               "INSTALL_PATH[sdk=watchos*]" = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
                                LIBRARY_SEARCH_PATHS = (
                                        "$(SYMROOT)",
                                        "$(SDKROOT)/usr/local/lib",
                                PRODUCT_NAME = SystemConfiguration;
                                SDKROOT = iphoneos.internal;
                                SUPPORTED_PLATFORMS = "iphoneos tvos watchos bridgeos";
-                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=appletv*]" = NO;
-                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=bridge*]" = NO;
-                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=iphone*]" = NO;
-                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=watch*]" = YES;
+                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=appletvos*]" = NO;
+                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=bridgeos*]" = NO;
+                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=iphoneos*]" = NO;
+                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=watchos*]" = YES;
                                WRAPPER_EXTENSION = framework;
                        };
                        name = Debug;
                                );
                                INFOPLIST_FILE = "SystemConfiguration.fproj/Info-Embedded.plist";
                                INSTALLHDRS_SCRIPT_PHASE = YES;
-                               "INSTALL_PATH[sdk=appletv*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
-                               "INSTALL_PATH[sdk=iphone*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
-                               "INSTALL_PATH[sdk=watch*]" = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+                               "INSTALL_PATH[sdk=appletvos*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
+                               "INSTALL_PATH[sdk=bridgeos*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
+                               "INSTALL_PATH[sdk=iphoneos*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
+                               "INSTALL_PATH[sdk=watchos*]" = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
                                LIBRARY_SEARCH_PATHS = (
                                        "$(SYMROOT)",
                                        "$(SDKROOT)/usr/local/lib",
                                PRODUCT_NAME = SystemConfiguration;
                                SDKROOT = iphoneos.internal;
                                SUPPORTED_PLATFORMS = "iphoneos tvos watchos bridgeos";
-                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=appletv*]" = NO;
-                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=bridge*]" = NO;
-                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=iphone*]" = NO;
-                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=watch*]" = YES;
+                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=appletvos*]" = NO;
+                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=bridgeos*]" = NO;
+                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=iphoneos*]" = NO;
+                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=watchos*]" = YES;
                                WRAPPER_EXTENSION = framework;
                        };
                        name = Release;
                                );
                                PRODUCT_NAME = configd_sim;
                                SDKROOT = iphoneos.internal;
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Debug;
                };
                                );
                                PRODUCT_NAME = configd_sim;
                                SDKROOT = iphoneos.internal;
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Release;
                };
                                );
                                PRODUCT_NAME = scutil_sim;
                                SDKROOT = iphoneos.internal;
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Debug;
                };
                                );
                                PRODUCT_NAME = scutil_sim;
                                SDKROOT = iphoneos.internal;
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Release;
                };
                                OTHER_LDFLAGS = (
                                        "-Wl,-umbrella,System",
                                        "-L/usr/lib/system",
-                                       "-lcompiler_rt",
                                        "-ldispatch",
                                        "-ldyld",
-                                       "-lsystem_asl",
                                        "-lsystem_blocks",
                                        "-lsystem_c",
-                                       "-lsystem$(INTERPOSITION_SIM_SUFFIX)_kernel",
                                        "-lsystem_malloc",
                                        "-lsystem_notify",
-                                       "-lsystem$(INTERPOSITION_SIM_SUFFIX)_platform",
                                        "-lsystem$(INTERPOSITION_SIM_SUFFIX)_pthread",
                                        "-lsystem_trace",
                                        "-lxpc",
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include;
                                SDKROOT = iphoneos.internal;
                                STRIP_INSTALLED_PRODUCT_normal = YES;
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Debug;
                };
                                OTHER_LDFLAGS = (
                                        "-Wl,-umbrella,System",
                                        "-L/usr/lib/system",
-                                       "-lcompiler_rt",
                                        "-ldispatch",
                                        "-ldyld",
-                                       "-lsystem_asl",
                                        "-lsystem_blocks",
                                        "-lsystem_c",
-                                       "-lsystem$(INTERPOSITION_SIM_SUFFIX)_kernel",
                                        "-lsystem_malloc",
                                        "-lsystem_notify",
-                                       "-lsystem$(INTERPOSITION_SIM_SUFFIX)_platform",
                                        "-lsystem$(INTERPOSITION_SIM_SUFFIX)_pthread",
                                        "-lsystem_trace",
                                        "-lxpc",
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include;
                                SDKROOT = iphoneos.internal;
                                STRIP_INSTALLED_PRODUCT_normal = YES;
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Release;
                };
                                OTHER_LDFLAGS = (
                                        "-Wl,-umbrella,System",
                                        "-L/usr/lib/system",
-                                       "-lcompiler_rt",
                                        "-ldispatch",
-                                       "-ldyld",
                                        "-lsystem_asl",
                                        "-lsystem_blocks",
                                        "-lsystem_c",
-                                       "-lsystem_kernel",
                                        "-lsystem_malloc",
                                        "-lsystem_notify",
-                                       "-lsystem_platform",
                                        "-lsystem_pthread",
                                        "-lsystem_trace",
                                        "-lxpc",
                                        "-Wl,-upward-lSystem",
                                );
                                "OTHER_LDFLAGS_asan[arch=i386]" = "";
+                               "OTHER_LDFLAGS_asan[sdk=appletvos*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.asan_tvos_dynamic";
+                               "OTHER_LDFLAGS_asan[sdk=appletvossimulator*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.asan_tvossim_dynamic";
                                "OTHER_LDFLAGS_asan[sdk=bridgeos*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.asan_bridgeos_dynamic";
                                "OTHER_LDFLAGS_asan[sdk=iphoneos*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.asan_ios_dynamic";
                                "OTHER_LDFLAGS_asan[sdk=iphonesimulator*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.asan_iossim_dynamic";
                                "OTHER_LDFLAGS_asan[sdk=macosx*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.asan_osx_dynamic";
-                               "OTHER_LDFLAGS_asan[sdk=tvos*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.asan_tvos_dynamic";
-                               "OTHER_LDFLAGS_asan[sdk=tvossimulator*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.asan_tvossim_dynamic";
                                "OTHER_LDFLAGS_asan[sdk=watchos*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.asan_watchos_dynamic";
                                "OTHER_LDFLAGS_asan[sdk=watchsimulator*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.asan_watchossim_dynamic";
                                "OTHER_LDFLAGS_tsan[arch=i386]" = "";
+                               "OTHER_LDFLAGS_tsan[sdk=appletvos*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.tsan_tvos_dynamic";
+                               "OTHER_LDFLAGS_tsan[sdk=appletvossimulator*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.tsan_tvossim_dynamic";
                                "OTHER_LDFLAGS_tsan[sdk=bridgeos*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.tsan_bridgeos_dynamic";
                                "OTHER_LDFLAGS_tsan[sdk=iphoneos*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.tsan_ios_dynamic";
                                "OTHER_LDFLAGS_tsan[sdk=iphonesimulator*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.tsan_iossim_dynamic";
                                "OTHER_LDFLAGS_tsan[sdk=macosx*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.tsan_osx_dynamic";
-                               "OTHER_LDFLAGS_tsan[sdk=tvos*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.tsan_tvos_dynamic";
-                               "OTHER_LDFLAGS_tsan[sdk=tvossimulator*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.tsan_tvossim_dynamic";
                                "OTHER_LDFLAGS_tsan[sdk=watchos*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.tsan_watchos_dynamic";
                                "OTHER_LDFLAGS_tsan[sdk=watchsimulator*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.tsan_watchossim_dynamic";
                                OTHER_TAPI_FLAGS = "$(inherited) -umbrella System --extra-private-header=$(PROJECT_DIR)/libSystemConfiguration/libSystemConfiguration_internal.h --extra-private-header=$(PROJECT_DIR)/nwi/network_information_internal.h --extra-private-header=$(PROJECT_DIR)/nwi/network_config_agent_info_priv.h";
                                OTHER_LDFLAGS = (
                                        "-Wl,-umbrella,System",
                                        "-L/usr/lib/system",
-                                       "-lcompiler_rt",
                                        "-ldispatch",
-                                       "-ldyld",
                                        "-lsystem_asl",
                                        "-lsystem_blocks",
                                        "-lsystem_c",
-                                       "-lsystem_kernel",
                                        "-lsystem_malloc",
                                        "-lsystem_notify",
-                                       "-lsystem_platform",
                                        "-lsystem_pthread",
                                        "-lsystem_trace",
                                        "-lxpc",
                                        "-Wl,-upward-lSystem",
                                );
                                "OTHER_LDFLAGS_asan[arch=i386]" = "";
+                               "OTHER_LDFLAGS_asan[sdk=appletvos*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.asan_tvos_dynamic";
+                               "OTHER_LDFLAGS_asan[sdk=appletvossimulator*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.asan_tvossim_dynamic";
                                "OTHER_LDFLAGS_asan[sdk=bridgeos*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.asan_bridgeos_dynamic";
                                "OTHER_LDFLAGS_asan[sdk=iphoneos*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.asan_ios_dynamic";
                                "OTHER_LDFLAGS_asan[sdk=iphonesimulator*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.asan_iossim_dynamic";
                                "OTHER_LDFLAGS_asan[sdk=macosx*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.asan_osx_dynamic";
-                               "OTHER_LDFLAGS_asan[sdk=tvos*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.asan_tvos_dynamic";
-                               "OTHER_LDFLAGS_asan[sdk=tvossimulator*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.asan_tvossim_dynamic";
                                "OTHER_LDFLAGS_asan[sdk=watchos*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.asan_watchos_dynamic";
                                "OTHER_LDFLAGS_asan[sdk=watchsimulator*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.asan_watchossim_dynamic";
                                "OTHER_LDFLAGS_tsan[arch=i386]" = "";
+                               "OTHER_LDFLAGS_tsan[sdk=appletvos*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.tsan_tvos_dynamic";
+                               "OTHER_LDFLAGS_tsan[sdk=appletvossimulator*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.tsan_tvossim_dynamic";
                                "OTHER_LDFLAGS_tsan[sdk=bridgeos*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.tsan_bridgeos_dynamic";
                                "OTHER_LDFLAGS_tsan[sdk=iphoneos*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.tsan_ios_dynamic";
                                "OTHER_LDFLAGS_tsan[sdk=iphonesimulator*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.tsan_iossim_dynamic";
                                "OTHER_LDFLAGS_tsan[sdk=macosx*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.tsan_osx_dynamic";
-                               "OTHER_LDFLAGS_tsan[sdk=tvos*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.tsan_tvos_dynamic";
-                               "OTHER_LDFLAGS_tsan[sdk=tvossimulator*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.tsan_tvossim_dynamic";
                                "OTHER_LDFLAGS_tsan[sdk=watchos*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.tsan_watchos_dynamic";
                                "OTHER_LDFLAGS_tsan[sdk=watchsimulator*]" = "$(inherited) -L/usr/appleinternal/lib/sanitizers -lclang_rt.tsan_watchossim_dynamic";
                                OTHER_TAPI_FLAGS = "$(inherited) -umbrella System --extra-private-header=$(PROJECT_DIR)/libSystemConfiguration/libSystemConfiguration_internal.h --extra-private-header=$(PROJECT_DIR)/nwi/network_information_internal.h --extra-private-header=$(PROJECT_DIR)/nwi/network_config_agent_info_priv.h";
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                PRODUCT_NAME = "configd_libSystem (EmbeddedSimulator)";
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                PRODUCT_NAME = "configd_libSystem (EmbeddedSimulator)";
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Release;
                };
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
-                               "INSTALL_PATH[sdk=appletv*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks/SystemConfiguration.framework";
-                               "INSTALL_PATH[sdk=iphone*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks/SystemConfiguration.framework";
-                               "INSTALL_PATH[sdk=watch*]" = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks/SystemConfiguration.framework";
+                               "INSTALL_PATH[sdk=appletvos*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks/SystemConfiguration.framework";
+                               "INSTALL_PATH[sdk=bridgeos*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks/SystemConfiguration.framework";
+                               "INSTALL_PATH[sdk=iphoneos*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks/SystemConfiguration.framework";
+                               "INSTALL_PATH[sdk=watchos*]" = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks/SystemConfiguration.framework";
                                PRODUCT_NAME = SCHelper;
                                SDKROOT = iphoneos.internal;
                                SUPPORTED_PLATFORMS = "iphoneos tvos watchos bridgeos";
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
-                               "INSTALL_PATH[sdk=appletv*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks/SystemConfiguration.framework";
-                               "INSTALL_PATH[sdk=iphone*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks/SystemConfiguration.framework";
-                               "INSTALL_PATH[sdk=watch*]" = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks/SystemConfiguration.framework";
+                               "INSTALL_PATH[sdk=appletvos*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks/SystemConfiguration.framework";
+                               "INSTALL_PATH[sdk=bridgeos*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks/SystemConfiguration.framework";
+                               "INSTALL_PATH[sdk=iphoneos*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks/SystemConfiguration.framework";
+                               "INSTALL_PATH[sdk=watchos*]" = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks/SystemConfiguration.framework";
                                PRODUCT_NAME = SCHelper;
                                SDKROOT = iphoneos.internal;
                                SUPPORTED_PLATFORMS = "iphoneos tvos watchos bridgeos";
                        };
                        name = Release;
                };
+               1584B5DD2469B65A00AFF758 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               SUPPORTED_PLATFORMS = "iphoneos tvos watchos bridgeos";
+                       };
+                       name = Debug;
+               };
+               1584B5DE2469B65A00AFF758 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               SUPPORTED_PLATFORMS = "iphoneos tvos watchos bridgeos";
+                       };
+                       name = Release;
+               };
                15A5A2670D5B94190087BDA0 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                );
                                INFOPLIST_FILE = "SystemConfiguration.fproj/Info-Embedded.plist";
                                INSTALLHDRS_SCRIPT_PHASE = YES;
-                               "INSTALL_PATH[sdk=appletv*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
-                               "INSTALL_PATH[sdk=iphone*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
-                               "INSTALL_PATH[sdk=watch*]" = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+                               "INSTALL_PATH[sdk=appletvsimulator*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
+                               "INSTALL_PATH[sdk=iphonesimulator*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
+                               "INSTALL_PATH[sdk=watchsimulator*]" = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
                                LIBRARY_SEARCH_PATHS = (
                                        "$(SYMROOT)",
                                        "$(SDKROOT)/usr/local/lib",
                                PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration;
                                PRODUCT_NAME = SystemConfiguration;
                                SDKROOT = iphoneos.internal;
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
-                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=appletv*]" = NO;
-                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=bridge*]" = NO;
-                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=iphone*]" = NO;
-                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=watch*]" = YES;
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
+                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=appletvsimulator*]" = NO;
+                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=iphonesimulator*]" = NO;
+                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=watchsimulator*]" = YES;
                                WRAPPER_EXTENSION = framework;
                        };
                        name = Debug;
                                );
                                INFOPLIST_FILE = "SystemConfiguration.fproj/Info-Embedded.plist";
                                INSTALLHDRS_SCRIPT_PHASE = YES;
-                               "INSTALL_PATH[sdk=appletv*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
-                               "INSTALL_PATH[sdk=iphone*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
-                               "INSTALL_PATH[sdk=watch*]" = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+                               "INSTALL_PATH[sdk=appletvsimulator*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
+                               "INSTALL_PATH[sdk=iphonesimulator*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
+                               "INSTALL_PATH[sdk=watchsimulator*]" = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
                                LIBRARY_SEARCH_PATHS = (
                                        "$(SYMROOT)",
                                        "$(SDKROOT)/usr/local/lib",
                                PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration;
                                PRODUCT_NAME = SystemConfiguration;
                                SDKROOT = iphoneos.internal;
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
-                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=appletv*]" = NO;
-                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=bridge*]" = NO;
-                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=iphone*]" = NO;
-                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=watch*]" = YES;
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
+                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=appletvsimulator*]" = NO;
+                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=iphonesimulator*]" = NO;
+                               "USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK[sdk=watchsimulator*]" = YES;
                                WRAPPER_EXTENSION = framework;
                        };
                        name = Release;
                                PRODUCT_NAME = SimulatorSupport_sim;
                                SDKROOT = iphoneos.internal;
                                STRIP_INSTALLED_PRODUCT = NO;
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Debug;
                };
                                PRODUCT_NAME = SimulatorSupport_sim;
                                SDKROOT = iphoneos.internal;
                                STRIP_INSTALLED_PRODUCT = NO;
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Release;
                };
                                PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.SimulatorSupport;
                                PRODUCT_NAME = SimulatorSupport;
                                SDKROOT = iphoneos.internal;
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Debug;
                };
                                PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.SimulatorSupport;
                                PRODUCT_NAME = SimulatorSupport;
                                SDKROOT = iphoneos.internal;
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Release;
                };
                                PRODUCT_NAME = IPMonitor_sim;
                                SDKROOT = iphoneos.internal;
                                STRIP_INSTALLED_PRODUCT = NO;
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Debug;
                };
                                PRODUCT_NAME = IPMonitor_sim;
                                SDKROOT = iphoneos.internal;
                                STRIP_INSTALLED_PRODUCT = NO;
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Release;
                };
                                PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.IPMonitor;
                                PRODUCT_NAME = IPMonitor;
                                SDKROOT = iphoneos.internal;
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Debug;
                };
                                PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.IPMonitor;
                                PRODUCT_NAME = IPMonitor;
                                SDKROOT = iphoneos.internal;
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Release;
                };
                                STRIP_INSTALLED_PRODUCT_normal = YES;
                                STRIP_INSTALLED_PRODUCT_profile = NO;
                                STRIP_INSTALLED_PRODUCT_tsan = NO;
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Debug;
                };
                                STRIP_INSTALLED_PRODUCT_normal = YES;
                                STRIP_INSTALLED_PRODUCT_profile = NO;
                                STRIP_INSTALLED_PRODUCT_tsan = NO;
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Release;
                };
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                PRODUCT_NAME = configdAggregateEmbeddedSimulator;
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                PRODUCT_NAME = configdAggregateEmbeddedSimulator;
-                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+                               SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
                        };
                        name = Release;
                };
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
+               1584B5DC2469B65A00AFF758 /* Build configuration list for PBXAggregateTarget "configd_plugins-EmbeddedSimulator" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               1584B5DD2469B65A00AFF758 /* Debug */,
+                               1584B5DE2469B65A00AFF758 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
                15A5A2660D5B94190087BDA0 /* Build configuration list for PBXNativeTarget "SystemConfiguration.framework-EmbeddedSimulator" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
 
 /*
- * Copyright (c) 2009, 2011, 2012, 2014, 2015, 2017-2019 Apple Inc. All rights reserved.
+ * Copyright (c) 2009, 2011, 2012, 2014, 2015, 2017-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <unistd.h>
+#include <SystemConfiguration/SCPrivate.h>     // for SC_log
 
-#ifdef MAIN
-#define        my_log(__level, __format, ...)  SCPrint(TRUE, stdout, CFSTR(__format "\n"), ## __VA_ARGS__)
-#endif // MAIN
+#ifdef SC_LOG_HANDLE
+#include <os/log.h>
+os_log_t       SC_LOG_HANDLE(void);
+#endif //SC_LOG_HANDLE
 
 #include "dnsinfo.h"
 #include "dnsinfo_private.h"
                }
                if (token == -1) {
                        // if not a recognized token
+                       SC_log(LOG_NOTICE,
+                              "Unrecognized token (%s) found in: %s",
+                              word,
+                              filename);
                        continue;
                }
 
 
                for if in ${IF_LIST}
                do
                        echo "#"                                        >> netstat.txt
-                       echo "# netstat -s -I ${if}"                    >> netstat.txt
+                       echo "# netstat -n -s -I ${if}"                 >> netstat.txt
                        echo "#"                                        >> netstat.txt
-                       /usr/sbin/netstat -s -I ${if}                   >> netstat.txt          2>&1
+                       /usr/sbin/netstat -n -s -I ${if}                >> netstat.txt          2>&1
 
                        IF_INFO=`/sbin/ifconfig -v ${if}`
                        `echo $IF_INFO | grep -q TXSTART`
                                echo "not available"                    >> ipconfig-info.txt
                        fi
 
+                       echo""                                          >> ipconfig-info.txt
+
+                       echo "IPv6 information:"                        >> ipconfig-info.txt
+
+                       IPCONFIG_INFO=`/usr/sbin/ipconfig getra ${if}`
+                       if [ "${IPCONFIG_INFO}" != "" ]; then
+                               echo "${IPCONFIG_INFO}"                 >> ipconfig-info.txt
+                       else
+                               echo "not available"                    >> ipconfig-info.txt
+                       fi
+
                        echo""                                          >> ipconfig-info.txt
                        ;;
                esac
 
 /*
- * Copyright (c) 2012, 2013, 2015, 2016, 2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2012, 2013, 2015, 2016, 2018, 2019 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 {
        xpc_connection_t        c;
        libSC_info_client_t     *client;
-#if    !TARGET_OS_SIMULATOR || TARGET_OS_IOSMAC
+#if    !TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
        const uint64_t          flags   =       XPC_CONNECTION_MACH_SERVICE_PRIVILEGED;
-#else  // !TARGET_OS_SIMULATOR || TARGET_OS_IOSMAC
+#else  // !TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
        const uint64_t          flags   =       0;
-#endif // !TARGET_OS_SIMULATOR || TARGET_OS_IOSMAC
+#endif // !TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
 
        if (!_available) {
                return NULL;
 
 /*
- * Copyright (c) 2012, 2013, 2015-2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2012, 2013, 2015-2019 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 
 #define        DNSINFO_SERVER_VERSION          20130408
 
-#if    !TARGET_OS_SIMULATOR || TARGET_OS_IOSMAC
+#if    !TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
 #define        DNSINFO_SERVICE_NAME            "com.apple.SystemConfiguration.DNSConfiguration"
-#else  // !TARGET_OS_SIMULATOR || TARGET_OS_IOSMAC
+#else  // !TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
 #define        DNSINFO_SERVICE_NAME            "com.apple.SystemConfiguration.DNSConfiguration_sim"
-#endif // !TARGET_OS_SIMULATOR || TARGET_OS_IOSMAC
+#endif // !TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
 
 #define        DNSINFO_PROC_NAME               "proc_name"     // string
 
 
 #define        NWI_SERVER_VERSION              20130408
 
-#if    !TARGET_OS_SIMULATOR || TARGET_OS_IOSMAC
+#if    !TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
 #define        NWI_SERVICE_NAME                "com.apple.SystemConfiguration.NetworkInformation"
-#else  // !TARGET_OS_SIMULATOR || TARGET_OS_IOSMAC
+#else  // !TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
 #define        NWI_SERVICE_NAME                "com.apple.SystemConfiguration.NetworkInformation_sim"
-#endif // !TARGET_OS_SIMULATOR || TARGET_OS_IOSMAC
+#endif // !TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
 
 #define        NWI_PROC_NAME                   "proc_name"     // string
 
        NWI_STATE_REQUEST_COPY          = 0x20001,
        NWI_STATE_REQUEST_ACKNOWLEDGE,
 
-#if    !TARGET_OS_SIMULATOR || TARGET_OS_IOSMAC
+#if    !TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
        /* NWI config agent requests  */
        NWI_CONFIG_AGENT_REQUEST_COPY
-#endif // !TARGET_OS_SIMULATOR || TARGET_OS_IOSMAC
+#endif // !TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
 };
 
 #define        NWI_CONFIGURATION               "configuration" // data
 
 /*
- * Copyright (c) 2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2017, 2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 static NS_RETURNS_RETAINED NSString *
 _SC_OSStateCopyFormattedString_nwi(uint32_t data_size, void *data)
 {
+       nwi_ifindex_t           index;
+       nwi_ifindex_t           *scan;
        nwi_state_t             state   = (nwi_state_t)data;
        NSMutableString         *string;
 
 
        if ((data_size == 0) || (data == NULL)) {
                return @"No network information";
-       } else if (data_size < sizeof(nwi_state)) {
+       }
+
+       if (data_size < sizeof(nwi_state)) {
                return SCNSWithFormat(@"Network information: size error (%d < %zd)",
                                      data_size,
                                      sizeof(_dns_config_buf_t));
-       } else if (state->version != NWI_STATE_VERSION) {
+       }
+
+       if (state->version != NWI_STATE_VERSION) {
                return SCNSWithFormat(@"Network information: version error (%d != %d)",
                                      state->version,
                                      NWI_STATE_VERSION);
        }
 
+       if (data_size != nwi_state_size(state)) {
+               return SCNSWithFormat(@"Network information: size error (%d != %zd)",
+                                     data_size,
+                                     nwi_state_size(state));
+       }
+
+       if (state->ipv4_count > state->max_if_count) {
+               return SCNSWithFormat(@"Network information: ipv4 count error (%d > %d)",
+                                     state->ipv4_count,
+                                     state->max_if_count);
+       }
+
+       if (state->ipv6_count > state->max_if_count) {
+               return SCNSWithFormat(@"Network information: ipv6 count error (%d > %d)",
+                                     state->ipv6_count,
+                                     state->max_if_count);
+       }
+
+       if (state->if_list_count > state->max_if_count) {
+               return SCNSWithFormat(@"Network information: if_list count error (%d > %d)",
+                                     state->if_list_count,
+                                     state->max_if_count);
+       }
+
+       for (index = 0; index < state->ipv4_count; index++) {
+               nwi_ifindex_t   alias_index;
+               nwi_ifindex_t   alias_offset    = state->ifstate_list[index].af_alias_offset;
+
+               if (alias_offset == 0) {
+                       continue;
+               }
+               alias_index = alias_offset + index - state->max_if_count;
+               if ((alias_index < 0) || (alias_index >= state->ipv6_count)) {
+                       return SCNSWithFormat(@"Network information: IPv4 alias [%d] offset error (%d < 0 || %d >= %d)",
+                                             index,
+                                             alias_index,
+                                             alias_index,
+                                             state->ipv6_count);
+               }
+       }
+
+       for (index = 0; index < state->ipv6_count; index++) {
+               nwi_ifindex_t   alias_index;
+               nwi_ifindex_t   alias_offset    = state->ifstate_list[state->max_if_count + index].af_alias_offset;
+
+               if (alias_offset == 0) {
+                       continue;
+               }
+               alias_index = alias_offset + index + state->max_if_count;
+               if ((alias_index < 0) || (alias_index >= state->ipv4_count)) {
+                       return SCNSWithFormat(@"Network information: IPv6 alias [%d] offset error (%d < 0 || %d >= %d)",
+                                             index,
+                                             alias_index,
+                                             alias_index,
+                                             state->ipv4_count);
+               }
+       }
+
+       // check if_list[] indices
+       for (index = 0, scan = nwi_state_if_list(state);
+            index < state->if_list_count;
+            index++, scan++) {
+               if (*scan >= (state->max_if_count * 2)) {
+                       return SCNSWithFormat(@"Network information: if_list index error (%d > %d)",
+                                             *scan,
+                                             state->max_if_count * 2);
+               }
+       }
+
        string = [NSMutableString string];
        _nwi_state_log(state, TRUE, string);
        if (string.length == 0) {
 
 /*
- * Copyright (c) 2011-2019 Apple Inc. All rights reserved.
+ * Copyright (c) 2011-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
                size_t          dataLen = 0;
 
                dataRef = xpc_dictionary_get_data(reply, NWI_CONFIGURATION, &dataLen);
-               if (dataRef != NULL) {
+               if ((dataRef != NULL) && (dataLen >= sizeof(nwi_state))) {
                        nwi_state = malloc(dataLen);
                        memcpy(nwi_state, (void *)dataRef, dataLen);
                        if (nwi_state->version != NWI_STATE_VERSION) {
                return (state->if_list_count);
        }
        for (i = 0, scan = nwi_state_if_list(state);
-            i < state->if_list_count; i++, scan++) {
-               names[i] = state->ifstate_list[*scan].ifname;
+            i < state->if_list_count;
+            i++, scan++) {
+               if (*scan < (state->max_if_count * 2)) {
+                   names[i] = state->ifstate_list[*scan].ifname;
+               } else {
+                   // nwi_state is corrupt
+                   return (0);
+               }
        }
        return (state->if_list_count);
 }
 
 /*
- * Copyright (c) 2011-2013, 2016-2019 Apple Inc. All rights reserved.
+ * Copyright (c) 2011-2013, 2016-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 {
        int i_idx = idx;
 
+       if (idx >= state->max_if_count) {
+               return (NULL);
+       }
+
        if (idx >= nwi_state_get_ifstate_count(state, af)) {
                return (NULL);
        }
        nwi_ifstate_t ifstate = NULL;
 
        if (state == NULL) {
-               return NULL;
+               return (NULL);
        }
 
-       count = (af == AF_INET)
-       ?state->ipv4_count:state->ipv6_count;
-
+       count = (af == AF_INET) ? state->ipv4_count : state->ipv6_count;
+       if (count > state->max_if_count) {
+               return (NULL);
+       }
 
        while (idx < count) {
                ifstate = nwi_state_get_ifstate_with_index(state, af, idx);
 
                CFPropertyListRef value = SCDynamicStoreCopyValue(self.store, key);
                SCTestLog("%@ : %@", key, value);
                CFRelease(key);
+               if (value != NULL) {
+                       CFRelease(value);
+               }
        }
 
        if (self.options[kSCTestDynamicStoreOptionIPv4]) {
                CFPropertyListRef value = SCDynamicStoreCopyValue(self.store, key);
                SCTestLog("%@ : %@", key, value);
                CFRelease(key);
+               if (value != NULL) {
+                       CFRelease(value);
+               }
        }
 
        if (self.options[kSCTestDynamicStoreOptionIPv6]) {
                CFPropertyListRef value = SCDynamicStoreCopyValue(self.store, key);
                SCTestLog("%@ : %@", key, value);
                CFRelease(key);
+               if (value != NULL) {
+                       CFRelease(value);
+               }
        }
 
        if (self.options[kSCTestDynamicStoreOptionProxies]) {
                CFPropertyListRef value = SCDynamicStoreCopyValue(self.store, key);
                SCTestLog("%@ : %@", key, value);
                CFRelease(key);
+               if (value != NULL) {
+                       CFRelease(value);
+               }
        }
 
        [self cleanupAndExitWithErrorCode:0];
 
 #include <IOKit/network/IOUserEthernetController.h>
 #include <IOKit/storage/IOStorageDeviceCharacteristics.h>
 #include <IOKit/usb/USB.h>
+#include "plugin_shared.h"
 
 #define        INTERFACES_KEY                  @"State:/Network/Interface"
 #define        PLUGIN_INTERFACE_NAMER_KEY      @"Plugin:InterfaceNamer"
 
        BOOL allUnitTestsPassed = YES;
        allUnitTestsPassed &= [self unitTestInsertRemoveOneInterface];
+       allUnitTestsPassed &= [self unitTestInsertRemoveMultipleInterfaces];
+       allUnitTestsPassed &= [self unitTestCheckIOKitQuiet];
+       allUnitTestsPassed &= [self unitTestCheckEN0];
 
        if(![self tearDown]) {
                return NO;
        return ok;
 }
 
+#pragma mark -
+#pragma mark unitTestCheckIOKitQuiet
+
+- (BOOL)unitTestCheckIOKitQuiet
+{
+       CFDictionaryRef         dict;
+       const char              *err            = NULL;
+       Boolean                 hasNamer        = FALSE;
+       Boolean                 hasQuiet        = FALSE;
+       Boolean                 hasTimeout      = FALSE;
+       CFArrayRef              interfaces;
+       CFStringRef             key;
+       BOOL                    ok              = FALSE;
+
+       SCTestLog("Checking IOKit quiet");
+
+       // first off, we need to wait for *QUIET* or *TIMEOUT*
+       interfaces = SCNetworkInterfaceCopyAll();
+       if (interfaces != NULL) {
+               CFRelease(interfaces);
+       }
+
+       // now, we check the configd/InterfaceNamer status
+       key = SCDynamicStoreKeyCreate(NULL, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin);
+       dict = SCDynamicStoreCopyValue(NULL, key);
+       CFRelease(key);
+       if (dict != NULL) {
+               hasNamer   = TRUE;
+               hasQuiet   = CFDictionaryContainsKey(dict, kInterfaceNamerKey_Quiet);
+               hasTimeout = CFDictionaryContainsKey(dict, kInterfaceNamerKey_Timeout);
+               CFRelease(dict);
+       } else {
+               SCTestLog("*** configd/InterfaceNamer status not available");
+       }
+
+       if (hasQuiet) {
+               if (hasTimeout) {
+                       err = "*** configd/InterfaceNamer quiet after timeout";
+               } else {
+                       // quiet
+                       ok = TRUE;
+               }
+       } else {
+               if (hasTimeout) {
+                       err = "*** configd/InterfaceNamer timeout, not quiet";
+               } else {
+                       kern_return_t   ret;
+                       mach_timespec_t waitTime        = { 60, 0 };
+
+                       /*
+                        * Here, we're in limbo.
+                        * 1. InterfaceNamer has not reported that the IORegistry
+                        *    to be quiet
+                        * 2. InterfaceNamer was happy yet quiet, but has not
+                        *    reported the timeout
+                        *
+                        * This likely means that we detected the previousl named
+                        * interfaces and released any waiting processes.  But, we
+                        * don't know if the IORegistry actually quiesced.
+                        *
+                        * So, let's just check/wait.
+                        */
+                       ret = IOKitWaitQuiet(kIOMasterPortDefault, &waitTime);
+                       if (ret == kIOReturnSuccess) {
+                               if (hasNamer) {
+                                       SCTestLog("*** configd/InterfaceNamer released before quiet");
+                                       ok = TRUE;
+                               } else {
+                                       err = "*** configd/InterfaceNamer did not report quiet status";
+                               }
+                       } else {
+                               err = "*** IOKit not quiet";
+                       }
+               }
+       }
+
+       if (ok) {
+               SCTestLog("IOKit quiesced");
+       } else if (err != NULL) {
+               SCTestLog("%s", err);
+       }
+
+       return ok;
+}
+
+#pragma mark -
+#pragma mark unitTestCheckEN0
+
+- (BOOL)unitTestCheckEN0
+{
+       CFStringRef             en0             = CFSTR("en0");
+       Boolean                 en0Found        = FALSE;
+       char                    *if_name;
+       CFArrayRef              interfaces;
+       BOOL                    ok              = FALSE;
+
+       SCTestLog("Checking interfaces");
+
+       // for debugging, provide a way to use an alternate interface name
+       if_name = getenv("EN0");
+       if (if_name != NULL) {
+               en0 = CFStringCreateWithCString(NULL, if_name, kCFStringEncodingUTF8);
+       } else {
+               CFRetain(en0);
+       }
+
+       interfaces = SCNetworkInterfaceCopyAll();
+       if (interfaces != NULL) {
+               CFIndex         n;
+
+               n = CFArrayGetCount(interfaces);
+               for (CFIndex i = 0; i < n; i++) {
+                       CFStringRef             bsdName;
+                       SCNetworkInterfaceRef   interface;
+
+                       interface = CFArrayGetValueAtIndex(interfaces, i);
+                       bsdName = SCNetworkInterfaceGetBSDName(interface);
+                       if (_SC_CFEqual(bsdName, en0)) {
+                               CFStringRef     interfaceType;
+
+                               en0Found = TRUE;
+
+                               if (!_SCNetworkInterfaceIsBuiltin(interface)) {
+                                       SCTestLog("*** Network interface \"%@\" not built-in", en0);
+                                       break;
+                               }
+
+                               interfaceType = SCNetworkInterfaceGetInterfaceType(interface);
+                               if (CFEqual(interfaceType, kSCNetworkInterfaceTypeEthernet)) {
+                                       if (!_SCNetworkInterfaceIsThunderbolt(interface) &&
+                                           !_SCNetworkInterfaceIsApplePreconfigured(interface)) {
+                                               // if Ethernet (and not Thunderbolt, Bridge, ...)
+                                               ok = TRUE;
+                                               break;
+                                       }
+                               } else if (CFEqual(interfaceType, kSCNetworkInterfaceTypeIEEE80211)) {
+                                       // if Wi-Fi
+                                       ok = TRUE;
+                                       break;
+                               }
+
+                               SCTestLog("*** Network interface \"%@\" not Ethernet or Wi-Fi", en0);
+                               break;
+                       }
+               }
+
+               CFRelease(interfaces);
+       }
+
+       if (!en0Found) {
+               SCTestLog("*** Network interface \"%@\" not found", en0);
+       }
+
+       if (ok) {
+               SCTestLog("Verified \"%@\"", en0);
+       }
+
+       return ok;
+}
+
 @end
 
 /*
- * Copyright (c) 2016, 2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2016, 2017, 2019 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 
 #import "SCTest.h"
 #import "SCTestUtils.h"
+#import <notify.h>
+#import <SystemConfiguration/scprefs_observer.h>
 
 @interface SCTestPreferences : SCTest
 @property SCPreferencesRef prefs;
+@property dispatch_semaphore_t sem;
+@property int counter;
 @end
 
 @implementation SCTestPreferences
        BOOL allUnitTestsPassed = YES;
        allUnitTestsPassed &= [self unitTestNetworkServicesSanity];
        allUnitTestsPassed &= [self unitTestPreferencesAPI];
+       allUnitTestsPassed &= [self unitTestPreferencesNotifications];
+       allUnitTestsPassed &= [self unitTestPreferencesObserver];
        allUnitTestsPassed &= [self unitTestPreferencesSession];
        return  allUnitTestsPassed;
 
        return YES;
 }
 
+static void
+myNotificationsCallback(SCPreferencesRef prefs, SCPreferencesNotification notificationType, void *ctx)
+{
+#pragma unused(prefs)
+#pragma unused(notificationType)
+       SCTestPreferences *test = (__bridge SCTestPreferences *)ctx;
+       test.counter++;
+       if (test.sem != NULL) {
+               dispatch_semaphore_signal(test.sem);
+       }
+}
+
+- (BOOL)unitTestPreferencesNotifications
+{
+       dispatch_queue_t        callbackQ;
+       const int               iterations      = 10;
+       BOOL                    ok              = FALSE;
+       SCTestPreferences       *test;
+       const int               timeout         = 1;    // second
+
+       test = [[SCTestPreferences alloc] initWithOptions:self.options];
+       if (test.prefs != NULL) {
+               CFRelease(test.prefs);
+               test.prefs = NULL;
+       }
+
+       test.sem = dispatch_semaphore_create(0);
+
+       SCPreferencesContext ctx = {0, (__bridge void * _Nullable)(test), CFRetain, CFRelease, NULL};
+       NSDictionary *prefsOptions = @{(__bridge NSString *)kSCPreferencesOptionRemoveWhenEmpty:(__bridge NSNumber *)kCFBooleanTrue};
+       test.prefs = SCPreferencesCreateWithOptions(NULL,
+                                                   CFSTR("SCTest"),
+                                                   CFSTR("SCTestPreferences.plist"),
+                                                   kSCPreferencesUseEntitlementAuthorization,
+                                                   (__bridge CFDictionaryRef)prefsOptions);
+       if (test.prefs == NULL) {
+               SCTestLog("Failed to create SCPreferences. Error: %s", SCErrorString(SCError()));
+               ok = FALSE;
+               goto done;
+       }
+
+       ok = SCPreferencesSetCallback(test.prefs, myNotificationsCallback, &ctx);
+       if (!ok) {
+               SCTestLog("Failed to set callback. Error: %s", SCErrorString(SCError()));
+               goto done;
+       }
+
+       callbackQ = dispatch_queue_create("SCTestPreferences callback queue", NULL);
+       ok = SCPreferencesSetDispatchQueue(test.prefs, callbackQ);
+       if (!ok) {
+               SCTestLog("Failed to set dispatch queue. Error: %s", SCErrorString(SCError()));
+               goto done;
+       }
+
+       for (int i = 0; i < iterations; i++) {
+               NSUUID *uuid = [NSUUID UUID];
+               ok = SCPreferencesSetValue(test.prefs, CFSTR("test"), (__bridge CFStringRef)uuid.UUIDString);
+               if (!ok) {
+                       SCTestLog("Failed to set value. Error: %s", SCErrorString(SCError()));
+                       goto done;
+               }
+               ok = SCPreferencesCommitChanges(test.prefs);
+               if (!ok) {
+                       SCTestLog("Failed to commit change. Error: %s", SCErrorString(SCError()));
+                       goto done;
+               }
+               if (dispatch_semaphore_wait(test.sem, dispatch_time(DISPATCH_TIME_NOW, timeout * NSEC_PER_SEC))) {
+                       SCTestLog("Failed to get SCPreferences notification callback: #%d", i);
+                       ok = FALSE;
+                       goto done;
+               }
+       }
+
+       ok = SCPreferencesRemoveValue(test.prefs, CFSTR("test"));
+       if (!ok) {
+               SCTestLog("Failed to remove value. Error: %s", SCErrorString(SCError()));
+               goto done;
+       }
+       ok = SCPreferencesCommitChanges(test.prefs);
+       if (!ok) {
+               SCTestLog("Failed to commit change. Error: %s", SCErrorString(SCError()));
+               goto done;
+       }
+       if (dispatch_semaphore_wait(test.sem, dispatch_time(DISPATCH_TIME_NOW, timeout * NSEC_PER_SEC))) {
+               SCTestLog("Failed to get SCPreferences notification callback: cleanup");
+               ok = FALSE;
+               goto done;
+       }
+
+       ok = SCPreferencesSetDispatchQueue(test.prefs, NULL);
+       if (!ok) {
+               SCTestLog("Failed to clear dispatch queue. Error: %s", SCErrorString(SCError()));
+               goto done;
+       }
+
+       SCTestLog("Verified that %d SCPreferences notification callbacks were delivered", iterations);
+
+    done :
+
+       CFRelease(test.prefs);
+       test.prefs = NULL;
+
+       return ok;
+}
+
+#define        PREFS_OBSERVER_DOMAIN           "com.apple.sctest"
+#define        PREFS_OBSERVER_PLIST            PREFS_OBSERVER_DOMAIN ".plist"
+#define        MANAGED_PREFERENCES_PATH        "/Library/Managed Preferences"
+#if    !TARGET_OS_IPHONE
+#define        PREFS_OBSERVER_KEY              "com.apple.MCX._managementStatusChangedForDomains"
+#define PREFS_OBSERVER_TYPE            scprefs_observer_type_mcx
+#define MANAGED_PREFERENCES_USER       kCFPreferencesAnyUser
+#else
+#define        PREFS_OBSERVER_KEY              "com.apple.ManagedConfiguration.profileListChanged"
+#define PREFS_OBSERVER_TYPE            scprefs_observer_type_global
+#define        MANAGED_PREFERENCES_MOBILE_PATH MANAGED_PREFERENCES_PATH "/mobile"
+#define MANAGED_PREFERENCES_USER       CFSTR("mobile")
+#endif
+
+#import <CoreFoundation/CFPreferences_Private.h>
+
+- (BOOL)unitTestPreferencesObserver
+{
+       dispatch_queue_t        callbackQ;
+       const int               iterations      = 10;
+       scprefs_observer_t      observer;
+       Boolean                 ok              = FALSE;
+       SCTestPreferences       *test;
+       const int               timeout         = 1;    // second
+
+       test = [[SCTestPreferences alloc] initWithOptions:self.options];
+       if (test.prefs != NULL) {
+               CFRelease(test.prefs);
+               test.prefs = NULL;
+       }
+
+       test.sem = dispatch_semaphore_create(0);
+
+       callbackQ = dispatch_queue_create("SCTestPreferences callback queue", NULL);
+       observer = _scprefs_observer_watch(PREFS_OBSERVER_TYPE, PREFS_OBSERVER_PLIST, callbackQ, ^{
+               test.counter++;
+               if (test.sem != NULL) {
+                       dispatch_semaphore_signal(test.sem);
+               }
+       });
+
+       NSDictionary *prefsOptions = @{(__bridge NSString *)kSCPreferencesOptionRemoveWhenEmpty:(__bridge NSNumber *)kCFBooleanTrue};
+       test.prefs = SCPreferencesCreateWithOptions(NULL,
+                                                   CFSTR("SCTest"),
+                                                   CFSTR(MANAGED_PREFERENCES_PATH "/" PREFS_OBSERVER_PLIST),
+                                                   NULL,
+                                                   (__bridge CFDictionaryRef)prefsOptions);
+       if (test.prefs == NULL) {
+               SCTestLog("Failed to create SCPreferences. Error: %s", SCErrorString(SCError()));
+               goto done;
+       }
+
+       // let's make sure that the "/Library/Managed Configuration[/mobile]" directory exists
+       mkdir(MANAGED_PREFERENCES_PATH, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
+#if    TARGET_OS_IPHONE
+       mkdir(MANAGED_PREFERENCES_MOBILE_PATH, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
+#endif // TARGET_OS_IPHONE
+
+       for (int i = 0; i < iterations; i++) {
+               // update prefs
+               NSUUID *uuid = [NSUUID UUID];
+               NSDictionary *keysAndValues = @{@"test" : uuid.UUIDString};
+               ok = _CFPreferencesWriteManagedDomain((__bridge CFDictionaryRef)keysAndValues,
+                                                     MANAGED_PREFERENCES_USER,
+                                                     FALSE,
+                                                     CFSTR(PREFS_OBSERVER_DOMAIN));
+               if (!ok) {
+                       SCTestLog("Failed to write (update) managed preferences");
+                       goto done;
+               }
+#if    TARGET_OS_IPHONE
+               notify_post(PREFS_OBSERVER_KEY);
+#endif // TARGET_OS_IPHONE
+               if (dispatch_semaphore_wait(test.sem, dispatch_time(DISPATCH_TIME_NOW, timeout * NSEC_PER_SEC))) {
+                       SCTestLog("Failed to get SCPreferences observer callback: #%d", i);
+                       ok = FALSE;
+                       goto done;
+               }
+       }
+
+       // post w/no changes
+       notify_post(PREFS_OBSERVER_KEY);
+       [test waitFor:0.01];            // delay after unrelated change
+
+       // zap prefs
+       ok = _CFPreferencesWriteManagedDomain((__bridge CFDictionaryRef)[NSDictionary dictionary],
+                                             MANAGED_PREFERENCES_USER,
+                                             FALSE,
+                                             CFSTR(PREFS_OBSERVER_DOMAIN));
+       if (!ok) {
+               SCTestLog("Failed to write (remove) managed preferences");
+               goto done;
+       }
+#if    TARGET_OS_IPHONE
+       notify_post(PREFS_OBSERVER_KEY);
+#endif // TARGET_OS_IPHONE
+       if (dispatch_semaphore_wait(test.sem, dispatch_time(DISPATCH_TIME_NOW, timeout * NSEC_PER_SEC))) {
+               SCTestLog("Failed to get SCPreferences observer callback: cleanup");
+               ok = FALSE;
+               goto done;
+       }
+
+       SCTestLog("Verified that %d CF/SCPreferences observer callbacks were delivered", iterations);
+
+    done :
+
+       _scprefs_observer_cancel(observer);
+
+       // cleanup the "/Library/Managed Configuration[/mobile]" directory
+#if    TARGET_OS_IPHONE
+       rmdir(MANAGED_PREFERENCES_MOBILE_PATH);
+#endif // TARGET_OS_IPHONE
+       rmdir(MANAGED_PREFERENCES_PATH);
+
+       return ok;
+}
+
 - (BOOL)unitTestPreferencesSession
 {
        SCPreferencesRef prefs;
+
        prefs = SCPreferencesCreate(kCFAllocatorDefault, CFSTR("SCTest"), NULL);
        if (prefs == NULL) {
                SCTestLog("Failed to create SCPreferences. Error: %s", SCErrorString(SCError()));
                return NO;
-       } else {
-               CFRelease(prefs);
        }
+       CFRelease(prefs);
 
        prefs = SCPreferencesCreateWithOptions(kCFAllocatorDefault, CFSTR("SCTest"), NULL, kSCPreferencesUseEntitlementAuthorization, NULL);
        if (prefs == NULL) {
                SCTestLog("Failed to create SCPreferences w/options. Error: %s", SCErrorString(SCError()));
                return NO;
-       } else {
-               CFRelease(prefs);
        }
+       CFRelease(prefs);
 
        prefs = SCPreferencesCreateWithAuthorization(kCFAllocatorDefault, CFSTR("SCTest"), NULL, kSCPreferencesUseEntitlementAuthorization);
        if (prefs == NULL) {
                SCTestLog("Failed to create SCPreferences w/options. Error: %s", SCErrorString(SCError()));
                return NO;
-       } else {
-               CFRelease(prefs);
        }
+       CFRelease(prefs);
 
        SCTestLog("Verified that the preferences session can be created");
        return YES;
 
        prefsOptions = @{(__bridge NSString *)kSCPreferencesOptionRemoveWhenEmpty:(__bridge NSNumber *)kCFBooleanTrue};
        test.prefs = SCPreferencesCreateWithOptions(kCFAllocatorDefault,
-                                                       CFSTR("SCTest"),
-                                                       CFSTR("SCTestPreferences.plist"),
-                                                       kSCPreferencesUseEntitlementAuthorization,
-                                                       (__bridge CFDictionaryRef)prefsOptions);
+                                                   CFSTR("SCTest"),
+                                                   CFSTR("SCTestPreferences.plist"),
+                                                   kSCPreferencesUseEntitlementAuthorization,
+                                                   (__bridge CFDictionaryRef)prefsOptions);
        if (test.prefs == NULL) {
                SCTestLog("Failed to create a preferences session. Error: %s", SCErrorString(SCError()));
                return NO;
 
        CFRelease(test.prefs);
        test.prefs = SCPreferencesCreateWithOptions(kCFAllocatorDefault,
-                                                       CFSTR("SCTest"),
-                                                       CFSTR("SCTestPreferences.plist"),
-                                                       kSCPreferencesUseEntitlementAuthorization,
-                                                       (__bridge CFDictionaryRef)prefsOptions);
+                                                   CFSTR("SCTest"),
+                                                   CFSTR("SCTestPreferences.plist"),
+                                                   kSCPreferencesUseEntitlementAuthorization,
+                                                   (__bridge CFDictionaryRef)prefsOptions);
        if (test.prefs == NULL) {
                SCTestLog("Failed to create a preferences session. Error: %s", SCErrorString(SCError()));
                return NO;
 
        CFRelease(test.prefs);
        test.prefs = SCPreferencesCreateWithOptions(kCFAllocatorDefault,
-                                                       CFSTR("SCTest"),
-                                                       CFSTR("SCTestPreferences.plist"),
-                                                       kSCPreferencesUseEntitlementAuthorization,
-                                                       (__bridge CFDictionaryRef)prefsOptions);
+                                                   CFSTR("SCTest"),
+                                                   CFSTR("SCTestPreferences.plist"),
+                                                   kSCPreferencesUseEntitlementAuthorization,
+                                                   (__bridge CFDictionaryRef)prefsOptions);
        if (test.prefs == NULL) {
                SCTestLog("Failed to create a preferences session. Error: %s", SCErrorString(SCError()));
                return NO;
 
 /*
- * Copyright (c) 2016, 2017, 2020 Apple Inc. All rights reserved.
+ * Copyright (c) 2016, 2017, 2019, 2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 
                currentConfiguration = argv[2];
        }
 
-       SCPrint(_sc_debug, stdout, CFSTR("sourceConfiguration: %s\ntargetConfiguration: %s\ncurrentConfiguration: %s\n"),
-               sourceConfiguration, targetConfiguration, (currentConfiguration != NULL) ? currentConfiguration : "<current system>" );
+       SCPrint(_sc_debug, stdout,
+               CFSTR("sourceConfiguration: %s\n"
+                     "targetConfiguration: %s\n"
+                     "currentConfiguration: %s\n"),
+               sourceConfiguration,
+               targetConfiguration,
+               (currentConfiguration != NULL) ? currentConfiguration : "<current system>" );
 
        str = CFStringCreateWithCString(NULL, sourceConfiguration, kCFStringEncodingUTF8);
        sourceConfigurationURL = CFURLCreateWithFileSystemPath(NULL, str, kCFURLPOSIXPathStyle, TRUE);
        migrationFiles = _SCNetworkConfigurationPerformMigration(sourceConfigurationURL, currentConfigurationURL, targetConfigurationURL, NULL);
 
        if (migrationFiles != NULL) {
-               SCPrint(TRUE, stdout, CFSTR("Migration Successful: %@ \n"), migrationFiles);
-       }
-       else {
-               SCPrint(TRUE, stdout, CFSTR("Migration Unsuccessful \n"));
+               SCPrint(TRUE, stdout, CFSTR("Migration complete\n"));
+               SCPrint(_sc_debug, stdout, CFSTR("updated files: %@\n"), migrationFiles);
+       } else {
+               SCPrint(TRUE, stdout, CFSTR("Migration failed\n"));
        }
 
        if (sourceConfigurationURL != NULL) {
 void
 do_net_migrate(int argc, char **argv)
 {
-       char *key;
-       SCPrint(TRUE, stdout, CFSTR("do_net_migrate called, %d\n"), argc);
+       char    *key;
 
        key = argv[0];
        argv++;
 
 /*
- * Copyright (c) 2004-2011, 2013-2017, 2019 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2011, 2013-2017, 2019, 2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 
        if_bsd_name = SCNetworkInterfaceGetBSDName(interface);
        if (if_bsd_name != NULL) {
-               SCPrint(TRUE, stdout, CFSTR("%@  interface name       = %@\n"), prefix, if_bsd_name);
+               SCPrint(TRUE, stdout, CFSTR("%@  interface name       = %@"), prefix, if_bsd_name);
+
+#if    !TARGET_OS_IPHONE
+               if (isA_SCBondInterface(interface)) {
+                       CFArrayRef      members;
+
+                       members = SCBondInterfaceGetMemberInterfaces(interface);
+                       if (members != NULL) {
+                               CFIndex n       = CFArrayGetCount(members);
+
+                               SCPrint(TRUE, stdout, CFSTR(", members = ("));
+                               for (CFIndex i = 0; i < n; i++) {
+                                       SCNetworkInterfaceRef   member;
+                                       CFStringRef             bsdName;
+
+                                       member = CFArrayGetValueAtIndex(members, i);
+                                       bsdName = SCNetworkInterfaceGetBSDName(member);
+                                       SCPrint(TRUE, stdout, CFSTR("%s%@"),
+                                               i == 0 ? "" : ", ",
+                                               bsdName != NULL ? bsdName : CFSTR("?"));
+                               }
+                               SCPrint(TRUE, stdout, CFSTR(")"));
+                       }
+               } else
+#endif // !TARGET_OS_IPHONE
+
+               if (isA_SCBridgeInterface(interface)) {
+                       CFArrayRef      members;
+
+                       members = SCBridgeInterfaceGetMemberInterfaces(interface);
+                       if (members != NULL) {
+                               CFIndex n       = CFArrayGetCount(members);
+
+                               SCPrint(TRUE, stdout, CFSTR(", members = ("));
+                               for (CFIndex i = 0; i < n; i++) {
+                                       SCNetworkInterfaceRef   member;
+                                       CFStringRef             bsdName;
+
+                                       member = CFArrayGetValueAtIndex(members, i);
+                                       bsdName = SCNetworkInterfaceGetBSDName(member);
+                                       SCPrint(TRUE, stdout, CFSTR("%s%@"),
+                                               i == 0 ? "" : ", ",
+                                               bsdName != NULL ? bsdName : CFSTR("?"));
+                               }
+                               SCPrint(TRUE, stdout, CFSTR(")"));
+                       }
+               } else
+
+               if (isA_SCVLANInterface(interface)) {
+                       SCNetworkInterfaceRef   physical;
+                       CFNumberRef             tag;
+
+                       physical = SCVLANInterfaceGetPhysicalInterface(interface);
+                       tag = SCVLANInterfaceGetTag(interface);
+                       if ((physical != NULL) && (tag != NULL)) {
+                               SCPrint(TRUE, stdout, CFSTR(", physical interface = %@, tag = %@"),
+                                       physical,
+                                       tag);
+                       }
+               }
+
+               SCPrint(TRUE, stdout, CFSTR("\n"));
        }
 
        if_type = SCNetworkInterfaceGetInterfaceType(interface);
 
 /*
- * Copyright (c) 2004-2009, 2011, 2014, 2017, 2019 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2009, 2011, 2014, 2017, 2019, 2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
        return 1;
 }
 
+static int
+__doIPv6PrefixLength(CFStringRef key, const char *description, void *info, int argc, char **argv, CFMutableDictionaryRef newConfiguration)
+{
+#pragma unused(description)
+#pragma unused(argc)
+#pragma unused(info)
+       char *  prefix = argv[0];
+       if (*prefix != '\0') {
+               char    *end;
+               int     prefixLength;
+
+               prefixLength = (int)strtol(prefix, &end, 10);
+               errno = 0;
+               if (*end == '\0' && errno == 0 && prefixLength > 0 && prefixLength <= 128) {
+                       CFArrayRef      prefixes;
+                       CFNumberRef     num;
+
+                       num = CFNumberCreate(NULL, kCFNumberIntType, &prefixLength);
+                       prefixes = CFArrayCreate(NULL, (const void **)&num, 1, &kCFTypeArrayCallBacks);
+                       CFRelease(num);
+                       CFDictionarySetValue(newConfiguration, key, prefixes);
+                       CFRelease(prefixes);
+               } else {
+                       SCPrint(TRUE, stdout, CFSTR("Invalid prefix length '%s' (valid range 1..128)\n"), prefix);
+                       return -1;
+               }
+       } else {
+               CFDictionaryRemoveValue(newConfiguration, key);
+       }
+
+       return 1;
+}
+
 
 static options ipv6Options[] = {
        { "ConfigMethod", "configuration method"
        { "Addresses"   , "address"      , isOther    , &kSCPropNetIPv6Addresses   , __doIPv6Addresses   , (void *)TRUE              },
        {   "address"   , "address"      , isOther    , &kSCPropNetIPv6Addresses   , __doIPv6Addresses   , (void *)TRUE              },
        { "EnableCGA"   , NULL           , isBoolean  , &kSCPropNetIPv6EnableCGA   , NULL                , NULL                      },
-       { "PrefixLength", "prefix length", isNumber   , &kSCPropNetIPv6PrefixLength, NULL                , NULL                      },
+       { "PrefixLength", "prefix length", isOther    , &kSCPropNetIPv6PrefixLength, __doIPv6PrefixLength, NULL                      },
        { "Router"      , "address"      , isOther    , &kSCPropNetIPv6Router      , __doIPv6Addresses   , (void *)FALSE             },
 
        { "?"           , NULL           , isHelp     , NULL                       , NULL                ,