From c956c85e3ac8d59d957268335ef7ccf1cc2bbcc2 Mon Sep 17 00:00:00 2001 From: Apple Date: Thu, 19 Nov 2020 01:06:35 +0000 Subject: [PATCH] configd-1109.40.9.tar.gz --- EventFactory/EventFactory.m | 135 +- EventFactory/Info.plist | 2 +- EventFactory/SCDynamicStoreParser.h | 27 + EventFactory/SCDynamicStoreParser.m | 38 + EventFactory/SCPreferencesParser.h | 27 + EventFactory/SCPreferencesParser.m | 38 + IPMonitorControl/IPMonitorAWDReport.m | 7 +- .../IPMonitor/Info-EmbeddedSimulator.plist | 4 +- Plugins/IPMonitor/Info.plist | 4 +- Plugins/IPMonitor/Makefile | 34 +- Plugins/IPMonitor/controller.m | 38 +- Plugins/IPMonitor/dns-configuration.c | 97 +- Plugins/IPMonitor/dns-configuration.h | 5 +- Plugins/IPMonitor/ip_plugin.c | 449 +++-- Plugins/IPMonitor/routelist_output_filter.sh | 24 +- Plugins/IPMonitor/smb-configuration.c | 6 +- .../test_ipv4_routelist_reference.txt | 13 - .../test_ipv6_routelist_reference.txt | 13 - Plugins/InterfaceNamer/Info.plist | 4 +- Plugins/InterfaceNamer/ifnamer.c | 171 +- Plugins/KernelEventMonitor/Info.plist | 4 +- Plugins/KernelEventMonitor/ev_dlil.c | 7 +- Plugins/KernelEventMonitor/ev_extra.m | 45 +- Plugins/LinkConfiguration/Info.plist | 4 +- Plugins/PreferencesMonitor/Info.plist | 4 +- Plugins/QoSMarking/Info-Embedded.plist | 4 +- Plugins/QoSMarking/Info.plist | 4 +- Plugins/QoSMarking/Makefile | 12 +- Plugins/QoSMarking/qos-marking.m | 22 +- Plugins/SimulatorSupport/Info.plist | 4 +- Plugins/SimulatorSupport/simulator_support.c | 4 +- SCMonitor/Info.plist | 4 +- SCMonitor/en.lproj/Localizable.strings | Bin 1604 -> 1604 bytes SCMonitor/monitor.c | 23 +- SystemConfiguration.fproj/CaptiveNetwork.c | 9 +- SystemConfiguration.fproj/CaptiveNetwork.h | 19 +- SystemConfiguration.fproj/Info-Embedded.plist | 6 +- SystemConfiguration.fproj/Info.plist | 6 +- SystemConfiguration.fproj/SCDHostName.c | 59 +- SystemConfiguration.fproj/SCDOpen.c | 212 ++- SystemConfiguration.fproj/SCDPrivate.c | 13 +- .../SCNetworkConfigurationInternal.h | 14 +- .../SCNetworkConfigurationPrivate.c | 12 +- .../SCNetworkConfigurationPrivate.h | 19 + .../SCNetworkInterface.c | 560 +++--- .../SCNetworkMigration.c | 1512 ++++++++++------- .../SCNetworkReachability.c | 204 ++- SystemConfiguration.fproj/SCNetworkService.c | 91 +- SystemConfiguration.fproj/SCNetworkSet.c | 20 +- SystemConfiguration.fproj/SCPOpen.c | 16 +- .../SCSchemaDefinitions.c | 6 +- .../SCSchemaDefinitions.h | 4 +- .../SCSchemaDefinitionsPrivate.h | 56 +- SystemConfiguration.fproj/config_types.h | 10 +- .../en.lproj/Localizable.strings | Bin 3482 -> 3482 bytes SystemConfiguration.fproj/genSCPreferences.c | 23 +- .../restore-temporary-headers | 51 - SystemConfiguration.fproj/scprefs_observer.c | 46 +- SystemConfiguration.fproj/scprefs_observer.h | 5 +- configd.tproj/_snapshot.c | 6 +- configd.tproj/configd.8 | 12 +- configd.tproj/configd.m | 18 +- configd.tproj/entitlements-ios.plist | 5 + configd.tproj/entitlements-macOS.plist | 10 + configd.tproj/plugin_support.c | 85 +- configd.tproj/plugin_support.h | 13 +- configd.tproj/session.c | 47 +- configd.xcodeproj/project.pbxproj | 598 +++---- dnsinfo/dnsinfo_flatfile.c | 14 +- get-network-info | 15 +- .../libSystemConfiguration_client.c | 8 +- .../libSystemConfiguration_client.h | 18 +- logging/liblog_SystemConfiguration.m | 81 +- nwi/network_information.c | 14 +- nwi/network_state_information_priv.h | 15 +- sctest/SCTestDynamicStore.m | 12 + sctest/SCTestInterfaceNamer.m | 164 ++ sctest/SCTestPreferences.m | 264 ++- sctest/genSCTestOptions.c | 2 +- scutil.tproj/net.c | 20 +- scutil.tproj/net_interface.c | 65 +- scutil.tproj/net_protocol.c | 37 +- 82 files changed, 3829 insertions(+), 1944 deletions(-) create mode 100644 EventFactory/SCDynamicStoreParser.h create mode 100644 EventFactory/SCDynamicStoreParser.m create mode 100644 EventFactory/SCPreferencesParser.h create mode 100644 EventFactory/SCPreferencesParser.m delete mode 100755 SystemConfiguration.fproj/restore-temporary-headers create mode 100644 configd.tproj/entitlements-macOS.plist diff --git a/EventFactory/EventFactory.m b/EventFactory/EventFactory.m index d1eb8e6..a4eaeab 100644 --- a/EventFactory/EventFactory.m +++ b/EventFactory/EventFactory.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 Apple Inc. All rights reserved. + * Copyright (c) 2017-2019 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -37,6 +37,8 @@ #import "PreferencesMonitorParser.h" #import "StateDumpParser.h" #import "IPConfigurationParser.h" +#import "SCDynamicStoreParser.h" +#import "SCPreferencesParser.h" #pragma mark - #pragma mark Logging @@ -56,8 +58,18 @@ __log_Spectacles(void) #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 *parserMap; +@property LogAccumulatingState accumulating; +@property EFLogEvent *accumulatingEvent; +@property NSString *accumulatingEventIdentifierString; @end @implementation EventFactory @@ -85,16 +97,35 @@ __log_Spectacles(void) 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 * _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"; } @@ -105,6 +136,102 @@ __log_Spectacles(void) 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); diff --git a/EventFactory/Info.plist b/EventFactory/Info.plist index b76c329..6d458c9 100644 --- a/EventFactory/Info.plist +++ b/EventFactory/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.19 + 1.20 CFBundleVersion 1 NSPrincipalClass diff --git a/EventFactory/SCDynamicStoreParser.h b/EventFactory/SCDynamicStoreParser.h new file mode 100644 index 0000000..19193ad --- /dev/null +++ b/EventFactory/SCDynamicStoreParser.h @@ -0,0 +1,27 @@ +/* + * 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 diff --git a/EventFactory/SCDynamicStoreParser.m b/EventFactory/SCDynamicStoreParser.m new file mode 100644 index 0000000..6834751 --- /dev/null +++ b/EventFactory/SCDynamicStoreParser.m @@ -0,0 +1,38 @@ +/* + * 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 +#import + +#import "SCDynamicStoreParser.h" + +@implementation SCDynamicStoreParser + +- (instancetype)init +{ + NSArray *matches = @[]; + EFLogEventParser *parser = [[EFLogEventParser alloc] initWithMatches:matches]; + return [super initWithCategory:@"SCDynamicStore" eventParser:parser]; +} + +@end diff --git a/EventFactory/SCPreferencesParser.h b/EventFactory/SCPreferencesParser.h new file mode 100644 index 0000000..6c1928e --- /dev/null +++ b/EventFactory/SCPreferencesParser.h @@ -0,0 +1,27 @@ +/* + * 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 diff --git a/EventFactory/SCPreferencesParser.m b/EventFactory/SCPreferencesParser.m new file mode 100644 index 0000000..1366fc2 --- /dev/null +++ b/EventFactory/SCPreferencesParser.m @@ -0,0 +1,38 @@ +/* + * 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 +#import + +#import "SCPreferencesParser.h" + +@implementation SCPreferencesParser + +- (instancetype)init +{ + NSArray *matches = @[]; + EFLogEventParser *parser = [[EFLogEventParser alloc] initWithMatches:matches]; + return [super initWithCategory:@"SCPreferences" eventParser:parser]; +} + +@end diff --git a/IPMonitorControl/IPMonitorAWDReport.m b/IPMonitorControl/IPMonitorAWDReport.m index 7c5ded5..825582d 100644 --- a/IPMonitorControl/IPMonitorAWDReport.m +++ b/IPMonitorControl/IPMonitorAWDReport.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Apple Inc. All rights reserved. + * Copyright (c) 2018, 2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -45,7 +45,6 @@ #endif /* TEST_IPMONITOR_AWD_REPORT || TEST_IPMONITOR_CONTROL */ - STATIC AWDServerConnection * IPMonitorAWDServerConnection(void) { @@ -126,14 +125,14 @@ InterfaceAdvisoryReportSubmit(InterfaceAdvisoryReportRef report) 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) { diff --git a/Plugins/IPMonitor/Info-EmbeddedSimulator.plist b/Plugins/IPMonitor/Info-EmbeddedSimulator.plist index b5f8f83..bcb3096 100644 --- a/Plugins/IPMonitor/Info-EmbeddedSimulator.plist +++ b/Plugins/IPMonitor/Info-EmbeddedSimulator.plist @@ -19,11 +19,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.19 + 1.20 CFBundleSignature ???? CFBundleVersion - 1.19 + 1.20 MachServices com.apple.SystemConfiguration.DNSConfiguration_sim diff --git a/Plugins/IPMonitor/Info.plist b/Plugins/IPMonitor/Info.plist index 3bd882d..4d5d31d 100644 --- a/Plugins/IPMonitor/Info.plist +++ b/Plugins/IPMonitor/Info.plist @@ -19,11 +19,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.19 + 1.20 CFBundleSignature ???? CFBundleVersion - 1.19 + 1.20 MachServices com.apple.SystemConfiguration.DNSConfiguration diff --git a/Plugins/IPMonitor/Makefile b/Plugins/IPMonitor/Makefile index f8e861a..bf7f340 100644 --- a/Plugins/IPMonitor/Makefile +++ b/Plugins/IPMonitor/Makefile @@ -15,12 +15,14 @@ endif # 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 @@ -56,6 +58,9 @@ dnsinfo_server.o: ../../dnsinfo/dnsinfo_copy.c ../../dnsinfo/dnsinfo_server.c 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 @@ -93,47 +98,48 @@ ip_pluginX.o: Makefile ip_plugin.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 @@ -150,7 +156,7 @@ test_ipv6_routelist.o: ip_plugin.c $(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 diff --git a/Plugins/IPMonitor/controller.m b/Plugins/IPMonitor/controller.m index 78f5573..b7b7c5d 100644 --- a/Plugins/IPMonitor/controller.m +++ b/Plugins/IPMonitor/controller.m @@ -713,6 +713,16 @@ typedef struct resolverList { 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; @@ -721,12 +731,17 @@ typedef struct resolverList { 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; } @@ -735,6 +750,8 @@ typedef struct resolverList { [self processSupplementalProxyChanges:proxies]; [self processServiceSpecificProxyChanges:proxies]; + [self applyPolicies]; + CFRelease(proxies); } @@ -1490,6 +1507,8 @@ remove_policy: done: [self processOnionResolver:dns_config]; + [self applyPolicies]; + if (dns_config != NULL) { dns_configuration_free(dns_config); } @@ -1752,7 +1771,6 @@ done: NEPolicySession * session; uint32_t multiple_entity_offset; NEPolicy * newPolicy; - BOOL ok; uint32_t order; uint32_t orderForSkip; NSMutableArray * policyArray; @@ -1849,12 +1867,6 @@ done: 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]; @@ -1864,7 +1876,7 @@ done: [policyArray addObject:numberToNSNumber(policyID2)]; [self.policyDB setObject:policyArray forKey:[agent getAgentName]]; - return ok; + return YES; } #pragma mark Agent manipulation functions @@ -2048,11 +2060,6 @@ done: } } - result = [session apply]; - if (result == NO) { - SC_log(LOG_NOTICE, "Could not apply removed policies for agent %@", [agent getAgentName]); - } - [self.policyDB removeObjectForKey:[agent getAgentName]]; } @@ -2082,11 +2089,6 @@ done: 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"); } diff --git a/Plugins/IPMonitor/dns-configuration.c b/Plugins/IPMonitor/dns-configuration.c index cb61799..910d8e4 100644 --- a/Plugins/IPMonitor/dns-configuration.c +++ b/Plugins/IPMonitor/dns-configuration.c @@ -41,8 +41,6 @@ #include #include #include -#include -#include #include #include @@ -65,6 +63,12 @@ #include #include +#if !TARGET_OS_IPHONE +#include +#else // TARGET_OS_IPHONE +#include +#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__") @@ -1552,7 +1556,8 @@ dns_configuration_set(CFDictionaryRef defaultResolver, CFDictionaryRef services, CFArrayRef serviceOrder, CFArrayRef multicastResolvers, - CFArrayRef privateResolvers) + CFArrayRef privateResolvers, + CFDictionaryRef *globalResolver) { dns_create_config_t dns_create_config; Boolean changed = FALSE; @@ -1689,6 +1694,10 @@ dns_configuration_set(CFDictionaryRef defaultResolver, 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); @@ -1757,12 +1766,19 @@ static SCDynamicStoreRef dns_configuration_store; 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; @@ -1820,12 +1836,18 @@ __private_extern__ 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); @@ -1835,38 +1857,24 @@ dns_configuration_monitor(SCDynamicStoreRef store, SCDynamicStoreCallBack callou 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; } @@ -1986,6 +1994,7 @@ int main(int argc, char **argv) { CFDictionaryRef entities; + CFDictionaryRef globalResolver = NULL; CFStringRef key; CFArrayRef multicast_resolvers; CFStringRef pattern; @@ -2086,13 +2095,15 @@ main(int argc, char **argv) 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); diff --git a/Plugins/IPMonitor/dns-configuration.h b/Plugins/IPMonitor/dns-configuration.h index 1753f70..d67f41a 100644 --- a/Plugins/IPMonitor/dns-configuration.h +++ b/Plugins/IPMonitor/dns-configuration.h @@ -1,5 +1,5 @@ /* - * 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@ * @@ -44,7 +44,8 @@ Boolean dns_configuration_set (CFDictionaryRef defaultResolver, CFDictionaryRef services, CFArrayRef serviceOrder, CFArrayRef multicastResolvers, - CFArrayRef privateResolvers); + CFArrayRef privateResolvers, + CFDictionaryRef *globalResolver); __END_DECLS diff --git a/Plugins/IPMonitor/ip_plugin.c b/Plugins/IPMonitor/ip_plugin.c index f770c0e..3eb06e5 100644 --- a/Plugins/IPMonitor/ip_plugin.c +++ b/Plugins/IPMonitor/ip_plugin.c @@ -641,7 +641,9 @@ static IPv6RouteListRef S_ipv6_routelist = NULL; 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; @@ -1530,9 +1532,10 @@ RouteListAddRouteAtIndex(RouteListInfoRef info, RouteListRef routes, 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); @@ -1556,9 +1559,10 @@ RouteListRemoveRouteAtIndex(RouteListInfoRef info, RouteListRef routes, 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; } @@ -3976,10 +3980,9 @@ log_service_entity(int level, CFStringRef serviceID, CFStringRef entity, 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); @@ -4625,13 +4628,13 @@ get_ipv6_changes(CFStringRef serviceID, CFDictionaryRef state_dict, __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 */ @@ -5747,16 +5750,11 @@ get_rank_changes(CFStringRef serviceID, CFDictionaryRef state_options, 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]; @@ -5784,13 +5782,8 @@ add_service_keys(CFStringRef serviceID, 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; @@ -5862,8 +5855,8 @@ services_info_copy(SCDynamicStoreRef session, CFArrayRef service_list) 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); @@ -6243,6 +6236,7 @@ update_dns(CFDictionaryRef services_info, keyChangeListRef keys) { #pragma unused(services_info) +#pragma unused(keys) Boolean changed = FALSE; CFDictionaryRef dict = NULL; @@ -6255,37 +6249,67 @@ update_dns(CFDictionaryRef services_info, } } - 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 @@ -6295,7 +6319,8 @@ update_dnsinfo(CFDictionaryRef services_info, CFArrayRef service_order) { Boolean changed; - CFDictionaryRef dict = NULL; + CFDictionaryRef dict = NULL; + CFDictionaryRef globalResolver = NULL; CFArrayRef multicastResolvers; CFArrayRef privateResolvers; @@ -6315,10 +6340,21 @@ update_dnsinfo(CFDictionaryRef services_info, 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; } @@ -6341,11 +6377,11 @@ update_nwi(nwi_state_t state) 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; } @@ -8846,15 +8882,63 @@ flush_inet_routes(void) #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; } @@ -8863,6 +8947,9 @@ ip_plugin_init() flush_inet_routes(); } + /* + * Initialize globals + */ S_session = SCDynamicStoreCreate(NULL, CFSTR("IPMonitor"), IPMonitorNotify, NULL); if (S_session == NULL) { @@ -8910,115 +8997,144 @@ ip_plugin_init() 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 @@ -9040,7 +9156,7 @@ S_get_plist_boolean(CFDictionaryRef plist, CFStringRef key, 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 @@ -9085,7 +9201,7 @@ StartIPMonitorControlServer(void) return; } -#endif /* !TARGET_OS_SIMULATOR */ +#endif /* !TARGET_OS_SIMULATOR && !TEST_IPV4_ROUTELIST && !TEST_IPV6_ROUTELIST && !TEST_DNS && !TEST_DNS_ORDER */ __private_extern__ void @@ -9110,7 +9226,7 @@ load_IPMonitor(CFBundleRef bundle, Boolean bundleVerbose) /* 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 @@ -9136,12 +9252,12 @@ load_IPMonitor(CFBundleRef bundle, Boolean bundleVerbose) 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); @@ -9193,7 +9309,32 @@ main(int argc, char **argv) } #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; @@ -10000,15 +10141,7 @@ main(int argc, char **argv) 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); } @@ -10665,15 +10798,7 @@ main(int argc, char **argv) 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); } @@ -10902,6 +11027,7 @@ apply_test(DNSOrderTestRef test) int main(int argc, char **argv) { + _sc_log = kSCLogDestinationFile; _sc_verbose = (argc > 1) ? TRUE : FALSE; S_IPMonitor_debug = kDebugFlag1 | kDebugFlag2 | kDebugFlag4; @@ -10912,16 +11038,7 @@ main(int argc, char **argv) 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); } diff --git a/Plugins/IPMonitor/routelist_output_filter.sh b/Plugins/IPMonitor/routelist_output_filter.sh index 7fc1439..7321682 100644 --- a/Plugins/IPMonitor/routelist_output_filter.sh +++ b/Plugins/IPMonitor/routelist_output_filter.sh @@ -1,18 +1,8 @@ #!/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 diff --git a/Plugins/IPMonitor/smb-configuration.c b/Plugins/IPMonitor/smb-configuration.c index fa51672..664c977 100644 --- a/Plugins/IPMonitor/smb-configuration.c +++ b/Plugins/IPMonitor/smb-configuration.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2018 Apple Inc. All rights reserved. + * Copyright (c) 2006-2018, 2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -57,8 +57,6 @@ #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 @@ -123,7 +121,7 @@ copy_default_name(void) 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; } diff --git a/Plugins/IPMonitor/test_ipv4_routelist_reference.txt b/Plugins/IPMonitor/test_ipv4_routelist_reference.txt index aa9f243..437ba6e 100644 --- a/Plugins/IPMonitor/test_ipv4_routelist_reference.txt +++ b/Plugins/IPMonitor/test_ipv4_routelist_reference.txt @@ -26170,16 +26170,3 @@ Add new[8]: Net 255.255.255.255/32 Ifp en0 Ifa 10.0.0.10 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. - diff --git a/Plugins/IPMonitor/test_ipv6_routelist_reference.txt b/Plugins/IPMonitor/test_ipv6_routelist_reference.txt index d5d5b9b..0fbaea2 100644 --- a/Plugins/IPMonitor/test_ipv6_routelist_reference.txt +++ b/Plugins/IPMonitor/test_ipv6_routelist_reference.txt @@ -1383,16 +1383,3 @@ failed to add: Host 2620:149:4:f01:225:ff:fecc:89a2 Gate 2620:149:4:f01:225:ff:f 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. - diff --git a/Plugins/InterfaceNamer/Info.plist b/Plugins/InterfaceNamer/Info.plist index d354d5a..dff3bba 100644 --- a/Plugins/InterfaceNamer/Info.plist +++ b/Plugins/InterfaceNamer/Info.plist @@ -17,10 +17,10 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.19 + 1.20 CFBundleSignature ???? CFBundleVersion - 1.19 + 1.20 diff --git a/Plugins/InterfaceNamer/ifnamer.c b/Plugins/InterfaceNamer/ifnamer.c index 2e5a074..c56e105 100644 --- a/Plugins/InterfaceNamer/ifnamer.c +++ b/Plugins/InterfaceNamer/ifnamer.c @@ -50,10 +50,10 @@ * 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 */ @@ -294,17 +294,17 @@ static CFComparisonResult 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); } @@ -453,7 +453,7 @@ readInterfaceList() 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); @@ -745,6 +745,10 @@ createInterfaceDict(SCNetworkInterfaceRef interface, CFArrayRef matchingMACs) CFDictionarySetValue(new_if, kSCNetworkInterfaceHiddenConfigurationKey, kCFBooleanTrue); } + if (_SCNetworkInterfaceIsHiddenInterface(interface)) { + CFDictionarySetValue(new_if, kSCNetworkInterfaceHiddenInterfaceKey, kCFBooleanTrue); + } + CFDictionarySetValue(new_if, CFSTR(kSCNetworkInterfaceActive), kCFBooleanTrue); if (matchingMACs != NULL) { @@ -759,30 +763,30 @@ lookupInterfaceByAddress(CFArrayRef db_list, SCNetworkInterfaceRef interface, CF { 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); @@ -807,7 +811,7 @@ lookupInterfaceByName(CFArrayRef db_list, CFStringRef bsdName, CFIndex * where) name = CFDictionaryGetValue(dict, CFSTR(kIOBSDNameKey)); if (_SC_CFEqual(name, bsdName)) { - if (where) { + if (where != NULL) { *where = i; } return (dict); @@ -820,33 +824,34 @@ static CFDictionaryRef 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); } } @@ -856,6 +861,7 @@ lookupInterfaceByUnit(CFArrayRef db_list, SCNetworkInterfaceRef interface, CFInd typedef struct { CFDictionaryRef match_info; CFStringRef match_type; + CFStringRef match_prefix; CFBooleanRef match_builtin; CFMutableArrayRef matches; } matchContext, *matchContextRef; @@ -911,6 +917,18 @@ matchKnown(const void *value, void *context) 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; @@ -1101,6 +1119,7 @@ lookupMatchingInterface(SCNetworkInterfaceRef interface, CFBooleanRef builtin) { CFStringRef if_type; + CFStringRef if_prefix; CFDictionaryRef match = NULL; matchContext match_context; @@ -1108,8 +1127,13 @@ lookupMatchingInterface(SCNetworkInterfaceRef interface, 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; @@ -1179,7 +1203,7 @@ insertInterface(CFMutableArrayRef db_list, SCNetworkInterfaceRef interface, CFDi 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); @@ -1240,21 +1264,21 @@ insertInterface(CFMutableArrayRef db_list, SCNetworkInterfaceRef interface, CFDi 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) @@ -1282,7 +1306,7 @@ removeInterface(CFMutableArrayRef db_list, SCNetworkInterfaceRef interface, CFDi 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) { @@ -1295,7 +1319,7 @@ removeInterface(CFMutableArrayRef db_list, SCNetworkInterfaceRef interface, CFDi 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) { @@ -1338,7 +1362,7 @@ replaceInterface(SCNetworkInterfaceRef interface) } static int -getNextUnitForType(CFNumberRef if_type, int requested) +getNextUnitForPrefix(CFStringRef if_prefix, int requested) { CFIndex n; @@ -1349,10 +1373,10 @@ getNextUnitForType(CFNumberRef if_type, int requested) 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; @@ -1561,19 +1585,19 @@ displayInterface(SCNetworkInterfaceRef interface) { 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) ? ", " : "", @@ -1585,7 +1609,7 @@ builtinAvailable(SCNetworkInterfaceRef interface, // new interface 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; @@ -1593,12 +1617,12 @@ builtinAvailable(SCNetworkInterfaceRef interface, // new interface 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)); @@ -1613,27 +1637,27 @@ builtinAvailable(SCNetworkInterfaceRef interface, // new interface 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 } @@ -2217,7 +2241,7 @@ lockedNotification_add(void) 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); } @@ -2339,6 +2363,7 @@ watchLockedInterface(SCNetworkInterfaceRef interface) S_locked = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); } CFArrayAppendValue(S_locked, watched); + CFRelease(watched); updated = TRUE; } @@ -2586,6 +2611,7 @@ updateTrustRequiredInterfaces(CFArrayRef interfaces) S_trustRequired = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); } CFArrayAppendValue(S_trustRequired, watched); + CFRelease(watched); updated = TRUE; } } @@ -2744,6 +2770,7 @@ updatePreConfiguredInterfaces(CFArrayRef interfaces) S_preconfigured = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); } CFArrayAppendValue(S_preconfigured, watched); + CFRelease(watched); updated = TRUE; } } @@ -2800,13 +2827,13 @@ nameInterfaces(CFMutableArrayRef if_list) 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); @@ -2905,7 +2932,7 @@ nameInterfaces(CFMutableArrayRef if_list) 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 @@ -2946,8 +2973,8 @@ nameInterfaces(CFMutableArrayRef if_list) 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); } @@ -3031,8 +3058,8 @@ nameInterfaces(CFMutableArrayRef if_list) 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); @@ -3309,18 +3336,18 @@ reportInactiveInterfaces(void) 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); } @@ -4017,8 +4044,8 @@ main(int argc, char ** argv) 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; } diff --git a/Plugins/KernelEventMonitor/Info.plist b/Plugins/KernelEventMonitor/Info.plist index 8e3020d..4b4dc96 100644 --- a/Plugins/KernelEventMonitor/Info.plist +++ b/Plugins/KernelEventMonitor/Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.19 + 1.20 CFBundleSignature ???? CFBundleVersion - 1.19 + 1.20 Requires com.apple.SystemConfiguration.InterfaceNamer diff --git a/Plugins/KernelEventMonitor/ev_dlil.c b/Plugins/KernelEventMonitor/ev_dlil.c index 27cbe05..55ce507 100644 --- a/Plugins/KernelEventMonitor/ev_dlil.c +++ b/Plugins/KernelEventMonitor/ev_dlil.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2019 Apple Inc. All rights reserved. + * Copyright (c) 2002-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -134,10 +134,11 @@ interface_update_status(const char *if_name, } } else { /* remove the value */ - if (oldDict != NULL) { + if (!only_if_different + || oldDict != NULL) { SC_log(LOG_DEBUG, "Update interface link status: %s: ", if_name); + SCDynamicStoreRemoveValue(store, key); } - SCDynamicStoreRemoveValue(store, key); } CFRelease(key); diff --git a/Plugins/KernelEventMonitor/ev_extra.m b/Plugins/KernelEventMonitor/ev_extra.m index 3af8018..2bb5b8a 100644 --- a/Plugins/KernelEventMonitor/ev_extra.m +++ b/Plugins/KernelEventMonitor/ev_extra.m @@ -1,5 +1,5 @@ /* - * 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@ * @@ -50,7 +50,7 @@ haveMobileWiFi() static CFBooleanRef is_expensive(SCNetworkInterfaceRef _Nonnull interface) { - CFBooleanRef expensive = NULL; + CFBooleanRef expensive; CFStringRef interfaceType; while (interface != NULL) { @@ -63,10 +63,8 @@ is_expensive(SCNetworkInterfaceRef _Nonnull interface) 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 @@ -86,12 +84,23 @@ is_expensive(SCNetworkInterfaceRef _Nonnull 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)) { @@ -109,26 +118,28 @@ __private_extern__ 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); } @@ -163,9 +174,9 @@ main(int argc, char **argv) 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); diff --git a/Plugins/LinkConfiguration/Info.plist b/Plugins/LinkConfiguration/Info.plist index 68baee0..744f438 100644 --- a/Plugins/LinkConfiguration/Info.plist +++ b/Plugins/LinkConfiguration/Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.19 + 1.20 CFBundleSignature ???? CFBundleVersion - 1.19 + 1.20 Requires com.apple.SystemConfiguration.InterfaceNamer diff --git a/Plugins/PreferencesMonitor/Info.plist b/Plugins/PreferencesMonitor/Info.plist index d4e8af9..1546762 100644 --- a/Plugins/PreferencesMonitor/Info.plist +++ b/Plugins/PreferencesMonitor/Info.plist @@ -15,11 +15,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.19 + 1.20 CFBundleSignature ???? CFBundleVersion - 1.19 + 1.20 Builtin Requires diff --git a/Plugins/QoSMarking/Info-Embedded.plist b/Plugins/QoSMarking/Info-Embedded.plist index f554c12..38accb0 100644 --- a/Plugins/QoSMarking/Info-Embedded.plist +++ b/Plugins/QoSMarking/Info-Embedded.plist @@ -17,11 +17,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.19 + 1.20 CFBundleSignature ???? CFBundleVersion - 1.19 + 1.20 QoSMarking_AppleAudioVideoCalls_BundleIDs com.apple.datausage.telephony.ims diff --git a/Plugins/QoSMarking/Info.plist b/Plugins/QoSMarking/Info.plist index 3c3a726..98275a2 100644 --- a/Plugins/QoSMarking/Info.plist +++ b/Plugins/QoSMarking/Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.19 + 1.20 CFBundleSignature ???? CFBundleVersion - 1.19 + 1.20 QoSMarking_AppleAudioVideoCalls_BundleIDs com.apple.datausage.telephony.ims diff --git a/Plugins/QoSMarking/Makefile b/Plugins/QoSMarking/Makefile index 8efa982..3366265 100644 --- a/Plugins/QoSMarking/Makefile +++ b/Plugins/QoSMarking/Makefile @@ -4,7 +4,7 @@ endif ifeq ($(PLATFORM),iphoneos) # iOS internal SDK -ARCHS=armv7 +ARCHS=arm64 endif ifeq ($(PLATFORM),macosx) @@ -13,17 +13,21 @@ ARCHS=x86_64 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 diff --git a/Plugins/QoSMarking/qos-marking.m b/Plugins/QoSMarking/qos-marking.m index 99de79c..eb0cf39 100644 --- a/Plugins/QoSMarking/qos-marking.m +++ b/Plugins/QoSMarking/qos-marking.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 Apple Inc. All rights reserved. + * Copyright (c) 2016-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -748,6 +748,9 @@ qosMarkingSetEnabled(int s, const char *ifname, BOOL enabled) 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 @@ -811,6 +814,8 @@ qosMarkingSetEnabled(int s, const char *ifname, BOOL enabled) } else { SC_log(LOG_ERR, "socket() failed: %s", strerror(errno)); } + + notify = true; } if (reqEnabled) { @@ -924,6 +929,21 @@ qosMarkingSetEnabled(int s, const char *ifname, BOOL enabled) 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); + } } diff --git a/Plugins/SimulatorSupport/Info.plist b/Plugins/SimulatorSupport/Info.plist index 8b4c01b..3e9af15 100644 --- a/Plugins/SimulatorSupport/Info.plist +++ b/Plugins/SimulatorSupport/Info.plist @@ -17,10 +17,10 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.19 + 1.20 CFBundleSignature ???? CFBundleVersion - 1.19 + 1.20 diff --git a/Plugins/SimulatorSupport/simulator_support.c b/Plugins/SimulatorSupport/simulator_support.c index b81ac1f..2d6fafa 100644 --- a/Plugins/SimulatorSupport/simulator_support.c +++ b/Plugins/SimulatorSupport/simulator_support.c @@ -37,7 +37,7 @@ #include #include -#if TARGET_OS_SIMULATOR && !TARGET_OS_IOSMAC +#if TARGET_OS_SIMULATOR && !TARGET_OS_MACCATALYST static CFMutableArrayRef mirror_keys = NULL; @@ -323,4 +323,4 @@ main(int argc, char **argv) } #endif -#endif // TARGET_OS_SIMULATOR && !TARGET_OS_IOSMAC +#endif // TARGET_OS_SIMULATOR && !TARGET_OS_MACCATALYST diff --git a/SCMonitor/Info.plist b/SCMonitor/Info.plist index 4b358da..79825d2 100644 --- a/SCMonitor/Info.plist +++ b/SCMonitor/Info.plist @@ -15,11 +15,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.19 + 1.20 CFBundleSignature ???? CFBundleVersion - 1.19 + 1.20 CFPlugInDynamicRegistration NO CFPlugInFactories diff --git a/SCMonitor/en.lproj/Localizable.strings b/SCMonitor/en.lproj/Localizable.strings index 1234856f1d9e5a586a7b612bb3ca50f21c77c13a..1b6bb9087c14540ed45d96216023b5519f0e1556 100644 GIT binary patch delta 23 dcmX@YbA)Gu5-Vfg #include #include -#include +#include #include "UserEventAgentInterface.h" #define MY_BUNDLE_ID "com.apple.SystemConfiguration.SCMonitor" @@ -419,7 +419,7 @@ notify_add(MyType *myInstance) 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); } @@ -476,6 +476,7 @@ static void notify_configure(MyType *myInstance) { CFIndex i; + Boolean locked; CFIndex n = CFArrayGetCount(myInstance->interfaces_configure); Boolean ok; SCPreferencesRef prefs = NULL; @@ -494,6 +495,14 @@ notify_configure(MyType *myInstance) 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 @@ -540,11 +549,13 @@ notify_configure(MyType *myInstance) 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; diff --git a/SystemConfiguration.fproj/CaptiveNetwork.c b/SystemConfiguration.fproj/CaptiveNetwork.c index b618167..5714cf1 100644 --- a/SystemConfiguration.fproj/CaptiveNetwork.c +++ b/SystemConfiguration.fproj/CaptiveNetwork.c @@ -1,5 +1,5 @@ /* - * 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@ * @@ -93,18 +93,13 @@ CNCopySupportedInterfaces(void) } 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 } diff --git a/SystemConfiguration.fproj/CaptiveNetwork.h b/SystemConfiguration.fproj/CaptiveNetwork.h index 36ab01e..110df05 100644 --- a/SystemConfiguration.fproj/CaptiveNetwork.h +++ b/SystemConfiguration.fproj/CaptiveNetwork.h @@ -1,5 +1,5 @@ /* - * 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@ * @@ -145,15 +145,18 @@ extern const CFStringRef kCNNetworkInfoKeyBSSID /*! @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:
@@ -174,8 +177,8 @@ extern const CFStringRef kCNNetworkInfoKeyBSSID
  */
 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
 
diff --git a/SystemConfiguration.fproj/Info-Embedded.plist b/SystemConfiguration.fproj/Info-Embedded.plist
index 5515f5b..639f9ea 100644
--- a/SystemConfiguration.fproj/Info-Embedded.plist
+++ b/SystemConfiguration.fproj/Info-Embedded.plist
@@ -7,7 +7,7 @@
 	CFBundleExecutable
 	SystemConfiguration
 	CFBundleGetInfoString
-	1.19
+	1.20
 	CFBundleIdentifier
 	$(PRODUCT_BUNDLE_IDENTIFIER)
 	CFBundleInfoDictionaryVersion
@@ -17,10 +17,10 @@
 	CFBundlePackageType
 	FMWK
 	CFBundleShortVersionString
-	1.19
+	1.20
 	CFBundleSignature
 	????
 	CFBundleVersion
-	1.19
+	1.20
 
 
diff --git a/SystemConfiguration.fproj/Info.plist b/SystemConfiguration.fproj/Info.plist
index 5515f5b..639f9ea 100644
--- a/SystemConfiguration.fproj/Info.plist
+++ b/SystemConfiguration.fproj/Info.plist
@@ -7,7 +7,7 @@
 	CFBundleExecutable
 	SystemConfiguration
 	CFBundleGetInfoString
-	1.19
+	1.20
 	CFBundleIdentifier
 	$(PRODUCT_BUNDLE_IDENTIFIER)
 	CFBundleInfoDictionaryVersion
@@ -17,10 +17,10 @@
 	CFBundlePackageType
 	FMWK
 	CFBundleShortVersionString
-	1.19
+	1.20
 	CFBundleSignature
 	????
 	CFBundleVersion
-	1.19
+	1.20
 
 
diff --git a/SystemConfiguration.fproj/SCDHostName.c b/SystemConfiguration.fproj/SCDHostName.c
index 8c047e1..8d5e810 100644
--- a/SystemConfiguration.fproj/SCDHostName.c
+++ b/SystemConfiguration.fproj/SCDHostName.c
@@ -39,6 +39,41 @@
 #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
 
 
@@ -123,6 +158,12 @@ SCDynamicStoreCopyComputerName(SCDynamicStoreRef	store,
 	CFStringRef		key;
 	CFStringRef		name		= NULL;
 
+#ifndef	__OPEN_SOURCE
+	if (keepPrivate()) {
+		return NULL;
+	}
+#endif	// __OPEN_SOURCE
+
 	key  = SCDynamicStoreKeyCreateComputerName(NULL);
 	dict = SCDynamicStoreCopyValue(store, key);
 	CFRelease(key);
@@ -229,7 +270,7 @@ SCPreferencesSetComputerName(SCPreferencesRef	prefs,
 	}
 
 	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 {
@@ -255,6 +296,12 @@ SCPreferencesGetHostName(SCPreferencesRef	prefs)
 	CFStringRef	name;
 	CFStringRef	path;
 
+#ifndef	__OPEN_SOURCE
+	if (keepPrivate()) {
+		return NULL;
+	}
+#endif	// __OPEN_SOURCE
+
 	path = CFStringCreateWithFormat(NULL,
 					NULL,
 					CFSTR("/%@/%@"),
@@ -324,7 +371,7 @@ SCPreferencesSetHostName(SCPreferencesRef	prefs,
 	}
 
 	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 {
@@ -402,6 +449,12 @@ SCDynamicStoreCopyLocalHostName(SCDynamicStoreRef store)
 	CFStringRef		key;
 	CFStringRef		name		= NULL;
 
+#ifndef	__OPEN_SOURCE
+	if (keepPrivate()) {
+		return NULL;
+	}
+#endif	// __OPEN_SOURCE
+
 	key  = SCDynamicStoreKeyCreateHostNames(NULL);
 	dict = SCDynamicStoreCopyValue(store, key);
 	CFRelease(key);
@@ -563,7 +616,7 @@ SCPreferencesSetLocalHostName(SCPreferencesRef	prefs,
 	}
 
 	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 {
diff --git a/SystemConfiguration.fproj/SCDOpen.c b/SystemConfiguration.fproj/SCDOpen.c
index 7ef633b..94d4ce8 100644
--- a/SystemConfiguration.fproj/SCDOpen.c
+++ b/SystemConfiguration.fproj/SCDOpen.c
@@ -34,6 +34,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -44,11 +45,31 @@
 #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[] = {
 	"",
@@ -61,10 +82,132 @@ 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;
 }
 
@@ -145,6 +288,11 @@ __SCDynamicStoreDeallocate(CFTypeRef cf)
 
 	(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);
 
@@ -184,8 +332,6 @@ __SCDynamicStoreDeallocate(CFTypeRef cf)
 		_SCDynamicStoreCacheClose(store);
 	}
 
-	_SC_ATOMIC_DEC(&_sc_store_cnt);
-
 	return;
 }
 
@@ -227,6 +373,8 @@ __SCDynamicStoreInitialize(void)
 	/* add handler to cleanup after fork() */
 	(void) pthread_atfork(NULL, NULL, childForkHandler);
 
+	add_state_handler();
+
 	return;
 }
 
@@ -289,15 +437,27 @@ __SCDynamicStoreServerPort(SCDynamicStorePrivateRef storePrivate, kern_return_t
 }
 
 
+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);
@@ -334,13 +494,39 @@ __SCDynamicStoreCreatePrivate(CFAllocatorRef		allocator,
 	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;
diff --git a/SystemConfiguration.fproj/SCDPrivate.c b/SystemConfiguration.fproj/SCDPrivate.c
index b48c76b..54fb52a 100644
--- a/SystemConfiguration.fproj/SCDPrivate.c
+++ b/SystemConfiguration.fproj/SCDPrivate.c
@@ -1598,11 +1598,13 @@ void
 _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);
 
@@ -1611,9 +1613,8 @@ _SC_crash(const char *crash_info, CFStringRef notifyHeader, CFStringRef notifyMe
 			_SC_ReportCrash(notifyHeader, notifyMessage);
 		}
 
-		if (crash_info != NULL) {
-			CRSetCrashLogMessage(NULL);
-		}
+		// ... and cleanup after the crash report has been generated
+		CRSetCrashLogMessage(NULL);
 	}
 
 	return;
diff --git a/SystemConfiguration.fproj/SCNetworkConfigurationInternal.h b/SystemConfiguration.fproj/SCNetworkConfigurationInternal.h
index 8cf01f7..90fb90d 100644
--- a/SystemConfiguration.fproj/SCNetworkConfigurationInternal.h
+++ b/SystemConfiguration.fproj/SCNetworkConfigurationInternal.h
@@ -151,7 +151,8 @@ typedef struct {
 	CFStringRef		addressString;
 	Boolean			builtin;
 	CFStringRef		configurationAction;
-	Boolean			hidden;
+	Boolean			hiddenConfiguration;
+	Boolean			hiddenInterface;
 	CFStringRef		location;
 	CFStringRef		path;
 	uint64_t		entryID;
@@ -219,6 +220,10 @@ __SCNetworkConfigurationBackup			(SCPreferencesRef	prefs,
 #pragma mark SCNetworkInterface configuration (internal)
 
 
+extern const SCNetworkServiceRef __kSCNetworkInterfaceSearchExternal;
+
+extern const SCNetworkServiceRef __kSCNetworkInterfaceSearchSystem;
+
 Boolean
 __SCNetworkInterfaceMatchesName			(CFStringRef		name,
 						 CFStringRef		key);
@@ -481,21 +486,18 @@ Boolean
 __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);
 
diff --git a/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.c b/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.c
index 52ce138..b3a0863 100644
--- a/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.c
+++ b/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.c
@@ -125,16 +125,6 @@ __SCNetworkConfigurationBackup(SCPreferencesRef prefs, CFStringRef suffix, SCPre
 		       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);
@@ -876,7 +866,7 @@ __SCNetworkConfigurationCleanHiddenInterfaces(SCPreferencesRef prefs, SCPreferen
 					}
 					updated++;
 					continue;
-  				}
+				}
 			}
 
 			CFArrayAppendValue(interfaces_new, if_dict);
diff --git a/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h b/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h
index 3129569..fea0160 100644
--- a/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h
+++ b/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h
@@ -543,6 +543,25 @@ _SCNetworkInterfaceIsCarPlay				(SCNetworkInterfaceRef		interface)	API_AVAILABLE
 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).
diff --git a/SystemConfiguration.fproj/SCNetworkInterface.c b/SystemConfiguration.fproj/SCNetworkInterface.c
index bec3468..59a97f0 100644
--- a/SystemConfiguration.fproj/SCNetworkInterface.c
+++ b/SystemConfiguration.fproj/SCNetworkInterface.c
@@ -243,32 +243,31 @@ static const struct {
 	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                              }
 };
 
 
@@ -355,9 +354,12 @@ __SCNetworkInterfaceCopyFormattingDescription(CFTypeRef cf, CFDictionaryRef form
 		}
 	}
 	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"));
@@ -1166,8 +1168,14 @@ int
 __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;
 }
 
 
@@ -1263,36 +1271,6 @@ IOStringValueHasPrefix(CFTypeRef ioVal, CFStringRef prefix)
 }
 
 
-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 "),
@@ -1337,15 +1315,7 @@ pci_slot(io_registry_entry_t interface, CFTypeRef *pci_slot_name)
 			}
 		}
 
-		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);
 	}
@@ -1364,10 +1334,10 @@ pci_slot(io_registry_entry_t interface, CFTypeRef *pci_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;
@@ -1534,10 +1504,10 @@ pci_slot_info(io_registry_entry_t interface, int ift, CFStringRef *slot_name, CF
 	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;
@@ -1894,8 +1864,10 @@ processNetworkInterface(SCNetworkInterfacePrivateRef	interfacePrivate,
 				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)));
@@ -1960,14 +1932,40 @@ processNetworkInterface(SCNetworkInterfacePrivateRef	interfacePrivate,
 					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;
@@ -1985,7 +1983,6 @@ processNetworkInterface(SCNetworkInterfacePrivateRef	interfacePrivate,
 									interfacePrivate->localized_arg1 = slot_name;
 									interfacePrivate->localized_arg2 = port_name;
 								}
-
 							} else {
 								if (port_name == NULL) {
 									interfacePrivate->localized_key  = CFSTR("pci-ether");
@@ -2576,15 +2573,40 @@ copyIORegistryProperties(io_registry_entry_t reg_ent, const CFStringRef *reg_key
 	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;
@@ -2621,14 +2643,17 @@ createInterface(io_registry_entry_t interface, processInterface func,
 						      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);
@@ -2661,6 +2686,7 @@ createInterface(io_registry_entry_t interface, processInterface func,
 
 	interfacePrivate = __SCNetworkInterfaceCreatePrivate(NULL, NULL, NULL, NULL);
 	assert(interfacePrivate != NULL);
+	interfacePrivate->hiddenInterface = hidden_interface;
 	interfacePrivate->path = __SC_IORegistryEntryCopyPath(interface, kIOServicePlane);
 	interfacePrivate->entryID = entryID;
 
@@ -2698,7 +2724,7 @@ createInterface(io_registry_entry_t interface, processInterface func,
 						      NULL,
 						      kIORegistryIterateRecursively | kIORegistryIterateParents);
 		if (val != NULL) {
-			interfacePrivate->hidden = TRUE;
+			interfacePrivate->hiddenConfiguration = isHidden(val);
 			CFRelease(val);
 		}
 
@@ -2739,6 +2765,7 @@ static CF_RETURNS_RETAINED CFArrayRef
 findMatchingInterfaces(CFDictionaryRef	matching,
 		       processInterface	func,
 		       CFStringRef	hidden_key,
+		       Boolean		keep_hidden,
 		       Boolean		keep_pre_configured)
 {
 	CFMutableArrayRef	interfaces;
@@ -2764,7 +2791,7 @@ findMatchingInterfaces(CFDictionaryRef	matching,
 	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);
@@ -3151,6 +3178,21 @@ copyConfigurationPaths(SCNetworkInterfacePrivateRef	interfacePrivate,
 #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)
@@ -3183,7 +3225,7 @@ __SCNetworkInterfaceCopyInterfaceEntity(SCNetworkInterfaceRef interface)
 				     CFSTR("DeviceUniqueIdentifier"),
 				     interfacePrivate->entity_device_unique);
 	}
-	if (interfacePrivate->hidden) {
+	if (interfacePrivate->hiddenConfiguration) {
 		CFDictionarySetValue(entity,
 				     kSCNetworkInterfaceHiddenConfigurationKey,
 				     kCFBooleanTrue);
@@ -3440,7 +3482,7 @@ _SCNetworkInterfaceCreateWithBSDName(CFAllocatorRef	allocator,
 		CFDictionarySetValue(entity, CFSTR("_NO_VLAN_INTERFACES_"), kCFBooleanTrue);
 	}
 
-	interface = _SCNetworkInterfaceCreateWithEntity(NULL, entity, NULL);
+	interface = _SCNetworkInterfaceCreateWithEntity(NULL, entity, __kSCNetworkInterfaceSearchSystem);
 	CFRelease(entity);
 
 	return interface;
@@ -3683,9 +3725,12 @@ __SCNetworkInterfaceCopyStorageEntity(SCNetworkInterfaceRef 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);
@@ -3736,12 +3781,36 @@ __SCNetworkInterfaceSetService(SCNetworkInterfaceRef	interface,
 }
 
 
+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");
@@ -3754,41 +3823,29 @@ __SCNetworkInterfaceMatchesName(CFStringRef name, CFStringRef key)
 	}
 
 	// 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;
@@ -3804,34 +3861,37 @@ __SCNetworkInterfaceCreateWithStorageEntity(CFDictionaryRef interface_entity)
 	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) {
@@ -3841,7 +3901,7 @@ __SCNetworkInterfaceCreateWithStorageEntity(CFDictionaryRef interface_entity)
 	} 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;
@@ -3849,54 +3909,103 @@ __SCNetworkInterfaceCreateWithStorageEntity(CFDictionaryRef interface_entity)
 	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);
@@ -3904,21 +4013,6 @@ __SCNetworkInterfaceCreateWithStorageEntity(CFDictionaryRef interface_entity)
 #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) {
@@ -4000,6 +4094,7 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef	allocator,
 				    SCNetworkServiceRef	service)
 {
 #pragma unused(allocator)
+	Boolean				keepHidden		= FALSE;
 	SCNetworkInterfacePrivateRef	interfacePrivate	= NULL;
 	CFStringRef			ifDevice;
 	CFStringRef			ifName			= NULL;
@@ -4007,15 +4102,24 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef	allocator,
 	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);
@@ -4075,6 +4179,7 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef	allocator,
 				matching_interfaces = findMatchingInterfaces(matching,
 									     processNetworkInterface,
 									     kSCNetworkInterfaceHiddenInterfaceKey,
+									     keepHidden,
 									     TRUE);
 
 				__SCNetworkInterfaceCacheAdd(ifDevice, matching_interfaces);
@@ -4107,6 +4212,7 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef	allocator,
 				matching_interfaces = findMatchingInterfaces(matching,
 									     processSerialInterface,
 									     kSCNetworkInterfaceHiddenPortKey,
+									     keepHidden,
 									     TRUE);
 				CFRelease(matching);
 			}
@@ -4144,6 +4250,7 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef	allocator,
 					matching_interfaces = findMatchingInterfaces(matching,
 										     processSerialInterface,
 										     kSCNetworkInterfaceHiddenPortKey,
+										     keepHidden,
 										     TRUE);
 					CFRelease(matching);
 				}
@@ -4185,9 +4292,7 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef	allocator,
 	}
 
 	if (matching_interfaces != NULL) {
-		CFIndex 		n;
-		SCPreferencesRef	prefs;
-		Boolean			temp_preferences	= FALSE;
+		CFIndex		n;
 
 		n = CFArrayGetCount(matching_interfaces);
 		switch (n) {
@@ -4201,7 +4306,9 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef	allocator,
 
 				interfacePrivate = NULL;
 				// fall through
-			case 0 :
+			case 0 : {
+				Boolean	temp_preferences	= FALSE;
+
 				if (!CFEqual(ifType, kSCValNetInterfaceTypeEthernet)) {
 					break;
 				}
@@ -4213,32 +4320,35 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef	allocator,
 					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;
@@ -4301,6 +4411,9 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef	allocator,
     done :
 
 	if ((interfacePrivate == NULL) || !useSystemInterfaces)  {
+		CFStringRef	userDefinedName;
+		CFBooleanRef	val;
+
 		/*
 		 * if device not present on this system
 		 */
@@ -4316,11 +4429,13 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef	allocator,
 		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);
@@ -4336,15 +4451,15 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef	allocator,
 		}
 
 		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 {
@@ -4354,28 +4469,31 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef	allocator,
 					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 {
@@ -4386,6 +4504,9 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef	allocator,
 		} 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;
@@ -4425,6 +4546,7 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef	allocator,
 			}
 		} else if (CFEqual(ifType, kSCValNetInterfaceTypeVPN) && (ifSubType != NULL)) {
 			SCNetworkInterfaceRef	child;
+
 			CFRelease(interfacePrivate);
 			child = SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4, ifSubType);
 			interfacePrivate = (SCNetworkInterfacePrivateRef)child;
@@ -4461,9 +4583,8 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef	allocator,
 			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;
@@ -4558,6 +4679,7 @@ __SCNetworkInterfaceCopyAll_IONetworkInterface(Boolean keep_pre_configured)
 	new_interfaces = findMatchingInterfaces(matching,
 						processNetworkInterface,
 						kSCNetworkInterfaceHiddenInterfaceKey,
+						FALSE,
 						keep_pre_configured);
 	CFRelease(matching);
 
@@ -4589,6 +4711,7 @@ __SCNetworkInterfaceCopyAll_Modem()
 	new_interfaces = findMatchingInterfaces(matching,
 						processSerialInterface,
 						kSCNetworkInterfaceHiddenPortKey,
+						FALSE,
 						FALSE);
 	CFRelease(matching);
 
@@ -4620,6 +4743,7 @@ __SCNetworkInterfaceCopyAll_RS232()
 	new_interfaces = findMatchingInterfaces(matching,
 						processSerialInterface,
 						kSCNetworkInterfaceHiddenPortKey,
+						FALSE,
 						FALSE);
 	CFRelease(matching);
 
@@ -4681,7 +4805,7 @@ add_interfaces(CFMutableArrayRef all_interfaces, CFArrayRef new_interfaces)
 
 
 static void
-__waitForInterfaces()
+__wait_for_IOKit_to_quiesce(void)
 {
 	CFStringRef		key	= NULL;
 	CFArrayRef		keys;
@@ -4759,7 +4883,7 @@ _SCNetworkInterfaceCopyAllWithPreferences(SCPreferencesRef prefs)
 	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);
 
@@ -5092,7 +5216,9 @@ SCNetworkInterfaceCreateWithInterface(SCNetworkInterfaceRef child, CFStringRef i
 		goto fail;
 	}
 
-	parentPrivate->hidden = childPrivate->hidden;
+	parentPrivate->hiddenConfiguration = childPrivate->hiddenConfiguration;
+
+	parentPrivate->hiddenInterface = childPrivate->hiddenInterface;
 
 #if	TARGET_OS_IPHONE
 	parentPrivate->trustRequired = childPrivate->trustRequired;
@@ -7219,9 +7345,15 @@ _SCNetworkInterfaceCreateWithIONetworkInterfaceObject(io_object_t if_obj)
 	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;
@@ -7646,7 +7778,44 @@ _SCNetworkInterfaceIsHiddenConfiguration(SCNetworkInterfaceRef 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;
 }
 
 
@@ -7813,7 +7982,8 @@ __SCNetworkInterfaceCreateCopy(CFAllocatorRef		allocator,
 	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
diff --git a/SystemConfiguration.fproj/SCNetworkMigration.c b/SystemConfiguration.fproj/SCNetworkMigration.c
index ab9b39d..16c4c7c 100644
--- a/SystemConfiguration.fproj/SCNetworkMigration.c
+++ b/SystemConfiguration.fproj/SCNetworkMigration.c
@@ -34,6 +34,9 @@
 #include "SCPreferencesInternal.h"
 #include 
 #include 
+#if	!TARGET_OS_SIMULATOR
+#include 
+#endif	// !TARGET_OS_SIMULATOR
 #include 
 #include 
 #include 
@@ -113,14 +116,6 @@ _SCNetworkConfigurationCopyMigrationPaths(CFDictionaryRef options)
 	CFRelease(prefs);
 	CFRelease(interfaces);
 
-	SC_log(LOG_INFO,
-	       "_SCNetworkConfigurationCopyMigrationPaths() called%s"
-	       "\n  options = %@"
-	       "\n  paths   = %@",
-	       _SC_isInstallEnvironment() ? " (INSTALLER ENVIRONMENT)" : "",
-	       options,
-	       migrationPaths);
-
 	return migrationPaths;
 }
 
@@ -314,9 +309,9 @@ _SCNetworkConfigurationMakePathIfNeeded(CFURLRef pathURL)
 static void
 __SCNetworkPopulateDefaultPrefs(SCPreferencesRef prefs)
 {
-	SCNetworkSetRef		currentSet;
-	CFStringRef		model;
-	CFNumberRef		version;
+	SCNetworkSetRef	currentSet;
+	CFStringRef	model;
+	CFNumberRef	version;
 
 	SC_log(LOG_INFO,
 	       "Populating preferences.plist"
@@ -338,7 +333,7 @@ __SCNetworkPopulateDefaultPrefs(SCPreferencesRef prefs)
 
 	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);
@@ -348,8 +343,7 @@ __SCNetworkPopulateDefaultPrefs(SCPreferencesRef prefs)
 	return;
 }
 
-__private_extern__
-void
+static void
 __SCNetworkPopulateDefaultNIPrefs(SCPreferencesRef ni_prefs)
 {
 	CFMutableArrayRef	interfaces	= NULL;
@@ -448,16 +442,16 @@ CFArrayRef
 _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  = %@"
@@ -466,7 +460,7 @@ _SCNetworkConfigurationPerformMigration(CFURLRef sourceDir, CFURLRef currentDir,
 	       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);
@@ -584,10 +578,10 @@ done:
 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");
@@ -633,12 +627,12 @@ done:
 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");
@@ -677,10 +671,11 @@ done:
 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) {
@@ -690,13 +685,17 @@ _SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences(SCPreferencesR
 	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);
 		}
 	}
 
@@ -704,19 +703,22 @@ done:
 	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) {
@@ -725,8 +727,8 @@ _SCNetworkInterfaceStorageCopyMaxUnitPerInterfaceType(SCPreferencesRef ni_prefs)
 	}
 
 	interfaceTypeToMaxUnitMapping = CFDictionaryCreateMutable(NULL, 0,
-								    &kCFTypeDictionaryKeyCallBacks,
-								    &kCFTypeDictionaryValueCallBacks);
+								  &kCFTypeDictionaryKeyCallBacks,
+								  &kCFTypeDictionaryValueCallBacks);
 	count = CFArrayGetCount(ifList);
 	for (CFIndex idx = 0; idx < count; idx++) {
 		cfMaxUnit = NULL;
@@ -771,13 +773,13 @@ _SCNetworkInterfaceStorageCopyMaxUnitPerInterfaceType(SCPreferencesRef ni_prefs)
 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)) {
@@ -849,24 +851,54 @@ done:
 	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;
@@ -877,14 +909,15 @@ _SCNetworkConfigurationCopyExternalInterfaceMapping (SCPreferencesRef sourcePref
 		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++) {
@@ -928,6 +961,13 @@ _SCNetworkConfigurationCopyExternalInterfaceMapping (SCPreferencesRef sourcePref
 			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);
 
@@ -942,9 +982,10 @@ _SCNetworkConfigurationCopyExternalInterfaceMapping (SCPreferencesRef sourcePref
 		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) ||
@@ -971,6 +1012,9 @@ done:
 	if (interfaceTypeToMaxUnitMapping != NULL) {
 		CFRelease(interfaceTypeToMaxUnitMapping);
 	}
+	if (targetPrefs != NULL) {
+		CFRelease(targetPrefs);
+	}
 	return externalMapping;
 }
 static Boolean
@@ -980,14 +1024,14 @@ 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
@@ -1037,12 +1081,11 @@ _SCNetworkConfigurationIsInterfaceNamerMappable(SCNetworkInterfaceRef interface1
 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")) ||
@@ -1084,41 +1127,41 @@ __SCNetworkConfigurationInterfaceNameIsEquiv(CFStringRef interfaceName1, CFStrin
 }
 
 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.
@@ -1129,12 +1172,17 @@ _SCNetworkConfigurationValidateInterface (const void *key, const void *value, vo
 	// 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) {
@@ -1178,11 +1226,11 @@ _SCNetworkConfigurationValidateInterface (const void *key, const void *value, vo
 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)) {
@@ -1199,14 +1247,14 @@ static Boolean
 _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) {
@@ -1244,6 +1292,11 @@ _SCNetworkConfigurationCreateBuiltinInterfaceServices(SCPreferencesRef pref,
 	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;
@@ -1266,15 +1319,15 @@ done:
 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);
@@ -1335,11 +1388,11 @@ add_service(const void *value, void *context)
 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);
 
@@ -1381,10 +1434,10 @@ create_bsd_name_service_protocol_mapping(const void *value, void *context)
 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);
 
@@ -1394,14 +1447,15 @@ remove_service(const void *value, void *context)
 }
 
 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);
@@ -1412,6 +1466,7 @@ _SCNetworkConfigurationRepairUsingPreferences(SCPreferencesRef prefs,
 	}
 	// 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);
@@ -1424,15 +1479,15 @@ _SCNetworkConfigurationRepairUsingPreferences(SCPreferencesRef prefs,
 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) {
@@ -1455,19 +1510,20 @@ validate_bridge(const void *value, void *context)
 	}
 	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) {
@@ -1492,33 +1548,112 @@ validate_bond(const void *value, void *context)
 }
 #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);
@@ -1526,30 +1661,30 @@ done:
 }
 
 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);
@@ -1677,7 +1812,7 @@ _SCNetworkConfigurationCheckValidityWithPreferences(SCPreferencesRef prefs,
 		       prefs,
 		       ni_prefs);
 		if (repairConfiguration) {
-			isValid = _SCNetworkConfigurationRepairUsingPreferences(prefs, &context);
+			isValid = _SCNetworkConfigurationRepairUsingPreferences(prefs, ni_prefs, &context);
 			if (!isValid) {
 				goto done;
 			}
@@ -1780,7 +1915,11 @@ _SCNetworkConfigurationCheckValidityWithPreferences(SCPreferencesRef prefs,
 #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);
 	}
 
@@ -1833,16 +1972,16 @@ done:
 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: %@",
@@ -1923,15 +2062,15 @@ typedef struct {
 	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);
@@ -1949,12 +2088,12 @@ _SCNetworkConfigurationCollectInterfaceStorageEntity(const void *key, const void
 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");
@@ -2005,11 +2144,11 @@ done:
 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)) {
@@ -2050,29 +2189,24 @@ done:
 	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);
@@ -2087,9 +2221,10 @@ _SCNetworkMigrationCreateServiceSetMapping(SCPreferencesRef prefs)
 	}
 
 	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);
@@ -2111,14 +2246,14 @@ static CFDictionaryRef
 _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);
@@ -2197,32 +2332,32 @@ _SCNetworkMigrationCreateSetMapping(SCPreferencesRef sourcePrefs,
 // 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);
@@ -2249,7 +2384,7 @@ _SCNetworkMigrationCreateServiceMappingUsingBSDMapping(SCPreferencesRef sourcePr
 		sourceInterface = NULL;
 		sourceInterfaceType = NULL;
 		sourceInterfaceSubType = NULL;
-		bsdNameMapTarget = NULL;
+		targetBSDNameMapped = NULL;
 
 		targetCount = CFArrayGetCount(targetSCNetworkServicesMutable);
 		sourceService = (SCNetworkServiceRef) CFArrayGetValueAtIndex(sourceSCNetworkServicesMutable, idx);
@@ -2277,15 +2412,12 @@ _SCNetworkMigrationCreateServiceMappingUsingBSDMapping(SCPreferencesRef sourcePr
 			 !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;
 			}
 		}
@@ -2304,16 +2436,14 @@ _SCNetworkMigrationCreateServiceMappingUsingBSDMapping(SCPreferencesRef sourcePr
 				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;
@@ -2324,20 +2454,18 @@ _SCNetworkMigrationCreateServiceMappingUsingBSDMapping(SCPreferencesRef sourcePr
 				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;
@@ -2347,7 +2475,6 @@ _SCNetworkMigrationCreateServiceMappingUsingBSDMapping(SCPreferencesRef sourcePr
 		// 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);
 		}
 	}
@@ -2371,11 +2498,11 @@ _SCNetworkMigrationCreateServiceMappingUsingBSDMapping(SCPreferencesRef sourcePr
 }
 
 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
@@ -2383,66 +2510,226 @@ typedef struct {
 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;
@@ -2453,21 +2740,16 @@ done:
 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)) {
@@ -2510,7 +2792,6 @@ _SCNetworkMigrationDoSystemMigration(SCPreferencesRef sourcePrefs, SCPreferences
 						kSCPrefSystem,
 						kSCCompNetwork,
 						BACK_TO_MY_MAC_DSIDS);
-
 	btmmDSID = SCPreferencesPathGetValue(sourcePrefs, btmmDSIDPath);
 	if (btmmDSID != NULL) {
 		SCPreferencesPathSetValue(targetPrefs, btmmDSIDPath, btmmDSID);
@@ -2523,34 +2804,34 @@ _SCNetworkMigrationDoSystemMigration(SCPreferencesRef sourcePrefs, SCPreferences
 #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;
 	}
@@ -2568,25 +2849,25 @@ add_virtual_interface(const void *value, void *context)
 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;
 
@@ -2633,7 +2914,7 @@ done:
 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);
@@ -2653,8 +2934,8 @@ _SCNetworkMigrationRemoveBridgeServices(SCPreferencesRef prefs)
 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);
@@ -2679,24 +2960,24 @@ _SCNetworkMigrationCopyMappingBSDNameToBridgeServices(SCPreferencesRef prefs)
 
 
 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);
@@ -2720,7 +3001,7 @@ _SCNetworkMigrationDoBridgeMigration (SCPreferencesRef sourcePrefs,
 			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);
@@ -2747,8 +3028,8 @@ _SCNetworkMigrationDoBridgeMigration (SCPreferencesRef sourcePrefs,
 
 	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;
@@ -2770,26 +3051,26 @@ done:
 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;
 
@@ -2857,8 +3138,8 @@ _SCNetworkMigrationRemoveBondServices(SCPreferencesRef 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);
@@ -2883,24 +3164,24 @@ _SCNetworkMigrationCopyMappingBSDNameToBondServices(SCPreferencesRef prefs)
 
 
 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);
@@ -2923,7 +3204,7 @@ _SCNetworkMigrationDoBondMigration (SCPreferencesRef sourcePrefs,
 			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);
@@ -2950,8 +3231,8 @@ _SCNetworkMigrationDoBondMigration (SCPreferencesRef sourcePrefs,
 
 	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;
@@ -2972,27 +3253,27 @@ done:
 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) {
@@ -3006,7 +3287,7 @@ add_target_vlan(const void *value, void *context)
 		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;
@@ -3051,7 +3332,7 @@ add_target_vlan(const void *value, void *context)
 
 	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);
 		}
 	}
@@ -3113,24 +3394,24 @@ _SCNetworkMigrationCopyMappingBSDNameToVLANServices(SCPreferencesRef prefs)
 }
 
 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);
@@ -3147,7 +3428,7 @@ _SCNetworkMigrationDoVLANMigration (SCPreferencesRef sourcePrefs,
 		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);
@@ -3169,8 +3450,8 @@ _SCNetworkMigrationDoVLANMigration (SCPreferencesRef sourcePrefs,
 
 	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;
@@ -3193,28 +3474,28 @@ _SCNetworkMigrationDoVirtualNetworkInterfaceMigration(SCPreferencesRef sourcePre
 						      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;
@@ -3222,20 +3503,20 @@ _SCNetworkMigrationDoVirtualNetworkInterfaceMigration(SCPreferencesRef sourcePre
 #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;
@@ -3252,16 +3533,23 @@ create_migrated_order(const void *value, void *context)
 	}
 }
 
+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;
@@ -3270,7 +3558,7 @@ create_non_migrated_service_list(const void *value, void *context)
 	// 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;
 	}
@@ -3288,16 +3576,16 @@ create_non_migrated_service_list(const void *value, void *context)
 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;
@@ -3317,7 +3605,7 @@ preserve_service_order(const void *key, const void *value, void *context)
 
 	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
@@ -3332,8 +3620,8 @@ preserve_service_order(const void *key, const void *value, void *context)
 	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
@@ -3341,13 +3629,29 @@ preserve_service_order(const void *key, const void *value, void *context)
 		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:
@@ -3358,21 +3662,19 @@ 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;
 }
 
@@ -3383,45 +3685,38 @@ done:
 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)) {
@@ -3474,15 +3769,6 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD
 	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);
@@ -3504,31 +3790,31 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD
 						    &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"),
@@ -3630,14 +3916,17 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD
 			// 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);
@@ -3645,9 +3934,6 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD
 		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) {
@@ -3664,7 +3950,7 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD
 		// 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;
 		}
@@ -3673,16 +3959,19 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD
 
 		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)) {
@@ -3693,6 +3982,7 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD
 		if (!_SCNetworkMigrationDoServiceOrderMigration(sourcePrefs, targetPrefs, setMapping)) {
 			SC_log(LOG_NOTICE, "SCNetworkMigrationDoServiceMigration(): service order migration failed");
 		}
+		logConfiguration("Migrated", targetPrefs);
 	}
 
 skipServiceMigration:
diff --git a/SystemConfiguration.fproj/SCNetworkReachability.c b/SystemConfiguration.fproj/SCNetworkReachability.c
index 72f88e2..87fb509 100644
--- a/SystemConfiguration.fproj/SCNetworkReachability.c
+++ b/SystemConfiguration.fproj/SCNetworkReachability.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003-2019 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -53,6 +53,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -114,7 +115,9 @@ static CFStringRef	__SCNetworkReachabilityCopyDescription	(CFTypeRef cf);
 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,
@@ -239,20 +242,26 @@ static CFStringRef
 __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;
 }
 
@@ -1019,6 +1028,7 @@ static void
 __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) {
@@ -1029,7 +1039,10 @@ __SCNetworkReachabilityGetAgentVPNFlags(xpc_object_t dictionary, Boolean *vpn, B
 	*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;
 	}
 
@@ -1079,7 +1092,9 @@ nw_path_is_linklocal_direct(nw_path_t path)
 }
 
 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,
@@ -1175,7 +1190,13 @@ __SCNetworkReachabilityGetFlagsFromPath(nw_path_t			path,
 #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);
 }
 
@@ -1207,7 +1228,9 @@ SCNetworkReachabilityGetInterfaceIndex(SCNetworkReachabilityRef target)
 
 	MUTEX_LOCK(&targetPrivate->lock);
 
-	flags = __SCNetworkReachabilityGetFlagsFromPath(targetPrivate->lastPath,
+	flags = __SCNetworkReachabilityGetFlagsFromPath(targetPrivate->log_prefix,
+							"GetInterfaceIndex",
+							targetPrivate->lastPath,
 							targetPrivate->type,
 							nw_resolver_status_invalid,
 							NULL,
@@ -1238,7 +1261,8 @@ __SCNetworkReachabilityCreateCrazyIvan46Path(nw_path_t path, nw_endpoint_t endpo
 	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;
 	}
@@ -1331,7 +1355,9 @@ SCNetworkReachabilityGetFlags(SCNetworkReachabilityRef		target,
 
 	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,
@@ -1359,7 +1385,14 @@ SCNetworkReachabilityGetFlags(SCNetworkReachabilityRef		target,
 		}
 	}
 
-	*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);
 
@@ -1399,7 +1432,9 @@ reachPerformAndUnlock(SCNetworkReachabilityPrivateRef targetPrivate)
 		context_release	= NULL;
 	}
 
-	flags = __SCNetworkReachabilityGetFlagsFromPath(targetPrivate->lastPath,
+	flags = __SCNetworkReachabilityGetFlagsFromPath(targetPrivate->log_prefix,
+							"Perform",
+							targetPrivate->lastPath,
 							targetPrivate->type,
 							targetPrivate->lastResolverStatus,
 							targetPrivate->lastResolvedEndpoints,
@@ -1625,10 +1660,16 @@ SCNetworkReachabilityUnscheduleFromRunLoop(SCNetworkReachabilityRef	target,
 }
 
 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,
@@ -1647,10 +1688,15 @@ __SCNetworkReachabilityCopyPathStatus(SCNetworkReachabilityPrivateRef targetPriv
 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 ||
@@ -1658,7 +1704,7 @@ __SCNetworkReachabilityShouldUpdateClient(SCNetworkReachabilityPrivateRef target
 }
 
 static void
-__SCNetworkReachabilityRestartResolver(SCNetworkReachabilityPrivateRef targetPrivate)
+__SCNetworkReachabilityRestartResolver(SCNetworkReachabilityPrivateRef targetPrivate, const char *caller)
 {
 	if (targetPrivate &&
 	    !targetPrivate->resolverBypass &&
@@ -1692,10 +1738,15 @@ __SCNetworkReachabilityRestartResolver(SCNetworkReachabilityPrivateRef targetPri
 		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);
@@ -1707,16 +1758,76 @@ __SCNetworkReachabilityRestartResolver(SCNetworkReachabilityPrivateRef targetPri
 				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);
@@ -1804,7 +1915,7 @@ __SCNetworkReachabilitySetDispatchQueue(SCNetworkReachabilityPrivateRef	targetPr
 		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) {
@@ -1820,11 +1931,16 @@ __SCNetworkReachabilitySetDispatchQueue(SCNetworkReachabilityPrivateRef	targetPr
 		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);
@@ -1843,7 +1959,7 @@ __SCNetworkReachabilitySetDispatchQueue(SCNetworkReachabilityPrivateRef	targetPr
 
 				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)) {
diff --git a/SystemConfiguration.fproj/SCNetworkService.c b/SystemConfiguration.fproj/SCNetworkService.c
index a74c861..2b164d4 100644
--- a/SystemConfiguration.fproj/SCNetworkService.c
+++ b/SystemConfiguration.fproj/SCNetworkService.c
@@ -551,7 +551,7 @@ __SCNetworkServiceCopyAllInterfaces(SCPreferencesRef prefs)
 		service = CFArrayGetValueAtIndex(services, idx);
 		interface = SCNetworkServiceGetInterface(service);
 
-		if (isA_SCNetworkInterface(interface) == NULL) {
+		if (!isA_SCNetworkInterface(interface)) {
 			continue;
 		}
 		CFArrayAppendValue(interfaces, interface);
@@ -2388,34 +2388,34 @@ __private_extern__
 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;
@@ -2427,18 +2427,24 @@ __SCNetworkServiceMigrateNew(SCPreferencesRef		prefs,
 		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);
@@ -2453,20 +2459,24 @@ __SCNetworkServiceMigrateNew(SCPreferencesRef		prefs,
 			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;
@@ -2529,12 +2539,11 @@ __SCNetworkServiceMigrateNew(SCPreferencesRef		prefs,
 	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);
diff --git a/SystemConfiguration.fproj/SCNetworkSet.c b/SystemConfiguration.fproj/SCNetworkSet.c
index 915b577..43fca63 100644
--- a/SystemConfiguration.fproj/SCNetworkSet.c
+++ b/SystemConfiguration.fproj/SCNetworkSet.c
@@ -76,6 +76,9 @@ __SCNetworkSetCopyDescription(CFTypeRef cf)
 	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"));
 	}
@@ -169,7 +172,7 @@ __SCNetworkSetCreatePrivate(CFAllocatorRef      allocator,
 #pragma mark -
 
 
-static int
+static CFIndex
 _serviceOrder(SCNetworkServiceRef service)
 {
 	SCNetworkInterfaceRef	interface;
@@ -216,11 +219,11 @@ _serviceOrder_add(SCNetworkSetRef set, SCNetworkServiceRef service)
 {
 	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) {
@@ -238,10 +241,10 @@ _serviceOrder_add(SCNetworkSetRef set, SCNetworkServiceRef service)
 		_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;
 
@@ -260,13 +263,13 @@ _serviceOrder_add(SCNetworkSetRef set, SCNetworkServiceRef service)
 		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);
 
@@ -488,6 +491,7 @@ SCNetworkSetAddService(SCNetworkSetRef set, SCNetworkServiceRef service)
 		       service);
 		_SC_crash_once("SCNetworkSetAddService() w/removed set", NULL, NULL);
 		_SCErrorSet(kSCStatusInvalidArgument);
+		return FALSE;
 	}
 
 	if (!__SCNetworkServiceExists(service)) {
@@ -586,7 +590,7 @@ SCNetworkSetAddService(SCNetworkSetRef set, SCNetworkServiceRef service)
 	_serviceOrder_add(set, service);
 
 	// mark set as no longer "new"
-	setPrivate->established	= TRUE;
+	setPrivate->established = TRUE;
 
     done :
 
@@ -1168,6 +1172,7 @@ SCNetworkSetRemove(SCNetworkSetRef set)
 		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
@@ -1224,6 +1229,7 @@ SCNetworkSetRemoveService(SCNetworkSetRef set, SCNetworkServiceRef service)
 		       service);
 		_SC_crash_once("SCNetworkSetRemoveService() w/removed set", NULL, NULL);
 		_SCErrorSet(kSCStatusInvalidArgument);
+		return FALSE;
 	}
 
 	if (!__SCNetworkServiceExists(service)) {
diff --git a/SystemConfiguration.fproj/SCPOpen.c b/SystemConfiguration.fproj/SCPOpen.c
index ee73ee8..18081ab 100644
--- a/SystemConfiguration.fproj/SCPOpen.c
+++ b/SystemConfiguration.fproj/SCPOpen.c
@@ -973,7 +973,8 @@ __SCPreferencesAddSession(SCPreferencesRef prefs)
 							     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;
 		}
 
@@ -1177,11 +1178,22 @@ __SCPreferencesScheduleWithRunLoop(SCPreferencesRef	prefs,
 		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);
 		}
 
diff --git a/SystemConfiguration.fproj/SCSchemaDefinitions.c b/SystemConfiguration.fproj/SCSchemaDefinitions.c
index 3d3ee59..d6f60d3 100644
--- a/SystemConfiguration.fproj/SCSchemaDefinitions.c
+++ b/SystemConfiguration.fproj/SCSchemaDefinitions.c
@@ -63,6 +63,7 @@ const CFStringRef kSCEntNetSMB                                     = CFSTR("SMB"
 
 const CFStringRef kSCEntNet6to4                                    = CFSTR("6to4");
 const CFStringRef kSCEntNetAppLayer                                = CFSTR("AppLayer");
+const CFStringRef kSCEntNetCaptivePortal                           = CFSTR("CaptivePortal");
 
 
 const CFStringRef kSCEntNetEAPOL                                   = CFSTR("EAPOL");
@@ -127,6 +128,7 @@ const CFStringRef kSCPropNetDNSSupplementalMatchOrders             = CFSTR("Supp
 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");
@@ -200,6 +202,8 @@ const CFStringRef kSCValNetIPv4ConfigMethodLinkLocal               = CFSTR("Link
 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");
@@ -208,8 +212,6 @@ const CFStringRef kSCPropNetIPv4RouteDestinationAddress            = CFSTR("Dest
 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");
diff --git a/SystemConfiguration.fproj/SCSchemaDefinitions.h b/SystemConfiguration.fproj/SCSchemaDefinitions.h
index 012652a..458b6b3 100644
--- a/SystemConfiguration.fproj/SCSchemaDefinitions.h
+++ b/SystemConfiguration.fproj/SCSchemaDefinitions.h
@@ -193,7 +193,7 @@
  *   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
  *
@@ -1276,7 +1276,7 @@ extern const CFStringRef kSCPropNetIPv6DestAddresses                        API_
 
 /*!
   @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
diff --git a/SystemConfiguration.fproj/SCSchemaDefinitionsPrivate.h b/SystemConfiguration.fproj/SCSchemaDefinitionsPrivate.h
index ad84324..247f859 100644
--- a/SystemConfiguration.fproj/SCSchemaDefinitionsPrivate.h
+++ b/SystemConfiguration.fproj/SCSchemaDefinitionsPrivate.h
@@ -41,6 +41,7 @@
  * Network Entity Keys
  *
  *   kSCEntNetAppLayer                                  "AppLayer"                     CFDictionary
+ *   kSCEntNetCaptivePortal                             "CaptivePortal"                CFDictionary
  *   kSCEntNetCommCenter                                "com.apple.CommCenter"         CFDictionary
  *   kSCEntNetEAPOL                                     "EAPOL"                        CFDictionary
  *   kSCEntNetIdleRoute                                 "IdleRoute"
@@ -74,6 +75,10 @@
  *   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)
@@ -109,6 +114,8 @@
  * kSCEntNetIPv4 Entity Keys
  *
  *   kSCPropNetIPv4AdditionalRoutes                     "AdditionalRoutes"             CFArray[CFDictionary]
+ *   kSCPropNetIPv4ARPResolvedHardwareAddress           "ARPResolvedHardwareAddress"   CFString
+ *   kSCPropNetIPv4ARPResolvedIPAddress                 "ARPResolvedIPAddress"         CFString
  *   kSCPropNetIPv4CLAT46                               "CLAT46"                       CFBoolean
  *   kSCPropNetIPv4ExcludedRoutes                       "ExcludedRoutes"               CFArray[CFDictionary]
  *   kSCPropNetIPv4IncludedRoutes                       "IncludedRoutes"               CFArray[CFDictionary]
@@ -122,9 +129,6 @@
  *   kSCPropNetIPv4RouteGatewayAddress                  "GatewayAddress"               CFString
  *   kSCPropNetIPv4RouteInterfaceName                   "InterfaceName"                CFString
  *
- *   kSCPropNetIPv4ARPResolvedHardwareAddress           "ARPResolvedHardwareAddress"   CFString
- *   kSCPropNetIPv4ARPResolvedIPAddress                 "ARPResolvedIPAddress"         CFString
- *
  * kSCEntNetIPv6 Entity Keys
  *
  *   kSCPropNetIPv6AdditionalRoutes                     "AdditionalRoutes"             CFArray[CFDictionary]
@@ -381,6 +385,13 @@ extern const CFStringRef kSCPrefVirtualNetworkInterfaces                    API_
 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
@@ -562,6 +573,17 @@ extern const CFStringRef kSCPropNetDNSServiceIdentifier                     API_
 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
  */
@@ -722,6 +744,20 @@ extern const CFStringRef kSCPropNetIPSecOnDemandMatchDomainsNever           API_
 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
@@ -777,20 +813,6 @@ extern const CFStringRef kSCPropNetIPv4RouteGatewayAddress                  API_
 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
  */
diff --git a/SystemConfiguration.fproj/config_types.h b/SystemConfiguration.fproj/config_types.h
index 22a7053..1c4a5c0 100644
--- a/SystemConfiguration.fproj/config_types.h
+++ b/SystemConfiguration.fproj/config_types.h
@@ -1,5 +1,5 @@
 /*
- * 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@
  *
@@ -24,6 +24,8 @@
 #ifndef _CONFIG_TYPES_H
 #define _CONFIG_TYPES_H
 
+#include 
+
 /*
  * Keep IPC functions private to the framework
  */
@@ -41,12 +43,12 @@
 /*
  * 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, ...
diff --git a/SystemConfiguration.fproj/en.lproj/Localizable.strings b/SystemConfiguration.fproj/en.lproj/Localizable.strings
index f930b18cb482aff42fe8234b21246eb50a41a981..6ec93790abe6df0ba1d69cc70431e3ade608a1cf 100644
GIT binary patch
delta 28
kcmbOwJxh863nyzHgA#-Ft<8

diff --git a/SystemConfiguration.fproj/genSCPreferences.c b/SystemConfiguration.fproj/genSCPreferences.c
index c9ed85f..09fd827 100644
--- a/SystemConfiguration.fproj/genSCPreferences.c
+++ b/SystemConfiguration.fproj/genSCPreferences.c
@@ -133,6 +133,7 @@ typedef enum {
 	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,
@@ -215,6 +216,7 @@ typedef enum {
 #define CALLWAITINGAUDIBLEALERT	"CallWaitingAudibleAlert"
 #define CAPABILITIES		"Capabilities"
 #define CAPABILITY		"Capability"
+#define CAPTIVEPORTAL		"CaptivePortal"
 #define CAUSE			"Cause"
 #define CCP			"CCP"
 #define CELLULAR		"Cellular"
@@ -503,6 +505,7 @@ typedef enum {
 #define TYPE			"Type"
 #define UID			"UID"
 #define UPDATED			"Updated"
+#define URL			"URL"
 #define URLSTRING		"URLString"
 #define USE			"Use"
 #define USERDEFINEDNAME		"UserDefinedName"
@@ -617,6 +620,7 @@ static schemaDefinition names[] = {
   { 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},
@@ -719,6 +723,11 @@ static schemaDefinition names[] = {
     { 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 },
@@ -841,6 +850,8 @@ static schemaDefinition names[] = {
 
   { 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 },
@@ -859,16 +870,13 @@ static schemaDefinition names[] = {
     { 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 },
@@ -1533,6 +1541,9 @@ print_headerdoc(schemaDefinition *def)
 	    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;
@@ -1716,6 +1727,7 @@ dump_names(int type)
 			    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:
@@ -1756,6 +1768,7 @@ dump_names(int type)
 			    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:
@@ -1787,6 +1800,7 @@ dump_names(int type)
 			    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:
@@ -1816,6 +1830,7 @@ dump_names(int type)
 			    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:
diff --git a/SystemConfiguration.fproj/restore-temporary-headers b/SystemConfiguration.fproj/restore-temporary-headers
deleted file mode 100755
index fb1e9ba..0000000
--- a/SystemConfiguration.fproj/restore-temporary-headers
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/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 
- * or :
- *	#include 
- *
- * WARNING WARNING WARNING WARNING WARNING
- */
-#ifndef	NO_TAPI_WARNINGS
-#warning "Please #include , NOT . See rdar://41937689 for details"
-#endif	// NO_TAPI_WARNINGS
-
-#endif	// ${HACK}
-
-#include 
-_END_OF_INPUT
-done
-
-exit
diff --git a/SystemConfiguration.fproj/scprefs_observer.c b/SystemConfiguration.fproj/scprefs_observer.c
index 74369fa..5d36d3f 100644
--- a/SystemConfiguration.fproj/scprefs_observer.c
+++ b/SystemConfiguration.fproj/scprefs_observer.c
@@ -1,5 +1,5 @@
 /*
- * 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@
  *
@@ -37,20 +37,18 @@ os_log_t	SC_LOG_HANDLE(void);
 #include 
 #include 
 
-#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)
@@ -88,8 +86,8 @@ iterate_dir(const char *d_name, const char *f_name,
 				*/
 				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;
 			}
 		}
@@ -97,6 +95,26 @@ iterate_dir(const char *d_name, const char *f_name,
 	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)
@@ -107,7 +125,11 @@ 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));
@@ -136,9 +158,7 @@ prefs_observer_get_prefs_path(scprefs_observer_t observer)
 		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);
diff --git a/SystemConfiguration.fproj/scprefs_observer.h b/SystemConfiguration.fproj/scprefs_observer.h
index 8319094..b116f09 100644
--- a/SystemConfiguration.fproj/scprefs_observer.h
+++ b/SystemConfiguration.fproj/scprefs_observer.h
@@ -1,5 +1,5 @@
 /*
- * 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@
  *
@@ -34,7 +34,6 @@ typedef enum {
 		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;
 
@@ -58,7 +57,7 @@ _scprefs_observer_watch(_scprefs_observer_type type, const char *plist_name,
 
 /*!
  @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
diff --git a/configd.tproj/_snapshot.c b/configd.tproj/_snapshot.c
index 5197780..854d36c 100644
--- a/configd.tproj/_snapshot.c
+++ b/configd.tproj/_snapshot.c
@@ -142,12 +142,8 @@ __SCDynamicStoreSnapshot(SCDynamicStoreRef store)
 	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);
 
diff --git a/configd.tproj/configd.8 b/configd.tproj/configd.8
index 9006d7b..5f78312 100644
--- a/configd.tproj/configd.8
+++ b/configd.tproj/configd.8
@@ -1,7 +1,7 @@
 .\"
 .\"     @(#)configd.8
 .\"
-.Dd June 18, 2009
+.Dd April 14, 2020
 .Dt CONFIGD 8
 .Os "Mac OS X"
 .Sh NAME
@@ -73,9 +73,7 @@ This bundle provides a name to each of the system's network interfaces.  The bun
 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
@@ -92,13 +90,11 @@ Directory of
 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
diff --git a/configd.tproj/configd.m b/configd.tproj/configd.m
index 5043bb3..5e7fa4d 100644
--- a/configd.tproj/configd.m
+++ b/configd.tproj/configd.m
@@ -460,7 +460,7 @@ main(int argc, char * const argv[])
 	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 */
@@ -470,20 +470,16 @@ main(int argc, char * const argv[])
 			/* 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. */
 }
diff --git a/configd.tproj/entitlements-ios.plist b/configd.tproj/entitlements-ios.plist
index deff580..ffb4814 100644
--- a/configd.tproj/entitlements-ios.plist
+++ b/configd.tproj/entitlements-ios.plist
@@ -38,6 +38,11 @@
 	
 	com.apple.private.snhelper
 	
+	com.apple.security.iokit-user-client-class
+	
+		IONetworkStackUserClient
+		RootDomainUserClient
+	
 	com.apple.security.network.client
 	
 	com.apple.security.network.server
diff --git a/configd.tproj/entitlements-macOS.plist b/configd.tproj/entitlements-macOS.plist
new file mode 100644
index 0000000..65a8a9f
--- /dev/null
+++ b/configd.tproj/entitlements-macOS.plist
@@ -0,0 +1,10 @@
+
+
+
+
+	com.apple.private.necp.match
+	
+	com.apple.private.necp.policies
+	
+
+
diff --git a/configd.tproj/plugin_support.c b/configd.tproj/plugin_support.c
index 760cc9a..590cd7d 100644
--- a/configd.tproj/plugin_support.c
+++ b/configd.tproj/plugin_support.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2019 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -106,10 +106,6 @@ static CFMutableArrayRef	allBundles		= NULL;
 // exiting bundles
 static CFMutableDictionaryRef	exiting			= NULL;
 
-// plugin CFRunLoopRef
-__private_extern__
-CFRunLoopRef			plugin_runLoop		= NULL;
-
 
 extern SCDynamicStoreBundleLoadFunction		load_IPMonitor;
 extern SCDynamicStoreBundlePrimeFunction	prime_IPMonitor;
@@ -697,32 +693,11 @@ stopBundles()
 #pragma mark term
 
 
-static CFStringRef
-termRLSCopyDescription(const void *info)
-{
-#pragma unused(info)
-	return CFStringCreateWithFormat(NULL, NULL, CFSTR(""));
-}
-
-
 __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
@@ -740,12 +715,7 @@ plugin_term(int *status)
 					    &kCFTypeDictionaryKeyCallBacks,
 					    &kCFTypeDictionaryValueCallBacks);
 
-	termRls = CFRunLoopSourceCreate(NULL, 0, &termContext);
-	CFRunLoopAddSource(plugin_runLoop, termRls, kCFRunLoopDefaultMode);
-	CFRunLoopSourceSignal(termRls);
-	CFRelease(termRls);
-	CFRunLoopWakeUp(plugin_runLoop);
-
+	stopBundles();
 	return TRUE;
 }
 
@@ -866,7 +836,7 @@ ALT_CFRelease(CFTypeRef cf)
 
 
 __private_extern__
-void *
+void
 plugin_exec(void *arg)
 {
 	CFIndex		nLoaded		= 0;
@@ -897,7 +867,7 @@ plugin_exec(void *arg)
 			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");
@@ -910,7 +880,7 @@ plugin_exec(void *arg)
 			} 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));
@@ -1029,7 +999,7 @@ plugin_exec(void *arg)
 
 	if (nLoaded == 0) {
 		// if no bundles loaded
-		goto done;
+		return;
 	}
 
 	/*
@@ -1063,40 +1033,15 @@ plugin_exec(void *arg)
 			     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;
 }
diff --git a/configd.tproj/plugin_support.h b/configd.tproj/plugin_support.h
index 2b035fa..31a1199 100644
--- a/configd.tproj/plugin_support.h
+++ b/configd.tproj/plugin_support.h
@@ -1,15 +1,15 @@
 /*
- * 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,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -33,14 +33,11 @@
 
 #include 
 
-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 */
diff --git a/configd.tproj/session.c b/configd.tproj/session.c
index f3cc0d8..2e88cc3 100644
--- a/configd.tproj/session.c
+++ b/configd.tproj/session.c
@@ -1,5 +1,5 @@
 /*
- * 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@
  *
@@ -55,6 +55,7 @@ static serverSessionRef		server_session		= NULL;
  * 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
@@ -271,7 +272,7 @@ add_state_handler()
 		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);
@@ -375,6 +376,42 @@ getSessionStr(CFStringRef serverKey)
 }
 
 
+#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)
@@ -384,7 +421,9 @@ 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);
 	});
 
@@ -422,7 +461,7 @@ addSession(serverSessionRef session, Boolean isMain)
 							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
diff --git a/configd.xcodeproj/project.pbxproj b/configd.xcodeproj/project.pbxproj
index 0f89bc4..b094e96 100644
--- a/configd.xcodeproj/project.pbxproj
+++ b/configd.xcodeproj/project.pbxproj
@@ -31,12 +31,6 @@
 			);
 			dependencies = (
 				15A5A2710D5B942D0087BDA0 /* PBXTargetDependency */,
-				15E1B06416EBAF2A00E5F06F /* PBXTargetDependency */,
-				15E1B06616EBAF2A00E5F06F /* PBXTargetDependency */,
-				15D3083016F3EAD000014F82 /* PBXTargetDependency */,
-				15D3083216F3EAD000014F82 /* PBXTargetDependency */,
-				15E1B03E16EBAB8A00E5F06F /* PBXTargetDependency */,
-				15E1B04016EBAB9400E5F06F /* PBXTargetDependency */,
 			);
 			name = "configd_base-EmbeddedSimulator";
 			productName = Frameworks;
@@ -72,6 +66,13 @@
 				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;
@@ -98,11 +99,9 @@
 			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;
@@ -176,6 +175,17 @@
 			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" */;
@@ -260,6 +270,7 @@
 			dependencies = (
 				157FDE44164A079B0040D6A8 /* PBXTargetDependency */,
 				151FE37A0D5B713C000D6DB1 /* PBXTargetDependency */,
+				1584B5E12469B6CE00AFF758 /* PBXTargetDependency */,
 				15631D2D1ECF99A00088EEDD /* PBXTargetDependency */,
 				15401C3021991B31006326B7 /* PBXTargetDependency */,
 				15EF89C62189484C003B2C5C /* PBXTargetDependency */,
@@ -659,6 +670,8 @@
 		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 */; };
@@ -750,6 +763,8 @@
 		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, ); }; };
@@ -894,6 +909,7 @@
 		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 */; };
@@ -1048,7 +1064,7 @@
 		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 */; };
@@ -1106,7 +1122,7 @@
 		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 */; };
@@ -1342,33 +1358,61 @@
 			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;
@@ -1517,6 +1561,13 @@
 			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 */;
@@ -1594,13 +1645,6 @@
 			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 */;
@@ -1629,55 +1673,6 @@
 			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 */;
@@ -1979,7 +1974,6 @@
 		1532629006281C9D00B1C10C /* dnsinfo_create.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dnsinfo_create.h; path = dnsinfo/dnsinfo_create.h; sourceTree = ""; };
 		153338BA14BE7978004FCE22 /* libSystemConfiguration_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libSystemConfiguration_client.c; path = libSystemConfiguration/libSystemConfiguration_client.c; sourceTree = ""; };
 		153338BB14BE7978004FCE22 /* libSystemConfiguration_client.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = libSystemConfiguration_client.h; path = libSystemConfiguration/libSystemConfiguration_client.h; sourceTree = ""; };
-		153393E20D34994100FE74E7 /* restore-temporary-headers */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.perl; path = "restore-temporary-headers"; sourceTree = ""; };
 		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 = ""; 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 = ""; };
 		1540E3600987DA9500157C07 /* com.apple.configd.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = com.apple.configd.plist; sourceTree = ""; };
@@ -2035,6 +2029,10 @@
 		15812A2D1EA5540B001CF384 /* nat64-configuration.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "nat64-configuration.c"; sourceTree = ""; };
 		15812A2E1EA5540B001CF384 /* nat64-configuration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "nat64-configuration.h"; sourceTree = ""; };
 		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 = ""; };
+		1583DFBA2360D0E700AA397A /* SCDynamicStoreParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCDynamicStoreParser.m; sourceTree = ""; };
+		1583DFBB2360D0E700AA397A /* SCDynamicStoreParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCDynamicStoreParser.h; sourceTree = ""; };
+		1583DFBC2360D0E800AA397A /* SCPreferencesParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCPreferencesParser.h; sourceTree = ""; };
 		158AD8700754E3D400124717 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
 		158AD8C00754E3EF00124717 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
 		158AD9100754E40E00124717 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
@@ -2072,6 +2070,7 @@
 		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 = ""; };
 		15A1FF3110597F17004C9CC9 /* CaptiveNetwork.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CaptiveNetwork.c; sourceTree = ""; };
 		15A2972D0A13C08C009879B3 /* SCNetworkConnectionPrivate.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = SCNetworkConnectionPrivate.c; sourceTree = ""; };
@@ -2269,7 +2268,7 @@
 		15FD73EE0754DE62001CC321 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
 		15FD743E0754DE7A001CC321 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
 		15FD7B3B101E439200C56621 /* BridgeConfiguration.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = BridgeConfiguration.c; sourceTree = ""; };
-		15FEE80D0CCFD341001312F9 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; sourceTree = ""; };
+		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 = ""; };
 		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 = ""; };
@@ -2354,6 +2353,7 @@
 		D6AEB89815AE4446009F2FAF /* ip_plugin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ip_plugin.h; sourceTree = ""; };
 		F90E43542012AD3900EF27C4 /* SCNetworkInterfaceProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCNetworkInterfaceProvider.h; sourceTree = ""; };
 		F90E43552012AD4500EF27C4 /* SCNetworkInterfaceProvider.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SCNetworkInterfaceProvider.c; sourceTree = ""; };
+		F9292ACB24AEAB1C0039975D /* entitlements-macOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "entitlements-macOS.plist"; sourceTree = ""; };
 		F95B8A420B03E07A00993BA3 /* SCNetworkSignature.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = SCNetworkSignature.c; sourceTree = ""; };
 		F95B8A440B03E09300993BA3 /* SCNetworkSignature.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCNetworkSignature.h; sourceTree = ""; };
 		F95B8A450B03E09300993BA3 /* SCNetworkSignaturePrivate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCNetworkSignaturePrivate.h; sourceTree = ""; };
@@ -2375,8 +2375,8 @@
 		F9D7304820DD89C600521181 /* AWDMetricIds_IPMonitor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AWDMetricIds_IPMonitor.h; sourceTree = ""; };
 		F9D7304920DD89C600521181 /* AWDIPMonitorInterfaceAdvisoryReport.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AWDIPMonitorInterfaceAdvisoryReport.m; sourceTree = ""; };
 		F9D7304A20DDA59600521181 /* awdgen.yaml */ = {isa = PBXFileReference; lastKnownFileType = text; path = awdgen.yaml; sourceTree = ""; };
-		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 = ""; };
-		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 = ""; };
+		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 */
@@ -2394,10 +2394,10 @@
 			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;
 		};
@@ -2406,8 +2406,8 @@
 			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;
 		};
@@ -2457,6 +2457,7 @@
 			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 */,
@@ -2512,16 +2513,17 @@
 			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 */,
@@ -2533,8 +2535,8 @@
 			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;
@@ -2543,16 +2545,17 @@
 			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 */,
 			);
@@ -3015,7 +3018,6 @@
 				158D6D871C974DBA00A08E78 /* com.apple.SystemConfiguration.plist */,
 				15CFC229068B222F00123568 /* get-mobility-info */,
 				72499BA31AC9B7AB0090C49F /* get-network-info */,
-				153393E20D34994100FE74E7 /* restore-temporary-headers */,
 			);
 			name = "Supporting Files";
 			sourceTree = "";
@@ -3427,6 +3429,7 @@
 		15CB6A1805C0722B0099E85F /* Supporting Files */ = {
 			isa = PBXGroup;
 			children = (
+				F9292ACB24AEAB1C0039975D /* entitlements-macOS.plist */,
 				1540E3600987DA9500157C07 /* com.apple.configd.plist */,
 				15D3083A16F4E6D900014F82 /* com.apple.configd_sim.plist */,
 				15CB6A2005C0722B0099E85F /* configd.8 */,
@@ -3527,15 +3530,15 @@
 		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 */,
@@ -3653,24 +3656,25 @@
 		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 = "";
@@ -3694,6 +3698,10 @@
 				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;
@@ -4574,7 +4582,6 @@
 			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 */,
@@ -4606,8 +4613,6 @@
 			buildRules = (
 			);
 			dependencies = (
-				15AB752A16EC254D00FAA8CE /* PBXTargetDependency */,
-				15D3083516F3EB2500014F82 /* PBXTargetDependency */,
 			);
 			name = "configd-EmbeddedSimulator";
 			productInstallPath = /usr/sbin;
@@ -5032,7 +5037,6 @@
 			buildConfigurationList = 15A5A2660D5B94190087BDA0 /* Build configuration list for PBXNativeTarget "SystemConfiguration.framework-EmbeddedSimulator" */;
 			buildPhases = (
 				15A5A1E60D5B94190087BDA0 /* Headers */,
-				15A5A2170D5B94190087BDA0 /* Restore temporary headers */,
 				15A5A21D0D5B94190087BDA0 /* Sources */,
 				15A5A2620D5B94190087BDA0 /* Frameworks */,
 				15A5A2180D5B94190087BDA0 /* Resources */,
@@ -5518,6 +5522,7 @@
 				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 */,
@@ -5945,22 +5950,6 @@
 			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;
@@ -5973,7 +5962,7 @@
 			);
 			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 */ = {
@@ -6082,6 +6071,25 @@
 			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;
@@ -6116,35 +6124,37 @@
 			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 */ = {
@@ -6345,7 +6355,7 @@
 			);
 			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 */ = {
@@ -7133,14 +7143,16 @@
 			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;
 		};
@@ -7242,25 +7254,45 @@
 			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;
@@ -7367,6 +7399,11 @@
 			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 */;
@@ -7422,11 +7459,6 @@
 			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 */;
@@ -7447,41 +7479,6 @@
 			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 */;
@@ -7719,7 +7716,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				PRODUCT_NAME = "configd_base (EmbeddedSimulator)";
-				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
 			};
 			name = Debug;
 		};
@@ -7727,7 +7724,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				PRODUCT_NAME = "configd_base (EmbeddedSimulator)";
-				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
 			};
 			name = Release;
 		};
@@ -7765,7 +7762,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				PRODUCT_NAME = "configd_extras (EmbeddedSimulator)";
-				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
 			};
 			name = Debug;
 		};
@@ -7773,7 +7770,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				PRODUCT_NAME = "configd_extras (EmbeddedSimulator)";
-				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
 			};
 			name = Release;
 		};
@@ -7886,7 +7883,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				PRODUCT_NAME = "configd_executables (EmbeddedSimulator)";
-				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
 			};
 			name = Debug;
 		};
@@ -7894,7 +7891,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				PRODUCT_NAME = "configd_executables (EmbeddedSimulator)";
-				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
 			};
 			name = Release;
 		};
@@ -7917,13 +7914,10 @@
 				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",
@@ -7931,6 +7925,10 @@
 					"-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]" = "";
@@ -7964,13 +7962,10 @@
 				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",
@@ -7978,6 +7973,10 @@
 					"-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]" = "";
@@ -8355,6 +8354,7 @@
 			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",
@@ -8381,6 +8381,7 @@
 		156EB6240905594A00EEF749 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
+				CODE_SIGN_ENTITLEMENTS = "configd.tproj/entitlements-macOS.plist";
 				FRAMEWORK_SEARCH_PATHS = (
 					"$(SYMROOT)",
 					"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
@@ -8532,11 +8533,9 @@
 				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)",
@@ -8620,11 +8619,9 @@
 				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)",
@@ -8708,9 +8705,10 @@
 				);
 				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",
@@ -8722,10 +8720,10 @@
 				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;
@@ -8740,9 +8738,10 @@
 				);
 				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",
@@ -8754,10 +8753,10 @@
 				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;
@@ -8779,7 +8778,7 @@
 				);
 				PRODUCT_NAME = configd_sim;
 				SDKROOT = iphoneos.internal;
-				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
 			};
 			name = Debug;
 		};
@@ -8800,7 +8799,7 @@
 				);
 				PRODUCT_NAME = configd_sim;
 				SDKROOT = iphoneos.internal;
-				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
 			};
 			name = Release;
 		};
@@ -8820,7 +8819,7 @@
 				);
 				PRODUCT_NAME = scutil_sim;
 				SDKROOT = iphoneos.internal;
-				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
 			};
 			name = Debug;
 		};
@@ -8840,7 +8839,7 @@
 				);
 				PRODUCT_NAME = scutil_sim;
 				SDKROOT = iphoneos.internal;
-				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
 			};
 			name = Release;
 		};
@@ -8856,16 +8855,12 @@
 				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",
@@ -8876,7 +8871,7 @@
 				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;
 		};
@@ -8892,16 +8887,12 @@
 				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",
@@ -8912,7 +8903,7 @@
 				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;
 		};
@@ -8989,37 +8980,33 @@
 				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";
@@ -9045,37 +9032,33 @@
 				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";
@@ -9254,7 +9237,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				PRODUCT_NAME = "configd_libSystem (EmbeddedSimulator)";
-				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
 			};
 			name = Debug;
 		};
@@ -9262,7 +9245,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				PRODUCT_NAME = "configd_libSystem (EmbeddedSimulator)";
-				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
 			};
 			name = Release;
 		};
@@ -9494,9 +9477,10 @@
 			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";
@@ -9507,15 +9491,32 @@
 			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 = {
@@ -9527,9 +9528,9 @@
 				);
 				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",
@@ -9545,11 +9546,10 @@
 				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;
@@ -9565,9 +9565,9 @@
 				);
 				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",
@@ -9583,11 +9583,10 @@
 				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;
@@ -9637,7 +9636,7 @@
 				PRODUCT_NAME = SimulatorSupport_sim;
 				SDKROOT = iphoneos.internal;
 				STRIP_INSTALLED_PRODUCT = NO;
-				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
 			};
 			name = Debug;
 		};
@@ -9656,7 +9655,7 @@
 				PRODUCT_NAME = SimulatorSupport_sim;
 				SDKROOT = iphoneos.internal;
 				STRIP_INSTALLED_PRODUCT = NO;
-				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
 			};
 			name = Release;
 		};
@@ -9668,7 +9667,7 @@
 				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;
 		};
@@ -9680,7 +9679,7 @@
 				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;
 		};
@@ -9701,7 +9700,7 @@
 				PRODUCT_NAME = IPMonitor_sim;
 				SDKROOT = iphoneos.internal;
 				STRIP_INSTALLED_PRODUCT = NO;
-				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
 			};
 			name = Debug;
 		};
@@ -9722,7 +9721,7 @@
 				PRODUCT_NAME = IPMonitor_sim;
 				SDKROOT = iphoneos.internal;
 				STRIP_INSTALLED_PRODUCT = NO;
-				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
 			};
 			name = Release;
 		};
@@ -9734,7 +9733,7 @@
 				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;
 		};
@@ -9746,7 +9745,7 @@
 				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;
 		};
@@ -9926,7 +9925,7 @@
 				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;
 		};
@@ -9948,7 +9947,7 @@
 				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;
 		};
@@ -9956,7 +9955,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				PRODUCT_NAME = configdAggregateEmbeddedSimulator;
-				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
 			};
 			name = Debug;
 		};
@@ -9964,7 +9963,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				PRODUCT_NAME = configdAggregateEmbeddedSimulator;
-				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator bridgesimulator";
+				SUPPORTED_PLATFORMS = "iphonesimulator tvossimulator watchsimulator";
 			};
 			name = Release;
 		};
@@ -10655,6 +10654,15 @@
 			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 = (
diff --git a/dnsinfo/dnsinfo_flatfile.c b/dnsinfo/dnsinfo_flatfile.c
index 2820371..900f9ec 100644
--- a/dnsinfo/dnsinfo_flatfile.c
+++ b/dnsinfo/dnsinfo_flatfile.c
@@ -1,5 +1,5 @@
 /*
- * 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@
  *
@@ -34,10 +34,12 @@
 #include 
 #include 
 #include 
+#include 	// 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_t	SC_LOG_HANDLE(void);
+#endif	//SC_LOG_HANDLE
 
 #include "dnsinfo.h"
 #include "dnsinfo_private.h"
@@ -333,6 +335,10 @@ _dnsinfo_flatfile_create_resolver(const char *dir, const char *path)
 		}
 		if (token == -1) {
 			// if not a recognized token
+			SC_log(LOG_NOTICE,
+			       "Unrecognized token (%s) found in: %s",
+			       word,
+			       filename);
 			continue;
 		}
 
diff --git a/get-network-info b/get-network-info
index 4a18b49..156b0c2 100755
--- a/get-network-info
+++ b/get-network-info
@@ -162,9 +162,9 @@ run_netstat () {
 		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`
@@ -281,6 +281,17 @@ run_ipconfig () {
 				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
diff --git a/libSystemConfiguration/libSystemConfiguration_client.c b/libSystemConfiguration/libSystemConfiguration_client.c
index 8f25077..760c301 100644
--- a/libSystemConfiguration/libSystemConfiguration_client.c
+++ b/libSystemConfiguration/libSystemConfiguration_client.c
@@ -1,5 +1,5 @@
 /*
- * 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@
  *
@@ -106,11 +106,11 @@ libSC_info_client_create(dispatch_queue_t	q,
 {
 	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;
diff --git a/libSystemConfiguration/libSystemConfiguration_client.h b/libSystemConfiguration/libSystemConfiguration_client.h
index 082cef8..63d46cb 100644
--- a/libSystemConfiguration/libSystemConfiguration_client.h
+++ b/libSystemConfiguration/libSystemConfiguration_client.h
@@ -1,5 +1,5 @@
 /*
- * 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@
  *
@@ -37,11 +37,11 @@
 
 #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
 
@@ -62,11 +62,11 @@ enum {
 
 #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
 
@@ -77,10 +77,10 @@ enum {
 	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
diff --git a/logging/liblog_SystemConfiguration.m b/logging/liblog_SystemConfiguration.m
index e440427..35c22a7 100644
--- a/logging/liblog_SystemConfiguration.m
+++ b/logging/liblog_SystemConfiguration.m
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2017, 2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -135,6 +135,8 @@ _SC_OSStateCopyFormattedString_dnsinfo(uint32_t data_size, void *data)
 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;
 
@@ -145,16 +147,89 @@ _SC_OSStateCopyFormattedString_nwi(uint32_t data_size, void *data)
 
 	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) {
diff --git a/nwi/network_information.c b/nwi/network_information.c
index 96c5f86..cddacc2 100644
--- a/nwi/network_information.c
+++ b/nwi/network_information.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2019 Apple Inc. All rights reserved.
+ * Copyright (c) 2011-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -232,7 +232,7 @@ _nwi_state_copy_data()
 		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) {
@@ -813,8 +813,14 @@ nwi_state_get_interface_names(nwi_state_t state,
 		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);
 }
diff --git a/nwi/network_state_information_priv.h b/nwi/network_state_information_priv.h
index 06d31c4..ad6691c 100644
--- a/nwi/network_state_information_priv.h
+++ b/nwi/network_state_information_priv.h
@@ -1,5 +1,5 @@
 /*
- * 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@
  *
@@ -223,6 +223,10 @@ nwi_state_get_ifstate_with_index(nwi_state_t state, int af, int idx)
 {
 	int i_idx = idx;
 
+	if (idx >= state->max_if_count) {
+		return (NULL);
+	}
+
 	if (idx >= nwi_state_get_ifstate_count(state, af)) {
 		return (NULL);
 	}
@@ -252,12 +256,13 @@ nwi_state_get_ifstate_with_name(nwi_state_t state,
 	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);
diff --git a/sctest/SCTestDynamicStore.m b/sctest/SCTestDynamicStore.m
index 3100473..7d9ec96 100644
--- a/sctest/SCTestDynamicStore.m
+++ b/sctest/SCTestDynamicStore.m
@@ -74,6 +74,9 @@
 		CFPropertyListRef value = SCDynamicStoreCopyValue(self.store, key);
 		SCTestLog("%@ : %@", key, value);
 		CFRelease(key);
+		if (value != NULL) {
+			CFRelease(value);
+		}
 	}
 
 	if (self.options[kSCTestDynamicStoreOptionIPv4]) {
@@ -81,6 +84,9 @@
 		CFPropertyListRef value = SCDynamicStoreCopyValue(self.store, key);
 		SCTestLog("%@ : %@", key, value);
 		CFRelease(key);
+		if (value != NULL) {
+			CFRelease(value);
+		}
 	}
 
 	if (self.options[kSCTestDynamicStoreOptionIPv6]) {
@@ -88,6 +94,9 @@
 		CFPropertyListRef value = SCDynamicStoreCopyValue(self.store, key);
 		SCTestLog("%@ : %@", key, value);
 		CFRelease(key);
+		if (value != NULL) {
+			CFRelease(value);
+		}
 	}
 
 	if (self.options[kSCTestDynamicStoreOptionProxies]) {
@@ -95,6 +104,9 @@
 		CFPropertyListRef value = SCDynamicStoreCopyValue(self.store, key);
 		SCTestLog("%@ : %@", key, value);
 		CFRelease(key);
+		if (value != NULL) {
+			CFRelease(value);
+		}
 	}
 
 	[self cleanupAndExitWithErrorCode:0];
diff --git a/sctest/SCTestInterfaceNamer.m b/sctest/SCTestInterfaceNamer.m
index bbf42ff..4dc48be 100644
--- a/sctest/SCTestInterfaceNamer.m
+++ b/sctest/SCTestInterfaceNamer.m
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include "plugin_shared.h"
 
 #define	INTERFACES_KEY			@"State:/Network/Interface"
 #define	PLUGIN_INTERFACE_NAMER_KEY	@"Plugin:InterfaceNamer"
@@ -127,6 +128,9 @@ storeCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info)
 
 	BOOL allUnitTestsPassed = YES;
 	allUnitTestsPassed &= [self unitTestInsertRemoveOneInterface];
+	allUnitTestsPassed &= [self unitTestInsertRemoveMultipleInterfaces];
+	allUnitTestsPassed &= [self unitTestCheckIOKitQuiet];
+	allUnitTestsPassed &= [self unitTestCheckEN0];
 
 	if(![self tearDown]) {
 		return NO;
@@ -553,4 +557,164 @@ create_hidden_interface(u_char ea_unique)
 	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
diff --git a/sctest/SCTestPreferences.m b/sctest/SCTestPreferences.m
index eaae58a..062076c 100644
--- a/sctest/SCTestPreferences.m
+++ b/sctest/SCTestPreferences.m
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2016, 2017, 2019 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -23,9 +23,13 @@
 
 #import "SCTest.h"
 #import "SCTestUtils.h"
+#import 
+#import 
 
 @interface SCTestPreferences : SCTest
 @property SCPreferencesRef prefs;
+@property dispatch_semaphore_t sem;
+@property int counter;
 @end
 
 @implementation SCTestPreferences
@@ -99,6 +103,8 @@
 	BOOL allUnitTestsPassed = YES;
 	allUnitTestsPassed &= [self unitTestNetworkServicesSanity];
 	allUnitTestsPassed &= [self unitTestPreferencesAPI];
+	allUnitTestsPassed &= [self unitTestPreferencesNotifications];
+	allUnitTestsPassed &= [self unitTestPreferencesObserver];
 	allUnitTestsPassed &= [self unitTestPreferencesSession];
 	return  allUnitTestsPassed;
 
@@ -234,32 +240,252 @@
 	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 
+
+- (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;
@@ -283,10 +509,10 @@
 
 	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;
@@ -328,10 +554,10 @@
 
 	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;
@@ -371,10 +597,10 @@
 
 	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;
diff --git a/sctest/genSCTestOptions.c b/sctest/genSCTestOptions.c
index b06d135..7d1ae2c 100644
--- a/sctest/genSCTestOptions.c
+++ b/sctest/genSCTestOptions.c
@@ -1,5 +1,5 @@
 /*
- * 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@
  *
diff --git a/scutil.tproj/net.c b/scutil.tproj/net.c
index 3cee939..005606b 100644
--- a/scutil.tproj/net.c
+++ b/scutil.tproj/net.c
@@ -811,8 +811,13 @@ do_net_migrate_perform(int argc, char **argv)
 		currentConfiguration = argv[2];
 	}
 
-	SCPrint(_sc_debug, stdout, CFSTR("sourceConfiguration: %s\ntargetConfiguration: %s\ncurrentConfiguration: %s\n"),
-		sourceConfiguration, targetConfiguration, (currentConfiguration != NULL) ? currentConfiguration : "" );
+	SCPrint(_sc_debug, stdout,
+		CFSTR("sourceConfiguration: %s\n"
+		      "targetConfiguration: %s\n"
+		      "currentConfiguration: %s\n"),
+		sourceConfiguration,
+		targetConfiguration,
+		(currentConfiguration != NULL) ? currentConfiguration : "" );
 
 	str = CFStringCreateWithCString(NULL, sourceConfiguration, kCFStringEncodingUTF8);
 	sourceConfigurationURL = CFURLCreateWithFileSystemPath(NULL, str, kCFURLPOSIXPathStyle, TRUE);
@@ -831,10 +836,10 @@ do_net_migrate_perform(int argc, char **argv)
 	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) {
@@ -890,8 +895,7 @@ __private_extern__
 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++;
diff --git a/scutil.tproj/net_interface.c b/scutil.tproj/net_interface.c
index 37f6fc5..734442d 100644
--- a/scutil.tproj/net_interface.c
+++ b/scutil.tproj/net_interface.c
@@ -1,5 +1,5 @@
 /*
- * 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@
  *
@@ -486,7 +486,68 @@ _show_interface(SCNetworkInterfaceRef interface, CFStringRef prefix, Boolean sho
 
 	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);
diff --git a/scutil.tproj/net_protocol.c b/scutil.tproj/net_protocol.c
index f76b6e0..b0392fa 100644
--- a/scutil.tproj/net_protocol.c
+++ b/scutil.tproj/net_protocol.c
@@ -1,5 +1,5 @@
 /*
- * 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@
  *
@@ -848,6 +848,39 @@ __doIPv6Addresses(CFStringRef key, const char *description, void *info, int argc
 	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"
@@ -857,7 +890,7 @@ static options ipv6Options[] = {
 	{ "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                ,
-- 
2.45.2