From 942cecd7bb3d0412e584f1a3ca1871e3c0384926 Mon Sep 17 00:00:00 2001 From: Apple Date: Thu, 22 Sep 2016 17:54:09 +0000 Subject: [PATCH] configd-888.1.2.tar.gz --- IPMonitorControl/IPMonitorControl.c | 55 +- IPMonitorControl/IPMonitorControlServer.c | 27 +- IPMonitorControl/main.c | 18 +- IPMonitorControl/test_rank.sh | 12 + .../IPMonitor/Info-EmbeddedSimulator.plist | 29 +- Plugins/IPMonitor/Info.plist | 29 +- Plugins/IPMonitor/Makefile | 68 +- .../IPMonitor/agent-monitor.h | 45 +- Plugins/IPMonitor/agent-monitor.m | 122 + .../IPMonitor/com.apple.networking.IPMonitor | 1 - Plugins/IPMonitor/configAgent.h | 90 + Plugins/IPMonitor/configAgent.m | 191 ++ Plugins/IPMonitor/configAgentDefines.h | 44 + Plugins/IPMonitor/controller.h | 43 + Plugins/IPMonitor/controller.m | 2107 +++++++++++++++++ Plugins/IPMonitor/dns-configuration.c | 32 +- Plugins/IPMonitor/dnsAgent.h | 33 + Plugins/IPMonitor/dnsAgent.m | 92 + Plugins/IPMonitor/ip_plugin.c | 965 ++++++-- Plugins/IPMonitor/ip_plugin.h | 14 +- Plugins/IPMonitor/proxy-configuration.c | 35 +- Plugins/IPMonitor/proxy-configuration.h | 4 +- Plugins/IPMonitor/proxyAgent.h | 34 + Plugins/IPMonitor/proxyAgent.m | 86 + Plugins/IPMonitor/set-hostname.c | 12 +- Plugins/IPMonitor/smb-configuration.c | 6 +- Plugins/InterfaceNamer/Info.plist | 2 +- Plugins/InterfaceNamer/ifnamer.c | 171 +- Plugins/KernelEventMonitor/Info.plist | 6 +- Plugins/KernelEventMonitor/ev_dlil.c | 19 +- Plugins/KernelEventMonitor/ev_extra.m | 9 +- Plugins/KernelEventMonitor/ev_ipv6.c | 2 +- Plugins/KernelEventMonitor/eventmon.c | 187 +- Plugins/KernelEventMonitor/eventmon.h | 20 +- Plugins/LinkConfiguration/Info.plist | 6 +- Plugins/LinkConfiguration/linkconfig.c | 118 +- Plugins/PreferencesMonitor/Info.plist | 2 +- Plugins/PreferencesMonitor/prefsmon.c | 71 +- Plugins/QoSMarking/Info.plist | 41 + Plugins/QoSMarking/Makefile | 30 + Plugins/QoSMarking/qos-marking.m | 1252 ++++++++++ Plugins/SimulatorSupport/Info.plist | 2 +- Plugins/SimulatorSupport/simulator_support.c | 29 +- Plugins/common/IPMonitorControlPrefs.c | 35 +- Plugins/common/cache.c | 15 +- SCMonitor/Info.plist | 2 +- SCMonitor/monitor.c | 98 +- SystemConfiguration.fproj/BondConfiguration.c | 22 +- .../BridgeConfiguration.c | 116 +- SystemConfiguration.fproj/CaptiveNetwork.c | 27 +- SystemConfiguration.fproj/CaptiveNetwork.h | 41 +- SystemConfiguration.fproj/DHCP.c | 5 +- SystemConfiguration.fproj/DeviceOnHold.c | 369 --- SystemConfiguration.fproj/DeviceOnHold.h | 155 -- SystemConfiguration.fproj/Info-Embedded.plist | 2 +- SystemConfiguration.fproj/Info.plist | 2 +- SystemConfiguration.fproj/LinkConfiguration.c | 46 +- .../NetworkConfiguration.plist | 65 - SystemConfiguration.fproj/SCD.c | 219 +- SystemConfiguration.fproj/SCD.h | 59 +- SystemConfiguration.fproj/SCDAdd.c | 17 +- SystemConfiguration.fproj/SCDConsoleUser.c | 4 +- SystemConfiguration.fproj/SCDGet.c | 17 +- SystemConfiguration.fproj/SCDHostName.c | 55 +- SystemConfiguration.fproj/SCDList.c | 15 +- SystemConfiguration.fproj/SCDNotifierAdd.c | 15 +- SystemConfiguration.fproj/SCDNotifierCancel.c | 34 +- .../SCDNotifierGetChanges.c | 15 +- .../SCDNotifierInformViaCallback.c | 132 +- .../SCDNotifierInformViaFD.c | 24 +- .../SCDNotifierInformViaSignal.c | 9 +- SystemConfiguration.fproj/SCDNotifierRemove.c | 15 +- .../SCDNotifierSetKeys.c | 16 +- SystemConfiguration.fproj/SCDNotifierWait.c | 13 +- SystemConfiguration.fproj/SCDNotify.c | 15 +- SystemConfiguration.fproj/SCDOpen.c | 111 +- SystemConfiguration.fproj/SCDPlugin.c | 27 +- SystemConfiguration.fproj/SCDPrivate.c | 215 +- SystemConfiguration.fproj/SCDRemove.c | 14 +- SystemConfiguration.fproj/SCDSet.c | 17 +- SystemConfiguration.fproj/SCDSnapshot.c | 15 +- .../SCDynamicStoreInternal.h | 24 +- .../SCDynamicStorePrivate.h | 8 +- SystemConfiguration.fproj/SCLocation.c | 4 +- SystemConfiguration.fproj/SCNetwork.h | 4 +- .../SCNetworkConfiguration.h | 19 +- .../SCNetworkConfigurationInternal.c | 48 +- .../SCNetworkConfigurationInternal.h | 59 +- .../SCNetworkConfigurationPrivate.h | 55 +- .../SCNetworkConnection.c | 205 +- .../SCNetworkConnectionInternal.h | 19 +- .../SCNetworkConnectionPrivate.c | 5 +- .../SCNetworkConnectionPrivate.h | 12 +- .../SCNetworkInterface.c | 617 ++--- .../SCNetworkMigration.c | 326 ++- SystemConfiguration.fproj/SCNetworkProtocol.c | 32 +- .../SCNetworkReachability.c | 538 +++-- .../SCNetworkReachability.h | 31 +- .../SCNetworkReachabilityInternal.h | 30 +- SystemConfiguration.fproj/SCNetworkService.c | 131 +- SystemConfiguration.fproj/SCNetworkSet.c | 138 +- .../SCNetworkSignature.c | 6 +- SystemConfiguration.fproj/SCP.c | 8 +- SystemConfiguration.fproj/SCPAdd.c | 10 +- SystemConfiguration.fproj/SCPApply.c | 7 +- SystemConfiguration.fproj/SCPCommit.c | 7 +- SystemConfiguration.fproj/SCPGet.c | 10 +- SystemConfiguration.fproj/SCPList.c | 10 +- SystemConfiguration.fproj/SCPLock.c | 42 +- SystemConfiguration.fproj/SCPOpen.c | 83 +- SystemConfiguration.fproj/SCPPath.c | 11 +- SystemConfiguration.fproj/SCPRemove.c | 10 +- SystemConfiguration.fproj/SCPSet.c | 10 +- SystemConfiguration.fproj/SCPUnlock.c | 34 +- .../SCPreferencesInternal.h | 16 +- .../SCPreferencesKeychainPrivate.c | 11 +- .../SCPreferencesSetSpecific.h | 4 +- SystemConfiguration.fproj/SCPrivate.h | 186 +- SystemConfiguration.fproj/SCProxies.c | 30 +- .../SCSchemaDefinitions.c | 24 +- .../SCSchemaDefinitions.h | 169 +- .../SCSchemaDefinitionsPrivate.h | 49 +- SystemConfiguration.fproj/VLANConfiguration.c | 25 +- SystemConfiguration.fproj/VPNAppLayer.c | 2 +- SystemConfiguration.fproj/VPNConfiguration.c | 2 +- SystemConfiguration.fproj/VPNConfiguration.h | 2 +- SystemConfiguration.fproj/VPNPrivate.c | 2 +- SystemConfiguration.fproj/VPNService.c | 5 +- .../com.apple.SystemConfiguration.plist | 148 ++ SystemConfiguration.fproj/config_types.h | 14 +- SystemConfiguration.fproj/dy_framework.c | 74 +- SystemConfiguration.fproj/genSCPreferences.c | 194 +- .../helper/SCHelper_client.c | 32 +- .../helper/SCHelper_server.c | 48 +- .../helper/com.apple.SCHelper-embedded.plist | 4 + SystemConfiguration.fproj/moh.c | 207 -- SystemConfiguration.fproj/moh_msg.h | 64 - SystemConfiguration.fproj/scprefs_observer.c | 27 +- config-agent-info/config_agent_info.c | 238 ++ config-agent-info/config_agent_info.h | 98 + configd.tproj/_SCD.c | 35 +- configd.tproj/_SCD.h | 4 +- configd.tproj/_configadd.c | 5 +- configd.tproj/_configclose.c | 6 +- configd.tproj/_configget.c | 8 +- configd.tproj/_configlist.c | 5 +- configd.tproj/_confignotify.c | 4 +- configd.tproj/_configopen.c | 4 +- configd.tproj/_configremove.c | 6 +- configd.tproj/_configset.c | 6 +- configd.tproj/_configunlock.c | 12 +- configd.tproj/_notifyadd.c | 6 +- configd.tproj/_notifychanges.c | 4 +- configd.tproj/_notifyremove.c | 4 +- configd.tproj/_snapshot.c | 6 +- configd.tproj/configd.h | 33 +- configd.tproj/configd.m | 43 +- configd.tproj/configd_server.c | 13 +- configd.tproj/entitlements-ios.plist | 8 + configd.tproj/plugin_support.c | 161 +- configd.tproj/session.c | 72 +- configd.tproj/session.h | 5 +- configd.tproj/update-mach-services | 10 +- configd.xcodeproj/project.pbxproj | 1039 ++++++-- dnsinfo/dnsinfo_copy.c | 34 +- dnsinfo/dnsinfo_create.c | 37 +- dnsinfo/dnsinfo_flatfile.c | 3 +- dnsinfo/dnsinfo_internal.h | 13 +- dnsinfo/dnsinfo_server.c | 142 +- dnsinfo/dnsinfo_server.h | 9 +- get-mobility-info | 73 +- get-network-info | 175 +- .../libSystemConfiguration_client.c | 91 +- .../libSystemConfiguration_client.h | 33 +- .../libSystemConfiguration_server.c | 10 +- nwi/network_config_agent_info_priv.h | 37 + nwi/network_information.c | 213 +- nwi/network_information.h | 3 +- nwi/network_information_server.c | 237 +- nwi/network_information_server.h | 9 +- ...riv.c => network_state_information_priv.c} | 7 +- ...riv.h => network_state_information_priv.h} | 9 +- scutil.tproj/dictionary.c | 12 +- scutil.tproj/nc.c | 4 +- scutil.tproj/net.c | 96 +- scutil.tproj/net.h | 11 +- scutil.tproj/net_interface.c | 201 +- scutil.tproj/net_protocol.c | 2 +- scutil.tproj/net_service.c | 24 +- scutil.tproj/net_set.c | 6 +- scutil.tproj/notifications.c | 8 +- scutil.tproj/prefs.c | 140 +- scutil.tproj/prefs.h | 4 +- scutil.tproj/scutil.c | 36 +- scutil.tproj/scutil.h | 18 +- scutil.tproj/tests.c | 21 +- 196 files changed, 10882 insertions(+), 4797 deletions(-) create mode 100644 IPMonitorControl/test_rank.sh rename SystemConfiguration.fproj/moh.h => Plugins/IPMonitor/agent-monitor.h (68%) create mode 100644 Plugins/IPMonitor/agent-monitor.m delete mode 100644 Plugins/IPMonitor/com.apple.networking.IPMonitor create mode 100644 Plugins/IPMonitor/configAgent.h create mode 100644 Plugins/IPMonitor/configAgent.m create mode 100644 Plugins/IPMonitor/configAgentDefines.h create mode 100644 Plugins/IPMonitor/controller.h create mode 100644 Plugins/IPMonitor/controller.m create mode 100644 Plugins/IPMonitor/dnsAgent.h create mode 100644 Plugins/IPMonitor/dnsAgent.m create mode 100644 Plugins/IPMonitor/proxyAgent.h create mode 100644 Plugins/IPMonitor/proxyAgent.m create mode 100644 Plugins/QoSMarking/Info.plist create mode 100644 Plugins/QoSMarking/Makefile create mode 100644 Plugins/QoSMarking/qos-marking.m delete mode 100644 SystemConfiguration.fproj/DeviceOnHold.c delete mode 100644 SystemConfiguration.fproj/DeviceOnHold.h create mode 100644 SystemConfiguration.fproj/com.apple.SystemConfiguration.plist delete mode 100644 SystemConfiguration.fproj/moh.c delete mode 100644 SystemConfiguration.fproj/moh_msg.h create mode 100644 config-agent-info/config_agent_info.c create mode 100644 config-agent-info/config_agent_info.h create mode 100644 nwi/network_config_agent_info_priv.h rename nwi/{network_information_priv.c => network_state_information_priv.c} (98%) rename nwi/{network_information_priv.h => network_state_information_priv.h} (97%) diff --git a/IPMonitorControl/IPMonitorControl.c b/IPMonitorControl/IPMonitorControl.c index a85ebc2..ed8d861 100644 --- a/IPMonitorControl/IPMonitorControl.c +++ b/IPMonitorControl/IPMonitorControl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015 Apple Inc. All rights reserved. + * Copyright (c) 2013-2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -44,11 +44,13 @@ #include #ifdef TEST_IPMONITOR_CONTROL -#define my_log(__level, fmt, ...) SCPrint(TRUE, stdout, CFSTR(fmt "\n"), ## __VA_ARGS__) + +#define my_log(__level, __format, ...) SCPrint(TRUE, stdout, CFSTR(__format "\n"), ## __VA_ARGS__) #else /* TEST_IPMONITOR_CONTROL */ -#define my_log(__level, fmt, ...) SCLog(TRUE, __level, CFSTR(fmt), ## __VA_ARGS__) +#define my_log(__level, __format, ...) SC_log(__level, __format, ## __VA_ARGS__) + #endif /* TEST_IPMONITOR_CONTROL */ /** @@ -58,6 +60,7 @@ struct IPMonitorControl { CFRuntimeBase cf_base; + os_activity_t activity; dispatch_queue_t queue; xpc_connection_t connection; CFMutableDictionaryRef assertions; /* ifname = rank */ @@ -99,6 +102,9 @@ __IPMonitorControlDeallocate(CFTypeRef cf) if (control->connection != NULL) { xpc_release(control->connection); } + if (control->activity != NULL) { + os_release(control->activity); + } if (control->queue != NULL) { xpc_release(control->queue); } @@ -131,7 +137,6 @@ __IPMonitorControlAllocate(CFAllocatorRef allocator) control = (IPMonitorControlRef) _CFRuntimeCreateInstance(allocator, __kIPMonitorControlTypeID, size, NULL); - bzero(((void *)control) + sizeof(CFRuntimeBase), size); return (control); } @@ -229,11 +234,11 @@ ApplyInterfaceRank(const void * key, const void * value, void * context) SCNetworkServicePrimaryRank rank; xpc_object_t request; - if (CFStringGetCString(key, ifname, sizeof(ifname), - kCFStringEncodingUTF8) == FALSE) { + if (!CFStringGetCString(key, ifname, sizeof(ifname), + kCFStringEncodingUTF8)) { return; } - if (CFNumberGetValue(value, kCFNumberSInt32Type, &rank) == FALSE) { + if (!CFNumberGetValue(value, kCFNumberSInt32Type, &rank)) { return; } request = xpc_dictionary_create(NULL, NULL, 0); @@ -270,11 +275,13 @@ IPMonitorControlCreate(void) = xpc_connection_create_mach_service(kIPMonitorControlServerName, queue, flags); handler = ^(xpc_object_t event) { - os_activity_t activity_id; + os_activity_t activity; Boolean retry; - activity_id = os_activity_start("processing IPMonitor [rank] reply", - OS_ACTIVITY_FLAG_DEFAULT); + activity = os_activity_create("processing IPMonitor [rank] reply", + OS_ACTIVITY_CURRENT, + OS_ACTIVITY_FLAG_DEFAULT); + os_activity_scope(activity); (void)IPMonitorControlHandleResponse(event, TRUE, &retry); if (retry && control->assertions != NULL) { @@ -283,9 +290,12 @@ IPMonitorControlCreate(void) control->connection); } - os_activity_end(activity_id); + os_release(activity); }; xpc_connection_set_event_handler(connection, handler); + control->activity = os_activity_create("accessing IPMonitor [rank] controls", + OS_ACTIVITY_CURRENT, + OS_ACTIVITY_FLAG_DEFAULT); control->connection = connection; control->queue = queue; xpc_connection_resume(connection); @@ -301,10 +311,13 @@ IPMonitorControlSetInterfacePrimaryRank(IPMonitorControlRef control, xpc_object_t request; Boolean success = FALSE; - if (CFStringGetCString(ifname_cf, ifname, sizeof(ifname), - kCFStringEncodingUTF8) == FALSE) { + if (!CFStringGetCString(ifname_cf, ifname, sizeof(ifname), + kCFStringEncodingUTF8)) { return (FALSE); } + + os_activity_scope(control->activity); + request = xpc_dictionary_create(NULL, NULL, 0); xpc_dictionary_set_uint64(request, kIPMonitorControlRequestKeyType, @@ -358,15 +371,18 @@ SCNetworkServicePrimaryRank IPMonitorControlGetInterfacePrimaryRank(IPMonitorControlRef control, CFStringRef ifname_cf) { - char ifname[IF_NAMESIZE]; - SCNetworkServicePrimaryRank rank; - xpc_object_t request; + char ifname[IF_NAMESIZE]; + SCNetworkServicePrimaryRank rank; + xpc_object_t request; rank = kSCNetworkServicePrimaryRankDefault; - if (CFStringGetCString(ifname_cf, ifname, sizeof(ifname), - kCFStringEncodingUTF8) == FALSE) { - goto done; + if (!CFStringGetCString(ifname_cf, ifname, sizeof(ifname), + kCFStringEncodingUTF8)) { + return rank; } + + os_activity_scope(control->activity); + request = xpc_dictionary_create(NULL, NULL, 0); xpc_dictionary_set_uint64(request, kIPMonitorControlRequestKeyType, @@ -402,7 +418,6 @@ IPMonitorControlGetInterfacePrimaryRank(IPMonitorControlRef control, } xpc_release(request); - done: return (rank); } diff --git a/IPMonitorControl/IPMonitorControlServer.c b/IPMonitorControl/IPMonitorControlServer.c index 53ad39d..b3a9fb6 100644 --- a/IPMonitorControl/IPMonitorControlServer.c +++ b/IPMonitorControl/IPMonitorControlServer.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015 Apple Inc. All rights reserved. + * Copyright (c) 2013-2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -46,7 +46,7 @@ #include #ifdef TEST_IPMONITOR_CONTROL -#define my_log(__level, fmt, ...) SCPrint(TRUE, stdout, CFSTR(fmt "\n"), ## __VA_ARGS__) +#define my_log(__level, __format, ...) SCPrint(TRUE, stdout, CFSTR(__format "\n"), ## __VA_ARGS__) #else /* TEST_IPMONITOR_CONTROL */ #include "ip_plugin.h" @@ -81,8 +81,7 @@ InterfaceChangedListAddInterface(CFStringRef ifname) CFArrayAppendValue(S_if_changes, ifname); S_if_changes_range.length = 1; } - else if (CFArrayContainsValue(S_if_changes, S_if_changes_range, - ifname) == FALSE) { + else if (!CFArrayContainsValue(S_if_changes, S_if_changes_range, ifname)) { CFArrayAppendValue(S_if_changes, ifname); S_if_changes_range.length++; } @@ -111,14 +110,14 @@ InterfaceRankAssertionAdd(const void * key, const void * value, void * context) = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFDictionarySetValue(*assertions_p, key, value); + CFDictionarySetValue(*assertions_p, key, rank); return; } existing_rank = CFDictionaryGetValue(*assertions_p, key); if (existing_rank == NULL || (CFNumberCompare(rank, existing_rank, NULL) == kCFCompareGreaterThan)) { - CFDictionarySetValue(*assertions_p, key, value); + CFDictionarySetValue(*assertions_p, key, rank); } return; } @@ -316,7 +315,7 @@ IPMonitorControlServerHandleSetInterfaceRank(xpc_connection_t connection, SCNetworkServicePrimaryRank rank; ControlSessionRef session; - if (IPMonitorControlServerValidateConnection(connection) == FALSE) { + if (!IPMonitorControlServerValidateConnection(connection)) { my_log(LOG_INFO, "connection %p pid %d permission denied", connection, xpc_connection_get_pid(connection)); return (EPERM); @@ -454,16 +453,10 @@ IPMonitorControlServerHandleNewConnection(xpc_connection_t connection) xpc_handler_t handler; handler = ^(xpc_object_t event) { - os_activity_t activity_id; - - activity_id = os_activity_start("processing IPMonitor [rank] request", - OS_ACTIVITY_FLAG_DEFAULT); - IPMonitorControlServerHandleRequest(connection, event); - - os_activity_end(activity_id); }; xpc_connection_set_event_handler(connection, handler); + xpc_connection_set_target_queue(connection, S_IPMonitorControlServerQueue); xpc_connection_resume(connection); return; } @@ -480,12 +473,8 @@ IPMonitorControlServerCreate(dispatch_queue_t queue, const char * name) return (NULL); } handler = ^(xpc_object_t event) { - os_activity_t activity_id; xpc_type_t type; - activity_id = os_activity_start("processing IPMonitor [rank] connection request", - OS_ACTIVITY_FLAG_DEFAULT); - type = xpc_get_type(event); if (type == XPC_TYPE_CONNECTION) { IPMonitorControlServerHandleNewConnection(event); @@ -505,8 +494,6 @@ IPMonitorControlServerCreate(dispatch_queue_t queue, const char * name) else { my_log(LOG_NOTICE, "unknown event %p", type); } - - os_activity_end(activity_id); }; S_IPMonitorControlServerQueue = queue; xpc_connection_set_event_handler(connection, handler); diff --git a/IPMonitorControl/main.c b/IPMonitorControl/main.c index 7d4080e..150b2b1 100644 --- a/IPMonitorControl/main.c +++ b/IPMonitorControl/main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 Apple Inc. All rights reserved. + * Copyright (c) 2013, 2015 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -70,6 +70,7 @@ main(int argc, char * argv[]) IPMonitorControlRef control; SCNetworkServicePrimaryRank rank; Boolean rank_set = FALSE; + Boolean wait = FALSE; rank = kSCNetworkServicePrimaryRankDefault; control = IPMonitorControlCreate(); @@ -78,7 +79,7 @@ main(int argc, char * argv[]) exit(1); } - while ((ch = getopt(argc, argv, "i:r:")) != EOF) { + while ((ch = getopt(argc, argv, "i:r:w")) != EOF) { CFStringRef ifname; SCNetworkServicePrimaryRank existing_rank; @@ -103,6 +104,9 @@ main(int argc, char * argv[]) case 'r': rank = strtoul(optarg, NULL, 0); break; + case 'w': + wait = TRUE; + break; default: fprintf(stderr, "unexpected option '%c'\n", (char)ch); exit(1); @@ -114,9 +118,12 @@ main(int argc, char * argv[]) if (argc > 0) { fprintf(stderr, "ignoring additional parameters\n"); } - if (rank_set == FALSE) { + if (!rank_set) { exit(1); } + if (wait) { + CFRunLoopRun(); + } } else { CFRunLoopSourceContext context; @@ -129,13 +136,12 @@ main(int argc, char * argv[]) rls = CFRunLoopSourceCreate(NULL, 0, &context); CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode); - if (IPMonitorControlServerStart(CFRunLoopGetCurrent(), rls, - &verbose) == FALSE) { + if (!IPMonitorControlServerStart(CFRunLoopGetCurrent(), rls, &verbose)) { fprintf(stderr, "failed to create connection\n"); exit(1); } + CFRunLoopRun(); } - CFRunLoopRun(); exit(0); return (0); } diff --git a/IPMonitorControl/test_rank.sh b/IPMonitorControl/test_rank.sh new file mode 100644 index 0000000..6c62215 --- /dev/null +++ b/IPMonitorControl/test_rank.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +while true +do + ./if_rank_assert -i en0 -r 1 & + ./if_rank_assert -i en0 -r 2 & + ./if_rank_assert -i en0 -r 3 & + ./if_rank_assert -i en0 -r 4 & + wait +done + + diff --git a/Plugins/IPMonitor/Info-EmbeddedSimulator.plist b/Plugins/IPMonitor/Info-EmbeddedSimulator.plist index 31b373f..411ec7d 100644 --- a/Plugins/IPMonitor/Info-EmbeddedSimulator.plist +++ b/Plugins/IPMonitor/Info-EmbeddedSimulator.plist @@ -2,12 +2,16 @@ + AppendStateArrayToSetupArray + + Builtin + CFBundleDevelopmentRegion English CFBundleExecutable IPMonitor CFBundleIdentifier - com.apple.SystemConfiguration.IPMonitor + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -20,28 +24,23 @@ ???? CFBundleVersion 1.14 + MachServices + + com.apple.SystemConfiguration.DNSConfiguration_sim + + com.apple.SystemConfiguration.NetworkInformation_sim + + Requires com.apple.SystemConfiguration.IPConfiguration com.apple.SystemConfiguration.PreferencesMonitor - com.apple.SystemConfiguration.SCNetworkReachability - Builtin - + SupplementalProxiesFollowSupplementalDNS + mdns_timeout 5 pdns_timeout 5 - AppendStateArrayToSetupArray - - SupplementalProxiesFollowSupplementalDNS - - MachServices - - com.apple.SystemConfiguration.DNSConfiguration_sim - - com.apple.SystemConfiguration.NetworkInformation_sim - - diff --git a/Plugins/IPMonitor/Info.plist b/Plugins/IPMonitor/Info.plist index adb5cbd..0907a58 100644 --- a/Plugins/IPMonitor/Info.plist +++ b/Plugins/IPMonitor/Info.plist @@ -2,12 +2,16 @@ + AppendStateArrayToSetupArray + + Builtin + CFBundleDevelopmentRegion English CFBundleExecutable IPMonitor CFBundleIdentifier - com.apple.SystemConfiguration.IPMonitor + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -20,28 +24,23 @@ ???? CFBundleVersion 1.14 + MachServices + + com.apple.SystemConfiguration.DNSConfiguration + + com.apple.SystemConfiguration.IPMonitorControl + + com.apple.SystemConfiguration.NetworkInformation + + Requires com.apple.SystemConfiguration.IPConfiguration com.apple.SystemConfiguration.PreferencesMonitor - com.apple.SystemConfiguration.SCNetworkReachability - Builtin - mdns_timeout 5 pdns_timeout 5 - AppendStateArrayToSetupArray - - MachServices - - com.apple.SystemConfiguration.DNSConfiguration - - com.apple.SystemConfiguration.NetworkInformation - - com.apple.SystemConfiguration.IPMonitorControl - - diff --git a/Plugins/IPMonitor/Makefile b/Plugins/IPMonitor/Makefile index bf6f4f5..96fa4e4 100644 --- a/Plugins/IPMonitor/Makefile +++ b/Plugins/IPMonitor/Makefile @@ -29,6 +29,21 @@ all: test_ipv4_routelist test_ipv6_routelist # ---------- +agent-monitor.o: agent-monitor.m + $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) ${TEST_INCLUDE} -Wall -O0 -g -c agent-monitor.m + +configAgent.o: configAgent.m + $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) ${TEST_INCLUDE} -Wall -O0 -g -c configAgent.m + +controller.o: controller.m + $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) ${TEST_INCLUDE} -Wall -O0 -g -c controller.m + +dnsAgent.o: dnsAgent.m + $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) ${TEST_INCLUDE} -Wall -O0 -g -c dnsAgent.m + +proxyAgent.o: proxyAgent.m + $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) ${TEST_INCLUDE} -Wall -O0 -g -c proxyAgent.m + dnsinfo_create.o: ../../dnsinfo/dnsinfo_create.h ../../dnsinfo/dnsinfo_create.c $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) ${TEST_INCLUDE} -Wall -O0 -g -c ../../dnsinfo/dnsinfo_create.c @@ -41,8 +56,8 @@ 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 -network_information_priv.o: ../../nwi/network_information_priv.h ../../nwi/network_information_priv.c - $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) ${TEST_INCLUDE} -Wall -O0 -g -c ../../nwi/network_information_priv.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 network_information_server.o: ../../nwi/network_information_server.h ../../nwi/network_information_server.c $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) ${TEST_INCLUDE} -Wall -O0 -g -c ../../nwi/network_information_server.c @@ -70,43 +85,56 @@ IPMonitorControlServer.o: ../../IPMonitorControl/IPMonitorControlServer.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 - ip_pluginX.o: Makefile ip_plugin.c $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -DTEST_DNS ${TEST_INCLUDE} ${EXTRA_CFLAGS} -Wall -O0 -g -c -o ip_pluginX.o ip_plugin.c -test_dns: Makefile dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o ip_pluginX.o IPMonitorControlPrefs.o network_information_priv.o network_information_server.o dns-configurationX.o proxy-configuration.o set-hostname.o smb-configuration.o libSystemConfiguration_client.o libSystemConfiguration_server.o IPMonitorControlServer.o - $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -Wall -O0 -g -o test_dns dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o ip_pluginX.o IPMonitorControlPrefs.o network_information_priv.o network_information_server.o dns-configurationX.o proxy-configuration.o set-hostname.o smb-configuration.o libSystemConfiguration_client.o libSystemConfiguration_server.o IPMonitorControlServer.o -framework SystemConfiguration -framework CoreFoundation +# ---------- + +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} -framework SystemConfiguration -framework CoreFoundation -framework Foundation -framework Network -framework NetworkExtension # ---------- -test_proxy: Makefile proxy-configuration.h proxy-configuration.c - $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -DMAIN -DDEBUG -Wall -O0 -g -o test_proxy proxy-configuration.c ${EXTRA_CFLAGS} -framework SystemConfiguration -framework CoreFoundation +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} -framework SystemConfiguration -framework CoreFoundation -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: Makefile dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o ip_pluginX.o IPMonitorControlPrefs.o network_information_priv.o network_information_server.o dns-configuration.o smb-configuration.o proxy-configuration.o set-hostnameX.o libSystemConfiguration_client.o libSystemConfiguration_server.o IPMonitorControlServer.o - $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -Wall -O0 -g -o test_hostname dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o ip_pluginX.o IPMonitorControlPrefs.o network_information_priv.o network_information_server.o dns-configuration.o smb-configuration.o proxy-configuration.o set-hostnameX.o libSystemConfiguration_client.o libSystemConfiguration_server.o IPMonitorControlServer.o ${EXTRA_CFLAGS} -framework SystemConfiguration -framework CoreFoundation +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} -framework SystemConfiguration -framework CoreFoundation -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: Makefile dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o ip_pluginX.o IPMonitorControlPrefs.o network_information_priv.o network_information_server.o dns-configuration.o smb-configurationX.o proxy-configuration.o set-hostname.o libSystemConfiguration_client.o libSystemConfiguration_server.o IPMonitorControlServer.o - $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -Wall -O0 -g -o test_smb dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o ip_pluginX.o IPMonitorControlPrefs.o network_information_priv.o network_information_server.o dns-configuration.o smb-configurationX.o proxy-configuration.o set-hostname.o libSystemConfiguration_client.o libSystemConfiguration_server.o IPMonitorControlServer.o ${EXTRA_CFLAGS} -framework SystemConfiguration -framework CoreFoundation +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} -framework SystemConfiguration -framework CoreFoundation -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} -framework SystemConfiguration -framework CoreFoundation -framework Foundation -framework Network -framework NetworkExtension # ---------- 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 network_information_priv.o network_information_server.o smb-configuration.o proxy-configuration.o libSystemConfiguration_server.o IPMonitorControlServer.o - $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -Wformat -Wall -O0 -g -o $@ $^ ${EXTRA_CFLAGS} -framework SystemConfiguration -framework CoreFoundation +test_ipv4_routelist: test_ipv4_routelist.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_ipv4_routelist test_ipv4_routelist.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} -framework SystemConfiguration -framework CoreFoundation -framework Foundation -framework Network -framework NetworkExtension test_ipv4_routelist_reference.txt: test_ipv4_routelist sh $(REFERENCE_OUTPUT) create test_ipv4_routelist test_ipv4_routelist_reference.txt routelist_output_filter.sh @@ -122,8 +150,8 @@ test_ipv4_routelist_coverage: test_ipv4_routelist test_ipv6_routelist.o: ip_plugin.c $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -DTEST_IPV6_ROUTELIST ${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 network_information_priv.o network_information_server.o smb-configuration.o proxy-configuration.o libSystemConfiguration_server.o IPMonitorControlServer.o - $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -Wformat -Wall -O0 -g -o $@ $^ ${EXTRA_CFLAGS} -framework SystemConfiguration -framework CoreFoundation +test_ipv6_routelist: test_ipv6_routelist.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_ipv6_routelist test_ipv6_routelist.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} -framework SystemConfiguration -framework CoreFoundation -framework Foundation -framework Network -framework NetworkExtension test_ipv6_routelist_reference.txt: test_ipv6_routelist sh $(REFERENCE_OUTPUT) create test_ipv6_routelist test_ipv6_routelist_reference.txt routelist_output_filter.sh @@ -139,10 +167,10 @@ test_ipv6_routelist_coverage: test_ipv6_routelist IPMonitor.o: ip_plugin.c $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -DTEST_IPMONITOR ${TEST_INCLUDE} ${EXTRA_CFLAGS} -Wall -O0 -g -c -o IPMonitor.o ip_plugin.c -IPMonitor: IPMonitor.o IPMonitorControlPrefs.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o network_information_priv.o network_information_server.o proxy-configuration.o smb-configuration.o libSystemConfiguration_client.o libSystemConfiguration_server.o - $(CC) $(PF_INC) $(ARCH_FLAGS) -isysroot $(SYSROOT) -Wall -O0 -g -o IPMonitor IPMonitor.o IPMonitorControlPrefs.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_server.o network_information_priv.o network_information_server.o proxy-configuration.o smb-configuration.o libSystemConfiguration_client.o libSystemConfiguration_server.o ${EXTRA_CFLAGS} -framework SystemConfiguration -framework CoreFoundation +IPMonitor: IPMonitor.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 IPMonitor IPMonitor.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} -framework SystemConfiguration -framework CoreFoundation -framework Foundation -framework Network -framework NetworkExtension # ---------- clean: - rm -rf *.dSYM *.o test_dns test_hostname test_proxy test_smb test_ipv4_routelist test_ipv6_routelist IPMonitor + rm -rf *.dSYM *.o test_dns test_hostname test_proxy test_smb test_ipv4_routelist test_ipv6_routelist test_dns_order IPMonitor diff --git a/SystemConfiguration.fproj/moh.h b/Plugins/IPMonitor/agent-monitor.h similarity index 68% rename from SystemConfiguration.fproj/moh.h rename to Plugins/IPMonitor/agent-monitor.h index 6af6760..0f13738 100644 --- a/SystemConfiguration.fproj/moh.h +++ b/Plugins/IPMonitor/agent-monitor.h @@ -1,15 +1,15 @@ /* - * Copyright (c) 2002, 2003, 2005 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2015, 2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,44 +17,25 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* - * Modification History * + * @APPLE_LICENSE_HEADER_END@ */ -#ifndef _MOH_H -#define _MOH_H +#ifndef AGENT_MONITOR_H +#define AGENT_MONITOR_H #include -#include +#include __BEGIN_DECLS -int -MOHInit ( - int *ref, - CFStringRef deviceName - ); - -int -MOHDispose ( - int ref - ); +void process_AgentMonitor(); +void process_AgentMonitor_DNS(); +void process_AgentMonitor_Proxy(); -int -MOHExec (int ref, - uint32_t link, - uint32_t cmd, - void *request, - size_t requestLen, - void **reply, - size_t *replyLen - ); +const void * copy_proxy_information_for_agent_uuid(uuid_t uuid, uint64_t *length); +const void * copy_dns_information_for_agent_uuid(uuid_t uuid, uint64_t *length); __END_DECLS -#endif /* _MOH_H */ +#endif /* AGENT_MONITOR_H */ diff --git a/Plugins/IPMonitor/agent-monitor.m b/Plugins/IPMonitor/agent-monitor.m new file mode 100644 index 0000000..6239870 --- /dev/null +++ b/Plugins/IPMonitor/agent-monitor.m @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2015, 2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * 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 "controller.h" + +void +process_AgentMonitor() +{ + SC_log(LOG_DEBUG, "Triggering AgentMonitor"); + @autoreleasepool { + AgentController *controller = [AgentController sharedController]; + if (controller == nil) { + SC_log(LOG_ERR, "AgentController could not be initialized"); + return; + } + + dispatch_sync(controller.controllerQueue, ^{ + [[AgentController sharedController] processDNSChanges]; + [[AgentController sharedController] processProxyChanges]; + }); + } + + return; +} + +void +process_AgentMonitor_DNS() +{ + SC_log(LOG_DEBUG, "Triggering AgentMonitor for DNS"); + @autoreleasepool { + AgentController *controller = [AgentController sharedController]; + if (controller == nil) { + SC_log(LOG_ERR, "AgentController could not be initialized"); + return; + } + + dispatch_sync(controller.controllerQueue, ^{ + [[AgentController sharedController] processDNSChanges]; + }); + } + + return; +} + +void +process_AgentMonitor_Proxy() +{ + SC_log(LOG_DEBUG, "Triggering AgentMonitor for Proxy"); + @autoreleasepool { + AgentController *controller = [AgentController sharedController]; + if (controller == nil) { + SC_log(LOG_ERR, "AgentController could not be initialized"); + return; + } + + dispatch_sync(controller.controllerQueue, ^{ + [[AgentController sharedController] processProxyChanges]; + }); + } + + return; +} + +const void * +copy_proxy_information_for_agent_uuid(uuid_t uuid, uint64_t *length) +{ + __block const void *buffer = NULL; + @autoreleasepool { + AgentController *controller = [AgentController sharedController]; + if (controller == nil) { + SC_log(LOG_ERR, "AgentController could not be initialized"); + return NULL; + } + + dispatch_sync(controller.controllerQueue, ^{ + buffer = [[AgentController sharedController] copyProxyAgentData:uuid + length:length]; + }); + } + + return buffer; +} + +const void * +copy_dns_information_for_agent_uuid(uuid_t uuid, uint64_t *length) +{ + __block const void *buffer = NULL; + @autoreleasepool { + AgentController *controller = [AgentController sharedController]; + if (controller == nil) { + SC_log(LOG_ERR, "AgentController could not be initialized"); + return NULL; + } + + dispatch_sync(controller.controllerQueue, ^{ + buffer = [[AgentController sharedController] copyDNSAgentData:uuid + length:length]; + }); + } + + return buffer; +} diff --git a/Plugins/IPMonitor/com.apple.networking.IPMonitor b/Plugins/IPMonitor/com.apple.networking.IPMonitor deleted file mode 100644 index 2f4a10a..0000000 --- a/Plugins/IPMonitor/com.apple.networking.IPMonitor +++ /dev/null @@ -1 +0,0 @@ -? [= LoggerID com.apple.networking.IPMonitor] file /Library/Logs/CrashReporter/com.apple.networking.IPMonitor.log crashlog rotate=local file_max=1M compress format=$((Time)(local.6))\ $Host\ $(Sender)[$(PID)]\ <$((Level)(str))>:\ $(Message) diff --git a/Plugins/IPMonitor/configAgent.h b/Plugins/IPMonitor/configAgent.h new file mode 100644 index 0000000..22e2df1 --- /dev/null +++ b/Plugins/IPMonitor/configAgent.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2015, 2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * 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@ + */ + +#ifndef CONFIG_AGENT_H +#define CONFIG_AGENT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#import +#import +#import +#import + +#import "configAgentDefines.h" + +typedef NS_ENUM(NSUInteger, AgentType) { + kAgentTypeUnknown = 0, + kAgentTypeProxy, + kAgentTypeDNS +}; + +typedef NS_ENUM(NSUInteger, AgentSubType) { + kAgentSubTypeUnknown = 0, + kAgentSubTypeScoped, + kAgentSubTypeSupplemental, + kAgentSubTypeDefault, + kAgentSubTypeMulticast, + kAgentSubTypePrivate, + kAgentSubTypeServiceSpecific +}; + +os_log_t __log_IPMonitor(); + +/* Parameters */ +#define kEntityName "EntityName" +#define kAgentSubType "AgentSubType" + +@interface ConfigAgent : NSObject + +- (instancetype)initWithParameters:(NSDictionary *)parameters; +- (void)addAgentRegistrationObject:(NWNetworkAgentRegistration *)regObject; +- (NWNetworkAgentRegistration *)getRegistrationObject; +- (NSString *)getAssociatedEntity; +- (NSString *)getAgentName; +- (NSData *)getAgentData; +- (AgentType)getAgentType; +- (AgentSubType)getAgentSubType; +- (NSUUID *)getAgentUUID; +- (void)setStartHandler:(void (^)(void))startHandler; +- (BOOL)startAgentWithOptions:(NSDictionary *)options; +- (void)updateAgentData:(NSData *)data; +- (BOOL)shouldUpdateAgent; +- (id)getAgentMapping; +- (void)setAgentMapping:(id)agent; + +- (NSUUID *)createUUIDForName:(NSString *)agentName; + +@end + +#endif /* CONFIG_AGENT_H */ diff --git a/Plugins/IPMonitor/configAgent.m b/Plugins/IPMonitor/configAgent.m new file mode 100644 index 0000000..502859f --- /dev/null +++ b/Plugins/IPMonitor/configAgent.m @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2015, 2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * 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 "configAgent.h" + +@interface ConfigAgent() + +@property (nonatomic) NWNetworkAgentRegistration * internalRegistrationObject; +@property (nonatomic) NSString *internalAssociatedEntity; +@property (nonatomic, copy) NSData *internalAgentData; +@property (nonatomic) BOOL internalShouldUpdateAgent; +@property (strong) void (^internalStartHandler)(void); +@property (nonatomic) id internalAgentMapping; + +@end + +@implementation ConfigAgent + +@synthesize agentUUID; +@synthesize agentDescription; +@synthesize active; +@synthesize kernelActivated; +@synthesize userActivated; +@synthesize voluntary; +@synthesize specificUseOnly; + ++ (NSString *)agentDomain +{ + return @kConfigAgentDomain; +} + ++ (NSString *)agentType +{ + return @kConfigAgentTypeGeneric; +} + ++ (instancetype)agentFromData:(__unused NSData *)data +{ + return nil; +} + +- (instancetype)initWithParameters:(NSDictionary *)parameters +{ + self = [super init]; + if (self) { + NSString *intf = [parameters valueForKey:@kEntityName]; + + _internalRegistrationObject = nil; + _internalAssociatedEntity = [intf copy]; + _internalAgentData = nil; + _internalShouldUpdateAgent = YES; + _internalAgentMapping = nil; + + active = YES; + kernelActivated = NO; + userActivated = YES; + voluntary = NO; + } + + return self; +} + +- (void)addAgentRegistrationObject:(NWNetworkAgentRegistration *)regObject +{ + _internalRegistrationObject = regObject; +} + +- (AgentType)getAgentType +{ + return kAgentTypeUnknown; +} + +- (NSUUID *)getAgentUUID +{ + return nil; +} + +- (NSString *)getAgentName +{ + return @kConfigAgentTypeGeneric; +} + +- (AgentSubType)getAgentSubType +{ + return kAgentSubTypeUnknown; +} + +- (NWNetworkAgentRegistration *)getRegistrationObject +{ + return _internalRegistrationObject; +} + +- (NSString *)getAssociatedEntity +{ + return _internalAssociatedEntity; +} + +- (NSData *)getAgentData +{ + return _internalAgentData; +} + +- (NSData *)copyAgentData +{ + return _internalAgentData; +} + +- (void)setAgentMapping:(id)agent +{ + _internalAgentMapping = agent; +} + +- (id)getAgentMapping +{ + return _internalAgentMapping; +} + +- (void)setStartHandler:(void (^)(void))startHandler +{ + if (startHandler != nil) { + self.internalStartHandler = startHandler; + } +} + +- (BOOL)startAgentWithOptions:(NSDictionary *)options +{ + BOOL ok = NO; + if (!self.active) { + self.active = YES; + ok = [self.internalRegistrationObject updateNetworkAgent:self]; + } + + return ok; +} + +- (void)updateAgentData:(NSData *)data +{ + if ([data isEqual:_internalAgentData]) { + _internalShouldUpdateAgent = NO; + return; + } + + _internalAgentData = [data copy]; + _internalShouldUpdateAgent = YES; +} + +- (BOOL)shouldUpdateAgent +{ + return _internalShouldUpdateAgent; +} + +- (NSUUID *)createUUIDForName:(NSString *)agentName +{ + /* We would like to have same UUIDs for an interface/domain. So here is a way to fix this, + without maintaining any state in configd. + + - We know that every agent has a unique name. + - Use that name to calculate an MD5 hash. MD5 because the digest size is 16 bytes, and so it uuid_t. + - create a NSUUID from these raw bytes. + + - So for a name, we would always have the same UUID. + + */ + unsigned char hashValue[CC_MD5_DIGEST_LENGTH]; + const char *strForHash = [agentName UTF8String]; + CC_MD5(strForHash, (CC_LONG)strlen(strForHash), hashValue); + + return [[NSUUID alloc] initWithUUIDBytes:hashValue]; +} + +@end \ No newline at end of file diff --git a/Plugins/IPMonitor/configAgentDefines.h b/Plugins/IPMonitor/configAgentDefines.h new file mode 100644 index 0000000..1d31c94 --- /dev/null +++ b/Plugins/IPMonitor/configAgentDefines.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2015, 2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * 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@ + */ + +#ifndef CONFIGAGENTDEFINES_H +#define CONFIGAGENTDEFINES_H + +#define kConfigAgentDomain "SystemConfig" +#define kConfigAgentType "AgentType" +#define kConfigAgentTypeGeneric "ConfigAgent" +#define kConfigAgentTypeProxy "ProxyAgent" +#define kConfigAgentTypeDNS "DNSAgent" + +#define kConfigAgentTypeDNSMulticast kConfigAgentTypeDNS "(m)" +#define kConfigAgentTypeDNSPrivate kConfigAgentTypeDNS "(p)" + +#define kConfigAgentDNSNameServers "NameServers" +#define kConfigAgentDNSSearchDomains "SearchDomains" + +#define kConfigAgentOutOfBandDataUUID "OutOfBandDataUUID" +#define kConfigAgentAgentName "AgentName" +#define kConfigAgentAgentData "AgentData" +#define kConfigAgentAgentUUID "AgentUUID" + +#endif /* CONFIGAGENTDEFINES_H */ diff --git a/Plugins/IPMonitor/controller.h b/Plugins/IPMonitor/controller.h new file mode 100644 index 0000000..9b90ff1 --- /dev/null +++ b/Plugins/IPMonitor/controller.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015, 2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * 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@ + */ + +#ifndef CONTROLLER_H +#define CONTROLLER_H + +#import "configAgent.h" +#import "dnsAgent.h" +#import "proxyAgent.h" + +@interface AgentController : NWNetworkAgentRegistration + +@property (readwrite) dispatch_queue_t controllerQueue; + +- (void)processProxyChanges; +- (void)processDNSChanges; ++ (AgentController *)sharedController; +- (const void *)copyProxyAgentData:(uuid_t)requested_uuid length:(uint64_t *)length; +- (const void *)copyDNSAgentData:(uuid_t)requested_uuid length:(uint64_t *)length; + +@end + +#endif /* CONTROLLER_H */ diff --git a/Plugins/IPMonitor/controller.m b/Plugins/IPMonitor/controller.m new file mode 100644 index 0000000..15471e3 --- /dev/null +++ b/Plugins/IPMonitor/controller.m @@ -0,0 +1,2107 @@ +/* + * Copyright (c) 2015, 2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * 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 "controller.h" +#import + +#define numberToNSNumber(x) [NSNumber numberWithUnsignedInteger:x] + +#define dnsAgentDefault "_defaultDNS" +#define proxyAgentDefault "_defaultProxy" +#define multipleEntitySuffix " #" +#define prefixForInterfaceName "@" + +/* These define the starting and ending order of each policy section */ +#define INIT_ORDER_FOR_SCOPED_INTERFACE_POLICY 100 +#define INIT_ORDER_FOR_DOMAIN_POLICY 500 +#define INIT_ORDER_FOR_DEFAULT_POLICY 1000 + +#define SKIP_ORDER_FOR_SCOPED_INTERFACE_POLICY 250 +#define SKIP_ORDER_FOR_DOMAIN_POLICY 750 +#define SKIP_ORDER_FOR_DEFAULT_POLICY 1250 + +#define POLICY_TYPE_NO_POLICY -1 +#define CONFIG_AGENT_DATA_LIMIT MIN(NETAGENT_MAX_DATA_SIZE, 1024) + +typedef struct resolverList { + dns_resolver_t **default_resolvers; + uint32_t n_default_resolvers; + dns_resolver_t **multicast_resolvers; + uint32_t n_multicast_resolvers; + dns_resolver_t **private_resolvers; + uint32_t n_private_resolvers; +} resolver_list_t; + +@interface AgentController() + +@property (nonatomic) NSMutableDictionary * floatingProxyAgentList; +@property (nonatomic) NSMutableDictionary * floatingDNSAgentList; +@property (nonatomic) NSMutableDictionary * policyDB; +@property (nonatomic) NEPolicySession * policySession; + +@end + +@implementation AgentController + +#pragma mark Init + ++ (AgentController *)sharedController +{ + static AgentController * gController = nil; + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + gController = [[AgentController alloc] init]; + }); + + @synchronized (gController) { + if (![gController isControllerReady]) { + if (![gController initializeController]) { + return nil; + } + } + } + + return gController; +} + +- (instancetype)init +{ + self = [super init]; + if (self) { + [self initializeController]; + } + + return self; +} + +- (BOOL)initializeController +{ + const char *errorMessage = NULL; + + do { + /* The NE policy session for the controller */ + + if (self.policySession == nil) { + self.policySession = [self createPolicySession]; + if (self.policySession == nil) { + errorMessage = "Failed to create a policy session"; + break; + } + } + + /* A dictionary of all floating proxy agents + * Key : (can be an interface name or domain name) + * Value : agent object + */ + + if (self.floatingProxyAgentList == nil) { + self.floatingProxyAgentList = [NSMutableDictionary dictionary]; + if (self.floatingProxyAgentList == nil) { + errorMessage = "Failed to create a dictionary"; + break; + } + } + + /* A dictionary of all floating dns agents + * Key : (can be an interface name or domain name) + * Value : agent object + */ + + if (self.floatingDNSAgentList == nil) { + self.floatingDNSAgentList = [NSMutableDictionary dictionary]; + if (self.floatingDNSAgentList == nil) { + errorMessage = "Failed to create a dictionary"; + break; + } + } + + /* A dictionary for the maintaining the policy IDs for all installed policy. + * These IDs would be necessary to uninstall a policy when an agent goes away + * Key : agent name (which can be retrieved by [agent getAgentName]) + * Value : An array of integers, each being a policy ID for that agent + */ + + if (self.policyDB == nil) { + self.policyDB = [NSMutableDictionary dictionary]; + if (self.policyDB == nil) { + errorMessage = "Failed to create a dictionary"; + break; + } + } + + /* The queue to run the all processing on */ + + if (self.controllerQueue == nil) { + self.controllerQueue = dispatch_queue_create("com.apple.SystemConfiguration.controllerQueue", NULL); + if (self.controllerQueue == nil) { + errorMessage = "Failed to create a queue"; + break; + } + } + } while (0); + + if (errorMessage != NULL) { + /* Some error occurred. This is unlikely during controller initialization... */ + SC_log(LOG_ERR, "Error occured while initializing AgentController: %s", errorMessage); + _SC_crash(errorMessage, NULL, NULL); + return NO; + } + + return YES; +} + +- (NEPolicySession *)createPolicySession +{ + NEPolicySession *session = nil; +#if !TARGET_OS_IPHONE + /* On OS X, since we cannot have entitlements, we open a kernel control + * socket and use it to create a policy session + */ + + /* Create kernel control socket */ + int sock = -1; + struct ctl_info kernctl_info; + struct sockaddr_ctl kernctl_addr; + const char *controlName = NECP_CONTROL_NAME; + + if ((sock = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL)) < 0) + { + SC_log(LOG_NOTICE, "Cannot create kernel control socket (errno = %d)\n", errno); + return nil; + } + + bzero(&kernctl_info, sizeof(kernctl_info)); + strlcpy(kernctl_info.ctl_name, controlName, sizeof(kernctl_info.ctl_name)); + if (ioctl(sock, CTLIOCGINFO, &kernctl_info)) + { + SC_log(LOG_NOTICE, "ioctl failed on kernel control socket (errno = %d)\n", errno); + close(sock); + return nil; + } + + bzero(&kernctl_addr, sizeof(kernctl_addr)); + kernctl_addr.sc_len = sizeof(kernctl_addr); + kernctl_addr.sc_family = AF_SYSTEM; + kernctl_addr.ss_sysaddr = AF_SYS_CONTROL; + kernctl_addr.sc_id = kernctl_info.ctl_id; + kernctl_addr.sc_unit = 0; + if (connect(sock, (struct sockaddr *)&kernctl_addr, sizeof(kernctl_addr))) + { + SC_log(LOG_NOTICE, "connect failed on kernel control socket (errno = %d)\n", errno); + close(sock); + return nil; + } + + /* Create policy session */ + session = [[NEPolicySession alloc] initWithSocket:sock]; + if (session == nil) { + close(sock); + } +#else //!TARGET_OS_IPHONE + session = [[NEPolicySession alloc] init]; +#endif //!TARGET_OS_IPHONE + + return session; +} + +- (BOOL)isControllerReady +{ + /* Make sure that we have all our data structures in place */ + return ((self.policySession != nil) && + (self.floatingProxyAgentList != nil) && + (self.floatingDNSAgentList != nil) && + (self.policyDB != nil) && + (self.controllerQueue != nil)); +} + +/* ========================== proxy agent helpers =========================== */ +#pragma mark Proxy agent helper functions + +- (NSData *)dataForProxyArray:(CFArrayRef)proxy_array_for_data +{ + NSData *data = [NSPropertyListSerialization dataWithPropertyList:(__bridge id _Nonnull)(proxy_array_for_data) + format:NSPropertyListBinaryFormat_v1_0 + options:0 + error:nil]; + + return data; +} + +- (NSData *)dataForProxyDictionary:(CFDictionaryRef)domain_proxy +{ + NSData * data = nil; + CFMutableDictionaryRef domain_proxy_dict; + CFArrayRef domain_proxy_array; + + if (domain_proxy == NULL) { + SC_log(LOG_NOTICE, "Invalid domain proxy dict"); + return nil; + } + + domain_proxy_dict = CFDictionaryCreateMutableCopy(NULL, 0, domain_proxy); + CFDictionaryRemoveValue(domain_proxy_dict, kSCPropNetProxiesSupplementalMatchDomain); + + domain_proxy_array = CFArrayCreate(NULL, (const void **)&domain_proxy_dict, 1, &kCFTypeArrayCallBacks); + CFRelease(domain_proxy_dict); + + data = [self dataForProxyArray:domain_proxy_array]; + CFRelease(domain_proxy_array); + + return data; +} + +- (NSData *)getProxyDataFromCurrentConfig:(CFDictionaryRef)proxies + domain:(NSString *)domain +{ + CFIndex count; + CFIndex idx; + CFArrayRef supplemental; + + if (proxies == NULL || domain == nil) { + SC_log(LOG_NOTICE, "Invalid proxies/domain"); + return nil; + } + + supplemental = CFDictionaryGetValue(proxies, kSCPropNetProxiesSupplemental); + count = supplemental ? CFArrayGetCount(supplemental) : 0; + + for (idx = 0; idx < count; idx++) { + CFDictionaryRef domain_proxy; + CFStringRef match_domain; + + domain_proxy = CFArrayGetValueAtIndex(supplemental, idx); + match_domain = CFDictionaryGetValue(domain_proxy, kSCPropNetProxiesSupplementalMatchDomain); + if (match_domain != NULL && CFEqual(match_domain, (__bridge CFTypeRef)(domain))) { + return [self dataForProxyDictionary:domain_proxy]; + } + } + + return nil; +} + +- (bool)getIntValue:(CFTypeRef)cf_value + valuePtr:(int *) int_value_ptr +{ + bool valid = false; + if (cf_value && CFGetTypeID(cf_value) == CFNumberGetTypeID() && CFNumberGetValue(cf_value, kCFNumberIntType, int_value_ptr)) + { + valid = true; + } + return valid; +} + +- (int)countProxyEntriesEnabled:(CFDictionaryRef)proxies +{ + int enabled = 0; + + if (proxies == NULL) { + SC_log(LOG_NOTICE, "Invalid proxies"); + return 0; + } + + if (([self getIntValue:CFDictionaryGetValue(proxies, kSCPropNetProxiesHTTPEnable) valuePtr:&enabled] && enabled > 0) || + ([self getIntValue:CFDictionaryGetValue(proxies, kSCPropNetProxiesHTTPSEnable) valuePtr:&enabled] && enabled > 0) || + ([self getIntValue:CFDictionaryGetValue(proxies, kSCPropNetProxiesProxyAutoConfigEnable) valuePtr:&enabled] && enabled > 0) || + ([self getIntValue:CFDictionaryGetValue(proxies, kSCPropNetProxiesFTPEnable) valuePtr:&enabled] && enabled > 0) || + ([self getIntValue:CFDictionaryGetValue(proxies, kSCPropNetProxiesGopherEnable) valuePtr:&enabled] && enabled > 0) || + ([self getIntValue:CFDictionaryGetValue(proxies, kSCPropNetProxiesRTSPEnable) valuePtr:&enabled] && enabled > 0) || + ([self getIntValue:CFDictionaryGetValue(proxies, kSCPropNetProxiesSOCKSEnable) valuePtr:&enabled] && enabled > 0) || + ([self getIntValue:CFDictionaryGetValue(proxies, kSCPropNetProxiesProxyAutoDiscoveryEnable) valuePtr:&enabled] && enabled > 0)) { + return enabled; + } + + return 0; +} + +- (void)processSupplementalProxyChanges:(CFDictionaryRef)proxies +{ + CFIndex count; + NSMutableArray * deleteList; + NSCountedSet * duplicate_domain_list; + CFIndex idx; + NSMutableArray * new_domain_list; + NSMutableArray * old_domain_list; + CFArrayRef supplemental; + NSMutableArray * update_agent_list; + + if (proxies == NULL) { + SC_log(LOG_INFO, "No proxy config to process"); + return; + } + + old_domain_list = [self getAgentList:self.floatingProxyAgentList + agentType:kAgentTypeProxy + agentSubType:kAgentSubTypeSupplemental]; + duplicate_domain_list = [[NSCountedSet alloc] initWithCapacity:0]; + new_domain_list = [NSMutableArray array]; + update_agent_list = [NSMutableArray array]; + supplemental = CFDictionaryGetValue(proxies, kSCPropNetProxiesSupplemental); + count = supplemental ? CFArrayGetCount(supplemental) : 0; + deleteList = [NSMutableArray array]; + + for (idx = 0; idx < count; idx++) { + CFDictionaryRef domain_proxy; + CFStringRef match_domain; + int proxy_count; + + domain_proxy = CFArrayGetValueAtIndex(supplemental, idx); + match_domain = CFDictionaryGetValue(domain_proxy, kSCPropNetProxiesSupplementalMatchDomain); + if (match_domain == NULL) { + continue; + } + + /* This domain is present in current config. But if it has generic (no protocols enabled) + * proxy content, there is no real use of that agent. Do NOT add it to + * the new_domain_list. + * + * This way, if there was an agent previously for this domain, + * it will be destroyed AND since it is not present in the new domain list, we wont + * spawn a new agent too! :) + */ + + proxy_count = [self countProxyEntriesEnabled:domain_proxy]; + if (proxy_count == 0) { + SC_log(LOG_INFO, "Proxy settings on %@ are generic. Not recognizing as new domain", match_domain); + continue; + } + + [new_domain_list addObject:(__bridge NSString *)match_domain]; + } + + [self cleanConflictingAgentsFromList:old_domain_list + new_list:new_domain_list + agentDictionary:self.floatingProxyAgentList]; + + for (NSString *key in old_domain_list) { + BOOL domain_present; + + domain_present = [new_domain_list containsObject:key]; + if (domain_present == NO) { + id agent; + + agent = [self.floatingProxyAgentList objectForKey:key]; + [self destroyFloatingAgent:agent]; + } + } + + /* At this point, whatever is in the controller's floating agent list, + * is present in the current proxy config. The current proxy config + * might have even more configs, not known to the controller, YET + */ + + for (NSString *domain in old_domain_list) { + id agent; + id mapped_agent; + + agent = [self.floatingProxyAgentList objectForKey:domain]; + if (agent == nil) { + continue; + } + + /* Am I mapped to some agent? */ + mapped_agent = [agent getAgentMapping]; + if (mapped_agent) { + /* OK, this agent is mapped to some other agent. We compare this agent's data + * to the current data of the agent to which it is mapped. If different, we destroy + * the agent and later map it to someone else OR spawn a new one. + */ + NSData * mapped_agent_data; + + mapped_agent_data = [self getProxyDataFromCurrentConfig:proxies domain:[mapped_agent getAssociatedEntity]]; + if (mapped_agent_data == nil || ![[agent getAgentData] isEqual:mapped_agent_data]) { + /* Something changed for mapped agent */ + [deleteList addObject:agent]; + continue; + } + } else { + /* Since this agent is NOT mapped to any other agent, this agent is + * registered with the kernel. So instead of destroying the agent and + * re-registering it, just update it here. + * + * All the agents which were mapped to this agent, will be deleted and + * re-mapped, if the data changed. + */ + NSData * agent_data; + + agent_data = [self getProxyDataFromCurrentConfig:proxies domain:[agent getAssociatedEntity]]; + if (![[agent getAgentData] isEqual:agent_data]) { + /* Something changed for agent */ + [agent updateAgentData:agent_data]; + + /* The reason I don't publish the data to agent here is that, if there were + * some agents mapping to this one, they will momentarily have a policy for + * using this agent UUID for some domain based on this agent's previous data. + */ + [update_agent_list addObject:agent]; + } + } + [new_domain_list removeObject:domain]; + } + + for (id agent in deleteList) { + SC_log(LOG_INFO, "Destroying agent %@ because something changed!", [agent getAgentName]); + [self destroyFloatingAgent:agent]; + } + + for (id agent in update_agent_list) { + [self publishToAgent:agent]; + } + + for (idx = 0; idx < count; idx++) { + CFDictionaryRef domain_proxy; + CFStringRef match_domain; + + domain_proxy = CFArrayGetValueAtIndex(supplemental, idx); + match_domain = CFDictionaryGetValue(domain_proxy, kSCPropNetProxiesSupplementalMatchDomain); + + if (match_domain != NULL) { + NSData * data; + NSUInteger found; + id mapped_agent; + + found = [new_domain_list indexOfObject:(__bridge id _Nonnull)(match_domain)]; + if (found == NSNotFound) { + continue; + } + + /* + * We will only process agents which are mapped AND the agent they were mapped to, changed OR + * agents for domains which we did not know before. + */ + + NSUInteger domainInstance = [duplicate_domain_list countForObject:(__bridge id _Nonnull)(match_domain)]; + if (domainInstance > 0) { + /* domainInstance will be > 0, only if we have conflicting domains */ + domainInstance++; + NSString *ns_domain_name_copy = [NSString stringWithFormat:@"%@" multipleEntitySuffix "%lu", match_domain, (unsigned long)domainInstance]; + + data = [self dataForProxyDictionary:domain_proxy]; + + BOOL ok = [self spawnFloatingAgent:[ProxyAgent class] + entity:ns_domain_name_copy + agentSubType:kAgentSubTypeSupplemental + addPolicyOfType:NEPolicyConditionTypeDomain + publishData:data]; + if (ok) { + id agent = [self.floatingProxyAgentList objectForKey:ns_domain_name_copy]; + SC_log(LOG_INFO, "Duplicate Proxy agent %@", [agent getAgentName]);; + } + } else { + data = [self dataForProxyDictionary:domain_proxy]; + mapped_agent = [self getAgentWithSameDataAndSubType:self.floatingProxyAgentList + data:data + subType:kAgentSubTypeSupplemental]; + if (mapped_agent != nil) { + [self spawnMappedFloatingAgent:mapped_agent + entity:(__bridge NSString *)(match_domain) + agentSubType:kAgentSubTypeSupplemental + addPolicyOfType:NEPolicyConditionTypeDomain + updateData:data]; + } else { + [self spawnFloatingAgent:[ProxyAgent class] + entity:(__bridge NSString *)(match_domain) + agentSubType:kAgentSubTypeSupplemental + addPolicyOfType:NEPolicyConditionTypeDomain + publishData:data]; + } + } + + [new_domain_list removeObjectAtIndex:found]; + [duplicate_domain_list addObject:(__bridge id _Nonnull)(match_domain)]; + } + } + + return; +} + +- (void)processScopedProxyChanges:(CFDictionaryRef)proxies +{ + NSMutableArray * old_intf_list; + CFDictionaryRef scoped_proxies; + CFIndex scoped_proxies_count; + + old_intf_list = [self getAgentList:self.floatingProxyAgentList + agentType:kAgentTypeProxy + agentSubType:kAgentSubTypeScoped]; + + scoped_proxies = CFDictionaryGetValue(proxies, kSCPropNetProxiesScoped); + scoped_proxies_count = scoped_proxies ? CFDictionaryGetCount(scoped_proxies) : 0; + + if (scoped_proxies_count > 0) { + const void **keys; + + keys = malloc(scoped_proxies_count * sizeof(void *)); + CFDictionaryGetKeysAndValues(scoped_proxies, keys, NULL); + + for (int i = 0; i < scoped_proxies_count; i++) { + NSData * data = nil; + NSUInteger idx; + CFArrayRef matching; + NSString * ns_if_name; + NSString * ns_if_name_with_prefix; + int proxy_count = 0; + id proxyAgent; + + ns_if_name = (__bridge NSString *)keys[i]; + ns_if_name_with_prefix = [NSString stringWithFormat:@"%s%@", prefixForInterfaceName, ns_if_name]; + + /* Does the proxy config have any protocols enabled? */ + proxy_count = [self countProxyEntriesEnabled:CFDictionaryGetValue(scoped_proxies, + (__bridge const void *)(ns_if_name))]; + + if (proxy_count == 0) { + SC_log(LOG_INFO, "Proxy settings on %@ are generic. Skipping", ns_if_name); + continue; + } + + idx = [old_intf_list indexOfObject:ns_if_name_with_prefix]; + + matching = SCNetworkProxiesCopyMatching(proxies, NULL, (__bridge CFStringRef)(ns_if_name)); + if (matching != NULL) { + data = [self dataForProxyArray:matching]; + CFRelease(matching); + } + + if (idx == NSNotFound) { + /* We need to spawn an agent */ + [self spawnFloatingAgent:[ProxyAgent class] + entity:ns_if_name_with_prefix + agentSubType:kAgentSubTypeScoped + addPolicyOfType:NEPolicyConditionTypeScopedInterface + publishData:data]; + + continue; + } else { + /* We have an agent for this interface. Update it */ + [old_intf_list removeObjectAtIndex:idx]; + } + + proxyAgent = [self.floatingProxyAgentList objectForKey:ns_if_name_with_prefix]; + if (proxyAgent != nil) { + /* Do we need to update this agent? */ + [proxyAgent updateAgentData:data]; + if ([proxyAgent shouldUpdateAgent]) { + [self publishToAgent:proxyAgent]; + } + } + } + + free(keys); + } + + [self deleteAgentList:self.floatingProxyAgentList list:old_intf_list]; +} + +- (void)processServiceSpecificProxyChanges:(CFDictionaryRef)proxies +{ + NSMutableArray * old_service_list; + CFDictionaryRef service_proxies; + CFIndex service_proxies_count; + + old_service_list = [self getAgentList:self.floatingProxyAgentList + agentType:kAgentTypeProxy + agentSubType:kAgentSubTypeServiceSpecific]; + + service_proxies = CFDictionaryGetValue(proxies, kSCPropNetProxiesServices); + service_proxies_count = service_proxies ? CFDictionaryGetCount(service_proxies) : 0; + + if (service_proxies_count > 0) { + const void **keys; + + keys = malloc(service_proxies_count * sizeof(void *)); + CFDictionaryGetKeysAndValues(service_proxies, keys, NULL); + + for (int i = 0; i < service_proxies_count; i++) { + NSData * data = nil; + NSUInteger idx; + NSString * ns_service_identifier = nil; + NSString * ns_service_with_prefix = nil; + int proxy_count = 0; + id proxyAgent; + CFDictionaryRef proxyDict = NULL; + + ns_service_identifier = (__bridge NSString *)keys[i]; + ns_service_with_prefix = [NSString stringWithFormat:@"%s%@", prefixForInterfaceName, ns_service_identifier]; + + /* Does the proxy config have any protocols enabled? */ + proxy_count = [self countProxyEntriesEnabled:CFDictionaryGetValue(service_proxies, + (__bridge const void *)(ns_service_identifier))]; + + if (proxy_count == 0) { + SC_log(LOG_INFO, "Proxy settings on %@ are generic. Skipping", ns_service_identifier); + continue; + } + + proxyDict = CFDictionaryGetValue(service_proxies, (__bridge CFStringRef)ns_service_identifier); + if (proxyDict != nil) { + data = [self dataForProxyArray:(__bridge CFArrayRef)(@[ (__bridge NSDictionary *)proxyDict ])]; + } + + idx = [old_service_list indexOfObject:ns_service_with_prefix]; + if (idx == NSNotFound) { + /* We need to spawn an agent */ + [self spawnFloatingAgent:[ProxyAgent class] + entity:ns_service_with_prefix + agentSubType:kAgentSubTypeServiceSpecific + addPolicyOfType:(POLICY_TYPE_NO_POLICY) /* Don't install a policy */ + publishData:data]; + + continue; + } else { + /* We have an agent for this service. Update it */ + [old_service_list removeObjectAtIndex:idx]; + } + + proxyAgent = [self.floatingProxyAgentList objectForKey:ns_service_with_prefix]; + if (proxyAgent != nil) { + /* Do we need to update this agent? */ + [proxyAgent updateAgentData:data]; + if ([proxyAgent shouldUpdateAgent]) { + [self publishToAgent:proxyAgent]; + } + } + } + + free(keys); + } + + [self deleteAgentList:self.floatingProxyAgentList list:old_service_list]; +} + +- (void)processDefaultProxyChanges:(CFDictionaryRef)proxies +{ + CFArrayRef global_proxy; + CFIndex global_proxy_count; + CFMutableDictionaryRef proxies_copy; + + proxies_copy = CFDictionaryCreateMutableCopy(NULL, 0, proxies); + CFDictionaryRemoveValue(proxies_copy, kSCPropNetProxiesScoped); + CFDictionaryRemoveValue(proxies_copy, kSCPropNetProxiesServices); + CFDictionaryRemoveValue(proxies_copy, kSCPropNetProxiesSupplemental); + + global_proxy = CFArrayCreate(NULL, (const void **)&proxies_copy, 1, &kCFTypeArrayCallBacks); + global_proxy_count = CFArrayGetCount(global_proxy); + if (global_proxy_count > 0 && + [self countProxyEntriesEnabled:proxies_copy] == 0) { + SC_log(LOG_INFO, "Proxy settings on defaultProxy are generic. Skipping"); + global_proxy_count = 0; + } + CFRelease(proxies_copy); + + if (global_proxy_count > 0) { + id proxyAgent; + NSData * data; + + data = [self dataForProxyArray:global_proxy]; + proxyAgent = [self.floatingProxyAgentList objectForKey:@proxyAgentDefault]; + if (proxyAgent == nil) { + [self spawnFloatingAgent:[ProxyAgent class] + entity:@proxyAgentDefault + agentSubType:kAgentSubTypeDefault + addPolicyOfType:NEPolicyConditionTypeNone + publishData:data]; + } else { + [proxyAgent updateAgentData:data]; + if ([proxyAgent shouldUpdateAgent]) { + [self publishToAgent:proxyAgent]; + } + } + } else { + /* No default proxy config OR generic (no protocols enabled) default proxy config. + * Destroy the default agent if we had one + */ + id proxyAgent; + + proxyAgent = [self.floatingProxyAgentList objectForKey:@proxyAgentDefault]; + if (proxyAgent != nil) { + [self destroyFloatingAgent:proxyAgent]; + } + } + + CFRelease(global_proxy); +} + +- (void)processProxyChanges +{ + CFDictionaryRef proxies; + + proxies = SCDynamicStoreCopyProxiesWithOptions(NULL, NULL); + if (proxies == NULL) { + SC_log(LOG_INFO, "No proxy information"); + + NSMutableDictionary *copy = [self.floatingProxyAgentList copy]; + for (NSString *entity in copy) { + id agent = [copy objectForKey:entity]; + [self destroyFloatingAgent:agent]; + } + + return; + } + + [self processDefaultProxyChanges:proxies]; + [self processScopedProxyChanges:proxies]; + [self processSupplementalProxyChanges:proxies]; + [self processServiceSpecificProxyChanges:proxies]; + + CFRelease(proxies); +} + +/* ========================== DNS agent helpers =========================== */ +#pragma mark DNS agent helper functions + +- (void)freeResolverList:(resolver_list_t *)resolvers +{ + /* This is a shallow free of resolver_list_t only. + * The actual resolver pointers are owned by 'dns_config' + */ + if (resolvers == NULL) { + return; + } + + if (resolvers->default_resolvers != NULL) { + free(resolvers->default_resolvers); + } + if (resolvers->multicast_resolvers != NULL) { + free(resolvers->multicast_resolvers); + } + if (resolvers->private_resolvers != NULL) { + free(resolvers->private_resolvers); + } + + free(resolvers); +} + +- (resolver_list_t *)copyResolverList:(dns_config_t *)dns_config +{ + resolver_list_t *resolvers = NULL; + + if ((dns_config->n_resolver > 0) && (dns_config->resolver != NULL)) { + int a = 0; + int b = 0; + int c = 0; + + resolvers = calloc(1, sizeof(resolver_list_t)); + for (int i = 0; i < dns_config->n_resolver; i++) { + dns_resolver_t *r = dns_config->resolver[i]; + + if ([self isResolverMulticast:r]) { + resolvers->n_multicast_resolvers++; + continue; + + } else if ([self isResolverPrivate:r]) { + resolvers->n_private_resolvers++; + continue; + } + + // do not consider default resolvers with no nameservers + if (r->domain == NULL && r->n_nameserver > 0) { + resolvers->n_default_resolvers++; + } + } + + SC_log(LOG_INFO, "Resolvers: %d default, %d multicast, %d private", + resolvers->n_default_resolvers, + resolvers->n_multicast_resolvers, + resolvers->n_private_resolvers); + + if (resolvers->n_default_resolvers > 0) { + resolvers->default_resolvers = calloc(resolvers->n_default_resolvers, + sizeof(dns_resolver_t *)); + } + if (resolvers->n_multicast_resolvers > 0) { + resolvers->multicast_resolvers = calloc(resolvers->n_multicast_resolvers, + sizeof(dns_resolver_t *)); + } + if (resolvers->n_private_resolvers > 0) { + resolvers->private_resolvers = calloc(resolvers->n_private_resolvers, + sizeof(dns_resolver_t *)); + } + + for (int i = 0; i < dns_config->n_resolver; i++) { + dns_resolver_t *r = dns_config->resolver[i]; + + if ([self isResolverMulticast:r] && + (a < resolvers->n_multicast_resolvers)) { + resolvers->multicast_resolvers[a++] = r; + continue; + + } else if ([self isResolverPrivate:r] && + (b < resolvers->n_private_resolvers)) { + resolvers->private_resolvers[b++] = r; + continue; + } + + if ((r->domain == NULL) && + (r->n_nameserver > 0) && + (c < resolvers->n_default_resolvers)) { + resolvers->default_resolvers[c++] = r; + } + } + } + + return resolvers; +} + +/* + * Generate a data blob for the resolver. + * Currently the blob only has: + * - nameserver count + * - sockaddr structs for each nameserver + * - ifindex + */ + +- (NSData *)dataForResolver:(dns_resolver_t *)resolver +{ + NSData * data = nil; + CFMutableDictionaryRef resolverDict = nil; + + if (resolver == NULL) { + SC_log(LOG_NOTICE, "Invalid dns resolver"); + return nil; + } + + if (resolver->n_search > 0) { + if (resolverDict == nil) { + resolverDict = CFDictionaryCreateMutable(NULL, + 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + } + + CFMutableArrayRef searchDomainArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + + /* Append search domains */ + for (int i = 0; i < resolver->n_search; i++) { + CFArrayAppendValue(searchDomainArray, (__bridge CFStringRef)(@(resolver->search[i]))); + } + + CFDictionaryAddValue(resolverDict, CFSTR(kConfigAgentDNSSearchDomains), searchDomainArray); + CFRelease(searchDomainArray); + } + + /* Get the count of nameservers */ + if (resolver->n_nameserver > 0) { + if (resolverDict == nil) { + resolverDict = CFDictionaryCreateMutable(NULL, + 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + } + + CFMutableArrayRef nameserverArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + + /* Get all the nameservers */ + for (int i = 0; i < resolver->n_nameserver; i++) { + char buf[128] = {0}; + _SC_sockaddr_to_string(resolver->nameserver[i], buf, sizeof(buf)); + if (*buf != '\0') { + CFArrayAppendValue(nameserverArray, (__bridge CFStringRef)(@(buf))); + } + } + + CFDictionaryAddValue(resolverDict, CFSTR(kConfigAgentDNSNameServers), nameserverArray); + CFRelease(nameserverArray); + } + + if (resolverDict != nil) { + data = [NSPropertyListSerialization dataWithPropertyList:(__bridge id _Nonnull)(resolverDict) + format:NSPropertyListBinaryFormat_v1_0 + options:0 + error:nil]; + + CFRelease(resolverDict); + } + + return (NSData *)data; +} + +- (NSData *)getDNSDataFromCurrentConfig:(dns_config_t *)dns_config + domain:(NSString *)domain +{ + if (dns_config == NULL || domain == nil) { + SC_log(LOG_NOTICE, "Invalid dns_config/domain"); + return nil; + } + + if ((dns_config->n_resolver > 0) && (dns_config->resolver != NULL)) { + for (int i = 0; i < dns_config->n_resolver; i++) { + dns_resolver_t * resolver; + + resolver = dns_config->resolver[i]; + if (resolver->domain != NULL && + ![self isResolverMulticast:resolver]) { + NSString * ns_domain_name; + + ns_domain_name = @(resolver->domain); + if ([ns_domain_name isEqualToString:domain]) { + return [self dataForResolver:resolver]; + } else { + continue; + } + } + } + } + + return nil; +} + +- (BOOL)isResolverMulticast:(dns_resolver_t *)resolver +{ + if (resolver->options == NULL) { + return NO; + } + + if (!strstr(resolver->options, "mdns")) { + return NO; + } + + return YES; +} + +- (BOOL)isResolverPrivate:(dns_resolver_t *)resolver +{ + if (resolver->options == NULL) { + return NO; + } + + if (!strstr(resolver->options, "pdns")) { + return NO; + } + + return YES; +} + +- (void)processSupplementalDNSResolvers:(dns_config_t *)dns_config +{ + NSMutableArray * deleteList; + NSMutableArray * new_domain_list; + NSCountedSet * duplicate_domain_list; + NSMutableArray * old_domain_list; + NSMutableArray * update_agent_list; + + + deleteList = [NSMutableArray array]; + duplicate_domain_list = [[NSCountedSet alloc] initWithCapacity:0]; + new_domain_list = [NSMutableArray array]; + update_agent_list = [NSMutableArray array]; + old_domain_list = [self getAgentList:self.floatingDNSAgentList + agentType:kAgentTypeDNS + agentSubType:kAgentSubTypeSupplemental]; + + if (dns_config->resolver == NULL) { + dns_config->n_resolver = 0; + } + if (dns_config->n_resolver > 0) { + for (int i = 0; i < dns_config->n_resolver; i++) { + dns_resolver_t * resolver; + + resolver = dns_config->resolver[i]; + if (resolver->domain != NULL && + ![self isResolverPrivate:resolver] && + ![self isResolverMulticast:resolver]) { + NSString * ns_domain_name; + + ns_domain_name = [NSString stringWithCString:resolver->domain encoding:NSASCIIStringEncoding]; + [new_domain_list addObject:ns_domain_name]; + } + } + } + + [self cleanConflictingAgentsFromList:old_domain_list + new_list:new_domain_list + agentDictionary:self.floatingDNSAgentList]; + + /* Sync between controller and current config */ + for (NSString *key in old_domain_list) { + BOOL domain_present = NO; + + domain_present = [new_domain_list containsObject:key]; + if (domain_present == NO) { + id agent; + + agent = [self.floatingDNSAgentList objectForKey:key]; + [self destroyFloatingAgent:agent]; + } + } + + /* At this point, whatever is in the controller's floating agent list, + is present in the current DNS config. The current DNS config + might have even more configs, not known to the controller, YET + */ + + for (NSString *domain in old_domain_list) { + id agent; + id mapped_agent; + + agent = [self.floatingDNSAgentList objectForKey:domain]; + if (agent == nil) { + continue; + } + + /* Am I mapped to some agent? */ + mapped_agent = [agent getAgentMapping]; + if (mapped_agent) { + /* OK, this agent is mapped to some other agent. We compare this agent's data + * to the current data of the agent to which it is mapped. If different, we destroy + * the agent and later map it to someone else OR spawn a new one. + */ + NSData *mapped_agent_data; + + mapped_agent_data = [self getDNSDataFromCurrentConfig:dns_config domain:[mapped_agent getAssociatedEntity]]; + if (mapped_agent_data == nil || ![[agent getAgentData] isEqual:mapped_agent_data]) { + /* Something changed for mapped agent */ + [deleteList addObject:agent]; + continue; + } + } else { + /* Since this agent is NOT mapped to any other agent, this agent is + * registered with the kernel. So instead of destroying the agent and + * re-registering it, just update it here. + * + * All the agents which were mapped to this agent, will be deleted and + * re-mapped, if the data changed. + */ + NSData *agent_data; + + agent_data = [self getDNSDataFromCurrentConfig:dns_config domain:[agent getAssociatedEntity]]; + if (![[agent getAgentData] isEqual:agent_data]) { + /* Something changed for agent */ + [agent updateAgentData:agent_data]; + + /* The reason I don't publish the data to agent here is that, if there were + * some agents mapping to this one, they will momentarily have a policy for + * using this agent UUID for some domain based on this agent's previous data. + */ + [update_agent_list addObject:agent]; + + } + } + [new_domain_list removeObject:domain]; + } + + for (id agent in deleteList) { + SC_log(LOG_INFO, "Destroying agent %@ because something changed!", [agent getAgentName]); + [self destroyFloatingAgent:agent]; + } + + for (id agent in update_agent_list) { + [self publishToAgent:agent]; + } + + for (int idx = 0; idx < dns_config->n_resolver; idx++) { + dns_resolver_t * resolver; + + resolver = dns_config->resolver[idx]; + if (resolver->domain != NULL && + ![self isResolverPrivate:resolver] && + ![self isResolverMulticast:resolver]) { + NSData * data; + NSUInteger found; + id mapped_agent; + NSString * ns_domain_name; + + ns_domain_name = @(resolver->domain); + found = [new_domain_list indexOfObject:ns_domain_name]; + if (found == NSNotFound) { + /* Nothing changed for this agent */ + continue; + } + + /* We will only process agents which are mapped AND if the agent they were mapped to, changed OR + * agents for domains which we did not know before. + */ + + NSUInteger domainInstance = [duplicate_domain_list countForObject:ns_domain_name]; + if (domainInstance > 0) { + /* domainInstance will be > 0, only if we have conflicting domains */ + domainInstance++; + data = [self dataForResolver:resolver]; + + NSString *ns_domain_name_copy = [NSString stringWithFormat:@"%@" multipleEntitySuffix "%lu", ns_domain_name, (unsigned long)domainInstance]; + + BOOL ok = [self spawnFloatingAgent:[DNSAgent class] + entity:ns_domain_name_copy + agentSubType:kAgentSubTypeSupplemental + addPolicyOfType:NEPolicyConditionTypeDomain + publishData:data]; + if (ok) { + id agent = [self.floatingDNSAgentList objectForKey:ns_domain_name_copy]; + SC_log(LOG_INFO, "Duplicate DNS agent %@", [agent getAgentName]);; + } + } else { + data = [self dataForResolver:resolver]; + mapped_agent = [self getAgentWithSameDataAndSubType:self.floatingDNSAgentList + data:data + subType:kAgentSubTypeSupplemental]; + if (mapped_agent != nil) { + [self spawnMappedFloatingAgent:mapped_agent + entity:ns_domain_name + agentSubType:kAgentSubTypeSupplemental + addPolicyOfType:NEPolicyConditionTypeDomain + updateData:data]; + } else { + [self spawnFloatingAgent:[DNSAgent class] + entity:ns_domain_name + agentSubType:kAgentSubTypeSupplemental + addPolicyOfType:NEPolicyConditionTypeDomain + publishData:data]; + } + } + + [new_domain_list removeObjectAtIndex:found]; + [duplicate_domain_list addObject:ns_domain_name]; + } + } + + return; + +} + +- (void)processDNSResolvers:(dns_config_t *)dns_config +{ + resolver_list_t *resolvers = [self copyResolverList:dns_config]; + if (resolvers) { + /* Process Default resolvers */ + NSMutableArray *old_default_resolver_list = [self getAgentList:self.floatingDNSAgentList + agentType:kAgentTypeDNS + agentSubType:kAgentSubTypeDefault]; + + // For default resolvers, their name will be '_defaultDNS', '_defaultDNS #2' so on... + if (resolvers->n_default_resolvers > 0 && resolvers->default_resolvers != NULL) { + for (int i = 0; i < resolvers->n_default_resolvers; i++) { + dns_resolver_t *default_resolver = resolvers->default_resolvers[i]; + NSData * data; + id dnsAgent; + NSString * resolverName; + + data = [self dataForResolver:default_resolver]; + if (i == 0) { + resolverName = @(dnsAgentDefault); + } else { + resolverName = [NSString stringWithFormat:@dnsAgentDefault multipleEntitySuffix "%d", i+1 ]; + } + + dnsAgent = [self.floatingDNSAgentList objectForKey:resolverName]; + + if (dnsAgent != nil) { + [old_default_resolver_list removeObject:resolverName]; + if ([data isEqual:[dnsAgent getAgentData]]) { + /* Leave this agent in place. Nothing changed! */ + continue; + } else { + [self destroyFloatingAgent:dnsAgent]; + } + } + + [self spawnFloatingAgent:[DNSAgent class] + entity:resolverName + agentSubType:kAgentSubTypeDefault + addPolicyOfType:NEPolicyConditionTypeNone + publishData:data]; + } + } + + // Only agents that are NOT present in the new config, will be present in the list + // and they need to be destroyed. + [self deleteAgentList:self.floatingDNSAgentList list:old_default_resolver_list]; + + /* Process Multicast resolvers */ + + NSMutableArray *old_multicast_resolver_list = [self getAgentList:self.floatingDNSAgentList + agentType:kAgentTypeDNS + agentSubType:kAgentSubTypeMulticast]; + + if (resolvers->n_multicast_resolvers > 0 && resolvers->multicast_resolvers != NULL) { + for (int i = 0; i < resolvers->n_multicast_resolvers; i++) { + dns_resolver_t * multicast_resolver = resolvers->multicast_resolvers[i]; + id dnsAgent; + NSString * resolverName; + + if (multicast_resolver == NULL) { + continue; + } + + if (multicast_resolver->domain == NULL) { + /* Multicast resolvers MUST have a domain */ + continue; + } + + resolverName = @(multicast_resolver->domain); + if (resolverName == NULL) { + /* Multicast resolvers MUST have a domain */ + continue; + } + + dnsAgent = [self.floatingDNSAgentList objectForKey:resolverName]; + if (dnsAgent != nil) { + [old_multicast_resolver_list removeObject:resolverName]; + continue; + } + + [self spawnFloatingAgent:[DNSAgent class] + entity:resolverName + agentSubType:kAgentSubTypeMulticast + addPolicyOfType:NEPolicyConditionTypeDomain + publishData:nil]; + // Don't care about data for mdns resolvers. Do we? + } + } + + [self deleteAgentList:self.floatingDNSAgentList list:old_multicast_resolver_list]; + + /* Process Private resolvers */ + + NSMutableArray *old_private_resolver_list = [self getAgentList:self.floatingDNSAgentList + agentType:kAgentTypeDNS + agentSubType:kAgentSubTypePrivate]; + + if (resolvers->n_private_resolvers > 0 && resolvers->private_resolvers != NULL) { + for (int i = 0; i < resolvers->n_private_resolvers; i++) { + dns_resolver_t * private_resolver = resolvers->private_resolvers[i]; + id dnsAgent; + NSString * resolverName; + + if (private_resolver == NULL) { + continue; + } + + if (private_resolver->domain == NULL) { + /* private resolvers MUST have a domain */ + continue; + } + + resolverName = @(private_resolver->domain); + if (resolverName == nil) { + /* Private resolvers MUST have a domain */ + continue; + } + + dnsAgent = [self.floatingDNSAgentList objectForKey:resolverName]; + if (dnsAgent != nil) { + [old_private_resolver_list removeObject:resolverName]; + continue; + } + + [self spawnFloatingAgent:[DNSAgent class] + entity:resolverName + agentSubType:kAgentSubTypePrivate + addPolicyOfType:NEPolicyConditionTypeDomain + publishData:nil]; + // Don't care about data for pdns resolvers. Do we? + } + } + + [self deleteAgentList:self.floatingDNSAgentList list:old_private_resolver_list]; + } + + [self freeResolverList:resolvers]; +} + +- (void)processScopedDNSResolvers:(dns_config_t *)dns_config; +{ + NSMutableArray * old_intf_list; + old_intf_list = [self getAgentList:self.floatingDNSAgentList + agentType:kAgentTypeDNS + agentSubType:kAgentSubTypeScoped]; + + if ((dns_config->n_scoped_resolver > 0) && (dns_config->scoped_resolver != NULL)) { + for (int i = 0; i < dns_config->n_scoped_resolver; i++) { + char buf[IFNAMSIZ]; + NSData * data; + id dnsAgent; + NSUInteger idx; + char * if_name; + NSString * ns_if_name; + NSString * ns_if_name_with_prefix; + dns_resolver_t * resolver; + + resolver = dns_config->scoped_resolver[i]; + if_name = if_indextoname(resolver->if_index, buf); + if (if_name) { + ns_if_name = @(if_name); + ns_if_name_with_prefix = [NSString stringWithFormat:@"%s%@", prefixForInterfaceName, ns_if_name]; + } else { + continue; + } + + data = [self dataForResolver:resolver]; + idx = [old_intf_list indexOfObject:ns_if_name_with_prefix]; + + if (idx == NSNotFound) { + /* We need to spawn an agent */ + [self spawnFloatingAgent:[DNSAgent class] + entity:ns_if_name_with_prefix + agentSubType:kAgentSubTypeScoped + addPolicyOfType:NEPolicyConditionTypeScopedInterface + publishData:data]; + continue; + } else { + /* We have an agent on this interface. Update it */ + [old_intf_list removeObjectAtIndex:idx]; + } + + /* Get the DNS agent for this interface? */ + dnsAgent = [self.floatingDNSAgentList objectForKey:ns_if_name_with_prefix]; + if (dnsAgent != nil) { + /* Do we need to update this agent? */ + [dnsAgent updateAgentData:data]; + if ([dnsAgent shouldUpdateAgent]) { + [self publishToAgent:dnsAgent]; + } + } + } + } + + [self deleteAgentList:self.floatingDNSAgentList list:old_intf_list]; +} + +- (void)processServiceSpecificDNSResolvers:(dns_config_t *)dns_config; +{ + NSMutableArray * old_service_list; + old_service_list = [self getAgentList:self.floatingDNSAgentList + agentType:kAgentTypeDNS + agentSubType:kAgentSubTypeServiceSpecific]; + + if ((dns_config->n_service_specific_resolver > 0) && (dns_config->service_specific_resolver != NULL)) { + for (int i = 0; i < dns_config->n_service_specific_resolver; i++) { + NSData * data; + id dnsAgent; + NSUInteger idx; + uint32_t service_identifier; + NSString * ns_service_identifier_with_prefix; + dns_resolver_t * resolver; + + resolver = dns_config->service_specific_resolver[i]; + service_identifier = resolver->service_identifier; + if (service_identifier != 0) { + ns_service_identifier_with_prefix = [NSString stringWithFormat:@"%s%u", prefixForInterfaceName, service_identifier]; + } else { + continue; + } + + data = [self dataForResolver:resolver]; + idx = [old_service_list indexOfObject:ns_service_identifier_with_prefix]; + + if (idx == NSNotFound) { + /* We need to spawn an agent */ + [self spawnFloatingAgent:[DNSAgent class] + entity:ns_service_identifier_with_prefix + agentSubType:kAgentSubTypeServiceSpecific + addPolicyOfType:(POLICY_TYPE_NO_POLICY) /* Don't install a policy */ + publishData:data]; + continue; + } else { + /* We have an agent on this interface. Update it */ + [old_service_list removeObjectAtIndex:idx]; + } + + /* Get the DNS agent for this interface? */ + dnsAgent = [self.floatingDNSAgentList objectForKey:ns_service_identifier_with_prefix]; + if (dnsAgent != nil) { + /* Do we need to update this agent? */ + [dnsAgent updateAgentData:data]; + if ([dnsAgent shouldUpdateAgent]) { + [self publishToAgent:dnsAgent]; + } + } + } + } + + [self deleteAgentList:self.floatingDNSAgentList list:old_service_list]; +} + +#define ONION_RESOLVER_DOMAIN "onion" +- (BOOL)isResolverOnion:(dns_resolver_t *)resolver +{ + if (resolver->domain != NULL && + (strcmp(resolver->domain, ONION_RESOLVER_DOMAIN) == 0)) { + return YES; + } + + return NO; +} + + +- (void)processOnionResolver:(dns_config_t *)dns_config +{ + static NSUInteger policy_id = 0; + + if (dns_config == NULL) { + goto remove_policy; + } + + /* Run through the resolver configurations. We only care for the supplemental resolvers. */ + for (int32_t i = 0; i < dns_config->n_resolver; i++) { + dns_resolver_t *resolver = dns_config->resolver[i]; + if ([self isResolverOnion:resolver]) { + goto remove_policy; + } + } + + /* We do not have any such resolver. Add a system-wide "drop" policy for this domain */ + if (policy_id == 0) { + NEPolicy *policy = [[NEPolicy alloc] initWithOrder:INIT_ORDER_FOR_DOMAIN_POLICY + result:[NEPolicyResult drop] + conditions:@[[NEPolicyCondition domain:@ONION_RESOLVER_DOMAIN]]]; + if (policy != nil) { + policy_id = [self.policySession addPolicy:policy]; + if (![self.policySession apply]) { + policy_id = 0; + SC_log(LOG_NOTICE, "Could not add a [." ONION_RESOLVER_DOMAIN "] drop policy"); + } else { + SC_log(LOG_INFO, "Added a [." ONION_RESOLVER_DOMAIN "] drop policy"); + } + } + } + + return; + +remove_policy: + + /* We have such a resolver in the config OR no DNS config at all. Remove the system-wide "drop" policy for this domain */ + if (policy_id > 0) { + [self.policySession removePolicyWithID:policy_id]; + if (![self.policySession apply]) { + SC_log(LOG_NOTICE, "Could not remove the [." ONION_RESOLVER_DOMAIN "] drop policy"); + } else { + policy_id = 0; + SC_log(LOG_INFO, "Removed the [." ONION_RESOLVER_DOMAIN "] drop policy"); + } + } + + return; +} +#undef ONION_RESOLVER_DOMAIN + + +- (void)processDNSChanges +{ + dns_config_t * dns_config; + + dns_config = dns_configuration_copy(); + if (dns_config == NULL) { + SC_log(LOG_INFO, "No DNS configuration"); + NSMutableDictionary *copy = [self.floatingDNSAgentList copy]; + for (NSString *entity in copy) { + id agent = [copy objectForKey:entity]; + + [self destroyFloatingAgent:agent]; + } + goto done; + } + + [self processDNSResolvers:dns_config]; + [self processScopedDNSResolvers:dns_config]; + [self processSupplementalDNSResolvers:dns_config]; + [self processServiceSpecificDNSResolvers:dns_config]; + +done: + + [self processOnionResolver:dns_config]; + if (dns_config != NULL) { + dns_configuration_free(dns_config); + } +} + +#pragma mark Helper functions + +- (const void *)copyConfigAgentData:(NSMutableDictionary *)controllerDict + uuid:(uuid_t)requested_uuid + length:(uint64_t *)length +{ + if (length == NULL) { + SC_log(LOG_NOTICE, "Invalid parameters for copying agent data"); + return NULL; + } + + id agent = nil; + void *buffer = NULL; + *length = 0; + + for (NSString *key in controllerDict) { + id temp_agent = [controllerDict objectForKey:key]; + + uuid_t agent_uuid; + + [[temp_agent getAgentUUID] getUUIDBytes:agent_uuid]; + if (uuid_compare(agent_uuid, requested_uuid) == 0) { + agent = temp_agent; + break; + } + } + + if (agent == nil) { + uuid_string_t uuid_str; + uuid_unparse(requested_uuid, uuid_str); + SC_log(LOG_NOTICE, "Invalid config agent uuid %s specified", uuid_str); + return NULL; + } + + NSData *data = [agent getAgentData]; + uint64_t len = [data length]; + if (len > 0) { + *length = len; + buffer = malloc((size_t)len); + memcpy(buffer, [data bytes], len); + } + + return (const void *)buffer; +} + +- (const void *)copyProxyAgentData:(uuid_t)requested_uuid + length:(uint64_t *)length +{ + return [self copyConfigAgentData:self.floatingProxyAgentList + uuid:requested_uuid + length:length]; +} + +- (const void *)copyDNSAgentData:(uuid_t)requested_uuid + length:(uint64_t *)length +{ + return [self copyConfigAgentData:self.floatingDNSAgentList + uuid:requested_uuid + length:length]; +} + +- (NSData *)dataLengthSanityCheck:(id)agent +{ + NSData * data = [agent getAgentData]; + + if ([data length] > CONFIG_AGENT_DATA_LIMIT) { + /* We impose a limit on the config agent data as 1KB. + * If we have a data blob larger than this limit, do NOT publish it into the agent. + * Instead publish a key which will trigger fetching of the configuration directly + * through NWI server. + */ + NSMutableDictionary *data_dict = [NSMutableDictionary dictionary]; + + NSUUID *uuid = [agent getAgentUUID]; + uuid_t c_uuid; + [uuid getUUIDBytes:c_uuid]; + NSData *uuid_data = [[NSData alloc] initWithBytes:c_uuid length:sizeof(c_uuid)]; + [data_dict setValue:uuid_data forKey:@kConfigAgentOutOfBandDataUUID]; + + NSData *new_data = [NSPropertyListSerialization dataWithPropertyList:data_dict + format:NSPropertyListBinaryFormat_v1_0 + options:0 + error:nil]; + + return new_data; + } + + return nil; +} + +/* + * For conflicting agents, the convention is that its name & entity, + * will have a suffix " #". This function will sanitize the + * suffix and just return the entity name + */ +- (NSString *)sanitizeEntity:(NSString *)entity +{ + NSRange range = [entity rangeOfString:@multipleEntitySuffix]; + if (range.location != NSNotFound) { + NSString *str = [entity substringToIndex:range.location]; + return str; + } + + return entity; +} + +/* + * For interface names, there is a prefix to differentiate then + * from the domain name (iff there were conflicting domain names). + * Returns the sanitized interface name + */ +- (NSString *)sanitizeInterfaceName:(NSString *)intf +{ + NSRange range = [intf rangeOfString:@prefixForInterfaceName]; + if (range.location != NSNotFound) { + NSString *str = [intf substringFromIndex:(range.location + strlen(prefixForInterfaceName))]; + return str; + } + + return intf; +} + +/* + * For conflicting agents, the convention is that its name & entity, + * will have a suffix " #". This function will return that + */ +- (int)entityInstanceNumber:(NSString *)entity +{ + NSRange range = [entity rangeOfString:@multipleEntitySuffix]; + if (range.location != NSNotFound) { + NSString *str = [entity substringFromIndex:(range.location + strlen(multipleEntitySuffix))]; + return str.intValue; + } + + return 0; +} + +/* + * In case that we have conflicting DNS/Proxy domains + * This function will remove all those conflicting agents, + * so that we can start afresh with the new config + */ +- (void)cleanConflictingAgentsFromList:(NSMutableArray *)old_list + new_list:(NSMutableArray *)new_list + agentDictionary:(NSMutableDictionary *)agent_list +{ + NSCountedSet * duplicate_domain_list; + + for (NSString *domain in old_list) { + /* If we had conflicting domains before, remove all of them */ + NSString *sanitizedDomain = [self sanitizeEntity:domain]; + if (![sanitizedDomain isEqualToString:domain]) { + /* Destroy the original domain */ + id agent = [agent_list objectForKey:sanitizedDomain]; + [self destroyFloatingAgent:agent]; + + /* Destroy the conflicting domain */ + agent = [agent_list objectForKey:domain]; + [self destroyFloatingAgent:agent]; + + SC_log(LOG_INFO, "Removing conflicting domain: %@, %@", sanitizedDomain, domain); + } + } + + duplicate_domain_list = [[NSCountedSet alloc] initWithArray:new_list]; + for (NSString *domain in old_list) { + if ([duplicate_domain_list countForObject:domain] > 1) { + id agent = [agent_list objectForKey:domain]; + [self destroyFloatingAgent:agent]; + SC_log(LOG_INFO, "Removing domain %@ as it has duplicates in the current config", domain); + } + } +} + +/* + * Get the list of agents from a specific dictionary. + * The list of agents will only consist of the ones which + * match the agent type and sub-type + */ + +- (NSMutableArray *)getAgentList:(NSMutableDictionary *)all_agents + agentType:(AgentType)type + agentSubType:(AgentSubType)subtype +{ + NSMutableArray *list = [NSMutableArray array]; + NSArray *agentObjects = [all_agents allValues]; + + for (id agent in agentObjects) { + if (([agent getAgentType] == type) && + ([agent getAgentSubType] == subtype)) { + + [list addObject:[agent getAssociatedEntity]]; + } + } + + return list; +} + +/* + * Destroy all the agents are listed in "list" + */ + +- (void)deleteAgentList:(NSMutableDictionary *)all_agents + list:(NSMutableArray *)list +{ + for (NSString *intf in list) { + id agent; + + agent = [all_agents objectForKey:intf]; + [self destroyFloatingAgent:agent]; + } +} + +/* + * In order to not duplicate agents with same content, + * we map an agent X to agent Y, when their content is the same. + * + * This function tries to find that agent Y + */ + +- (id)getAgentWithSameDataAndSubType:(NSMutableDictionary *)agentList + data:(NSData *)data + subType:(AgentSubType)subtype +{ + for (NSString *key in agentList) { + id agent = [agentList objectForKey:key]; + if ([[agent getAgentData] isEqual:data]) { + /* Do not map to default agents */ + if ([agent getAgentSubType] != subtype) { + continue; + } + + /* Return only registered agents */ + if ([agent getRegistrationObject] != nil) { + return agent; + } + } + } + + return nil; +} + +#pragma mark Policy installation function + +/* + * Add NECP policies for an agent + */ +- (BOOL)addPolicyToFloatingAgent:(id)agent + domain:(NSString *)domain + agentUUIDToUse:(NSUUID *)uuid + policyType:(NEPolicyConditionType)policyType +{ + NEPolicyCondition * condition = nil; + uint32_t multiple_entity_offset; + NEPolicy * newPolicy; + BOOL ok; + uint32_t order; + uint32_t orderForSkip; + NSMutableArray * policyArray; + NSUInteger policyID1; + NSUInteger policyID2; + NEPolicyResult * result; + uint32_t skipOrder; + AgentType type; + uint32_t typeOffset; + + type = [agent getAgentType]; + typeOffset = (type == kAgentTypeDNS) ? 0 : 5000; + skipOrder = (type == kAgentTypeDNS) ? 5000 : 0; + + multiple_entity_offset = (uint32_t)[self entityInstanceNumber:domain]; + domain = [self sanitizeEntity:domain]; + + switch (policyType) { + case NEPolicyConditionTypeScopedInterface: + order = INIT_ORDER_FOR_SCOPED_INTERFACE_POLICY + typeOffset + multiple_entity_offset; + domain = [self sanitizeInterfaceName:domain]; + condition = [NEPolicyCondition scopedInterface:domain]; + orderForSkip = SKIP_ORDER_FOR_SCOPED_INTERFACE_POLICY + typeOffset; + break; + + case NEPolicyConditionTypeDomain: + order = INIT_ORDER_FOR_DOMAIN_POLICY + typeOffset + multiple_entity_offset; + condition = [NEPolicyCondition domain:domain]; + orderForSkip = SKIP_ORDER_FOR_DOMAIN_POLICY + typeOffset; + break; + + case NEPolicyConditionTypeNone: + order = INIT_ORDER_FOR_DEFAULT_POLICY + typeOffset + multiple_entity_offset; + orderForSkip = SKIP_ORDER_FOR_DEFAULT_POLICY + typeOffset; + break; + + default: + SC_log(LOG_NOTICE, "Invalid policy condition specified"); + return NO; + } + + result = [NEPolicyResult netAgentUUID:uuid]; + newPolicy = [[NEPolicy alloc] initWithOrder:order + result:result + conditions: (condition ? @[condition] : nil)]; + + if (newPolicy == nil) { + SC_log(LOG_NOTICE, "Could not create a policy for agent %@", [agent getAgentName]); + return NO; + } + + policyID1 = [self.policySession addPolicy:newPolicy]; + if (policyID1 == 0) { + SC_log(LOG_NOTICE, "Could not add a netagent policy for agent %@", [agent getAgentName]); + return NO; + } + + result = [NEPolicyResult skipWithOrder:skipOrder]; + newPolicy = [[NEPolicy alloc] initWithOrder:orderForSkip + result:result + conditions:(condition ? @[condition] : nil)]; + + if (newPolicy == nil) { + SC_log(LOG_NOTICE, "Could not create a policy for agent %@", [agent getAgentName]); + return NO; + } + + policyID2 = [self.policySession addPolicy:newPolicy]; + if (policyID2 == 0) { + SC_log(LOG_NOTICE, "Could not add a skip policy for agent %@", [agent getAgentName]); + return NO; + } + + ok = [self.policySession apply]; + if (!ok) { + SC_log(LOG_NOTICE, "Could not apply policy for agent %@", [agent getAgentName]); + return NO; + } + + policyArray = [self.policyDB objectForKey:[agent getAgentName]]; + if (policyArray == nil) { + policyArray = [NSMutableArray array]; + } + + [policyArray addObject:numberToNSNumber(policyID1)]; + [policyArray addObject:numberToNSNumber(policyID2)]; + [self.policyDB setObject:policyArray forKey:[agent getAgentName]]; + + return ok; +} + +#pragma mark Agent manipulation functions + +/* + * Create an agent + */ +- (BOOL)spawnFloatingAgent:(Class)agentClass + entity:(NSString *)entity + agentSubType:(AgentSubType)subtype + addPolicyOfType:(NEPolicyConditionType)policyType + publishData:(NSData *)data +{ + id agent; + BOOL ok; + NSMutableDictionary * parameters; + + parameters =[NSMutableDictionary dictionary]; + [parameters setValue:entity forKey:@kEntityName]; + [parameters setValue:numberToNSNumber(subtype) forKey:@kAgentSubType]; + + agent = [[agentClass alloc] initWithParameters:parameters]; + ok = [self registerAgent:agent]; + if (!ok) { + return NO; + } + + if (data) { + /* Since we just spawned this agent, update its data */ + [agent updateAgentData:data]; + [self publishToAgent:agent]; + } + + /* Add a policy if there is a valid type. If POLICY_TYPE_NO_POLICY, then ignore policies. + * POLICY_TYPE_NO_POLICY will be set for service-specific agents, in which case we rely on + * service owners to install custom policies to point at the agents. */ + if (policyType >= NEPolicyResultTypeNone) { + ok = [self addPolicyToFloatingAgent:agent + domain:entity + agentUUIDToUse:[agent agentUUID] + policyType:policyType]; + + if (!ok) { + [self unregisterAgent:agent]; + return NO; + } + } + + SC_log(LOG_INFO, "Spawning floating agent for %@", entity); + + if ([agent getAgentType] == kAgentTypeProxy) { + [self.floatingProxyAgentList setObject:agent forKey:entity]; + } else { + [self.floatingDNSAgentList setObject:agent forKey:entity]; + } + + return ok; +} + +/* + * Create an agent mapped to another agent. + */ +- (BOOL)spawnMappedFloatingAgent:(id)mapped_agent + entity:(NSString *)entity + agentSubType:(AgentSubType)subtype + addPolicyOfType:(NEPolicyConditionType)policyType + updateData:(NSData *)data +{ + id dummyAgent; + NSMutableDictionary * parameters; + + parameters = [NSMutableDictionary dictionary]; + [parameters setValue:entity forKey:@kEntityName]; + [parameters setValue:numberToNSNumber(subtype) forKey:@kAgentSubType]; + + dummyAgent = [[[mapped_agent class] alloc] initWithParameters:parameters]; + + if (data) { + /* Since we just spawned this agent, update its data. + * We do not publish it since this agent is mapped + * to an agent which already has the same data + */ + [dummyAgent updateAgentData:data]; + } + + BOOL ok = [self addPolicyToFloatingAgent:dummyAgent + domain:entity + agentUUIDToUse:[mapped_agent agentUUID] + policyType:policyType]; + + if (!ok) { + return NO; + } + + if ([mapped_agent getAgentType] == kAgentTypeProxy) { + [self.floatingProxyAgentList setObject:dummyAgent forKey:entity]; + } else { + [self.floatingDNSAgentList setObject:dummyAgent forKey:entity]; + } + + [dummyAgent setAgentMapping:mapped_agent]; + + SC_log(LOG_INFO, "Mapped floating agent %@ to %@", [dummyAgent getAgentName], [mapped_agent getAgentName]); + return YES; +} + +/* + * Write into an agent + */ +- (BOOL)publishToAgent:(id)agent +{ + /* Before any data goes into the kernel, do a sanity check. */ + NSData *sanityCheckData = [self dataLengthSanityCheck:agent]; + NSData *tempAgentData = nil; + + if (sanityCheckData != nil) { + /* Data length is more than the limit! for updateNetworkAgent, the data blob + * has to be a part of the agent object. Thus the temporary data replacement! + */ + tempAgentData = [[agent getAgentData] copy]; + [agent updateAgentData:sanityCheckData]; + SC_log(LOG_NOTICE, "Data too large for %@ (%lu bytes)!", [agent getAgentName], (unsigned long)[tempAgentData length]); + } + + BOOL ok = NO; + + NWNetworkAgentRegistration *regObject = [agent valueForKey:@"registrationObject"]; + if (regObject != nil) { + SC_log(LOG_NOTICE, "Publishing data to agent %@ (%lu bytes)", [agent getAgentName], (unsigned long)[[agent getAgentData] length]); + ok = [regObject updateNetworkAgent:agent]; + if (!ok) { + SC_log(LOG_NOTICE, "Could not update config agent"); + } + } else { + SC_log(LOG_NOTICE, "Config Agent not registered. Cannot Update"); + } + + if (tempAgentData != nil) { + [agent updateAgentData:tempAgentData]; + } + + return ok; +} + +/* + * Destroy an agent + */ +- (BOOL)destroyFloatingAgent:(id)agent +{ + BOOL ok = NO; + + if ( agent != nil) { + NSMutableArray * policyArray; + + policyArray = [self.policyDB objectForKey:[agent getAgentName]]; + if (policyArray != nil) { + BOOL result = NO; + + for (NSNumber *policyID in policyArray) { + NSUInteger idVal; + + idVal = [policyID unsignedIntegerValue]; + result = [self.policySession removePolicyWithID:idVal]; + if (result == NO) { + SC_log(LOG_NOTICE, "Could not remove policy %@ for agent %@", [self.policySession policyWithID:idVal], [agent getAgentName]); + } + } + + result = [self.policySession apply]; + if (result == NO) { + SC_log(LOG_NOTICE, "Could not apply removed policies for agent %@", [agent getAgentName]); + } + + [self.policyDB removeObjectForKey:[agent getAgentName]]; + } + + if ([agent getAgentType] == kAgentTypeProxy) { + [self.floatingProxyAgentList removeObjectForKey:[agent getAssociatedEntity]]; + } else { + [self.floatingDNSAgentList removeObjectForKey:[agent getAssociatedEntity]]; + } + + if ([agent getRegistrationObject] != nil) { + [self unregisterAgent:agent]; + } + + SC_log(LOG_INFO, "X - Destroyed agent %@", [agent getAgentName]); + ok = YES; + } + + return ok; +} + +/* + * Register an agent + */ +- (BOOL)registerAgent:(id)agent +{ + BOOL ok = NO; + + NWNetworkAgentRegistration *registration = [[NWNetworkAgentRegistration alloc] initWithNetworkAgentClass:[agent class]]; + + ok = [registration registerNetworkAgent:agent]; + if (!ok) { + SC_log(LOG_NOTICE, "Could not register config agent"); + goto done; + } + + [agent addAgentRegistrationObject:registration]; + +done: + return ok; +} + +/* + * Unregister an agent + */ +- (BOOL)unregisterAgent:(id)agent +{ + BOOL ok = false; + + NWNetworkAgentRegistration *regObject = [agent valueForKey:@"registrationObject"]; + if (regObject != nil) { + ok = [regObject unregisterNetworkAgent]; + if (!ok) { + SC_log(LOG_NOTICE, "Could not unregister config agent"); + } + } else { + SC_log(LOG_NOTICE, "Config Agent not registered. Cannot unregister"); + } + + return ok; +} + + +@end diff --git a/Plugins/IPMonitor/dns-configuration.c b/Plugins/IPMonitor/dns-configuration.c index 2254e41..7beea02 100644 --- a/Plugins/IPMonitor/dns-configuration.c +++ b/Plugins/IPMonitor/dns-configuration.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2015 Apple Inc. All rights reserved. + * Copyright (c) 2004-2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -64,12 +64,7 @@ extern uint32_t notify_monitor_file(int token, const char *name, int flags); #include #include -#ifndef kDNSServiceCompMulticastDNS -#define kDNSServiceCompMulticastDNS "MulticastDNS" -#endif -#ifndef kDNSServiceCompPrivateDNS -#define kDNSServiceCompPrivateDNS "PrivateDNS" -#endif +#include #define DNS_CONFIGURATION_FLAGS_KEY CFSTR("__FLAGS__") #define DNS_CONFIGURATION_IF_INDEX_KEY CFSTR("__IF_INDEX__") @@ -116,8 +111,8 @@ add_dns_resolver_flags(const void *key, const void *value, void *context) uint32_t *resolver_flags = (uint32_t *)context; if (service_is_scoped_only(service)) { - return; -} + return; + } // update resovler flags based on configured (and available) protocols *resolver_flags = dns_resolver_flags_service(service, *resolver_flags); @@ -933,7 +928,7 @@ add_scoped_resolvers(CFMutableArrayRef scoped, // add "Request A/AAAA query" flag(s) dns_resolver_flags = dns_resolver_flags_service(service, 0); if (dns_resolver_flags == 0) { - goto skip; + goto skip; } flags |= dns_resolver_flags; @@ -1418,11 +1413,6 @@ compareDomain(const void *val1, const void *val2, void *context) } } - // must have domain names for any further comparisons - if ((domain1 == NULL) || (domain2 == NULL)) { - return kCFCompareEqualTo; - } - // forward (A, AAAA) domains sort before reverse (PTR) domains rev1 = CFStringHasSuffix(domain1, CFSTR(".arpa")); rev2 = CFStringHasSuffix(domain2, CFSTR(".arpa")); @@ -1670,15 +1660,17 @@ static SCDynamicStoreCallBack dns_configuration_callout; static void dns_configuration_changed(CFMachPortRef port, void *msg, CFIndex size, void *info) { - os_activity_t activity_id; - static const CFStringRef key = CFSTR(_PATH_RESOLVER_DIR); + os_activity_t activity; + static const CFStringRef key = CFSTR(_PATH_RESOLVER_DIR); CFArrayRef keys; Boolean resolvers_now; static Boolean resolvers_save = FALSE; struct stat statbuf; - activity_id = os_activity_start("processing DNS configuration change", - OS_ACTIVITY_FLAG_DEFAULT); + activity = os_activity_create("processing DNS configuration change", + OS_ACTIVITY_CURRENT, + OS_ACTIVITY_FLAG_DEFAULT); + os_activity_scope(activity); resolvers_now = (stat(_PATH_RESOLVER_DIR, &statbuf) == 0); if (!resolvers_save && (resolvers_save == resolvers_now)) { @@ -1698,7 +1690,7 @@ dns_configuration_changed(CFMachPortRef port, void *msg, CFIndex size, void *inf done : - os_activity_end(activity_id); + os_release(activity); return; } diff --git a/Plugins/IPMonitor/dnsAgent.h b/Plugins/IPMonitor/dnsAgent.h new file mode 100644 index 0000000..86598fa --- /dev/null +++ b/Plugins/IPMonitor/dnsAgent.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2015 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@ + */ + +#ifndef DNS_AGENT_H +#define DNS_AGENT_H + +#import "configAgent.h" + +@interface DNSAgent : ConfigAgent + +@end + +#endif /* DNS_AGENT_H */ diff --git a/Plugins/IPMonitor/dnsAgent.m b/Plugins/IPMonitor/dnsAgent.m new file mode 100644 index 0000000..cbda2c4 --- /dev/null +++ b/Plugins/IPMonitor/dnsAgent.m @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2015, 2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * 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 "configAgent.h" + +@interface DNSAgent:ConfigAgent + +@property (nonatomic) AgentType internalAgentType; +@property (nonatomic) NSString *internalAgentName; +@property (nonatomic) AgentSubType internalAgentSubType; + +@end + +@implementation DNSAgent + +@synthesize agentUUID; +@synthesize agentDescription; + ++ (NSString *)agentType +{ + return @kConfigAgentTypeDNS; +} + +- (instancetype)initWithParameters:(NSDictionary *)parameters +{ + self = [super initWithParameters:parameters]; + if (self) { + NSString *intf = [parameters valueForKey:@kEntityName]; + NSNumber *subType = [parameters valueForKey:@kAgentSubType]; + NSString *type = [[self class] agentType]; + + if ([subType unsignedIntegerValue] == kAgentSubTypeMulticast) { + type = @kConfigAgentTypeDNSMulticast; + } else if ([subType unsignedIntegerValue] == kAgentSubTypePrivate) { + type = @kConfigAgentTypeDNSPrivate; + } + + _internalAgentName = [NSString stringWithFormat:@"%@-%@", type, intf]; + _internalAgentSubType = [subType unsignedIntegerValue]; + _internalAgentType = kAgentTypeDNS; + + agentDescription = _internalAgentName; + agentUUID = [super createUUIDForName:agentDescription]; + if (agentUUID == nil) { + agentUUID = [NSUUID UUID]; + } + } + + return self; +} + +- (AgentType)getAgentType +{ + return _internalAgentType; +} + +- (NSString *)getAgentName +{ + return _internalAgentName; +} + +- (AgentSubType)getAgentSubType +{ + return _internalAgentSubType; +} + +- (NSUUID *)getAgentUUID +{ + return agentUUID; +} + +@end \ No newline at end of file diff --git a/Plugins/IPMonitor/ip_plugin.c b/Plugins/IPMonitor/ip_plugin.c index fd8bed8..4270658 100644 --- a/Plugins/IPMonitor/ip_plugin.c +++ b/Plugins/IPMonitor/ip_plugin.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2015 Apple Inc. All Rights Reserved. + * Copyright (c) 2000-2016 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -86,6 +86,7 @@ #include #include #include +#include #include #include #include @@ -98,7 +99,7 @@ #include #include #include -#include /* for SCLog() */ +#include #include "SCNetworkReachabilityInternal.h" #include "SCNetworkSignaturePrivate.h" #include @@ -107,24 +108,24 @@ #include #include -#ifndef kDNSServiceCompMulticastDNS -#define kDNSServiceCompMulticastDNS "MulticastDNS" -#endif -#ifndef kDNSServiceCompPrivateDNS -#define kDNSServiceCompPrivateDNS "PrivateDNS" -#endif +#include + #include -#include "network_information_priv.h" +#include "network_state_information_priv.h" #include "network_information_server.h" #include #include "ip_plugin.h" -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR #include "set-hostname.h" -#endif /* !TARGET_IPHONE_SIMULATOR */ +#endif /* !TARGET_OS_SIMULATOR */ #include "dns-configuration.h" #include "proxy-configuration.h" +#if !TARGET_OS_SIMULATOR +#include "agent-monitor.h" +#endif // !TARGET_OS_SIMULATOR + #if !TARGET_OS_IPHONE #include "smb-configuration.h" #endif /* !TARGET_OS_IPHONE */ @@ -149,6 +150,28 @@ enum { typedef unsigned int IFIndex; + +#pragma mark - +#pragma mark Logging + + +__private_extern__ os_log_t +__log_IPMonitor() +{ + static os_log_t log = NULL; + + if (log == NULL) { + log = os_log_create("com.apple.SystemConfiguration", "IPMonitor"); + } + + return log; +} + + +#pragma mark - +#pragma mark interface index + + #ifndef TEST_ROUTELIST #define ROUTELIST_DEBUG(flag, fmt, ...) @@ -306,6 +329,9 @@ lo0_ifindex(void) } +#pragma mark - + + /* * Property: kServiceOptionRankAssertion * Purpose: @@ -367,6 +393,7 @@ typedef struct { } Route, * RouteRef; #define PREFIX_LENGTH_IN_CLASSC 24 +#define PREFIX_LENGTH_IN_CLASSD 4 typedef struct { ROUTE_COMMON @@ -553,10 +580,6 @@ static Boolean S_IPMonitor_verbose = FALSE; /* are we netbooted? If so, don't touch the default route */ static boolean_t S_netboot = FALSE; -/* is scoped routing enabled? */ -static boolean_t S_scopedroute = FALSE; -static boolean_t S_scopedroute_v6 = FALSE; - /* dictionary to hold per-service state: key is the serviceID */ static CFMutableDictionaryRef S_service_state_dict = NULL; static CFMutableDictionaryRef S_ipv4_service_rank_dict = NULL; @@ -589,11 +612,11 @@ static CFStringRef S_setup_service_prefix = NULL; static CFStringRef S_multicast_resolvers = NULL; static CFStringRef S_private_resolvers = NULL; -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR static IPv4RouteListRef S_ipv4_routelist = NULL; static IPv6RouteListRef S_ipv6_routelist = NULL; -#endif /* !TARGET_IPHONE_SIMULATOR */ +#endif /* !TARGET_OS_SIMULATOR */ static boolean_t S_append_state = FALSE; @@ -756,8 +779,17 @@ static GetEntityChangesFunc get_proxies_changes; static GetEntityChangesFunc get_smb_changes; #endif /* !TARGET_OS_IPHONE */ -static void -my_CFRelease(void * t); +static __inline__ void +my_CFRelease(void * t) +{ + void * * obj = (void * *)t; + + if (obj && *obj) { + CFRelease(*obj); + *obj = NULL; + } + return; +} static void my_CFArrayAppendUniqueValue(CFMutableArrayRef arr, CFTypeRef new); @@ -968,7 +1000,7 @@ S_is_network_boot() static int rtm_seq = 0; -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR static int open_routing_socket(void) { @@ -1024,37 +1056,7 @@ siocdrdel_in6(int s, int if_index, const struct in6_addr * addr) return (ioctl(s, SIOCDRDEL_IN6, &dr)); } -#endif /* !TARGET_IPHONE_SIMULATOR */ - -static boolean_t -S_is_scoped_routing_enabled() -{ - int scopedroute = 0; - size_t len = sizeof(scopedroute); - - if ((sysctlbyname("net.inet.ip.scopedroute", - &scopedroute, &len, - NULL, 0) == -1) - && (errno != ENOENT)) { - my_log(LOG_ERR, "sysctlbyname() failed: %s", strerror(errno)); - } - return (scopedroute); -} - -static boolean_t -S_is_scoped_v6_routing_enabled() -{ - int scopedroute_v6 = 0; - size_t len = sizeof(scopedroute_v6); - - if ((sysctlbyname("net.inet6.ip6.scopedroute", - &scopedroute_v6, &len, - NULL, 0) == -1) - && (errno != ENOENT)) { - my_log(LOG_ERR, "sysctlbyname() failed: %s", strerror(errno)); - } - return (scopedroute_v6); -} +#endif /* !TARGET_OS_SIMULATOR */ static void my_CFArrayAppendUniqueValue(CFMutableArrayRef arr, CFTypeRef new) @@ -1094,18 +1096,6 @@ my_CFArrayCreateCombinedArray(CFArrayRef array1, CFArrayRef array2) return (combined); } -static void -my_CFRelease(void * t) -{ - void * * obj = (void * *)t; - - if (obj && *obj) { - CFRelease(*obj); - *obj = NULL; - } - return; -} - static CFDictionaryRef my_CFDictionaryGetDictionary(CFDictionaryRef dict, CFStringRef key) { @@ -1482,7 +1472,7 @@ RouteListGetFirstRoute(RouteListInfoRef info, RouteListRef routes) return (RouteListGetRouteAtIndexSimple(info, routes, 0)); } -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR static CFIndex RouteListRouteIndex(RouteListInfoRef info, RouteListRef routes, RouteRef route) @@ -1491,7 +1481,7 @@ RouteListRouteIndex(RouteListInfoRef info, RouteListRef routes, - (void *)RouteListGetFirstRoute(info, routes)) / info->element_size); } -#endif /* !TARGET_IPHONE_SIMULATOR */ +#endif /* !TARGET_OS_SIMULATOR */ static RouteRef RouteGetNextRoute(RouteListInfoRef info, RouteRef route) @@ -1594,12 +1584,13 @@ RouteListAddRoute(RouteListInfoRef info, cmp = RouteCompare(info, this_route, this_rank, scan, scan->rank, &same_dest); - if (same_dest == TRUE && first_scan == NULL) { + if (same_dest && (first_scan == NULL)) { first_scan = scan; } if (cmp < 0) { if (where == kCFNotFound) { - if (same_dest == TRUE + if (same_dest + && (first_scan != NULL) && (first_scan->flags & kRouteFlagsIsScoped) == 0) { if ((scan->flags & kRouteFlagsIsScoped) != 0) { ROUTELIST_DEBUG(kDebugFlag8, @@ -1671,7 +1662,7 @@ RouteListAddRoute(RouteListInfoRef info, goto done; } else { - if (same_dest == TRUE) { + if (same_dest) { if (scope_which == kScopeNone) { ROUTELIST_DEBUG(kDebugFlag8, "Hit 6: set scope on self\n"); scope_which = kScopeThis; @@ -1822,7 +1813,7 @@ RouteAddFlagsToDescription(RouteRef r, CFMutableStringRef str) return; } -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR static RouteRef RouteListFindRoute(RouteListInfoRef info, RouteListRef routes, RouteRef route) { @@ -1969,7 +1960,7 @@ RouteProcess(RouteRef route, kRouteCommandAdd, context); context->depth--; - if (added == FALSE) { + if (!added) { (*route_log)(LOG_NOTICE, route, "failed to add"); return (FALSE); } @@ -2168,7 +2159,7 @@ RouteListFinalize(RouteListInfoRef info, RouteListRef routes) } return; } -#endif /* !TARGET_IPHONE_SIMULATOR */ +#endif /* !TARGET_OS_SIMULATOR */ /** ** IPv4Route* @@ -2455,10 +2446,6 @@ IPv4RouteApply(RouteRef r_route, int cmd, int sockfd) /* don't touch the default route */ return (EROUTENOTAPPLIED); } - if ((route->flags & kRouteFlagsIsScoped) != 0 - && !S_scopedroute) { - return (EROUTENOTAPPLIED); - } if ((route->flags & kRouteFlagsIsNULL) != 0) { return (EROUTENOTAPPLIED); } @@ -2574,7 +2561,7 @@ static const RouteListInfo IPv4RouteListInfo = { IPV4_ROUTE_ALL_BITS_SET }; -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR static __inline__ void IPv4RouteListLog(int level, IPv4RouteListRef routes) { @@ -2601,7 +2588,7 @@ IPv4RouteListFinalize(IPv4RouteListRef routes) RouteListFinalize(&IPv4RouteListInfo, (RouteListRef)routes); return; } -#endif /* !TARGET_IPHONE_SIMULATOR */ +#endif /* !TARGET_OS_SIMULATOR */ #ifdef TEST_IPV4_ROUTELIST static IPv4RouteListRef @@ -2625,8 +2612,7 @@ plist_get_string(CFDictionaryRef dict, CFStringRef prop_name, if (isA_CFString(val) == NULL) { return (NULL); } - if (CFStringGetCString(val, buf, buf_size, kCFStringEncodingUTF8) - == FALSE) { + if (!CFStringGetCString(val, buf, buf_size, kCFStringEncodingUTF8)) { return (NULL); } return (val); @@ -2664,7 +2650,7 @@ AddIPv4Route(const void * value, void * context) } goto skip; } - if (IPv4RouteSetPrefixLength(r) == FALSE) { + if (!IPv4RouteSetPrefixLength(r)) { my_log(LOG_NOTICE, "%s route has invalid subnet mask, %@", ctx->descr, dict); goto skip; @@ -2789,29 +2775,23 @@ IPv4RouteListCreateWithDictionary(IPv4RouteListRef routes, return (NULL); } allow_additional_routes = confirm_interface_name(dict, ifname_cf); - if (dict_get_ip(dict, kSCPropNetIPv4Router, &router) == FALSE) { + if (!dict_get_ip(dict, kSCPropNetIPv4Router, &router)) { (void)dict_get_first_ip(dict, kSCPropNetIPv4DestAddresses, &router); } if (dict_get_first_ip(dict, kSCPropNetIPv4Addresses, &addr) && dict_get_first_ip(dict, kSCPropNetIPv4SubnetMasks, &mask)) { /* subnet route */ subnet = subnet_addr(addr, mask); - /* ignore link-local subnets, let IPConfiguration handle them for now */ - if (ntohl(subnet.s_addr) != IN_LINKLOCALNETNUM) { - prefix_length = mask_get_prefix_length(mask); - if (prefix_length < 0) { - my_log(LOG_NOTICE, - "ignoring bad subnet mask " - IP_FORMAT " on %s", - IP_LIST(&mask), ifname); - } - else { - add_subnet = TRUE; - n++; - } + prefix_length = mask_get_prefix_length(mask); + if (prefix_length < 0) { + my_log(LOG_NOTICE, + "ignoring bad subnet mask " + IP_FORMAT " on %s", + IP_LIST(&mask), ifname); } - else if (router.s_addr == 0) { - exclude_from_nwi = TRUE; + else { + add_subnet = TRUE; + n++; } } if (addr.s_addr == 0) { @@ -2885,12 +2865,8 @@ IPv4RouteListCreateWithDictionary(IPv4RouteListRef routes, add_default = TRUE; n++; } -#define UTUN_PREFIX "utun" -#define UTUN_PREFIX_LENGTH (sizeof(UTUN_PREFIX) - 1) - if (strncmp(ifname, UTUN_PREFIX, UTUN_PREFIX_LENGTH) != 0) { - add_broadcast_multicast = TRUE; - n += 2; - } + add_broadcast_multicast = TRUE; + n += 2; } if (allow_additional_routes) { additional_routes @@ -2955,13 +2931,13 @@ IPv4RouteListCreateWithDictionary(IPv4RouteListRef routes, r->rank = primary_rank; r++; - /* add local net multicast route (rdar://problem/22184650) */ + /* add multicast route (rdar://problem/26457121) */ if ((flags & kRouteFlagsIsNULL) != 0) { r->flags |= kRouteFlagsIsNULL; } r->dest.s_addr = htonl(INADDR_UNSPEC_GROUP); - r->mask.s_addr = htonl(IN_CLASSC_NET); - r->prefix_length = PREFIX_LENGTH_IN_CLASSC; + r->mask.s_addr = htonl(IN_CLASSD_NET); + r->prefix_length = PREFIX_LENGTH_IN_CLASSD; r->ifindex = ifindex; r->ifa = addr; r->rank = primary_rank; @@ -3358,7 +3334,7 @@ IPv6RouteListCreateWithDictionary(IPv6RouteListRef routes, return (NULL); } allow_additional_routes = confirm_interface_name(dict, ifname_cf); - if (dict_get_ipv6(dict, kSCPropNetIPv6Router, &router) == FALSE) { + if (!dict_get_ipv6(dict, kSCPropNetIPv6Router, &router)) { (void)dict_get_first_ipv6(dict, kSCPropNetIPv6DestAddresses, &router); } if (dict_get_first_ipv6(dict, kSCPropNetIPv6Addresses, &addr)) { @@ -3480,9 +3456,7 @@ IPv6RouteListCreateWithDictionary(IPv6RouteListRef routes, r->gateway = addr; } r->rank = primary_rank; - if (S_scopedroute_v6) { - r->flags |= kRouteFlagsKernelManaged; - } + r->flags |= kRouteFlagsKernelManaged; r++; } @@ -3626,10 +3600,6 @@ IPv6RouteApply(RouteRef r_route, int cmd, int sockfd) void * ptr; } rtaddr; - if ((route->flags & kRouteFlagsIsScoped) != 0 - && !S_scopedroute_v6) { - return (EROUTENOTAPPLIED); - } if ((route->flags & kRouteFlagsKernelManaged) != 0) { /* the kernel manages this route, don't touch it */ return (EROUTENOTAPPLIED); @@ -3762,7 +3732,7 @@ IPv6RouteListAddRouteList(IPv6RouteListRef routes, int init_size, } #endif /* TEST_IPV6_ROUTELIST */ -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR static __inline__ void IPv6RouteListLog(int level, IPv6RouteListRef routes) { @@ -3789,7 +3759,7 @@ IPv6RouteListApply(IPv6RouteListRef old_routes, IPv6RouteListRef new_routes, sockfd); return; } -#endif /* !TARGET_IPHONE_SIMULATOR */ +#endif /* !TARGET_OS_SIMULATOR */ /* * Function: parse_component @@ -3810,7 +3780,7 @@ parse_component(CFStringRef key, CFStringRef prefix) CFMutableStringRef comp; CFRange range; - if (CFStringHasPrefix(key, prefix) == FALSE) { + if (!CFStringHasPrefix(key, prefix)) { return (NULL); } comp = CFStringCreateMutableCopy(NULL, 0, key); @@ -3994,7 +3964,7 @@ service_dict_set(CFStringRef serviceID, CFStringRef entity, } } else { - if (old_val == NULL || CFEqual(new_val, old_val) == FALSE) { + if (old_val == NULL || !CFEqual(new_val, old_val)) { if ((S_IPMonitor_debug & kDebugFlag1) != 0) { log_service_entity(LOG_DEBUG, serviceID, entity, CFSTR("Changed: old"), old_val); @@ -4057,7 +4027,7 @@ copy_dhcp_hostname(CFStringRef serviceID) return (hostname); } -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR static struct in6_addr * ipv6_service_get_router(CFDictionaryRef service, @@ -4145,7 +4115,7 @@ ipv6_service_update_router(CFStringRef serviceID, CFDictionaryRef new_service) done: return; } -#endif /* !TARGET_IPHONE_SIMULATOR */ +#endif /* !TARGET_OS_SIMULATOR */ #define ALLOW_EMPTY_STRING 0x1 @@ -4480,9 +4450,9 @@ get_ipv6_changes(CFStringRef serviceID, CFDictionaryRef state_dict, dict = IPDictCreate(AF_INET6, state_dict, setup_dict, rank_assertion); done: -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR ipv6_service_update_router(serviceID, dict); -#endif /* !TARGET_IPHONE_SIMULATOR */ +#endif /* !TARGET_OS_SIMULATOR */ changed = service_dict_set(serviceID, kSCEntNetIPv6, dict); if (dict == NULL) { /* clean up the rank too */ @@ -4577,14 +4547,99 @@ accumulate_dns_servers(CFArrayRef in_servers, ProtocolFlags active_protos, return; } +static CF_RETURNS_RETAINED CFArrayRef +order_dns_servers(CFArrayRef servers, ProtocolFlags active_protos) +{ + Boolean favor_v4 = FALSE; + CFMutableArrayRef ordered_servers; + ProtocolFlags proto_last = kProtocolFlagsIPv4; + struct sockaddr_in v4_dns1 = { .sin_family = AF_INET, + .sin_len = sizeof(struct sockaddr_in) }; + CFIndex v4_n = 0; + struct sockaddr_in6 v6_dns1 = { .sin6_family = AF_INET6, + .sin6_len = sizeof(struct sockaddr_in6), + .sin6_scope_id = 0 }; + CFIndex v6_n = 0; + + if (((active_protos & kProtocolFlagsIPv4) == 0) || + ((active_protos & kProtocolFlagsIPv6) == 0)) { + /* only one protocol */ +#ifdef TEST_DNS_ORDER + printf("only one protocol\n"); +#endif // TEST_DNS_ORDER + return CFRetain(servers); + } + + ordered_servers = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + for (CFIndex i = 0, n = CFArrayGetCount(servers); i < n; i++) { + struct in_addr ia; + struct in6_addr ia6; + ProtocolFlags proto; + CFStringRef server; + + server = CFArrayGetValueAtIndex(servers, i); + if (cfstring_to_ip(server, &ia)) { + proto = kProtocolFlagsIPv4; + if (v4_n++ == 0) { + v4_dns1.sin_addr = ia; + } + } else if (cfstring_to_ip6(server, &ia6)) { + proto = kProtocolFlagsIPv6; + if (v6_n++ == 0) { + bcopy(&ia6, &v6_dns1.sin6_addr, sizeof(ia6)); + } + } else { + CFRelease(ordered_servers); + return CFRetain(servers); + } + + if ((i > 0) && (proto != proto_last)) { + /* if the protocol of the server addresses changed */ + if (((proto == kProtocolFlagsIPv4) && (v4_n == 1)) || + ((proto == kProtocolFlagsIPv6) && (v6_n == 1))) { + /* if we now have the 1st server address of another protocol */ + favor_v4 = (sa_dst_compare_no_stats((struct sockaddr *)&v4_dns1, + (struct sockaddr *)&v6_dns1, + 0) >= 0); +#ifdef TEST_DNS_ORDER + char v4_buf[INET_ADDRSTRLEN]; + char v6_buf[INET6_ADDRSTRLEN]; + printf("comparing %s vs %s, favoring %s\n", + inet_ntop(v4_dns1.sin_family, &v4_dns1.sin_addr, v4_buf, sizeof(v4_buf)), + inet_ntop(v6_dns1.sin6_family, &v6_dns1.sin6_addr, v6_buf, sizeof(v6_buf)), + favor_v4 ? "v4" : "v6"); +#endif // TEST_DNS_ORDER + } else { + /* if the server addresses array is randomly mixed */ +#ifdef TEST_DNS_ORDER + printf("v4/v6 not ordered\n"); +#endif // TEST_DNS_ORDER + CFRelease(ordered_servers); + return CFRetain(servers); + } + } + proto_last = proto; + + if ((proto == kProtocolFlagsIPv4) && favor_v4) { + CFArrayInsertValueAtIndex(ordered_servers, v4_n - 1, server); + } else if ((proto == kProtocolFlagsIPv6) && !favor_v4) { + CFArrayInsertValueAtIndex(ordered_servers, v6_n - 1, server); + } else { + CFArrayAppendValue(ordered_servers, server); + } + } + + return ordered_servers; +} + static void -merge_dns_servers(CFMutableDictionaryRef new_dict, - CFArrayRef state_servers, - CFArrayRef setup_servers, - Boolean have_setup, +merge_dns_servers(CFMutableDictionaryRef new_dict, + CFArrayRef state_servers, + CFArrayRef setup_servers, + Boolean have_setup, Boolean trust_state, - ProtocolFlags active_protos, - CFStringRef interface) + ProtocolFlags active_protos, + CFStringRef interface) { CFMutableArrayRef dns_servers; Boolean have_dns_setup = FALSE; @@ -4604,8 +4659,12 @@ merge_dns_servers(CFMutableDictionaryRef new_dict, } if ((CFArrayGetCount(dns_servers) == 0 || S_append_state) && state_servers != NULL) { - accumulate_dns_servers(state_servers, active_protos, + CFArrayRef ordered_servers; + + ordered_servers = order_dns_servers(state_servers, active_protos); + accumulate_dns_servers(ordered_servers, active_protos, dns_servers, NULL); + CFRelease(ordered_servers); } /* @@ -5083,7 +5142,7 @@ get_proxies_changes(CFStringRef serviceID, CFDictionaryRef state_dict, pacURL = CFDictionaryGetValue(new_dict, kSCPropNetProxiesProxyAutoConfigURLString); if (pacURL != NULL) { - if (!isA_CFString(pacURL)) { + if (!isA_CFString(pacURL) || (CFStringGetLength(pacURL) == 0)) { /* if we don't like the PAC URL */ pacEnabled = 0; } @@ -5091,7 +5150,7 @@ get_proxies_changes(CFStringRef serviceID, CFDictionaryRef state_dict, CFStringRef pacJS; pacJS = CFDictionaryGetValue(new_dict, kSCPropNetProxiesProxyAutoConfigJavaScript); - if (!isA_CFString(pacJS)) { + if (!isA_CFString(pacJS) || (CFStringGetLength(pacJS) == 0)) { /* if we don't have (or like) the PAC JavaScript */ pacEnabled = 0; } @@ -5338,6 +5397,36 @@ interface_is_expensive(CFStringRef ifname) return (is_expensive); } +static CFNumberRef +service_rank_entity_get_index(CFDictionaryRef dict, CFStringRef serviceID, + CFStringRef which, uint32_t * ret_val) +{ + CFNumberRef service_index = NULL; + + if (dict != NULL) { + service_index = CFDictionaryGetValue(dict, + kSCPropNetServiceServiceIndex); + service_index = isA_CFNumber(service_index); + } + if (service_index != NULL) { + SInt32 index_val; + + if (!CFNumberGetValue(service_index, kCFNumberSInt32Type, + &index_val) + || index_val <= 0) { + /* ServiceIndex must be >= 1 */ + my_log(LOG_NOTICE, + "%@%@ ServiceIndex %@ is invalid, ignoring", + which, serviceID, service_index); + service_index = NULL; + } + else if (ret_val != NULL) { + *ret_val = (uint32_t)index_val; + } + } + return (service_index); +} + static boolean_t get_rank_changes(CFStringRef serviceID, CFDictionaryRef state_options, CFDictionaryRef setup_options, CFDictionaryRef services_info) @@ -5349,44 +5438,68 @@ get_rank_changes(CFStringRef serviceID, CFDictionaryRef state_options, Boolean rank_assertion_is_set = FALSE; CFStringRef setup_rank = NULL; CFStringRef state_rank = NULL; + CFNumberRef service_index = NULL; - if (state_options != NULL) { + if (setup_options != NULL) { CFBooleanRef coupled; - state_rank - = CFDictionaryGetValue(state_options, kSCPropNetServicePrimaryRank); - state_rank = isA_CFString(state_rank); - coupled = CFDictionaryGetValue(state_options, kIPIsCoupled); + setup_rank + = CFDictionaryGetValue(setup_options, kSCPropNetServicePrimaryRank); + setup_rank = isA_CFString(setup_rank); + coupled = CFDictionaryGetValue(setup_options, kIPIsCoupled); if (isA_CFBoolean(coupled) != NULL && CFBooleanGetValue(coupled)) { ip_is_coupled = TRUE; } + service_index + = service_rank_entity_get_index(setup_options, + serviceID, + kSCDynamicStoreDomainSetup, + NULL); } - if (setup_options != NULL) { + if (state_options != NULL) { CFBooleanRef coupled; - setup_rank - = CFDictionaryGetValue(setup_options, kSCPropNetServicePrimaryRank); - setup_rank = isA_CFString(setup_rank); - coupled = CFDictionaryGetValue(setup_options, kIPIsCoupled); + state_rank + = CFDictionaryGetValue(state_options, kSCPropNetServicePrimaryRank); + state_rank = isA_CFString(state_rank); + coupled = CFDictionaryGetValue(state_options, kIPIsCoupled); if (isA_CFBoolean(coupled) != NULL && CFBooleanGetValue(coupled)) { ip_is_coupled = TRUE; } + if (service_index == NULL) { + service_index + = service_rank_entity_get_index(state_options, + serviceID, + kSCDynamicStoreDomainState, + NULL); + } } - if (ip_is_coupled == FALSE) { + if (!ip_is_coupled) { ip_is_coupled = service_is_expensive(serviceID, services_info); } if (setup_rank != NULL || state_rank != NULL) { /* rank assertion is set on the service */ Rank setup_assertion; + Boolean setup_assertion_is_set = FALSE; Rank state_assertion; Boolean state_assertion_is_set = FALSE; - setup_assertion = PrimaryRankGetRankAssertion(setup_rank, NULL); + setup_assertion = PrimaryRankGetRankAssertion(setup_rank, + &setup_assertion_is_set); state_assertion = PrimaryRankGetRankAssertion(state_rank, &state_assertion_is_set); - if (setup_assertion > state_assertion) { + if (setup_assertion_is_set && state_assertion_is_set) { + if (setup_assertion > state_assertion) { + rank_assertion = setup_assertion; + } + else { + rank_assertion = state_assertion; + } + rank_assertion_is_set = TRUE; + } + else if (setup_assertion_is_set) { rank_assertion = setup_assertion; rank_assertion_is_set = TRUE; } @@ -5396,7 +5509,7 @@ get_rank_changes(CFStringRef serviceID, CFDictionaryRef state_options, } } - if (rank_assertion_is_set == FALSE) { + if (!rank_assertion_is_set) { /* check for a rank assertion on the interface */ CFStringRef interface; @@ -5414,12 +5527,12 @@ get_rank_changes(CFStringRef serviceID, CFDictionaryRef state_options, "serviceID %@ interface %@ rank = %@", serviceID, interface, - (if_rank != NULL) ? if_rank : (CFNumberRef)CFSTR("Not set)")); + (if_rank != NULL) ? (CFTypeRef)if_rank : (CFTypeRef)CFSTR("Not set)")); } } - if (rank_assertion_is_set || ip_is_coupled) { + if (service_index != NULL || rank_assertion_is_set || ip_is_coupled) { new_dict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); @@ -5435,6 +5548,10 @@ get_rank_changes(CFStringRef serviceID, CFDictionaryRef state_options, if (ip_is_coupled) { CFDictionarySetValue(new_dict, kIPIsCoupled, kCFBooleanTrue); } + if (service_index != NULL) { + CFDictionarySetValue(new_dict, kSCPropNetServiceServiceIndex, + service_index); + } } changed = service_dict_set(serviceID, kSCEntNetService, new_dict); my_CFRelease(&new_dict); @@ -5570,7 +5687,7 @@ services_info_copy(SCDynamicStoreRef session, CFArrayRef service_list) return (info); } -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR static boolean_t set_ipv6_default_interface(IFIndex ifindex) @@ -5604,7 +5721,7 @@ done: return (success); } -#endif /* !TARGET_IPHONE_SIMULATOR */ +#endif /* !TARGET_OS_SIMULATOR */ #if !TARGET_OS_IPHONE static __inline__ void @@ -5680,7 +5797,7 @@ set_dns(CFArrayRef val_search_domains, } fclose(f); - rename(VAR_RUN_RESOLV_CONF "-", VAR_RUN_RESOLV_CONF); + (void)rename(VAR_RUN_RESOLV_CONF "-", VAR_RUN_RESOLV_CONF); } return; } @@ -5731,9 +5848,9 @@ update_ipv4(CFStringRef primary, IPv4RouteListRef new_routelist, keyChangeListRef keys) { -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR int sockfd; -#endif /* !TARGET_IPHONE_SIMULATOR */ +#endif /* !TARGET_OS_SIMULATOR */ if (keys != NULL) { if (new_routelist != NULL && primary != NULL) { @@ -5778,7 +5895,7 @@ update_ipv4(CFStringRef primary, } } -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR sockfd = open_routing_socket(); if (sockfd != -1) { /* go through routelist and bind any unbound routes */ @@ -5812,11 +5929,11 @@ update_ipv4(CFStringRef primary, free(S_ipv4_routelist); } S_ipv4_routelist = new_routelist; -#else /* !TARGET_IPHONE_SIMULATOR */ +#else /* !TARGET_OS_SIMULATOR */ if (new_routelist != NULL) { free(new_routelist); } -#endif /* !TARGET_IPHONE_SIMULATOR */ +#endif /* !TARGET_OS_SIMULATOR */ return; } @@ -5833,9 +5950,9 @@ update_ipv6(CFStringRef primary, IPv6RouteListRef new_routelist, keyChangeListRef keys) { -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR int sockfd; -#endif /* !TARGET_IPHONE_SIMULATOR */ +#endif /* !TARGET_OS_SIMULATOR */ if (keys != NULL) { if (new_routelist != NULL && primary != NULL) { @@ -5874,23 +5991,19 @@ update_ipv6(CFStringRef primary, primary); keyChangeListSetValue(keys, S_state_global_ipv6, dict); CFRelease(dict); -#if !TARGET_IPHONE_SIMULATOR - if (S_scopedroute_v6) { - set_ipv6_default_interface(r->ifindex); - } -#endif /* !TARGET_IPHONE_SIMULATOR */ +#if !TARGET_OS_SIMULATOR + set_ipv6_default_interface(r->ifindex); +#endif /* !TARGET_OS_SIMULATOR */ } else { -#if !TARGET_IPHONE_SIMULATOR - if (S_scopedroute_v6) { - set_ipv6_default_interface(0); - } -#endif /* !TARGET_IPHONE_SIMULATOR */ +#if !TARGET_OS_SIMULATOR + set_ipv6_default_interface(0); +#endif /* !TARGET_OS_SIMULATOR */ keyChangeListRemoveValue(keys, S_state_global_ipv6); } } -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR sockfd = open_routing_socket(); if (sockfd != -1) { /* go through routelist and bind any unbound routes */ @@ -5918,11 +6031,11 @@ update_ipv6(CFStringRef primary, free(S_ipv6_routelist); } S_ipv6_routelist = new_routelist; -#else /* !TARGET_IPHONE_SIMULATOR */ +#else /* !TARGET_OS_SIMULATOR */ if (new_routelist != NULL) { free(new_routelist); } -#endif /* !TARGET_IPHONE_SIMULATOR */ +#endif /* !TARGET_OS_SIMULATOR */ return; } @@ -6030,7 +6143,7 @@ update_nwi(nwi_state_t state) my_log(LOG_INFO, "Updating network information"); S_nwi_state_dump(state); - if (_nwi_state_store(state) == FALSE) { + if (!_nwi_state_store(state)) { my_log(LOG_ERR, "Notifying nwi_state_store failed"); } @@ -6111,12 +6224,26 @@ update_smb(CFDictionaryRef services_info, #endif /* !TARGET_OS_IPHONE */ static Rank -get_service_rank(CFArrayRef order, CFIndex n_order, CFStringRef serviceID) +get_service_index(CFDictionaryRef rank_entity, + CFArrayRef order, CFIndex n_order, CFStringRef serviceID) { CFIndex i; Rank rank = kRankIndexMask; - - if (serviceID != NULL && order != NULL && n_order > 0) { + CFNumberRef service_index; + + service_index + = service_rank_entity_get_index(rank_entity, + serviceID, + CFSTR(""), + &rank); + if (service_index != NULL) { + /* ServiceIndex specified in service entity */ + rank += n_order; + my_log(LOG_INFO, + "%@ specifies ServiceIndex %@, effective index is %d", + serviceID, service_index, rank); + } + else if (serviceID != NULL && order != NULL && n_order > 0) { for (i = 0; i < n_order; i++) { CFStringRef s = isA_CFString(CFArrayGetValueAtIndex(order, i)); @@ -6144,12 +6271,16 @@ static Rank rank_dict_get_service_rank(CFDictionaryRef rank_dict, CFStringRef serviceID) { CFNumberRef rank; - Rank rank_val; + Rank rank_val = kRankAssertionDefault; rank_val = RankMake(kRankIndexMask, kRankAssertionDefault); rank = CFDictionaryGetValue(rank_dict, serviceID); if (rank != NULL) { - CFNumberGetValue(rank, kCFNumberSInt32Type, &rank_val); + if (!CFNumberGetValue(rank, kCFNumberSInt32Type, &rank_val)) { + /* if we don't like the rank value */ + rank_val = kRankAssertionDefault; + } + } return (rank_val); } @@ -6485,7 +6616,7 @@ VPNAttributesGet(CFStringRef service_id, kSCPropNetVPNStatus, // IPSecStatus, PPPStatus, VPNStatus (const void **)&num) || !isA_CFNumber(num) || - !CFNumberGetValue(num, kCFNumberSInt32Type, &status)) { + !CFNumberGetValue(num, kCFNumberIntType, &status)) { return; } @@ -6508,7 +6639,7 @@ VPNAttributesGet(CFStringRef service_id, kSCPropNetPPPDialOnDemand, (const void **)&num) && isA_CFNumber(num) && - CFNumberGetValue(num, kCFNumberSInt32Type, &ppp_demand) && + CFNumberGetValue(num, kCFNumberIntType, &ppp_demand) && (ppp_demand != 0)) { *flags |= kSCNetworkReachabilityFlagsConnectionOnTraffic; if (status == PPP_IDLE) { @@ -6712,7 +6843,7 @@ ElectionResultsCandidateNeedsDemotion(ElectionResultsRef other_results, Boolean ret = FALSE; if (other_results == NULL - || candidate->ip_is_coupled == FALSE + || !candidate->ip_is_coupled || RANK_ASSERTION_MASK(candidate->rank) == kRankAssertionNever) { goto done; } @@ -6755,7 +6886,7 @@ get_signature_sha1(CFStringRef signature, CC_SHA1_Init(&ctx); CC_SHA1_Update(&ctx, - signature_data, + CFDataGetBytePtr(signature_data), (CC_LONG)CFDataGetLength(signature_data)); CC_SHA1_Final(sha1, &ctx); @@ -6896,7 +7027,7 @@ ElectionResultsCopyPrimary(ElectionResultsRef results, RouteListRef service_routes; Boolean skip = FALSE; - if (scan->ineligible == FALSE + if (!scan->ineligible && primary == NULL && RANK_ASSERTION_MASK(scan->rank) != kRankAssertionNever) { if (ElectionResultsCandidateNeedsDemotion(other_results, @@ -6938,7 +7069,7 @@ ElectionResultsCopyPrimary(ElectionResultsRef results, primary_is_null = TRUE; } } - else if (scan->ineligible == FALSE) { + else if (!scan->ineligible) { Boolean not_in_iflist; add_reachability_flags_to_candidate(scan, services_info, af); @@ -6977,7 +7108,7 @@ service_dict_get_signature(CFDictionaryRef service_dict) ifname = CFDictionaryGetValue(service_dict, kSCPropInterfaceName); if (isA_CFString(ifname) == NULL - || confirm_interface_name(service_dict, ifname) == FALSE) { + || !confirm_interface_name(service_dict, ifname)) { return (NULL); } return (CFDictionaryGetValue(service_dict, kStoreKeyNetworkSignature)); @@ -6999,6 +7130,7 @@ elect_ip(const void * key, const void * value, void * context) CFStringRef if_name; CFDictionaryRef ipdict; Rank primary_rank; + CFDictionaryRef rank_entity; RouteListUnion routelist; CFDictionaryRef service_dict; @@ -7030,8 +7162,10 @@ elect_ip(const void * key, const void * value, void * context) /* no default route means it's ineligible to become primary */ candidate.ineligible = TRUE; } - candidate.rank = get_service_rank(elect_info->order, elect_info->n_order, - candidate.serviceID); + rank_entity = CFDictionaryGetValue(all_entities_dict, kSCEntNetService); + candidate.rank = get_service_index(rank_entity, + elect_info->order, elect_info->n_order, + candidate.serviceID); if (elect_info->af == AF_INET) { default_rank = routelist.v4->list->rank; candidate.addr.v4 = routelist.v4->list->ifa; @@ -7265,11 +7399,19 @@ get_changed_str(CFStringRef serviceID, CFStringRef entity, return ""; } -#if ! TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR + +#ifdef SIOCSIFORDER +#define MANAGE_IF_ORDER +#define MANAGE_IF_IOCTL +#endif /* SIOCSIFORDER */ #ifdef SIOCSIFNETSIGNATURE #define MANAGE_IF_SIGNATURE +#define MANAGE_IF_IOCTL +#endif /* SIOCSIFNETSIGNATURE */ +#ifdef MANAGE_IF_IOCTL static int inet_dgram_socket(void) { @@ -7282,7 +7424,81 @@ inet_dgram_socket(void) return sockfd; } +#endif /* MANAGE_IF_IOCTL */ + +#ifdef MANAGE_IF_ORDER +static Boolean +interface_order_changed(nwi_state_t old_state, nwi_state_t new_state) +{ + if (old_state == NULL && new_state == NULL) { + // Both are NULL, nothing changed + return FALSE; + } + + if (old_state == NULL || new_state == NULL) { + // One is NULL, something changed + return TRUE; + } + + if (old_state->if_list_count != new_state->if_list_count) { + // Count is different, something changed + return TRUE; + } + + if (new_state->if_list_count == 0) { + // Count is same and 0, nothing changed + return FALSE; + } + + int i; + nwi_ifindex_t *old_scan; + nwi_ifindex_t *new_scan; + for (i = 0, old_scan = nwi_state_if_list(old_state), new_scan = nwi_state_if_list(new_state); + i < new_state->if_list_count; i++, old_scan++, new_scan++) { + if (strcmp(old_state->ifstate_list[*old_scan].ifname, new_state->ifstate_list[*new_scan].ifname) != 0) { + // Some interface in the list is different, something changed + return TRUE; + } + } + + // Count and contents are the same, nothing changed + return FALSE; +} + +static Boolean +update_interface_order(nwi_state_t state, int sockfd) +{ + Boolean success = FALSE; + + // Set interface order into the kernel + struct if_order interface_order; + interface_order.ifo_count = (uint32_t)state->if_list_count; + interface_order.ifo_ordered_indices = calloc((size_t)interface_order.ifo_count, sizeof(uint32_t)); + if (((uint32_t *)interface_order.ifo_ordered_indices) != NULL) { + int i; + nwi_ifindex_t *scan; + for (i = 0, scan = nwi_state_if_list(state); + i < state->if_list_count; i++, scan++) { + const char *ifname = state->ifstate_list[*scan].ifname; + ((uint32_t *)interface_order.ifo_ordered_indices)[i] = my_if_nametoindex(ifname); + } + } + if (ioctl(sockfd, SIOCSIFORDER, &interface_order) != 0) { + my_log(LOG_ERR, "SIOCSIFORDER for %u(%p) failed on %d: %s", interface_order.ifo_count, (void *)interface_order.ifo_ordered_indices, sockfd, strerror(errno)); + } else { + my_log(LOG_INFO, "Set kernel interface order for %u interfaces", interface_order.ifo_count); + success = TRUE; + } + if (((uint32_t *)interface_order.ifo_ordered_indices) != NULL) { + free(interface_order.ifo_ordered_indices); + interface_order.ifo_ordered_indices = NULL; + } + + return success; +} +#endif /* MANAGE_IF_ORDER */ +#ifdef MANAGE_IF_SIGNATURE static int siocsifnetsignature(int s, const char * ifname, int af, const uint8_t * signature, int signature_length) @@ -7379,14 +7595,15 @@ process_state_differences(nwi_state_t state, int af, int sockfd) } return; } +#endif /* MANAGE_IF_SIGNATURE */ -#endif /* SIOCSIFNETSIGNATURE */ - -#endif /* !TARGET_IPHONE_SIMULATOR */ +#endif /* !TARGET_OS_SIMULATOR */ static void process_nwi_changes(CFMutableStringRef log_output, nwi_state_t changes_state, + nwi_state_t new_state, + nwi_state_t old_state, boolean_t dns_changed, boolean_t dnsinfo_changed, CFDictionaryRef old_primary_dns, @@ -7400,9 +7617,15 @@ process_nwi_changes(CFMutableStringRef log_output, if (changes_state != NULL) { const sa_family_t af_list[] = {AF_INET, AF_INET6}; nwi_ifstate_t scan; -#ifdef MANAGE_IF_SIGNATURE +#ifdef MANAGE_IF_IOCTL int sockfd = inet_dgram_socket(); -#endif /* MANAGE_IF_SIGNATURE */ +#endif /* MANAGE_IF_IOCTL */ + +#ifdef MANAGE_IF_ORDER + if (interface_order_changed(new_state, old_state)) { + update_interface_order(new_state, sockfd); + } +#endif /* MANAGE_IF_ORDER */ for (idx = 0; idx < countof(af_list); idx++) { int af = af_list[idx]; @@ -7461,11 +7684,11 @@ process_nwi_changes(CFMutableStringRef log_output, my_CFRelease(&changes); } } -#ifdef MANAGE_IF_SIGNATURE +#ifdef MANAGE_IF_IOCTL if (sockfd >= 0) { close(sockfd); } -#endif /* MANAGE_IF_SIGNATURE */ +#endif /* MANAGE_IF_IOCTL */ } if (dns_changed || dnsinfo_changed) { @@ -7567,6 +7790,9 @@ post_network_change_when_ready() S_network_change_needed); } + + /* We are about to post a network change to everyone, get the agents up to date */ + if ((S_network_change_needed & NETWORK_CHANGE_NET) != 0) { status = notify_post(_SC_NOTIFY_NETWORK_CHANGE_NWI); if (status != NOTIFY_STATUS_OK) { @@ -7576,6 +7802,12 @@ post_network_change_when_ready() } if ((S_network_change_needed & NETWORK_CHANGE_DNS) != 0) { + + +#if !TARGET_OS_SIMULATOR + /* Setup or Update config agents */ + process_AgentMonitor_DNS(); +#endif //!TARGET_OS_SIMULATOR status = notify_post(_SC_NOTIFY_NETWORK_CHANGE_DNS); if (status != NOTIFY_STATUS_OK) { my_log(LOG_ERR, @@ -7584,6 +7816,11 @@ post_network_change_when_ready() } if ((S_network_change_needed & NETWORK_CHANGE_PROXY) != 0) { + +#if !TARGET_OS_SIMULATOR + /* Setup or Update config agents */ + process_AgentMonitor_Proxy(); +#endif //!TARGET_OS_SIMULATOR status = notify_post(_SC_NOTIFY_NETWORK_CHANGE_PROXY); if (status != NOTIFY_STATUS_OK) { my_log(LOG_ERR, @@ -7630,15 +7867,17 @@ post_network_change(uint32_t change) 0, __network_change_queue()); dispatch_source_set_event_handler(S_network_change_timer, ^{ - os_activity_t activity_id; + os_activity_t activity; - activity_id = os_activity_start("posting delayed network change", - OS_ACTIVITY_FLAG_DEFAULT); + activity = os_activity_create("posting delayed network change", + OS_ACTIVITY_CURRENT, + OS_ACTIVITY_FLAG_DEFAULT); + os_activity_scope(activity); S_network_change_timeout = TRUE; post_network_change_when_ready(); - os_activity_end(activity_id); + os_release(activity); }); dispatch_source_set_timer(S_network_change_timer, dispatch_time(DISPATCH_TIME_NOW, @@ -8054,6 +8293,8 @@ IPMonitorProcessChanges(SCDynamicStoreRef session, CFArrayRef changed_keys, network_change_msg = CFStringCreateMutable(NULL, 0); process_nwi_changes(network_change_msg, changes_state, + S_nwi_state, + old_nwi_state, dns_changed, dnsinfo_changed, old_primary_dns, @@ -8115,23 +8356,28 @@ IPMonitorNotify(SCDynamicStoreRef session, CFArrayRef changed_keys, return; } -static void -watch_proxies() -{ #if !TARGET_OS_IPHONE - const _scprefs_observer_type type = scprefs_observer_type_mcx; +#define PROXY_GLOBAL_OBSERVER_TYPE scprefs_observer_type_mcx #else - const _scprefs_observer_type type = scprefs_observer_type_global; +#define PROXY_GLOBAL_OBSERVER_TYPE scprefs_observer_type_global #endif + +static void +watch_proxies() +{ static dispatch_queue_t proxy_cb_queue; proxy_cb_queue = dispatch_queue_create("com.apple.SystemConfiguration.IPMonitor.proxy", NULL); - _scprefs_observer_watch(type, + _scprefs_observer_watch(PROXY_GLOBAL_OBSERVER_TYPE, "com.apple.SystemConfiguration.plist", proxy_cb_queue, ^{ SCDynamicStoreNotifyValue(NULL, S_state_global_proxies); - notify_post(_SC_NOTIFY_NETWORK_CHANGE_PROXY); +#if !TARGET_OS_SIMULATOR + /* Setup or Update config agents */ + process_AgentMonitor_Proxy(); +#endif //!TARGET_OS_SIMULATOR + (void)notify_post(_SC_NOTIFY_NETWORK_CHANGE_PROXY); my_log(LOG_INFO, "Notifying:\n%@", S_state_global_proxies); }); @@ -8140,12 +8386,6 @@ watch_proxies() #include "IPMonitorControlPrefs.h" -__private_extern__ SCLoggerRef -my_log_get_logger() -{ - return (S_IPMonitor_logger); -} - static void prefs_changed(__unused SCPreferencesRef prefs) { @@ -8173,7 +8413,7 @@ my_log_init() } -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR static int flush_routes(int s) { @@ -8259,14 +8499,14 @@ flush_inet_routes(void) } } -#else /* !TARGET_IPHONE_SIMULATOR */ +#else /* !TARGET_OS_SIMULATOR */ static void flush_inet_routes(void) { } -#endif /* !TARGET_IPHONE_SIMULATOR */ +#endif /* !TARGET_OS_SIMULATOR */ @@ -8286,14 +8526,6 @@ ip_plugin_init() flush_inet_routes(); } - if (S_is_scoped_routing_enabled() != 0) { - S_scopedroute = TRUE; - } - - if (S_is_scoped_v6_routing_enabled() != 0) { - S_scopedroute_v6 = TRUE; - } - S_session = SCDynamicStoreCreate(NULL, CFSTR("IPMonitor"), IPMonitorNotify, NULL); if (S_session == NULL) { @@ -8435,6 +8667,11 @@ prime_IPMonitor() { /* initialize multicast route */ update_ipv4(NULL, NULL, NULL); + +#if !TARGET_OS_SIMULATOR + process_AgentMonitor(); +#endif // !TARGET_OS_SIMULATOR + return; } @@ -8452,18 +8689,20 @@ S_get_plist_boolean(CFDictionaryRef plist, CFStringRef key, return (ret); } -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR #include "IPMonitorControlServer.h" static void InterfaceRankChanged(void * info) { - os_activity_t activity_id; + os_activity_t activity; CFDictionaryRef assertions = NULL; CFArrayRef changes; - activity_id = os_activity_start("processing IPMonitor [rank] change", - OS_ACTIVITY_FLAG_DEFAULT); + activity = os_activity_create("processing IPMonitor [rank] change", + OS_ACTIVITY_CURRENT, + OS_ACTIVITY_FLAG_DEFAULT); + os_activity_scope(activity); changes = IPMonitorControlServerCopyInterfaceRankInformation(&assertions); if (S_if_rank_dict != NULL) { @@ -8475,7 +8714,7 @@ InterfaceRankChanged(void * info) CFRelease(changes); } - os_activity_end(activity_id); + os_release(activity); return; } @@ -8489,8 +8728,9 @@ StartIPMonitorControlServer(void) bzero(&context, sizeof(context)); context.perform = InterfaceRankChanged; rls = CFRunLoopSourceCreate(NULL, 0, &context); - if (IPMonitorControlServerStart(CFRunLoopGetCurrent(), rls, - &S_bundle_logging_verbose) == FALSE) { + if (!IPMonitorControlServerStart(CFRunLoopGetCurrent(), + rls, + &S_bundle_logging_verbose)) { my_log(LOG_ERR, "IPMonitorControlServerStart failed"); } else { @@ -8501,7 +8741,7 @@ StartIPMonitorControlServer(void) return; } -#endif /* !TARGET_IPHONE_SIMULATOR */ +#endif /* !TARGET_OS_SIMULATOR */ __private_extern__ void @@ -8530,7 +8770,6 @@ load_IPMonitor(CFBundleRef bundle, Boolean bundleVerbose) prefs_changed(NULL); load_DNSConfiguration(bundle, // bundle - S_IPMonitor_logger, // SCLogger ^(Boolean inSync) { // syncHandler dispatch_async(__network_change_queue(), ^{ S_dnsinfo_synced = inSync; @@ -8547,14 +8786,13 @@ load_IPMonitor(CFBundleRef bundle, Boolean bundleVerbose) }); load_NetworkInformation(bundle, // bundle - S_IPMonitor_logger, // SCLogger ^(Boolean inSync) { // syncHandler dispatch_async(__network_change_queue(), ^{ S_nwi_synced = inSync; post_network_change_when_ready(); }); }); -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR StartIPMonitorControlServer(); #endif /* !TARGET_OS_IPHONE */ @@ -8570,9 +8808,9 @@ load_IPMonitor(CFBundleRef bundle, Boolean bundleVerbose) } #endif /* !TARGET_OS_IPHONE */ -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR load_hostname(TRUE); -#endif /* !TARGET_IPHONE_SIMULATOR */ +#endif /* !TARGET_OS_SIMULATOR */ #if !TARGET_OS_IPHONE load_smb_configuration(TRUE); @@ -8588,12 +8826,6 @@ load_IPMonitor(CFBundleRef bundle, Boolean bundleVerbose) #ifdef TEST_IPMONITOR -#include "dns-configuration.c" - -#if !TARGET_IPHONE_SIMULATOR -#include "set-hostname.c" -#endif /* !TARGET_IPHONE_SIMULATOR */ - int main(int argc, char **argv) { @@ -8615,8 +8847,6 @@ main(int argc, char **argv) #endif /* TEST_IPMONITOR */ #ifdef TEST_ROUTELIST -#include "dns-configuration.c" -#include "set-hostname.c" struct route { const char * dest; @@ -9410,9 +9640,8 @@ main(int argc, char **argv) if (argc > 1) { S_IPMonitor_debug = strtoul(argv[1], NULL, 0); } - S_scopedroute = (argc < 3); for (test = ipv4_tests; *test != NULL; test++) { - if (routelist_build_test(*test) == FALSE) { + if (!routelist_build_test(*test)) { fprintf(stderr, "%s failed\n", (*test)->name); exit(1); } @@ -10077,9 +10306,8 @@ main(int argc, char **argv) if (argc > 1) { S_IPMonitor_debug = strtoul(argv[1], NULL, 0); } - S_scopedroute_v6 = (argc < 3); for (test = ipv6_tests; *test != NULL; test++) { - if (routelist_build_test(*test) == FALSE) { + if (!routelist_build_test(*test)) { fprintf(stderr, "%s failed\n", (*test)->name); exit(1); } @@ -10107,3 +10335,250 @@ main(int argc, char **argv) #endif /* TEST_IPV6_ROUTELIST */ +#ifdef TEST_DNS_ORDER + +#define kProtocolFlagsIPv4v6 (kProtocolFlagsIPv4 | kProtocolFlagsIPv6) + +#define V4_ADDR_LOOP CFSTR("127.0.0.1") +#define V4_ADDR_1 CFSTR("192.168.1.1") +#define V4_ADDR_2 CFSTR("192.168.1.2") +#define V4_ADDR_3 CFSTR("8.8.8.8") +#define V4_ADDR_4 CFSTR("8.8.4.4") + +#define V6_ADDR_LOOP CFSTR("::1") +#define V6_ADDR_1 CFSTR("fe80::0123:4567:89ab:cdef%en0") +#define V6_ADDR_2 CFSTR("fd00::2acf:e9ff:fe14:8c59") +#define V6_ADDR_3 CFSTR("2001:4860:4860::8888") + +typedef struct { + const char * name; + const ProtocolFlags flags; + const CFStringRef server_addrs[]; +} DNSOrderTest, * DNSOrderTestRef; + +static DNSOrderTest test0a = { + "test0a", + kProtocolFlagsIPv4, + { + V4_ADDR_1, V4_ADDR_2, V4_ADDR_3, V4_ADDR_4, NULL + } +}; + +static DNSOrderTest test0b = { + "test0b", + kProtocolFlagsIPv6, + { + V6_ADDR_1, V6_ADDR_2, V6_ADDR_3, NULL + } +}; + +static DNSOrderTest test1a = { + "test1a", + kProtocolFlagsIPv4v6, + { + V4_ADDR_1, V6_ADDR_1, NULL + } +}; + +static DNSOrderTest test2a = { + "test2a", + kProtocolFlagsIPv4v6, + { + V4_ADDR_1, V6_ADDR_2, NULL + } +}; + +static DNSOrderTest test3a = { + "test3a", + kProtocolFlagsIPv4v6, + { + V4_ADDR_1, V6_ADDR_3, NULL + } +}; + +static DNSOrderTest test1b = { + "test1b", + kProtocolFlagsIPv4v6, + { + V4_ADDR_3, V6_ADDR_1, NULL + } +}; + +static DNSOrderTest test2b = { + "test2b", + kProtocolFlagsIPv4v6, + { + V4_ADDR_3, V6_ADDR_2, NULL + } +}; + +static DNSOrderTest test3b = { + "test3b", + kProtocolFlagsIPv4v6, + { + V4_ADDR_3, V6_ADDR_3, NULL + } +}; + +static DNSOrderTest test1c = { + "test1c", + kProtocolFlagsIPv4v6, + { + V6_ADDR_1, V4_ADDR_1, NULL + } +}; + +static DNSOrderTest test2c = { + "test2c", + kProtocolFlagsIPv4v6, + { + V6_ADDR_2, V4_ADDR_1, NULL + } +}; + +static DNSOrderTest test3c = { + "test3c", + kProtocolFlagsIPv4v6, + { + V6_ADDR_3, V4_ADDR_1, NULL + } +}; + +static DNSOrderTest test1d = { + "test1d", + kProtocolFlagsIPv4v6, + { + V6_ADDR_1, V4_ADDR_3, NULL + } +}; + +static DNSOrderTest test2d = { + "test2d", + kProtocolFlagsIPv4v6, + { + V6_ADDR_2, V4_ADDR_3, NULL + } +}; + +static DNSOrderTest test3d = { + "test3d", + kProtocolFlagsIPv4v6, + { + V6_ADDR_3, V4_ADDR_3, NULL + } +}; + +static DNSOrderTest test4 = { + "test4", + kProtocolFlagsIPv4v6, + { + V4_ADDR_LOOP, V4_ADDR_3, V6_ADDR_2, NULL + } +}; + +static DNSOrderTest test5 = { + "test5", + kProtocolFlagsIPv4v6, + { + V4_ADDR_3, V6_ADDR_LOOP, V6_ADDR_2, NULL + } +}; + +static DNSOrderTest test6 = { + "test6", + kProtocolFlagsIPv4v6, + { + V4_ADDR_1, V4_ADDR_2, V4_ADDR_3, V4_ADDR_4, V6_ADDR_1, V6_ADDR_2, V6_ADDR_3, NULL + } +}; + +static DNSOrderTest test7 = { + "test7", + kProtocolFlagsIPv4v6, + { + V4_ADDR_1, V6_ADDR_1, V4_ADDR_3, V6_ADDR_2, NULL + } +}; + +static DNSOrderTestRef dns_order_tests[] = { + &test0a, &test0b, + &test1a, &test2a, &test3a, + &test1b, &test2b, &test3b, + &test1c, &test2c, &test3c, + &test1d, &test2d, &test3d, + &test4, + &test5, + &test6, + &test7, + NULL +}; + +#define EMPHASIS_CHARS "=================" + +static void +apply_order(CFArrayRef servers, ProtocolFlags flags) +{ + CFArrayRef ordered_servers; + + ordered_servers = order_dns_servers(servers, flags); + if (ordered_servers != NULL) { + SCPrint(TRUE, stdout, CFSTR("After :\n%@\n"), ordered_servers); + CFRelease(ordered_servers); + } else { + printf("FAIL: No ordered servers\n"); + } + + return; +} + +static void +apply_test(DNSOrderTestRef test) +{ + CFMutableArrayRef servers; + + printf("\n" EMPHASIS_CHARS "> '%s' Begin <" EMPHASIS_CHARS "\n\n", test->name); + + servers = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + for (int i = 0; test->server_addrs[i] != NULL; i++) { + CFStringRef server_addr = test->server_addrs[i]; + + CFArrayAppendValue(servers, server_addr); + } + + SCPrint(TRUE, stdout, CFSTR("Before :\n%@\n"), servers); + + apply_order(servers, test->flags); + + CFRelease(servers); + + return; +} + +int +main(int argc, char **argv) +{ + _sc_log = FALSE; + _sc_verbose = (argc > 1) ? TRUE : FALSE; + S_IPMonitor_debug = kDebugFlag1 | kDebugFlag2 | kDebugFlag4; + if (argc > 1) { + S_IPMonitor_debug = (uint32)strtoul(argv[1], NULL, 0); + } + + 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); + } + + exit(0); + return (0); +} + +#endif /* TEST_DNS_ORDER */ diff --git a/Plugins/IPMonitor/ip_plugin.h b/Plugins/IPMonitor/ip_plugin.h index 2f85dd1..85e4727 100644 --- a/Plugins/IPMonitor/ip_plugin.h +++ b/Plugins/IPMonitor/ip_plugin.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2015 Apple Inc. All Rights Reserved. + * Copyright (c) 2012-2016 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -29,9 +29,10 @@ #ifndef _IP_PLUGIN_H #define _IP_PLUGIN_H +#include #include +#include #include -#include #ifdef TEST_IPV4_ROUTELIST #define TEST_ROUTELIST @@ -48,15 +49,18 @@ #define kIsNULL CFSTR("IsNULL") /* CFBoolean */ #ifdef TEST_ROUTELIST -#define my_log(__level, fmt, ...) SCPrint(TRUE, stdout, CFSTR(fmt "\n"), ## __VA_ARGS__) + +#define my_log(__level, __format, ...) SCPrint(TRUE, stdout, CFSTR(__format "\n"), ## __VA_ARGS__) #else /* TEST_ROUTELIST */ -#define my_log(__level, fmt, ...) SCLoggerLog(my_log_get_logger(), __level, CFSTR(fmt), ## __VA_ARGS__) -SCLoggerRef my_log_get_logger(); +#define my_log(__level, __format, ...) SC_log(__level, __format, ## __VA_ARGS__) #endif /* TEST_ROUTELIST */ +os_log_t +__log_IPMonitor(); + boolean_t cfstring_to_ip(CFStringRef str, struct in_addr * ip_p); diff --git a/Plugins/IPMonitor/proxy-configuration.c b/Plugins/IPMonitor/proxy-configuration.c index 3645ad3..05dc0ae 100644 --- a/Plugins/IPMonitor/proxy-configuration.c +++ b/Plugins/IPMonitor/proxy-configuration.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014 Apple Inc. All rights reserved. + * Copyright (c) 2011-2015 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -248,13 +248,13 @@ compareBySearchOrder(const void *val1, const void *val2, void *context) num1 = CFDictionaryGetValue(proxy1, PROXY_MATCH_ORDER_KEY); if (!isA_CFNumber(num1) || - !CFNumberGetValue(num1, kCFNumberIntType, &order1)) { + !CFNumberGetValue(num1, kCFNumberSInt32Type, &order1)) { order1 = DEFAULT_MATCH_ORDER; } num2 = CFDictionaryGetValue(proxy2, PROXY_MATCH_ORDER_KEY); if (!isA_CFNumber(num2) || - !CFNumberGetValue(num2, kCFNumberIntType, &order2)) { + !CFNumberGetValue(num2, kCFNumberSInt32Type, &order2)) { order2 = DEFAULT_MATCH_ORDER; } @@ -264,8 +264,8 @@ compareBySearchOrder(const void *val1, const void *val2, void *context) CFDictionaryGetValueIfPresent(proxy2, ORDER_KEY, (const void **)&num2) && isA_CFNumber(num1) && isA_CFNumber(num2) && - CFNumberGetValue(num1, kCFNumberIntType, &order1) && - CFNumberGetValue(num2, kCFNumberIntType, &order2)) { + CFNumberGetValue(num1, kCFNumberSInt32Type, &order1) && + CFNumberGetValue(num2, kCFNumberSInt32Type, &order2)) { if (order1 == order2) { return kCFCompareEqualTo; } else { @@ -389,8 +389,9 @@ copy_app_layer_vpn_proxies(CFDictionaryRef services, CFArrayRef order, CFDiction CFDictionaryRef proxy; CFDictionaryRef service; CFStringRef serviceID; - CFNumberRef isServiceSpecific; - int boolValue = 0; + CFNumberRef serviceSpecificIdentifier; + int serviceIdentifier = 0; + CFStringRef serviceIdentifierString; serviceID = CFArrayGetValueAtIndex(order, i); service = CFDictionaryGetValue(services, serviceID); @@ -405,15 +406,22 @@ copy_app_layer_vpn_proxies(CFDictionaryRef services, CFArrayRef order, CFDiction continue; } - isServiceSpecific = CFDictionaryGetValue(proxy, kSCPropNetProxiesServiceSpecific); - if (!isA_CFNumber(isServiceSpecific) || !CFNumberGetValue(isServiceSpecific, kCFNumberIntType, &boolValue) || !boolValue) { + serviceSpecificIdentifier = CFDictionaryGetValue(proxy, kSCPropNetProxiesServiceSpecific); + if (!isA_CFNumber(serviceSpecificIdentifier) || + !CFNumberGetValue(serviceSpecificIdentifier, kCFNumberIntType, &serviceIdentifier) || + serviceIdentifier == 0) { // if not a service-specific proxy configuration continue; } + serviceIdentifierString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%u"), serviceIdentifier); + if (serviceIdentifierString == NULL) { + continue; + } if ((app_layer_proxies != NULL) && - CFDictionaryContainsKey(app_layer_proxies, serviceID)) { - // if we've already processed this [app_layer_proxies] interface + CFDictionaryContainsKey(app_layer_proxies, serviceIdentifierString)) { + // if we've already processed this [app_layer_proxies] identifier + CFRelease(serviceIdentifierString); continue; } @@ -428,7 +436,8 @@ copy_app_layer_vpn_proxies(CFDictionaryRef services, CFArrayRef order, CFDiction &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } - CFDictionarySetValue(app_layer_proxies, serviceID, newProxy); + CFDictionarySetValue(app_layer_proxies, serviceIdentifierString, newProxy); + CFRelease(serviceIdentifierString); CFRelease(newProxy); } @@ -532,7 +541,7 @@ add_default_proxy(CFMutableArrayRef proxies, // ensure that the default proxy has a search order if (!isA_CFNumber(order) || - !CFNumberGetValue(order, kCFNumberIntType, &myOrder)) { + !CFNumberGetValue(order, kCFNumberSInt32Type, &myOrder)) { myOrder = DEFAULT_MATCH_ORDER; order = CFNumberCreate(NULL, kCFNumberIntType, &myOrder); CFDictionarySetValue(myDefault, PROXY_MATCH_ORDER_KEY, order); diff --git a/Plugins/IPMonitor/proxy-configuration.h b/Plugins/IPMonitor/proxy-configuration.h index e86bd53..39b02dd 100644 --- a/Plugins/IPMonitor/proxy-configuration.h +++ b/Plugins/IPMonitor/proxy-configuration.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2013 Apple Inc. All rights reserved. + * Copyright (c) 2011-2013, 2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -29,7 +29,7 @@ #include -CFBooleanRef G_supplemental_proxies_follow_dns; +extern CFBooleanRef G_supplemental_proxies_follow_dns; __BEGIN_DECLS diff --git a/Plugins/IPMonitor/proxyAgent.h b/Plugins/IPMonitor/proxyAgent.h new file mode 100644 index 0000000..ecd5e6b --- /dev/null +++ b/Plugins/IPMonitor/proxyAgent.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2015 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@ + */ + +#ifndef PROXY_AGENT_H +#define PROXY_AGENT_H + + +#import "configAgent.h" + +@interface ProxyAgent : ConfigAgent + +@end + +#endif /* PROXY_AGENT_H */ diff --git a/Plugins/IPMonitor/proxyAgent.m b/Plugins/IPMonitor/proxyAgent.m new file mode 100644 index 0000000..96f17e6 --- /dev/null +++ b/Plugins/IPMonitor/proxyAgent.m @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2015, 2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * 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 "configAgent.h" + +@interface ProxyAgent:ConfigAgent + +@property (nonatomic) AgentType internalAgentType; +@property (nonatomic) NSString *internalAgentName; +@property (nonatomic) AgentSubType internalAgentSubType; + +@end + +@implementation ProxyAgent + +@synthesize agentUUID; +@synthesize agentDescription; + ++ (NSString *)agentType +{ + return @kConfigAgentTypeProxy; +} + +- (instancetype)initWithParameters:(NSDictionary *)parameters +{ + self = [super initWithParameters:parameters]; + if (self) { + NSString *intf = [parameters valueForKey:@kEntityName]; + NSNumber *subType = [parameters valueForKey:@kAgentSubType]; + NSString *type = [[self class] agentType]; + + _internalAgentName = [NSString stringWithFormat:@"%@-%@", type, intf]; + _internalAgentSubType = [subType unsignedIntegerValue]; + _internalAgentType = kAgentTypeProxy; + + agentDescription = _internalAgentName; + agentUUID = [super createUUIDForName:agentDescription]; + if (agentUUID == nil) { + agentUUID = [NSUUID UUID]; + } + } + + return self; +} + +- (AgentType)getAgentType +{ + return _internalAgentType; +} + +- (NSString *)getAgentName +{ + return _internalAgentName; +} + +- (AgentSubType)getAgentSubType +{ + return _internalAgentSubType; +} + +- (NSUUID *)getAgentUUID +{ + return agentUUID; +} + +@end \ No newline at end of file diff --git a/Plugins/IPMonitor/set-hostname.c b/Plugins/IPMonitor/set-hostname.c index 2c72f6a..56273de 100644 --- a/Plugins/IPMonitor/set-hostname.c +++ b/Plugins/IPMonitor/set-hostname.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2015 Apple Inc. All rights reserved. + * Copyright (c) 2004-2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -42,7 +42,7 @@ #include #ifdef MAIN -#define my_log(__level, fmt, ...) SCPrint(TRUE, stdout, CFSTR(fmt "\n"), ## __VA_ARGS__) +#define my_log(__level, __format, ...) SCPrint(TRUE, stdout, CFSTR(__format "\n"), ## __VA_ARGS__) #else // MAIN #include "ip_plugin.h" #endif // MAIN @@ -481,14 +481,14 @@ update_hostname(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info) address = copy_primary_ip(store, serviceID); if (address != NULL) { - Boolean ok; - boolean_t isExpensive = FALSE; + boolean_t isExpensive; // start reverse DNS query using primary IP address // if primary service is not expensive isExpensive = check_if_service_expensive(serviceID); + if (!isExpensive) { + Boolean ok; - if (isExpensive == FALSE) { ok = ptr_query_start(address); if (ok) { // if query started @@ -548,7 +548,7 @@ load_hostname(Boolean verbose) SCErrorString(SCError())); goto error; } - + queue = dispatch_queue_create(SET_HOSTNAME_QUEUE, NULL); if (queue == NULL) { my_log(LOG_ERR, diff --git a/Plugins/IPMonitor/smb-configuration.c b/Plugins/IPMonitor/smb-configuration.c index 73e0dfd..34dfc22 100644 --- a/Plugins/IPMonitor/smb-configuration.c +++ b/Plugins/IPMonitor/smb-configuration.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2015 Apple Inc. All rights reserved. + * Copyright (c) 2006-2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -49,10 +49,10 @@ #include // for __CFStringGetInstallationEncodingAndRegion() #include #include -#include // for SCLog(), SCPrint() +#include #ifdef MAIN -#define my_log(__level, fmt, ...) SCPrint(TRUE, stdout, CFSTR(fmt "\n"), ## __VA_ARGS__) +#define my_log(__level, __format, ...) SCPrint(TRUE, stdout, CFSTR(__format "\n"), ## __VA_ARGS__) #else // MAIN #include "ip_plugin.h" #endif // MAIN diff --git a/Plugins/InterfaceNamer/Info.plist b/Plugins/InterfaceNamer/Info.plist index dfaf270..79321b7 100644 --- a/Plugins/InterfaceNamer/Info.plist +++ b/Plugins/InterfaceNamer/Info.plist @@ -9,7 +9,7 @@ CFBundleExecutable InterfaceNamer CFBundleIdentifier - com.apple.SystemConfiguration.InterfaceNamer + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/Plugins/InterfaceNamer/ifnamer.c b/Plugins/InterfaceNamer/ifnamer.c index 254b90c..a3f4e96 100644 --- a/Plugins/InterfaceNamer/ifnamer.c +++ b/Plugins/InterfaceNamer/ifnamer.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2015 Apple Inc. All rights reserved. + * Copyright (c) 2001-2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -75,9 +75,10 @@ #include +#define SC_LOG_HANDLE __log_InterfaceNamer() #include #include -#include // for SCLog(), SCPrint() +#include #include #include @@ -207,6 +208,22 @@ static CFArrayRef S_bonds = NULL; static CFArrayRef S_bridges = NULL; static CFArrayRef S_vlans = NULL; +/* + * Logging + */ +static os_log_t +__log_InterfaceNamer() +{ + static os_log_t log = NULL; + + if (log == NULL) { + log = os_log_create("com.apple.SystemConfiguration", "InterfaceNamer"); + } + + return log; +} + + static void addTimestamp(CFMutableDictionaryRef dict, CFStringRef key) { @@ -247,21 +264,6 @@ if_unit_compare(const void *val1, const void *val2, void *context) return (CFNumberCompare(unit1, unit2, NULL)); } -static void -reportIssue(const char *signature, CFStringRef issue) -{ - asl_object_t m; - - m = asl_new(ASL_TYPE_MSG); - asl_set(m, "com.apple.message.domain", "com.apple.SystemConfiguration." MY_PLUGIN_NAME); - asl_set(m, "com.apple.message.signature", signature); - asl_set(m, "com.apple.message.result", "failure"); - SCLOG(NULL, m, ~ASL_LEVEL_ERR, CFSTR("%s\n%@"), signature, issue); - asl_release(m); - - return; -} - static void writeInterfaceList(CFArrayRef if_list) { @@ -291,7 +293,6 @@ writeInterfaceList(CFArrayRef if_list) // if new hardware if ((old_model != NULL) && (cur_list != NULL)) { CFStringRef history; - CFStringRef issue; // if interface list was created on other hardware history = CFStringCreateWithFormat(NULL, NULL, @@ -301,18 +302,11 @@ writeInterfaceList(CFArrayRef if_list) SCPreferencesSetValue(prefs, history, cur_list); CFRelease(history); - SC_log(LOG_INFO, "Hardware model changed\n" - " created on \"%@\"\n" - " now on \"%@\"", - old_model, - new_model); - - issue = CFStringCreateWithFormat(NULL, NULL, - CFSTR("%@ --> %@"), - old_model, - new_model); - reportIssue("Hardware model changed", issue); - CFRelease(issue); + SC_log(LOG_NOTICE, "Hardware model changed\n" + " created on \"%@\"\n" + " now on \"%@\"", + old_model, + new_model); } SCPreferencesSetValue(prefs, MODEL, new_model); @@ -554,17 +548,19 @@ updateVLANInterfaceConfiguration(SCPreferencesRef prefs) static void updateVirtualNetworkInterfaceConfiguration(SCPreferencesRef prefs, - SCPreferencesNotification notificationType, + SCPreferencesNotification notificationType, void *info) { - os_activity_t activity_id; + os_activity_t activity; if ((notificationType & kSCPreferencesNotificationApply) != kSCPreferencesNotificationApply) { return; } - activity_id = os_activity_start("check/update virtual network interface configuration", - OS_ACTIVITY_FLAG_DEFAULT); + activity = os_activity_create("check/update virtual network interface configuration", + OS_ACTIVITY_CURRENT, + OS_ACTIVITY_FLAG_DEFAULT); + os_activity_scope(activity); if (prefs == NULL) { // if a new interface has been "named" @@ -592,7 +588,7 @@ updateVirtualNetworkInterfaceConfiguration(SCPreferencesRef prefs, // we are finished with current prefs, wait for changes SCPreferencesSynchronize(prefs); - os_activity_end(activity_id); + os_release(activity); return; } @@ -1172,14 +1168,7 @@ replaceInterface(SCNetworkInterfaceRef interface) insertInterface(S_dblist, interface); if (n > 1) { - CFStringRef issue; - - issue = CFStringCreateWithFormat(NULL, NULL, - CFSTR("n = %d, %@"), - n, - interface); - reportIssue("Multiple interfaces updated", issue); - CFRelease(issue); + SC_log(LOG_ERR, "Multiple interfaces updated (n = %d, %@)", n, interface); } return; @@ -1496,7 +1485,6 @@ nameInterfaces(CFMutableArrayRef if_list) SCNetworkInterfaceRef interface; SCNetworkInterfaceRef new_interface; CFStringRef path; - CFStringRef str; CFNumberRef type; CFNumberRef unit; CFIndex where; @@ -1651,15 +1639,6 @@ nameInterfaces(CFMutableArrayRef if_list) displayInterface(interface); - // report issue w/MessageTracer - str = CFStringCreateWithFormat(NULL, NULL, - CFSTR("kr=0x%x, path=%@, unit=%@"), - kr, - path, - unit); - reportIssue(signature, str); - CFRelease(str); - if ((dbdict != NULL) && (retries++ < 5)) { usleep(50 * 1000); // sleep 50ms between attempts goto retry; @@ -1699,7 +1678,7 @@ nameInterfaces(CFMutableArrayRef if_list) } new_unit = _SCNetworkInterfaceGetIOInterfaceUnit(new_interface); - if (CFEqual(unit, new_unit) == FALSE) { + if (!CFEqual(unit, new_unit)) { SC_log(LOG_INFO, "interface type %@ assigned unit %@ instead of %@", type, new_unit, unit); } @@ -1849,7 +1828,7 @@ updateInterfaces() (n > 1) ? "s" : ""); } for (i = 0; i < n; i++) { - CFDictionaryRef if_dict; + CFDictionaryRef if_dict; CFStringRef name; CFNumberRef type; CFNumberRef unit; @@ -1889,11 +1868,13 @@ updateInterfaces() static void interfaceArrivalCallback(void *refcon, io_iterator_t iter) { - os_activity_t activity_id; - io_object_t obj; + os_activity_t activity; + io_object_t obj; - activity_id = os_activity_start("process new network interface", - OS_ACTIVITY_FLAG_DEFAULT); + activity = os_activity_create("process new network interface", + OS_ACTIVITY_CURRENT, + OS_ACTIVITY_FLAG_DEFAULT); + os_activity_scope(activity); while ((obj = IOIteratorNext(iter)) != MACH_PORT_NULL) { SCNetworkInterfaceRef interface; @@ -1911,7 +1892,7 @@ interfaceArrivalCallback(void *refcon, io_iterator_t iter) updateInterfaces(); - os_activity_end(activity_id); + os_release(activity); return; } @@ -1928,12 +1909,14 @@ interfaceArrivalCallback(void *refcon, io_iterator_t iter) static void stackCallback(void *refcon, io_iterator_t iter) { - os_activity_t activity_id; + os_activity_t activity; kern_return_t kr; io_object_t stack; - activity_id = os_activity_start("process IONetworkStack", - OS_ACTIVITY_FLAG_DEFAULT); + activity = os_activity_create("process IONetworkStack", + OS_ACTIVITY_CURRENT, + OS_ACTIVITY_FLAG_DEFAULT); + os_activity_scope(activity); stack = IOIteratorNext(iter); if (stack == MACH_PORT_NULL) { @@ -1970,7 +1953,7 @@ stackCallback(void *refcon, io_iterator_t iter) IOObjectRelease(stack); } - os_activity_end(activity_id); + os_release(activity); return; } @@ -1981,15 +1964,17 @@ quietCallback(void *refcon, natural_t messageType, void *messageArgument) { - os_activity_t activity_id; + os_activity_t activity; if (messageArgument != NULL) { // if not yet quiet return; } - activity_id = os_activity_start("process IOKit quiet", - OS_ACTIVITY_FLAG_DEFAULT); + activity = os_activity_create("process IOKit quiet", + OS_ACTIVITY_CURRENT, + OS_ACTIVITY_FLAG_DEFAULT); + os_activity_scope(activity); if (messageType == kIOMessageServiceBusyStateChange) { addTimestamp(S_state, CFSTR("*QUIET*")); @@ -2022,13 +2007,13 @@ quietCallback(void *refcon, done : - os_activity_end(activity_id); + os_release(activity); return; } static void -iterateRegistryBusy(io_iterator_t iterator, CFArrayRef nodes, CFMutableStringRef snapshot, int *count) +iterateRegistryBusy(io_iterator_t iterator, CFArrayRef nodes, int *count) { kern_return_t kr = kIOReturnSuccess;; io_object_t obj; @@ -2091,18 +2076,17 @@ iterateRegistryBusy(io_iterator_t iterator, CFArrayRef nodes, CFMutableStringRef CFStringRef path; if ((*count)++ == 0) { - CFStringAppend(snapshot, CFSTR("Busy services :")); + SC_log(LOG_ERR, "Busy services :"); } path = CFStringCreateByCombiningStrings(NULL, newNodes, CFSTR("/")); - CFStringAppendFormat(snapshot, NULL, - CFSTR("\n %@ [%s%s%s%d, %lld ms]"), - path, - (state & kIOServiceRegisteredState) ? "" : "!registered, ", - (state & kIOServiceMatchedState) ? "" : "!matched, ", - (state & kIOServiceInactiveState) ? "inactive, " : "", - busy_state, - accumulated_busy_time / kMillisecondScale); + SC_log(LOG_ERR, " %@ [%s%s%s%d, %lld ms]", + path, + (state & kIOServiceRegisteredState) ? "" : "!registered, ", + (state & kIOServiceMatchedState) ? "" : "!matched, ", + (state & kIOServiceInactiveState) ? "inactive, " : "", + busy_state, + accumulated_busy_time / kMillisecondScale); CFRelease(path); } @@ -2112,7 +2096,7 @@ iterateRegistryBusy(io_iterator_t iterator, CFArrayRef nodes, CFMutableStringRef goto next; } - iterateRegistryBusy(iterator, newNodes, snapshot, count); + iterateRegistryBusy(iterator, newNodes, count); kr = IORegistryIteratorExitEntry(iterator); if (kr != kIOReturnSuccess) { @@ -2128,15 +2112,12 @@ iterateRegistryBusy(io_iterator_t iterator, CFArrayRef nodes, CFMutableStringRef return; } -static CF_RETURNS_RETAINED CFStringRef +static void captureBusy() { int count = 0; io_iterator_t iterator = MACH_PORT_NULL; kern_return_t kr; - CFMutableStringRef snapshot; - - snapshot = CFStringCreateMutable(NULL, 0); kr = IORegistryCreateIterator(kIOMasterPortDefault, kIOServicePlane, @@ -2144,43 +2125,41 @@ captureBusy() &iterator); if (kr != kIOReturnSuccess) { SC_log(LOG_NOTICE, "IORegistryCreateIterator() returned 0x%x", kr); - return snapshot; + return; } - iterateRegistryBusy(iterator, NULL, snapshot, &count); + iterateRegistryBusy(iterator, NULL, &count); if (count == 0) { - CFStringAppend(snapshot, CFSTR("w/no busy services")); + SC_log(LOG_ERR, "w/no busy services"); } IOObjectRelease(iterator); - return snapshot; } static void timerCallback(CFRunLoopTimerRef timer, void *info) { - os_activity_t activity_id; - CFStringRef snapshot; + os_activity_t activity; - activity_id = os_activity_start("process IOKit timer", - OS_ACTIVITY_FLAG_DEFAULT); + activity = os_activity_create("process IOKit timer", + OS_ACTIVITY_CURRENT, + OS_ACTIVITY_FLAG_DEFAULT); + os_activity_scope(activity); // We've been waiting for IOKit to quiesce and it just // hasn't happenned. Time to just move on! addTimestamp(S_state, CFSTR("*TIMEOUT*")); // log busy nodes - snapshot = captureBusy(); - SC_log(LOG_ERR, "timed out waiting for IOKit to quiesce\n%@", snapshot); - reportIssue("timed out waiting for IOKit to quiesce", snapshot); - CFRelease(snapshot); + SC_log(LOG_ERR, "timed out waiting for IOKit to quiesce"); + captureBusy(); quietCallback((void *)S_notify, MACH_PORT_NULL, 0, NULL); addTimestamp(S_state, CFSTR("*TIMEOUT&NAMED*")); updateStore(); - os_activity_end(activity_id); + os_release(activity); return; } diff --git a/Plugins/KernelEventMonitor/Info.plist b/Plugins/KernelEventMonitor/Info.plist index 327a47a..54ce80e 100644 --- a/Plugins/KernelEventMonitor/Info.plist +++ b/Plugins/KernelEventMonitor/Info.plist @@ -2,12 +2,14 @@ + Builtin + CFBundleDevelopmentRegion English CFBundleExecutable KernelEventMonitor CFBundleIdentifier - com.apple.SystemConfiguration.KernelEventMonitor + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -24,7 +26,5 @@ com.apple.SystemConfiguration.InterfaceNamer - Builtin - diff --git a/Plugins/KernelEventMonitor/ev_dlil.c b/Plugins/KernelEventMonitor/ev_dlil.c index aff1b0d..9157a1a 100644 --- a/Plugins/KernelEventMonitor/ev_dlil.c +++ b/Plugins/KernelEventMonitor/ev_dlil.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2006, 2009, 2011, 2013, 2015 Apple Inc. All rights reserved. + * Copyright (c) 2002-2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -109,7 +109,7 @@ interface_update_status(const char *if_name, CFDictionaryRemoveValue(newDict, kSCPropNetLinkActive); } - if (attach == TRUE) { + if (attach) { /* the interface was attached, remove stale state */ CFDictionaryRemoveValue(newDict, kSCPropNetLinkDetaching); } @@ -131,7 +131,9 @@ interface_update_status(const char *if_name, } } else { /* remove the value */ - SC_log(LOG_DEBUG, "Update interface link status: %s: ", if_name); + if (oldDict != NULL) { + SC_log(LOG_DEBUG, "Update interface link status: %s: ", if_name); + } cache_SCDynamicStoreRemoveValue(store, key); } @@ -186,7 +188,7 @@ interface_update_quality_metric(const char *if_name, SC_log(LOG_DEBUG, "Update interface link quality: %s: %@", if_name, newDict); cache_SCDynamicStoreSetValue(store, key, newDict); } else { - SC_log(LOG_DEBUG, "Update interface link quality: %s: ", if_name); + SC_log(LOG_DEBUG, "Update interface link quality: %s: ", if_name); cache_SCDynamicStoreRemoveValue(store, key); } @@ -350,7 +352,7 @@ link_update_status(const char *if_name, boolean_t attach, boolean_t only_if_diff /* get "Link" */ bzero((char *)&ifm, sizeof(ifm)); - (void) strncpy(ifm.ifm_name, if_name, sizeof(ifm.ifm_name)); + (void) strlcpy(ifm.ifm_name, if_name, sizeof(ifm.ifm_name)); if (ioctl(sock, SIOCGIFMEDIA, (caddr_t)&ifm) == -1) { /* if media status not available for this interface */ @@ -488,9 +490,9 @@ interfaceListAddInterface(CFMutableArrayRef ifList, const char * if_name) CFStringRef interface; interface = CFStringCreateWithCString(NULL, if_name, kCFStringEncodingMacRoman); - if (CFArrayContainsValue(ifList, - CFRangeMake(0, CFArrayGetCount(ifList)), - interface) == FALSE) { + if (!CFArrayContainsValue(ifList, + CFRangeMake(0, CFArrayGetCount(ifList)), + interface)) { /* interface was added, prime the link-specific values */ added = TRUE; CFArrayAppendValue(ifList, interface); @@ -538,6 +540,7 @@ link_add(const char *if_name) /* interface was added, update the global list */ messages_add_msg_with_arg("link_add", if_name); interfaceListUpdate(ifList); + config_new_interface(if_name); } CFRelease(ifList); return; diff --git a/Plugins/KernelEventMonitor/ev_extra.m b/Plugins/KernelEventMonitor/ev_extra.m index 8f615be..32bf151 100644 --- a/Plugins/KernelEventMonitor/ev_extra.m +++ b/Plugins/KernelEventMonitor/ev_extra.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015 Apple Inc. All rights reserved. + * Copyright (c) 2013-2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -29,16 +29,13 @@ */ -#include -#include -#include - #include "eventmon.h" #include "ev_extra.h" + static CFBooleanRef -is_expensive(SCNetworkInterfaceRef interface) +is_expensive(SCNetworkInterfaceRef _Nonnull interface) { CFBooleanRef expensive = NULL; CFStringRef interfaceType; diff --git a/Plugins/KernelEventMonitor/ev_ipv6.c b/Plugins/KernelEventMonitor/ev_ipv6.c index 7b9f42e..43468d0 100644 --- a/Plugins/KernelEventMonitor/ev_ipv6.c +++ b/Plugins/KernelEventMonitor/ev_ipv6.c @@ -331,7 +331,7 @@ interface_update_ipv6(struct ifaddrs *ifap, const char *if_name) } bzero((char *)&ifr6, sizeof(ifr6)); - strncpy(ifr6.ifr_name, ifa->ifa_name, sizeof(ifr6.ifr_name)); + strlcpy(ifr6.ifr_name, ifa->ifa_name, sizeof(ifr6.ifr_name)); ifr6.ifr_addr = *sin6; if (ioctl(sock, SIOCGIFAFLAG_IN6, &ifr6) == -1) { /* if flags not available for this address */ diff --git a/Plugins/KernelEventMonitor/eventmon.c b/Plugins/KernelEventMonitor/eventmon.c index b120be2..dc9d36a 100644 --- a/Plugins/KernelEventMonitor/eventmon.c +++ b/Plugins/KernelEventMonitor/eventmon.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2015 Apple Inc. All rights reserved. + * Copyright (c) 2000-2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -61,15 +61,26 @@ #include #include #include - -// from ip_fw2.c -#define KEV_LOG_SUBCLASS 10 +#include static dispatch_queue_t S_kev_queue; static dispatch_source_t S_kev_source; -__private_extern__ Boolean network_changed = FALSE; -__private_extern__ SCDynamicStoreRef store = NULL; -__private_extern__ Boolean _verbose = FALSE; +__private_extern__ Boolean network_changed = FALSE; +__private_extern__ SCDynamicStoreRef store = NULL; +__private_extern__ Boolean _verbose = FALSE; + + +__private_extern__ os_log_t +__log_KernelEventMonitor() +{ + static os_log_t log = NULL; + + if (log == NULL) { + log = os_log_create("com.apple.SystemConfiguration", "KernelEventMonitor"); + } + + return log; +} #define MESSAGES_MAX 100 @@ -358,11 +369,11 @@ processEvent_Apple_Network(struct kern_event_msg *ev_msg) break; } default : - handled = FALSE; break; } break; } + case KEV_INET6_SUBCLASS : { struct kev_in6_data * ev; @@ -395,11 +406,11 @@ processEvent_Apple_Network(struct kern_event_msg *ev_msg) break; default : - handled = FALSE; break; } break; } + case KEV_DL_SUBCLASS : { struct net_event_data * ev; @@ -535,57 +546,67 @@ processEvent_Apple_Network(struct kern_event_msg *ev_msg) issues->modid, DLIL_MODIDLEN, issues->info, - (bcmp(issues->info, info_zero, DLIL_MODIDLEN) != 0) - ?DLIL_MODARGLEN - :0); + (bcmp(issues->info, info_zero, DLIL_MODARGLEN) != 0) + ? DLIL_MODARGLEN + : 0); break; } #endif // KEV_DL_ISSUES - case KEV_DL_SIFFLAGS : - case KEV_DL_SIFMETRICS : - case KEV_DL_SIFMTU : - case KEV_DL_SIFPHYS : - case KEV_DL_SIFMEDIA : - case KEV_DL_SIFGENERIC : - case KEV_DL_ADDMULTI : - case KEV_DL_DELMULTI : - case KEV_DL_LINK_ADDRESS_CHANGED : - case KEV_DL_WAKEFLAGS_CHANGED : -#ifdef KEV_DL_IFCAP_CHANGED - case KEV_DL_IFCAP_CHANGED : -#endif // KEV_DL_IFCAP_CHANGED - break; - default : - handled = FALSE; break; } break; } + +#ifdef KEV_NETPOLICY_SUBCLASS + case KEV_NETPOLICY_SUBCLASS : { + break; + } +#endif // KEV_NETPOLICY_SUBCLASS + +#ifdef KEV_SOCKET_SUBCLASS + case KEV_SOCKET_SUBCLASS : { + break; + } +#endif // KEV_SOCKET_SUBCLASS + #ifdef KEV_ND6_SUBCLASS case KEV_ND6_SUBCLASS : { - switch (ev_msg->event_code) { - case KEV_KEV_ND6_RA : - break; - - default : - handled = FALSE; - break; - } break; } #endif // KEV_ND6_SUBCLASS + +#ifdef KEV_NECP_SUBCLASS + case KEV_NECP_SUBCLASS : { + break; + } +#endif // KEV_NECP_SUBCLASS + +#ifdef KEV_NETAGENT_SUBCLASS + case KEV_NETAGENT_SUBCLASS : { + break; + } +#endif // KEV_NETAGENT_SUBCLASS + +#ifdef KEV_LOG_SUBCLASS case KEV_LOG_SUBCLASS : { break; } +#endif // KEV_LOG_SUBCLASS + +#ifdef KEV_NETEVENT_SUBCLASS + case KEV_NETEVENT_SUBCLASS : { + break; + } +#endif // KEV_NETEVENT_SUBCLASS + default : - handled = FALSE; break; } if (!handled) { - logEvent(CFSTR("New Apple network subclass"), ev_msg); + logEvent(CFSTR("Error processing (Apple network subclass)"), ev_msg); } return; } @@ -621,21 +642,12 @@ eventCallback(int so) case KEV_NETWORK_CLASS : processEvent_Apple_Network(ev_msg); break; - case KEV_IOKIT_CLASS : - case KEV_SYSTEM_CLASS : - case KEV_APPLESHARE_CLASS : - case KEV_FIREWALL_CLASS : - case KEV_IEEE80211_CLASS : - break; + default : - /* unrecognized (Apple) event class */ - logEvent(CFSTR("New (Apple) class"), ev_msg); break; } break; default : - /* unrecognized vendor code */ - logEvent(CFSTR("New vendor"), ev_msg); break; } offset += ev_msg->total_size; @@ -651,8 +663,24 @@ eventCallback(int so) } +__private_extern__ void +config_new_interface(const char * ifname) +{ + xpc_object_t if_list; + + if (ifname == NULL) { + network_config_check_interface_settings(NULL); + return; + } + if_list = xpc_array_create(NULL, 0); + xpc_array_set_string(if_list, XPC_ARRAY_APPEND, ifname); + network_config_check_interface_settings(if_list); + xpc_release(if_list); + return; +} + static void -update_interfaces(const char * msg, Boolean ipv4_ipv6_too) +update_interfaces(const char * msg, Boolean first_time) { Boolean added = FALSE; struct ifaddrs * ifap = NULL; @@ -676,6 +704,9 @@ update_interfaces(const char * msg, Boolean ipv4_ipv6_too) if (interfaceListAddInterface(ifList, scan->ifa_name)) { messages_add_msg_with_arg(msg, scan->ifa_name); added = TRUE; + if (!first_time) { + config_new_interface(scan->ifa_name); + } } } @@ -686,7 +717,7 @@ update_interfaces(const char * msg, Boolean ipv4_ipv6_too) CFRelease(ifList); /* update IPv4/IPv6 addresses that are already assigned */ - if (ipv4_ipv6_too) { + if (first_time) { ipv4_interface_update(ifap, NULL); interface_update_ipv6(ifap, NULL); } @@ -694,6 +725,10 @@ update_interfaces(const char * msg, Boolean ipv4_ipv6_too) freeifaddrs(ifap); done: + if (first_time) { + /* tell networkd to get the interface list itself */ + config_new_interface(NULL); + } return; } @@ -713,43 +748,21 @@ schedule_timer(void) return; } -static boolean_t -kernel_events_lost(void) -{ - boolean_t events_lost = FALSE; - struct kevtstat kevtstat; - size_t len = sizeof(kevtstat); - const char * mibvar = "net.systm.kevt.stats"; - static u_int64_t old_kes_nomem; - - if (sysctlbyname(mibvar, &kevtstat, &len, 0, 0) < 0) { - SC_log(LOG_NOTICE, "sysctl(%s) failed, %s", - mibvar, strerror(errno)); - } - else if (old_kes_nomem != kevtstat.kes_nomem) { - SC_log(LOG_NOTICE, "KernelEventMonitor: lost kernel event"); - old_kes_nomem = kevtstat.kes_nomem; - events_lost = TRUE; - } - return (events_lost); -} - static void check_for_new_interfaces(void * context) { static int count; + char msg[32]; count++; - if (kernel_events_lost()) { - char msg[32]; - - snprintf(msg, sizeof(msg), "timeout %d (of %d)", count, MAX_TIMER_COUNT); - cache_open(); - update_interfaces(msg, FALSE); - cache_write(store); - cache_close(); - messages_post(); - } + + /* update KEV driven content in case a message got dropped */ + snprintf(msg, sizeof(msg), "update %d (of %d)", count, MAX_TIMER_COUNT); + cache_open(); + update_interfaces(msg, FALSE); + cache_write(store); + cache_close(); + messages_post(); /* schedule the next timer, if needed */ if (count < MAX_TIMER_COUNT) { @@ -871,11 +884,13 @@ load_KernelEventMonitor(CFBundleRef bundle, Boolean bundleVerbose) close(so); }); dispatch_source_set_event_handler(S_kev_source, ^{ - os_activity_t activity_id; - Boolean ok; + os_activity_t activity; + Boolean ok; - activity_id = os_activity_start("processing network kernel events", - OS_ACTIVITY_FLAG_DEFAULT); + activity = os_activity_create("processing network kernel events", + OS_ACTIVITY_CURRENT, + OS_ACTIVITY_FLAG_DEFAULT); + os_activity_scope(activity); ok = eventCallback(so); if (!ok) { @@ -883,7 +898,7 @@ load_KernelEventMonitor(CFBundleRef bundle, Boolean bundleVerbose) dispatch_source_cancel(S_kev_source); } - os_activity_end(activity_id); + os_release(activity); }); // NOTE: dispatch_resume() will be called in prime() diff --git a/Plugins/KernelEventMonitor/eventmon.h b/Plugins/KernelEventMonitor/eventmon.h index aabc939..0098bae 100644 --- a/Plugins/KernelEventMonitor/eventmon.h +++ b/Plugins/KernelEventMonitor/eventmon.h @@ -1,15 +1,15 @@ /* - * Copyright (c) 2002-2015 Apple Inc. All rights reserved. + * Copyright (c) 2002-2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,7 +17,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ */ @@ -63,10 +63,18 @@ extern Boolean _verbose; __BEGIN_DECLS -int dgram_socket (int domain); +os_log_t +__log_KernelEventMonitor (); + +int +dgram_socket (int domain); + +void +messages_add_msg_with_arg (const char *msg, + const char *arg); void -messages_add_msg_with_arg(const char * msg, const char * arg); +config_new_interface(const char * ifname); __END_DECLS diff --git a/Plugins/LinkConfiguration/Info.plist b/Plugins/LinkConfiguration/Info.plist index 63de67e..28308f6 100644 --- a/Plugins/LinkConfiguration/Info.plist +++ b/Plugins/LinkConfiguration/Info.plist @@ -2,12 +2,14 @@ + Builtin + CFBundleDevelopmentRegion English CFBundleExecutable LinkConfiguration CFBundleIdentifier - com.apple.SystemConfiguration.LinkConfiguration + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -24,7 +26,5 @@ com.apple.SystemConfiguration.InterfaceNamer - Builtin - diff --git a/Plugins/LinkConfiguration/linkconfig.c b/Plugins/LinkConfiguration/linkconfig.c index 0af3e51..1690d54 100644 --- a/Plugins/LinkConfiguration/linkconfig.c +++ b/Plugins/LinkConfiguration/linkconfig.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2007, 2011, 2013, 2015 Apple Inc. All rights reserved. + * Copyright (c) 2002-2007, 2011, 2013, 2015, 2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -37,19 +37,33 @@ #include #include -#include -#include -#include +#define SC_LOG_HANDLE __log_LinkConfiguration() +#include "SCNetworkConfigurationInternal.h" #include // for _SCDPluginExecCommand -#include "SCNetworkConfigurationInternal.h" +static CFMutableDictionaryRef baseSettings = NULL; +static CFStringRef interfacesKey = NULL; +static SCDynamicStoreRef store = NULL; +static CFRunLoopSourceRef rls = NULL; +static CFMutableDictionaryRef wantSettings = NULL; + + +#pragma mark - +#pragma mark Logging + + +static os_log_t +__log_LinkConfiguration() +{ + static os_log_t log = NULL; + + if (log == NULL) { + log = os_log_create("com.apple.SystemConfiguration", "LinkConfiguration"); + } -static CFMutableDictionaryRef baseSettings = NULL; -static CFStringRef interfacesKey = NULL; -static SCDynamicStoreRef store = NULL; -static CFRunLoopSourceRef rls = NULL; -static CFMutableDictionaryRef wantSettings = NULL; + return log; +} #pragma mark - @@ -318,12 +332,17 @@ Boolean _SCNetworkInterfaceSetMTU(SCNetworkInterfaceRef interface, CFDictionaryRef options) { - CFStringRef interfaceName; - int mtu_cur = -1; - int mtu_max = -1; - int mtu_min = -1; - int requested; - CFNumberRef val; + CFArrayRef bridge_members = NULL; + Boolean bridge_updated = FALSE; + CFStringRef interfaceName; + SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; + CFStringRef interfaceType; + int mtu_cur = -1; + int mtu_max = -1; + int mtu_min = -1; + Boolean ok = TRUE; + int requested; + CFNumberRef val; interfaceName = SCNetworkInterfaceGetBSDName(interface); if (interfaceName == NULL) { @@ -367,6 +386,37 @@ _SCNetworkInterfaceSetMTU(SCNetworkInterfaceRef interface, return FALSE; } + interfaceType = SCNetworkInterfaceGetInterfaceType(interface); + if (CFEqual(interfaceType, kSCNetworkInterfaceTypeBridge)) { + bridge_members = SCBridgeInterfaceGetMemberInterfaces(interface); + if ((bridge_members != NULL) && (CFArrayGetCount(bridge_members) == 0)) { + /* if no members */ + bridge_members = NULL; + } + if (bridge_members != NULL) { + SCNetworkInterfaceRef member0; + + /* temporarily, remove all bridge members */ + CFRetain(bridge_members); + ok = SCBridgeInterfaceSetMemberInterfaces(interface, NULL); + if (!ok) { + goto done; + } + + /* and update the (bridge) configuration */ + ok = _SCBridgeInterfaceUpdateConfiguration(interfacePrivate->prefs); + if (!ok) { + goto done; + } + + /* switch from updating the MTU of the bridge to the first member */ + member0 = CFArrayGetValueAtIndex(bridge_members, 0); + interfaceName = SCNetworkInterfaceGetBSDName(member0); + + bridge_updated = TRUE; + } + } + #ifdef USE_SIOCSIFMTU { struct ifreq ifr; @@ -380,14 +430,16 @@ _SCNetworkInterfaceSetMTU(SCNetworkInterfaceRef interface, sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock == -1) { SC_log(LOG_ERR, "socket() failed: %s", strerror(errno)); - return FALSE; + ok = FALSE; + goto done; } ret = ioctl(sock, SIOCSIFMTU, (caddr_t)&ifr); (void)close(sock); if (ret == -1) { SC_log(LOG_NOTICE, "ioctl(SIOCSIFMTU) failed: %s", strerror(errno)); - return FALSE; + ok = FALSE; + goto done; } } #else /* !USE_SIOCSIFMTU */ @@ -410,12 +462,26 @@ _SCNetworkInterfaceSetMTU(SCNetworkInterfaceRef interface, free(ifconfig_argv[3]); if (pid <= 0) { - return FALSE; + ok = FALSE; + goto done; } } #endif /* !USE_SIOCSIFMTU */ - return TRUE; + done : + + if (bridge_members != NULL) { + /* restore bridge members */ + (void) SCBridgeInterfaceSetMemberInterfaces(interface, bridge_members); + CFRelease(bridge_members); + + if (bridge_updated) { + /* and update the (bridge) configuration */ + (void) _SCBridgeInterfaceUpdateConfiguration(interfacePrivate->prefs); + } + } + + return ok; } @@ -442,7 +508,7 @@ parse_component(CFStringRef key, CFStringRef prefix) CFMutableStringRef comp; CFRange range; - if (CFStringHasPrefix(key, prefix) == FALSE) { + if (!CFStringHasPrefix(key, prefix)) { return NULL; } comp = CFStringCreateMutableCopy(NULL, 0, key); @@ -592,14 +658,16 @@ updateLink(CFStringRef interfaceName, CFDictionaryRef options) static void linkConfigChangedCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void *arg) { - os_activity_t activity_id; + os_activity_t activity; CFDictionaryRef changes; CFIndex i; CFIndex n; static CFStringRef prefix = NULL; - activity_id = os_activity_start("processing link configuration changes", - OS_ACTIVITY_FLAG_DEFAULT); + activity = os_activity_create("processing link configuration changes", + OS_ACTIVITY_CURRENT, + OS_ACTIVITY_FLAG_DEFAULT); + os_activity_scope(activity); if (prefix == NULL) { prefix = SCDynamicStoreKeyCreate(NULL, @@ -643,7 +711,7 @@ linkConfigChangedCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void CFRelease(changes); } - os_activity_end(activity_id); + os_release(activity); return; } diff --git a/Plugins/PreferencesMonitor/Info.plist b/Plugins/PreferencesMonitor/Info.plist index 04bfd35..7532788 100644 --- a/Plugins/PreferencesMonitor/Info.plist +++ b/Plugins/PreferencesMonitor/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable PreferencesMonitor CFBundleIdentifier - com.apple.SystemConfiguration.PreferencesMonitor + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/Plugins/PreferencesMonitor/prefsmon.c b/Plugins/PreferencesMonitor/prefsmon.c index 5727a67..c0d6b9d 100644 --- a/Plugins/PreferencesMonitor/prefsmon.c +++ b/Plugins/PreferencesMonitor/prefsmon.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2008, 2010, 2012-2015 Apple Inc. All rights reserved. + * Copyright (c) 2000-2008, 2010, 2012-2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -42,13 +42,13 @@ #include +#define SC_LOG_HANDLE __log_PreferencesMonitor() #include #include #include - /* globals */ static SCPreferencesRef prefs = NULL; static SCDynamicStoreRef store = NULL; @@ -66,8 +66,22 @@ static CFMutableArrayRef removedPrefsKeys; /* old prefs keys to be removed */ static Boolean rofs = FALSE; static Boolean restorePrefs = FALSE; -#define MY_PLUGIN_NAME "PreferencesMonitor" -#define MY_PLUGIN_ID CFSTR("com.apple.SystemConfiguration." MY_PLUGIN_NAME) +#define MY_PLUGIN_NAME "PreferencesMonitor" +#define MY_PLUGIN_ID CFSTR("com.apple.SystemConfiguration." MY_PLUGIN_NAME) + + +static os_log_t +__log_PreferencesMonitor() +{ + static os_log_t log = NULL; + + if (log == NULL) { + log = os_log_create("com.apple.SystemConfiguration", "PreferencesMonitor"); + } + + return log; +} + static Boolean restorePreferences() @@ -122,7 +136,7 @@ restorePreferences() continue; } - if (CFStringHasPrefix(existingKey, modelPrefixStr) == FALSE) { + if (!CFStringHasPrefix(existingKey, modelPrefixStr)) { continue; } @@ -135,7 +149,7 @@ restorePreferences() CFRelease(splitKey); } - if (modified == TRUE) { + if (modified) { SCPreferencesRef ni_prefs = NULL; ni_prefs = SCPreferencesCreate(NULL, MY_PLUGIN_ID, CFSTR("NetworkInterfaces.plist")); if (ni_prefs == NULL) { @@ -146,7 +160,7 @@ restorePreferences() CFRelease(ni_prefs); //Commit the changes only if prefs files valid - if (ok == TRUE) { + if (ok) { if (!SCPreferencesCommitChanges(prefs)) { if (SCError() != EROFS) { SC_log(LOG_NOTICE, "SCPreferencesCommitChanges() failed: %s", @@ -176,13 +190,11 @@ error: static Boolean establishNewPreferences() { - CFBundleRef bundle; SCNetworkSetRef current = NULL; CFStringRef new_model; Boolean ok = FALSE; int sc_status = kSCStatusFailed; SCNetworkSetRef set = NULL; - CFStringRef setName = NULL; Boolean updated = FALSE; while (TRUE) { @@ -261,32 +273,12 @@ establishNewPreferences() } if (set == NULL) { - set = SCNetworkSetCreate(prefs); + set = _SCNetworkSetCreateDefault(prefs); if (set == NULL) { ok = FALSE; sc_status = SCError(); goto done; } - - bundle = _SC_CFBundleGet(); - if (bundle != NULL) { - setName = CFBundleCopyLocalizedString(bundle, - CFSTR("DEFAULT_SET_NAME"), - CFSTR("Automatic"), - NULL); - } - - ok = SCNetworkSetSetName(set, (setName != NULL) ? setName : CFSTR("Automatic")); - if (!ok) { - sc_status = SCError(); - goto done; - } - - ok = SCNetworkSetSetCurrent(set); - if (!ok) { - sc_status = SCError(); - goto done; - } } ok = SCNetworkSetEstablishDefaultConfiguration(set); @@ -325,7 +317,6 @@ establishNewPreferences() } (void)SCPreferencesUnlock(prefs); - if (setName != NULL) CFRelease(setName); if (set != NULL) CFRelease(set); return updated; } @@ -338,6 +329,9 @@ quiet(Boolean *timeout) Boolean _quiet = FALSE; Boolean _timeout = FALSE; + // keep the static analyzer happy + assert(initKey != NULL); + // check if quiet dict = SCDynamicStoreCopyValue(store, initKey); if (dict != NULL) { @@ -445,7 +439,7 @@ watchQuietCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info) (void) establishNewPreferences(); - if (restorePrefs == TRUE) { + if (restorePrefs) { (void) restorePreferences(); restorePrefs = FALSE; } @@ -775,11 +769,12 @@ updateConfiguration(SCPreferencesRef prefs, SCPreferencesNotification notificationType, void *info) { - os_activity_t activity_id; - + os_activity_t activity; - activity_id = os_activity_start("processing [SC] preferences.plist changes", - OS_ACTIVITY_FLAG_DEFAULT); + activity = os_activity_create("processing [SC] preferences.plist changes", + OS_ACTIVITY_CURRENT, + OS_ACTIVITY_FLAG_DEFAULT); + os_activity_scope(activity); #if !TARGET_OS_IPHONE if ((notificationType & kSCPreferencesNotificationCommit) == kSCPreferencesNotificationCommit) { @@ -810,7 +805,7 @@ updateConfiguration(SCPreferencesRef prefs, done : - os_activity_end(activity_id); + os_release(activity); return; } @@ -872,7 +867,7 @@ load_PreferencesMonitor(CFBundleRef bundle, Boolean bundleVerbose) } } - if (need_update == FALSE) { + if (!need_update) { SCNetworkSetRef current; current = SCNetworkSetCopyCurrent(prefs); diff --git a/Plugins/QoSMarking/Info.plist b/Plugins/QoSMarking/Info.plist new file mode 100644 index 0000000..e0a7b05 --- /dev/null +++ b/Plugins/QoSMarking/Info.plist @@ -0,0 +1,41 @@ + + + + + Builtin + + CFBundleDevelopmentRegion + English + CFBundleExecutable + QoSMarking + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + com.apple.SystemConfiguration.QoSMarking + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.14 + CFBundleSignature + ???? + CFBundleVersion + 1.14 + QoSMarking_AppleAudioVideoCalls_BundleIDs + + com.apple.datausage.telephony.ims + com.apple.facetime + com.apple.siri + + QoSMarking_AppleAudioVideoCalls_ExecutablePaths + + /usr/libexec/networkserviceproxy + + Requires + + com.apple.SystemConfiguration.InterfaceNamer + com.apple.SystemConfiguration.PreferencesMonitor + + + diff --git a/Plugins/QoSMarking/Makefile b/Plugins/QoSMarking/Makefile new file mode 100644 index 0000000..8efa982 --- /dev/null +++ b/Plugins/QoSMarking/Makefile @@ -0,0 +1,30 @@ +ifeq ($(PLATFORM),) +PLATFORM=macosx +endif + +ifeq ($(PLATFORM),iphoneos) +# iOS internal SDK +ARCHS=armv7 +endif + +ifeq ($(PLATFORM),macosx) +# Mac OS X internal SDK +ARCHS=x86_64 +endif + +# Mac OS X or iOS internal SDK +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 + +qos-marking: qos-marking.o Makefile + $(CC) -o qos-marking qos-marking.o -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 new file mode 100644 index 0000000..c08f1b5 --- /dev/null +++ b/Plugins/QoSMarking/qos-marking.m @@ -0,0 +1,1252 @@ +/* + * Copyright (c) 2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + * Modification History + * + * March 1, 2016 Allan Nathanson + * - initial revision + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SC_LOG_HANDLE __log_QoSMarking() +#include +#include +#include + +#import +#import +#import + +// define the QoSMarking.bundle Info.plist key containing [application] bundleIDs to be white-listed +#define kQoSMarkingBundleIdentifiersAppleAudioVideoCallsKey CFSTR("QoSMarking_AppleAudioVideoCalls_BundleIDs") + +// define the QoSMarking.bundle Info.plist key containing paths to be white-listed +#define kQoSMarkingExecutablePathsAppleAudioVideoCallsKey CFSTR("QoSMarking_AppleAudioVideoCalls_ExecutablePaths") + +// define the starting "order" value for any QoS Marking NEPolicy rules +#define QOS_MARKING_PRIORITY_BLOCK_AV_APPS 1000 +#define QOS_MARKING_PRIORITY_BLOCK_AV_PATHS 1500 +#define QOS_MARKING_PRIORITY_BLOCK_APPS 2000 + + +static CFStringRef interfacesKey = NULL; +static NSArray * qosMarkingAudioVideoCalls_bundleIDs = nil; +static NSArray * qosMarkingAudioVideoCalls_executablePaths = nil; + + +#pragma mark - +#pragma mark Logging + + +__private_extern__ os_log_t +__log_QoSMarking() +{ + static os_log_t log = NULL; + + if (log == NULL) { + log = os_log_create("com.apple.SystemConfiguration", "QoSMarking"); + } + + return log; +} + + +#pragma mark - +#pragma mark QoSMarking support (system) + + +static void +qosMarkingSetPolicyRestriction(const char *ctl, BOOL yn) +{ + int restricted = yn ? 1 : 0; + int ret; + + ret = sysctlbyname(ctl, NULL, 0, &restricted, sizeof(restricted)); + if (ret != -1) { + SC_log(LOG_NOTICE, "QoS marking policy: sysctl %s=%d", ctl, restricted); + } else { + if (errno != ENOENT) { + SC_log(LOG_ERR, "sysctlbyname() failed: %s", strerror(errno)); + } + } + + return; +} + + +static void +qosMarkingSetHavePolicies(BOOL havePolicies) +{ + qosMarkingSetPolicyRestriction("net.qos.policy.restricted", havePolicies); + return; +} + + +static void +qosMarkingSetRestrictAVApps(BOOL restrictApps) +{ + qosMarkingSetPolicyRestriction("net.qos.policy.restrict_avapps", restrictApps); + return; +} + + +#pragma mark - +#pragma mark QoSMarking support (per-interface) + + +static BOOL +supportsQoSMarking(int s, const char *ifname) +{ + struct ifreq ifr; + + bzero(&ifr, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + if (ioctl(s, SIOCGIFTYPE, (caddr_t)&ifr) == -1) { + SC_log(LOG_NOTICE, "%s: ioctl(SIOCGIFTYPE) failed: %m", ifname); + ifr.ifr_type.ift_type = 0; + ifr.ifr_type.ift_family = IFRTYPE_FAMILY_ANY; + ifr.ifr_type.ift_subfamily = IFRTYPE_SUBFAMILY_ANY; + } + + if ((ifr.ifr_type.ift_family == IFRTYPE_FAMILY_ETHERNET) && + (ifr.ifr_type.ift_subfamily == IFRTYPE_SUBFAMILY_WIFI)) { + return true; + } + + return false; +} + + +static void +qosMarkingSetEnabled(int s, const char *ifname, BOOL enabled) +{ + struct ifreq ifr; + int ret; + + bzero(&ifr, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + ifr.ifr_qosmarking_enabled = enabled ? 1 : 0; + ret = ioctl(s, SIOCSQOSMARKINGENABLED, &ifr); + if (ret == -1) { + SC_log(LOG_ERR, "%s: ioctl(SIOCSQOSMARKINGENABLED) failed: %s", + ifname, + strerror(errno)); + } + + return; +} + + +#pragma mark - +#pragma mark QoSMarking Policy support + + +@interface QoSMarkingController : NSObject + ++ (QoSMarkingController *)sharedController; +- (void)setInterfaces:(NSArray *)interfaces; +- (void)setPolicy:(NSDictionary *)policy forInterface:(NSString *)interface; + +@end + + +@interface QoSMarkingController() + +/* + * interfaces + * An array of network interface names on the system/device + */ +@property (nonatomic) NSArray * interfaces; + +/* + * policySessions + * A dictionary for the maintaining the QoS marking policies. + * + * Key : interface [name] + * Value : the NEPolicySession* for the interface + */ +@property (nonatomic) NSMutableDictionary * policySessions; + +/* + * requested + * A dictionary for the tracking the QoS marking policies. + * + * Key : interface [name] + * Value : the [requested] NSDictionary* "policy" for the interface + */ +@property (nonatomic) NSMutableDictionary * requested; + +/* + * enabled, enabledAV + * Dictionaries for tracking the "enabled" interfaces with QoS [AV] + * marking policies. + * + * Key : interface [name] + * Value : the enabled NSDictionary* "policy" for the interface + */ +@property (nonatomic) NSMutableDictionary * enabled; +@property (nonatomic) NSMutableDictionary * enabledAV; + +@end + + +@implementation QoSMarkingController + +- (NEPolicySession *)createPolicySession +{ + NEPolicySession *session = nil; +#if !TARGET_OS_IPHONE + /* + * Note: we cannot have entitlements on OSX so we open a kernel + * control socket and use it to create a policy session + */ + + struct sockaddr_ctl kernctl_addr; + struct ctl_info kernctl_info; + int sock; + + // Create kernel control socket + sock = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL); + if (sock == -1) { + SC_log(LOG_ERR, "socket() failed: %s", strerror(errno)); + return nil; + } + + bzero(&kernctl_info, sizeof(kernctl_info)); + strlcpy(kernctl_info.ctl_name, NECP_CONTROL_NAME, sizeof(kernctl_info.ctl_name)); + if (ioctl(sock, CTLIOCGINFO, &kernctl_info)) { + SC_log(LOG_ERR, "ioctl() failed: %s", strerror(errno)); + close(sock); + return nil; + } + + bzero(&kernctl_addr, sizeof(kernctl_addr)); + kernctl_addr.sc_len = sizeof(kernctl_addr); + kernctl_addr.sc_family = AF_SYSTEM; + kernctl_addr.ss_sysaddr = AF_SYS_CONTROL; + kernctl_addr.sc_id = kernctl_info.ctl_id; + kernctl_addr.sc_unit = 0; + if (connect(sock, (struct sockaddr *)&kernctl_addr, sizeof(kernctl_addr))) { + SC_log(LOG_ERR, "connect() failed: %s", strerror(errno)); + close(sock); + return nil; + } + + /* Create policy session */ + session = [[NEPolicySession alloc] initWithSocket:sock]; + if (session == nil) { + close(sock); + } + +#else // !TARGET_OS_IPHONE + session = [[NEPolicySession alloc] init]; +#endif // !TARGET_OS_IPHONE + + return session; +} + + +#pragma mark - + + +- (BOOL)qosMarkingPolicyEnabled:(NSDictionary *)policy forKey:(NSString *)key +{ + NSNumber * enabled; + + enabled = policy[key]; + if (enabled != nil) { + if (![enabled isKindOfClass:[NSNumber class]]) { + SC_log(LOG_ERR, "%@ not valid", key); + return false; + } + } else { + // assume "enabled" if no key + return true; + } + + return enabled.boolValue; +} + + +- (BOOL)qosMarkingIsEnabled:(NSDictionary *)policy +{ + return [self qosMarkingPolicyEnabled:policy + forKey:(NSString *)kSCPropNetQoSMarkingEnabled]; +} + + +- (BOOL)qosMarkingIsAppleAudioVideoCallsEnabled:(NSDictionary *)policy +{ + return [self qosMarkingPolicyEnabled:policy + forKey:(NSString *)kSCPropNetQoSMarkingAppleAudioVideoCalls]; +} + + +- (NSArray *)qosMarkingWhitelistedAppIdentifiers:(NSDictionary *)policy +{ + NSArray * appIDs; + + appIDs = policy[(NSString *)kSCPropNetQoSMarkingWhitelistedAppIdentifiers]; + if ((appIDs != nil) && ![appIDs isKindOfClass:[NSArray class]]) { + SC_log(LOG_ERR, "QoSMarkingWhitelistedAppIdentifier list not valid"); + return nil; + } + + for (NSString *appID in appIDs) { + if ((appID != nil) && + (![appID isKindOfClass:[NSString class]] || (appID.length == 0))) { + SC_log(LOG_ERR, "QoSMarkingWhitelistedAppIdentifier not valid"); + return nil; + } + } + + return appIDs; +} + + +#pragma mark - + + +- (NSUUID *)copyUUIDForSingleArch:(int)fd +{ + struct mach_header header; + NSUUID * uuid = nil; + + if (read(fd, &header, sizeof(header)) != sizeof(header)) { + return nil; + } + + // Go past the 64 bit header if we have a 64 arch + if (header.magic == MH_MAGIC_64) { + if (lseek(fd, sizeof(uint32_t), SEEK_CUR) == -1) { + SC_log(LOG_ERR, "could not lseek() past 64 bit header"); + return nil; + } + } + + // Find LC_UUID in the load commands + for (size_t i = 0; i < header.ncmds; i++) { + struct load_command lcmd; + + if (read(fd, &lcmd, sizeof(lcmd)) != sizeof(lcmd)) { + SC_log(LOG_ERR, "could not read() load_command"); + break; + } + + if (lcmd.cmd == LC_UUID) { + struct uuid_command uuid_cmd; + + if (read(fd, uuid_cmd.uuid, sizeof(uuid_t)) != sizeof(uuid_t)) { + SC_log(LOG_ERR, "could not read() uuid_command"); + break; + } + + uuid = [[NSUUID alloc] initWithUUIDBytes:uuid_cmd.uuid]; + break; + } else { + if (lseek(fd, lcmd.cmdsize - sizeof(lcmd), SEEK_CUR) == -1) { + SC_log(LOG_ERR, "could not lseek() past load command"); + return nil; + } + } + } + + return uuid; +} + +#define MAX_NFAT_ARCH 32 + +- (NSArray *)copyUUIDsForFatBinary:(int)fd +{ + struct fat_arch * arches = NULL; + mach_msg_type_number_t count; + struct fat_header hdr; + struct host_basic_info hostinfo; + kern_return_t kr; + NSMutableArray * uuids = nil; + + // For a fat architecture, we need find the section that is closet to the host cpu + bzero(&hostinfo, sizeof(hostinfo)); + count = HOST_BASIC_INFO_COUNT; + kr = host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostinfo, &count); + if (kr != KERN_SUCCESS) { + SC_log(LOG_ERR, "host_info() failed: %d", kr); + return nil; + } + + if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) { + SC_log(LOG_ERR, "could not read() fat_header"); + return nil; + } + + // Fat header info are always big-endian + hdr.nfat_arch = OSSwapInt32(hdr.nfat_arch); + if (hdr.nfat_arch > MAX_NFAT_ARCH) { + SC_log(LOG_ERR, "fat_header.nfat_arch (%d) > %d", hdr.nfat_arch, MAX_NFAT_ARCH); + return nil; + } + + arches = (struct fat_arch *)malloc(hdr.nfat_arch * sizeof(struct fat_arch)); + if (arches == NULL) { + // if we could not allocate space for architectures + return nil; + } + + uuids = [[NSMutableArray alloc] init]; + + for (size_t i = 0; i < hdr.nfat_arch; ++i) { + struct fat_arch arch; + + if (read(fd, &arch, sizeof(arch)) != sizeof(arch)) { + SC_log(LOG_ERR, "could not read() fat_arch"); + goto done; + } + arch.cputype = (int)OSSwapInt32(arch.cputype); + arch.offset = OSSwapInt32(arch.offset); + memcpy(&arches[i], &arch, sizeof(arch)); + } + + for (size_t i = 0; i < hdr.nfat_arch; ++i) { + struct fat_arch arch; + NSUUID * uuid; + + memcpy(&arch, &arches[i], sizeof(arch)); + + if (arch.offset == 0) { + SC_log(LOG_ERR, "invalid offset for arch %d", arch.cputype); + goto done; + } + + if (lseek(fd, arch.offset, SEEK_SET) == -1) { + SC_log(LOG_ERR, "could not lseek() to arch %d", arch.cputype); + goto done; + } + + uuid = [self copyUUIDForSingleArch:fd]; + if (uuid == nil) { + SC_log(LOG_ERR, "could not get uuid for arch %d", arch.cputype); + goto done; + } + + if (arch.cputype == hostinfo.cpu_type) { + [uuids insertObject:uuid atIndex:0]; + } else { + [uuids addObject:uuid]; + } + } + + done: + + if (arches != NULL) { + free(arches); + } + if (uuids.count == 0) { + uuids = nil; + } + return uuids; +} + +- (NSArray *)copyUUIDsForExecutable:(const char *)executablePath +{ + int fd; + uint32_t magic; + NSArray * uuids = nil; + + if (executablePath == NULL) { + return nil; + } + + fd = open(executablePath, O_RDONLY); + if (fd == -1) { + if (errno != ENOENT) { + SC_log(LOG_ERR, "open(\"%s\", O_RDONLY) failed: %s", executablePath, strerror(errno)); + } + + return nil; + } + + // Read the magic format to decide which path to take + if (read(fd, &magic, sizeof(magic)) != sizeof(magic)) { + SC_log(LOG_ERR, "read() no magic format: %s", executablePath); + goto done; + } + + // Rewind to the beginning + lseek(fd, 0, SEEK_SET); + switch (magic) { + case FAT_CIGAM: { + uuids = [self copyUUIDsForFatBinary:fd]; + break; + } + + case MH_MAGIC: + case MH_MAGIC_64: { + NSUUID * uuid; + + uuid = [self copyUUIDForSingleArch:fd]; + if (uuid == nil) { + SC_log(LOG_ERR, "%s: failed to get UUID for single arch", __FUNCTION__); + goto done; + } + + uuids = @[ uuid ]; + break; + } + + default: { + break; + } + } + + done: + + close(fd); + return uuids; +} + + +- (void)addWhitelistedPathPolicy:(NSString *)interface forPath:(NSString *)path order:(uint32_t)order +{ + NEPolicyCondition * allInterfacesCondition; + NEPolicyResult * result; + NEPolicyRouteRule * routeRule; + NEPolicySession * session; + NSArray * uuids; + + session = _policySessions[interface]; + if (session == nil) { + SC_log(LOG_ERR, "QoS marking policy: %@: no session", interface); + return; + } + + // create QoS route rule + routeRule = [NEPolicyRouteRule routeRuleWithAction:NEPolicyRouteRuleActionQoSMarking + forInterfaceName:interface]; + result = [NEPolicyResult routeRules:@[ routeRule ]]; + + // create "all interfaces" condition + allInterfacesCondition = [NEPolicyCondition allInterfaces]; + + uuids = [self copyUUIDsForExecutable:[path UTF8String]]; + if ((uuids == nil) || (uuids.count == 0)) { + SC_log(LOG_ERR, "QoS marking policy: %@: could not add path \"%@\"", + interface, + path); + return; + } + + for (NSUUID *uuid in uuids) { + NEPolicy * policy; + NSUInteger policyID; + NEPolicyCondition * uuidCondition; + + // create per-app bundleID-->UUID condition + uuidCondition = [NEPolicyCondition effectiveApplication:uuid]; + + // create and add policy + policy = [[NEPolicy alloc] initWithOrder:order + result:result + conditions:@[ uuidCondition, allInterfacesCondition ]]; + policyID = [session addPolicy:policy]; + if (policyID != 0) { + SC_log(LOG_NOTICE, "QoS marking policy: %@: %u: whitelist path \"%@\" (%@)", + interface, + order, + path, + uuid.UUIDString); + + } else { + SC_log(LOG_ERR, "QoS marking policy: %@: could not add whitelist policy for path \"%@\" (%@)", + interface, + path, + uuid.UUIDString); + } + } + + + return; +} + + +#pragma mark - + + +- (NSArray *)copyUUIDsForUUIDMapping:(xpc_object_t)mapping +{ + NSMutableArray * uuids = nil; + + if ((mapping != NULL) && + (xpc_get_type(mapping) == XPC_TYPE_ARRAY)) { + uuids = [NSMutableArray array]; + + xpc_array_apply(mapping, ^bool(size_t index, xpc_object_t value) { + if ((value != NULL) && + (xpc_get_type(value) == XPC_TYPE_UUID)) { + NSUUID * uuid; + + uuid = [[NSUUID alloc] initWithUUIDBytes:xpc_uuid_get_bytes(value)]; + [uuids addObject:uuid]; + } + return YES; + }); + + if (uuids.count == 0) { + uuids = nil; + } + } + + return uuids; +} + + +- (NSArray *)copyUUIDsForBundleID:(NSString *)bundleID +{ + NSArray * uuids; + xpc_object_t uuidsFromHelper; + + uuidsFromHelper = NEHelperCacheCopyAppUUIDMapping([bundleID UTF8String], NULL); + + uuids = [self copyUUIDsForUUIDMapping:uuidsFromHelper]; + return uuids; +} + + +- (void)addWhitelistedAppIdentifierPolicy:(NSString *)interface forApp:(NSString *)appBundleID order:(uint32_t)order +{ + NEPolicyCondition * allInterfacesCondition; + NEPolicyResult * result; + NEPolicyRouteRule * routeRule; + NEPolicySession * session; + NSArray * uuids; + + if ([appBundleID hasPrefix:@"/"]) { + if (_SC_isAppleInternal()) { + // special case executable path handling (if internal) + [self addWhitelistedPathPolicy:interface forPath:appBundleID order:order]; + } + + return; + } + + session = _policySessions[interface]; + if (session == nil) { + SC_log(LOG_ERR, "QoS marking policy: %@: no session", interface); + return; + } + + // create QoS route rule + routeRule = [NEPolicyRouteRule routeRuleWithAction:NEPolicyRouteRuleActionQoSMarking + forInterfaceName:interface]; + result = [NEPolicyResult routeRules:@[ routeRule ]]; + + // create "all interfaces" condition + allInterfacesCondition = [NEPolicyCondition allInterfaces]; + + uuids = [self copyUUIDsForBundleID:appBundleID]; + if ((uuids == nil) || (uuids.count == 0)) { + SC_log(LOG_ERR, "QoS marking policy: %@: could not add bundleID \"%@\"", + interface, + appBundleID); + return; + } + + for (NSUUID *uuid in uuids) { + NEPolicy * policy; + NSUInteger policyID; + NEPolicyCondition * uuidCondition; + + // create per-app bundleID-->UUID condition + uuidCondition = [NEPolicyCondition effectiveApplication:uuid]; + + // create and add policy + policy = [[NEPolicy alloc] initWithOrder:order + result:result + conditions:@[ uuidCondition, allInterfacesCondition ]]; + policyID = [session addPolicy:policy]; + if (policyID != 0) { + SC_log(LOG_NOTICE, "QoS marking policy: %@: %u: whitelist bundleID \"%@\" (%@)", + interface, + order, + appBundleID, + uuid.UUIDString); + + } else { + SC_log(LOG_ERR, "QoS marking policy: %@: could not add whitelist policy for bundleID \"%@\" (%@)", + interface, + appBundleID, + uuid.UUIDString); + } + } + + return; +} + + +#pragma mark - + + +- (instancetype)init +{ + self = [super init]; + if (self != nil) { + _interfaces = nil; + _policySessions = [NSMutableDictionary dictionary]; + _requested = [NSMutableDictionary dictionary]; + _enabled = [NSMutableDictionary dictionary]; + _enabledAV = [NSMutableDictionary dictionary]; + } + + return self; +} + + +/* + + Have QoS Whitelist AppleAVCalls | net.qos.policy. | Interface Interface Interface + Profile Enabled Apps(#) Enabled | restricted restrict_avapps | QoS Enabled NECP rules NECP AV rules + ======= ======= ========= ============ + ========== =============== + =========== ========== ============= +1 [N] | 0 0 | [Y] [N] [N] + | | +2 [Y] [N] [0] [N] | 0 0 | [N] [N] [N] +3 [Y] [N] [0] [Y] | 0 0 | [N] [N] [N] + | | +4 [Y] [N] [> 0] [N] | 0 0 | [N] [N] [N] +5 [Y] [N] [> 0] [Y] | 0 0 | [N] [N] [N] + | | +6 [Y] [Y] [0] [N] | 1 1 | [Y] [N] [N] +7 [Y] [Y] [0] [Y] | 1 0 | [Y] [N] [Y] + | | +8 [Y] [Y] [> 0] [N] | 1 1 | [Y] [Y] [N] +9 [Y] [Y] [> 0] [Y] | 1 0 | [Y] [Y] [Y] + + Notes (QoSMarking policy) : + * If "QoSEnabled" is not present, assume "Y" + * If "QoSMarkingAppleAudioVideoCalls" is not present, assume "Y" + * If "QoSMarkingWhitelistedAppIdentifiers" is not present (or empty), assume no whitelisted applications + + Notes (sysctl) : + * net.qos.policy.restricted should be "1" when NECP policies are present + * net.qos.policy.restrict_avapps should be "1" when "QoSMarkingAppleAudioVideoCalls" is "N" + + */ + +- (void)updatePolicy:(NSDictionary *)reqPolicy forInterface:(NSString *)interface +{ + // currently enabled settings + NSDictionary * nowPolicy = _enabled[interface]; + BOOL nowDisabled = false; + BOOL nowEnabled = false; + BOOL nowAppleAV = false; + + // requested settings + BOOL reqDefault = false; + BOOL reqDisabled = false; + BOOL reqEnabled = false; + BOOL reqAppleAV = false; + + if (nowPolicy != nil) { + if ([self qosMarkingIsEnabled:nowPolicy]) { + // if we have an enabled QoS marking policy + nowEnabled = true; + } else { + // if we have a disabled QoS marking policy + nowDisabled = true; + } + + nowAppleAV = [self qosMarkingIsAppleAudioVideoCallsEnabled:nowPolicy]; + } + + if (reqPolicy != nil) { + if ([self qosMarkingIsEnabled:reqPolicy]) { + // if QoS marking policy requested + reqEnabled = true; + } else { + // if QoS marking policy present (but disabled) + reqDisabled = true; + } + + reqAppleAV = [self qosMarkingIsAppleAudioVideoCallsEnabled:reqPolicy]; + } else { + reqDefault = true; + } + + if ((!nowEnabled && reqDefault ) || + ( nowEnabled != reqEnabled ) || + ( nowDisabled != reqDisabled) || + ( nowEnabled && reqEnabled && ![nowPolicy isEqual:reqPolicy])) { + int s; + + if (reqEnabled) { + // if we are transitioning to enabled or we have a policy + // change, ensure that we rebuild policies + nowPolicy = nil; + } else { + if ((nowPolicy != nil) && (reqPolicy == nil)) { + SC_log(LOG_NOTICE, "QoS marking policy: %@: remove", interface); + } + + // if QoS marking was enabled (for this interface), close session + [_policySessions removeObjectForKey:interface]; + + // QoS marking policy for this interface is no longer enabled + [_enabled removeObjectForKey:interface]; + [_enabledAV removeObjectForKey:interface]; + } + + // update QoSMarking enabled (per-interface) + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s != -1) { + BOOL enable = reqEnabled || reqDefault; + + SC_log(LOG_NOTICE, "QoS marking policy: %@: %s%s", + interface, + enable ? "enable" : "disable", + reqDefault ? " (default)" : ""); + qosMarkingSetEnabled(s, interface.UTF8String, enable); + close(s); + } else { + SC_log(LOG_ERR, "socket() failed: %s", strerror(errno)); + } + } + + if (reqEnabled) { + NSArray * curAppIDs; + NSArray * reqAppIDs; + BOOL update = FALSE; + + if (nowAppleAV != reqAppleAV) { + update = true; + } + + curAppIDs = [self qosMarkingWhitelistedAppIdentifiers:nowPolicy]; + reqAppIDs = [self qosMarkingWhitelistedAppIdentifiers:reqPolicy]; + if (![curAppIDs isEqual:reqAppIDs]) { + update = true; + } + + if (update) { + BOOL ok; + uint32_t order; + NEPolicySession * session; + + // QoS marking being (or still) enabled for this interface + if (_enabled.count == 0) { + // if we now have a profile requiring us to check NECP policies + qosMarkingSetHavePolicies(true); + } + + // the QoS marking policy for this interface is now enabled + _enabled[interface] = reqPolicy; + + SC_log(LOG_NOTICE, "QoS marking policy: %@: %s", + interface, + nowEnabled ? "update" : "add"); + + // prepare [new] per-interface NECP session + + session = _policySessions[interface]; + if ((session == nil) && ((reqAppIDs.count > 0) || reqAppleAV)) { + // if we need to add NECP policies + session = [self createPolicySession]; + if (session != nil) { + _policySessions[interface] = session; + } else { + SC_log(LOG_ERR, "%@: failed to create policy session", interface); + } + } + + // zap any previously stored policies + if (session != nil) { + ok = [session removeAllPolicies]; + if (!ok) { + SC_log(LOG_ERR, "%@: could not remove policies", interface); + } + } + + // if needed, add policies for any whitelisted applications + if ((session != nil) && (reqAppIDs.count > 0)) { + order = QOS_MARKING_PRIORITY_BLOCK_APPS; + for (NSString *app in reqAppIDs) { + [self addWhitelistedAppIdentifierPolicy:interface forApp:app order:order++]; + } + } + + if (reqAppleAV) { + if (_enabledAV.count == 0) { + // if we are enabling the marking of Apple AV application + // then we do not want to restrict handling of traffic that + // cannot be handled by NECP + qosMarkingSetRestrictAVApps(false); + } + + // the QoS [AV] marking policy for this interface is now enabled + _enabledAV[interface] = reqPolicy; + + if (session != nil) { + // if needed, add Apple audio/video application policies + + order = QOS_MARKING_PRIORITY_BLOCK_AV_APPS; + for (NSString *app in qosMarkingAudioVideoCalls_bundleIDs) { + [self addWhitelistedAppIdentifierPolicy:interface forApp:app order:order++]; + } + + order = QOS_MARKING_PRIORITY_BLOCK_AV_PATHS; + for (NSString *path in qosMarkingAudioVideoCalls_executablePaths) { + [self addWhitelistedPathPolicy:interface forPath:path order:order++]; + } + } + } else { + // the QoS [AV] marking policy for this interface is no longer enabled + [_enabledAV removeObjectForKey:interface]; + + if (_enabledAV.count == 0) { + // if we do not (no longer want to) be marking AV then restrict + // handling traffic that cannot be handled by NECP + qosMarkingSetRestrictAVApps(true); + } + } + + if (session != nil) { + ok = [session apply]; + if (!ok) { + SC_log(LOG_ERR, "%@: could not apply new policies", interface); + } + } + } + } + + // Restore "default" state if no policies + if (_enabled.count == 0) { + qosMarkingSetRestrictAVApps(false); + qosMarkingSetHavePolicies(false); + } +} + + +#pragma mark - +#pragma mark Update QoSMarking Policy Configuration per [SC] changes + + ++ (QoSMarkingController *)sharedController +{ + static QoSMarkingController * controller; + static dispatch_once_t once; + + dispatch_once(&once, ^{ + controller = [[QoSMarkingController alloc] init]; + }); + + return controller; +} + + +- (void)setInterfaces:(NSArray *)newInterfaces +{ + NSArray * curInterfaces; + int s; + + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s == -1) { + SC_log(LOG_ERR, "socket() failed: %s", strerror(errno)); + return; + } + + curInterfaces = _interfaces; + _interfaces = newInterfaces; + + for (NSString *interface in newInterfaces) { + if (!supportsQoSMarking(s, interface.UTF8String)) { + // skip interfaces that do not support QoS marking + continue; + } + + if (![curInterfaces containsObject:interface]) { + NSDictionary * policy; + + // if new interface + policy = _requested[interface]; + [_requested removeObjectForKey:interface]; // make this look like a fresh "add" + [self setPolicy:policy forInterface:interface]; // and "set" the new policy + } + } + + close(s); + return; +} + + +- (void)setPolicy:(NSDictionary *)policy forInterface:(NSString *)interface +{ + if (policy != nil) { + if ([_interfaces containsObject:interface]) { + // set (update) per-interface policy + [self updatePolicy:policy forInterface:interface]; + } + + // track policy for future changes + [_requested setObject:policy forKey:interface]; + } else { + // remove (update) per-interface policy + [self updatePolicy:policy forInterface:interface]; + + // track policy for future changes + [_requested removeObjectForKey:interface]; + } + + return; +} + +@end + + +#pragma mark - +#pragma mark Update QoS Marking Policy Plugin + + +/* + * Function: parse_component + * Purpose: + * Given a string 'key' and a string prefix 'prefix', + * return the next component in the slash '/' separated + * key. + * + * Examples: + * 1. key = "a/b/c" prefix = "a/" + * returns "b" + * 2. key = "a/b/c" prefix = "a/b/" + * returns "c" + */ +static CF_RETURNS_RETAINED CFStringRef +parse_component(CFStringRef key, CFStringRef prefix) +{ + CFMutableStringRef comp; + CFRange range; + + if (!CFStringHasPrefix(key, prefix)) { + return NULL; + } + comp = CFStringCreateMutableCopy(NULL, 0, key); + CFStringDelete(comp, CFRangeMake(0, CFStringGetLength(prefix))); + range = CFStringFind(comp, CFSTR("/"), 0); + if (range.location == kCFNotFound) { + return comp; + } + range.length = CFStringGetLength(comp) - range.location; + CFStringDelete(comp, range); + return comp; +} + + + +static void +qosMarkingConfigChangedCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void *arg) +{ + os_activity_t activity; + CFDictionaryRef changes; + CFIndex n; + static CFStringRef prefix = NULL; + + activity = os_activity_create("processing QoS marking configuration changes", + OS_ACTIVITY_CURRENT, + OS_ACTIVITY_FLAG_DEFAULT); + os_activity_scope(activity); + + if (prefix == NULL) { + prefix = SCDynamicStoreKeyCreate(NULL, + CFSTR("%@/%@/%@/"), + kSCDynamicStoreDomainSetup, + kSCCompNetwork, + kSCCompInterface); + } + + changes = SCDynamicStoreCopyMultiple(store, changedKeys, NULL); + + n = CFArrayGetCount(changedKeys); + for (CFIndex i = 0; i < n; i++) { + CFStringRef key; + + key = CFArrayGetValueAtIndex(changedKeys, i); + + if (CFEqual(key, interfacesKey)) { + CFDictionaryRef info; + + info = (changes != NULL) ? CFDictionaryGetValue(changes, key) : NULL; + if (isA_CFDictionary(info) != NULL) { + CFArrayRef interfaces; + + interfaces = CFDictionaryGetValue(info, kSCPropNetInterfaces); + if (isA_CFArray(interfaces)) { + @autoreleasepool { + QoSMarkingController * controller; + + controller = [QoSMarkingController sharedController]; + [controller setInterfaces:(__bridge NSArray *)interfaces]; + } + } + } + } else { + CFStringRef interface; + + interface = parse_component(key, prefix); + if (interface != NULL) { + CFDictionaryRef policy; + + policy = (changes != NULL) ? CFDictionaryGetValue(changes, key) : NULL; + @autoreleasepool { + QoSMarkingController * controller; + + controller = [QoSMarkingController sharedController]; + [controller setPolicy:(__bridge NSDictionary *)policy + forInterface:(__bridge NSString *)interface]; + } + CFRelease(interface); + } + } + } + + if (changes != NULL) { + CFRelease(changes); + } + + return; +} + + +__private_extern__ +void +load_QoSMarking(CFBundleRef bundle, Boolean bundleVerbose) +{ + CFDictionaryRef dict; + CFStringRef key; + CFMutableArrayRef keys; + Boolean ok; + CFMutableArrayRef patterns; + CFRunLoopSourceRef rls; + SCDynamicStoreRef store; + + SC_log(LOG_DEBUG, "load() called"); + SC_log(LOG_DEBUG, " bundle ID = %@", CFBundleGetIdentifier(bundle)); + + // initialize a few globals + interfacesKey = SCDynamicStoreKeyCreateNetworkInterface(NULL, + kSCDynamicStoreDomainState); + + dict = CFBundleGetInfoDictionary(bundle); + if (isA_CFDictionary(dict)) { + CFArrayRef bundleIDs; + CFArrayRef paths; + + bundleIDs = CFDictionaryGetValue(dict, kQoSMarkingBundleIdentifiersAppleAudioVideoCallsKey); + bundleIDs = isA_CFArray(bundleIDs); + qosMarkingAudioVideoCalls_bundleIDs = (__bridge NSArray *)bundleIDs; + + paths = CFDictionaryGetValue(dict, kQoSMarkingExecutablePathsAppleAudioVideoCallsKey); + paths = isA_CFArray(paths); + qosMarkingAudioVideoCalls_executablePaths = (__bridge NSArray *)paths; + } + + // open a "configd" store to allow cache updates + store = SCDynamicStoreCreate(NULL, + CFSTR("QoS Marking Configuraton plug-in"), + qosMarkingConfigChangedCallback, + NULL); + if (store == NULL) { + SC_log(LOG_ERR, "SCDynamicStoreCreate() failed: %s", SCErrorString(SCError())); + goto error; + } + + // establish notification keys and patterns + keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + + // ...watch for a change in the list of network interfaces + CFArrayAppendValue(keys, interfacesKey); + + // ...watch for (per-interface) QoS marking policy changes + key = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, + kSCDynamicStoreDomainSetup, + kSCCompAnyRegex, + kSCEntNetQoSMarkingPolicy); + CFArrayAppendValue(patterns, key); + CFRelease(key); + + // register the keys/patterns + ok = SCDynamicStoreSetNotificationKeys(store, keys, patterns); + CFRelease(keys); + CFRelease(patterns); + if (!ok) { + SC_log(LOG_NOTICE, "SCDynamicStoreSetNotificationKeys() failed: %s", + SCErrorString(SCError())); + goto error; + } + + rls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0); + if (rls == NULL) { + SC_log(LOG_NOTICE, "SCDynamicStoreCreateRunLoopSource() failed: %s", + SCErrorString(SCError())); + goto error; + } + + CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode); + CFRelease(rls); + + error : + + if (store != NULL) CFRelease(store); + return; +} + + +#ifdef MAIN + + +#pragma mark - +#pragma mark Standalone test code + + +int +main(int argc, char **argv) +{ + _sc_log = FALSE; + _sc_verbose = (argc > 1) ? TRUE : FALSE; + + load_QoSMarking(CFBundleGetMainBundle(), (argc > 1) ? TRUE : FALSE); + CFRunLoopRun(); + // not reached + exit(0); + return 0; +} +#endif diff --git a/Plugins/SimulatorSupport/Info.plist b/Plugins/SimulatorSupport/Info.plist index 4ae6f27..a53febe 100644 --- a/Plugins/SimulatorSupport/Info.plist +++ b/Plugins/SimulatorSupport/Info.plist @@ -9,7 +9,7 @@ CFBundleExecutable SimulatorSupport CFBundleIdentifier - com.apple.SystemConfiguration.SimulatorSupport + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/Plugins/SimulatorSupport/simulator_support.c b/Plugins/SimulatorSupport/simulator_support.c index 7c19e4c..f05022d 100644 --- a/Plugins/SimulatorSupport/simulator_support.c +++ b/Plugins/SimulatorSupport/simulator_support.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015 Apple Inc. All rights reserved. + * Copyright (c) 2013, 2015, 2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -34,12 +34,7 @@ #include #include -#ifndef kDNSServiceCompMulticastDNS -#define kDNSServiceCompMulticastDNS "MulticastDNS" -#endif -#ifndef kDNSServiceCompPrivateDNS -#define kDNSServiceCompPrivateDNS "PrivateDNS" -#endif +#include #include "cache.h" @@ -50,6 +45,26 @@ static SCDynamicStoreRef store_host = NULL; static SCDynamicStoreRef store_sim = NULL; +#pragma mark - +#pragma mark Logging + + +/* + * Logging + */ +__private_extern__ os_log_t +__log_SimulatorSupport() +{ + static os_log_t log = NULL; + + if (log == NULL) { + log = os_log_create("com.apple.SystemConfiguration", "SimulatorSupport"); + } + + return log; +} + + #pragma mark - #pragma mark iOS Simulator Support diff --git a/Plugins/common/IPMonitorControlPrefs.c b/Plugins/common/IPMonitorControlPrefs.c index 0edbd8d..358e298 100644 --- a/Plugins/common/IPMonitorControlPrefs.c +++ b/Plugins/common/IPMonitorControlPrefs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015 Apple Inc. All rights reserved. + * Copyright (c) 2013, 2015, 2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -33,12 +33,14 @@ * - created */ +#include #include #include #include -#include #include "IPMonitorControlPrefs.h" +os_log_t __log_IPMonitor(); + /* * kIPMonitorControlPrefsID * - identifies the IPMonitor preferences file that contains 'Verbose' @@ -67,17 +69,19 @@ IPMonitorControlPrefsGet(void) static void prefs_changed(__unused void * arg) { - os_activity_t activity_id; + os_activity_t activity; - activity_id = os_activity_start("processing logging preference change", - OS_ACTIVITY_FLAG_DEFAULT); + activity = os_activity_create("processing IPMonitor [rank] preference change", + OS_ACTIVITY_CURRENT, + OS_ACTIVITY_FLAG_DEFAULT); + os_activity_scope(activity); /* get the current value */ if (S_callback != NULL) { (*S_callback)(S_prefs); } - os_activity_end(activity_id); + os_release(activity); return; } @@ -157,11 +161,20 @@ IPMonitorControlPrefsInit(CFRunLoopRef runloop, kIPMonitorControlPrefsID); if (runloop != NULL && callback != NULL) { S_callback = callback; - SCPreferencesSetCallback(S_prefs, IPMonitorControlPrefsChanged, NULL); - SCPreferencesScheduleWithRunLoop(S_prefs, runloop, - kCFRunLoopCommonModes); + if (!SCPreferencesSetCallback(S_prefs, IPMonitorControlPrefsChanged, NULL)) { + SC_log(LOG_NOTICE, "SCPreferencesSetCallBack() failed: %s", SCErrorString(SCError())); + goto done; + } + + if (!SCPreferencesScheduleWithRunLoop(S_prefs, runloop, kCFRunLoopCommonModes)) { + SC_log(LOG_NOTICE, "SCPreferencesScheduleWithRunLoop() failed: %s", SCErrorString(SCError())); + (void) SCPreferencesSetCallback(S_prefs, NULL, NULL); + } + enable_prefs_observer(runloop); } + +done : return (S_prefs); } @@ -247,7 +260,7 @@ IPMonitorControlPrefsIsVerbose(void) __private_extern__ Boolean IPMonitorControlPrefsSetVerbose(Boolean verbose) { - if (verbose == FALSE) { + if (!verbose) { prefs_set_boolean(kVerbose, NULL); } else { @@ -279,7 +292,7 @@ main(int argc, char * argv[]) fprintf(stderr, "usage: %s ( on | off )\n", argv[0]); exit(1); } - if (success == FALSE) { + if (!success) { fprintf(stderr, "failed to save prefs\n"); exit(2); } diff --git a/Plugins/common/cache.c b/Plugins/common/cache.c index 2158148..c006238 100644 --- a/Plugins/common/cache.c +++ b/Plugins/common/cache.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2004, 2006, 2011, 2015 Apple Inc. All rights reserved. + * Copyright (c) 2003, 2004, 2006, 2011, 2015, 2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -29,9 +29,14 @@ */ +#ifdef SC_LOG_HANDLE +#include +os_log_t SC_LOG_HANDLE; +#endif //SC_LOG_HANDLE + #include #include -#include // for SCLog() +#include #include "cache.h" @@ -157,9 +162,9 @@ cache_write(SCDynamicStoreRef store) (CFArrayGetCount(cached_removals) > 0) || (CFArrayGetCount(cached_notifys) > 0)) { if (!SCDynamicStoreSetMultiple(store, - cached_set, - cached_removals, - cached_notifys)) { + cached_set, + cached_removals, + cached_notifys)) { SC_log(LOG_NOTICE, "SCDynamicStoreSetMultiple() failed: %s", SCErrorString(SCError())); } diff --git a/SCMonitor/Info.plist b/SCMonitor/Info.plist index 4496add..9e12a86 100644 --- a/SCMonitor/Info.plist +++ b/SCMonitor/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.apple.SystemConfiguration.${EXECUTABLE_NAME} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/SCMonitor/monitor.c b/SCMonitor/monitor.c index cff5c5c..678ab93 100644 --- a/SCMonitor/monitor.c +++ b/SCMonitor/monitor.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2015 Apple Inc. All rights reserved. + * Copyright (c) 2007-2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -31,10 +31,12 @@ #include #include #include -#include #include + +#define SC_LOG_HANDLE __log_SCMonitor() #include #include + #include #include #include @@ -78,8 +80,6 @@ typedef struct { Boolean debug; - asl_object_t log_msg; - CFStringRef configuration_action; CFRunLoopSourceRef monitorRls; @@ -106,6 +106,26 @@ typedef struct { static CFMutableDictionaryRef notify_to_instance = NULL; +#pragma mark - +#pragma mark Logging + + +/* + * Logging + */ +static os_log_t +__log_SCMonitor() +{ + static os_log_t log = NULL; + + if (log == NULL) { + log = os_log_create("com.apple.SystemConfiguration", "SCMonitor"); + } + + return log; +} + + #pragma mark - #pragma mark Authorization @@ -122,9 +142,7 @@ getAuthorization(MyType *myInstance) flags, &myInstance->authorization); if (status != errAuthorizationSuccess) { - SCLOG(NULL, myInstance->log_msg, ASL_LEVEL_ERR, - CFSTR("AuthorizationCreate() failed: status = %d"), - (int)status); + SC_log(LOG_ERR, "AuthorizationCreate() failed: status = %d", (int)status); } } @@ -203,7 +221,7 @@ open_NetworkPrefPane(MyType *myInstance) strlen(NETWORK_PREF_CMD), &aeDesc); if (status != noErr) { - SCLOG(NULL, myInstance->log_msg, ASL_LEVEL_ERR, CFSTR("AECreateDesc() failed: %d"), (int)status); + SC_log(LOG_ERR, "AECreateDesc() failed: %d", (int)status); } prefSpec.appURL = NULL; @@ -214,7 +232,7 @@ open_NetworkPrefPane(MyType *myInstance) status = LSOpenFromURLSpec(&prefSpec, NULL); if (status != noErr) { - SCLOG(NULL, myInstance->log_msg, ASL_LEVEL_ERR, CFSTR("LSOpenFromURLSpec() failed: %d"), (int)status); + SC_log(LOG_ERR, "LSOpenFromURLSpec() failed: %d", (int)status); } CFRelease(prefArray); @@ -248,9 +266,9 @@ notify_remove(MyType *myInstance, Boolean cancel) status = CFUserNotificationCancel(myInstance->userNotification); if (status != 0) { - SCLOG(NULL, myInstance->log_msg, ASL_LEVEL_ERR, - CFSTR("CFUserNotificationCancel() failed, status=%d"), - (int)status); + SC_log(LOG_ERR, + "CFUserNotificationCancel() failed, status=%d", + (int)status); } } CFRelease(myInstance->userNotification); @@ -278,7 +296,7 @@ notify_reply(CFUserNotificationRef userNotification, CFOptionFlags response_flag } } if (myInstance == NULL) { - SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("can't find user notification")); + SC_log(LOG_ERR, "can't find user notification"); return; } @@ -348,7 +366,7 @@ notify_add(MyType *myInstance) CFDictionarySetValue(dict, kCFUserNotificationLocalizationURLKey, url); CFRelease(url); } else { - SCLOG(NULL, myInstance->log_msg, ASL_LEVEL_ERR, CFSTR("can't find bundle")); + SC_log(LOG_ERR, "can't find bundle"); goto done; } @@ -418,7 +436,7 @@ notify_add(MyType *myInstance) &error, dict); if (myInstance->userNotification == NULL) { - SCLOG(NULL, myInstance->log_msg, ASL_LEVEL_ERR, CFSTR("CFUserNotificationCreate() failed: %d"), (int)error); + SC_log(LOG_ERR, "CFUserNotificationCreate() failed: %d", (int)error); goto done; } @@ -428,7 +446,7 @@ notify_add(MyType *myInstance) notify_reply, 0); if (myInstance->userRls == NULL) { - SCLOG(NULL, myInstance->log_msg, ASL_LEVEL_ERR, CFSTR("CFUserNotificationCreateRunLoopSource() failed")); + SC_log(LOG_ERR, "CFUserNotificationCreateRunLoopSource() failed"); CFRelease(myInstance->userNotification); myInstance->userNotification = NULL; goto done; @@ -475,10 +493,12 @@ notify_configure(MyType *myInstance) set = SCNetworkSetCopyCurrent(prefs); if (set == NULL) { - set = SCNetworkSetCreate(prefs); + // if no "current" set, create new/default ("Automatic") set + set = _SCNetworkSetCreateDefault(prefs); if (set == NULL) { goto done; } + SC_log(LOG_DEBUG, "added new \"default\" set"); } for (i = 0; i < n; i++) { @@ -490,23 +510,23 @@ notify_configure(MyType *myInstance) CFStringRef name; name = SCNetworkInterfaceGetLocalizedDisplayName(interface); - SCLOG(NULL, myInstance->log_msg, ASL_LEVEL_NOTICE, CFSTR("add/update service for %@"), name); + SC_log(LOG_NOTICE, "add/update service for %@", name); } } ok = SCPreferencesCommitChanges(prefs); if (!ok) { - SCLOG(NULL, myInstance->log_msg, ASL_LEVEL_ERR, - CFSTR("SCPreferencesCommitChanges() failed: %s"), - SCErrorString(SCError())); + SC_log(LOG_ERR, + "SCPreferencesCommitChanges() failed: %s", + SCErrorString(SCError())); goto done; } ok = SCPreferencesApplyChanges(prefs); if (!ok) { - SCLOG(NULL, myInstance->log_msg, ASL_LEVEL_ERR, - CFSTR("SCPreferencesApplyChanges() failed: %s"), - SCErrorString(SCError())); + SC_log(LOG_ERR, + "SCPreferencesApplyChanges() failed: %s", + SCErrorString(SCError())); goto done; } @@ -554,7 +574,8 @@ updateInterfaceList(MyType *myInstance) set = SCNetworkSetCopyCurrent(prefs); if (set == NULL) { - set = SCNetworkSetCreate(prefs); + // if no "current" set, create new/default ("Automatic") set + set = _SCNetworkSetCreateDefault(prefs); if (set == NULL) { goto done; } @@ -709,9 +730,9 @@ watcher_add_lan(MyType *myInstance) store = SCDynamicStoreCreate(NULL, CFSTR("SCMonitor"), update_lan, &context); if (store == NULL) { - SCLOG(NULL, myInstance->log_msg, ASL_LEVEL_ERR, - CFSTR("SCDynamicStoreCreate() failed: %s"), - SCErrorString(SCError())); + SC_log(LOG_ERR, + "SCDynamicStoreCreate() failed: %s", + SCErrorString(SCError())); return; } @@ -912,8 +933,9 @@ add_node_watcher(MyType *myInstance, io_registry_entry_t node, io_registry_entry } CFArrayAppendValue(myInstance->notifyNodes, myData); } else { - SCLOG(NULL, myInstance->log_msg, ASL_LEVEL_ERR, - CFSTR("add_init_watcher IOServiceAddInterestNotification() failed, kr = 0x%x"), kr); + SC_log(LOG_ERR, + "add_init_watcher IOServiceAddInterestNotification() failed, kr = 0x%x", + kr); } CFRelease(myData); } @@ -948,7 +970,7 @@ add_init_watcher(MyType *myInstance, io_registry_entry_t interface) case kIOReturnNoDevice : // if we have hit the root node break; default : - SCLOG(NULL, myInstance->log_msg, ASL_LEVEL_ERR, CFSTR("add_init_watcher IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr); + SC_log(LOG_ERR, "add_init_watcher IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr); break; } if (node != interface) { @@ -1018,8 +1040,7 @@ watcher_add_serial(MyType *myInstance) myInstance->notifyPort = IONotificationPortCreate(kIOMasterPortDefault); if (myInstance->notifyPort == NULL) { - SCLOG(NULL, myInstance->log_msg, ASL_LEVEL_ERR, - CFSTR("IONotificationPortCreate failed")); + SC_log(LOG_ERR, "IONotificationPortCreate failed"); return; } @@ -1031,9 +1052,7 @@ watcher_add_serial(MyType *myInstance) (void *)myInstance, // refCon &myInstance->notifyIterator); // notification if (kr != KERN_SUCCESS) { - SCLOG(NULL, myInstance->log_msg, ASL_LEVEL_ERR, - CFSTR("SCMonitor : IOServiceAddMatchingNotification returned 0x%x"), - kr); + SC_log(LOG_ERR, "SCMonitor : IOServiceAddMatchingNotification returned 0x%x", kr); return; } @@ -1136,11 +1155,6 @@ watcher_add(MyType *myInstance) { CFBundleRef bundle; - if (myInstance->log_msg == NULL) { - myInstance->log_msg = asl_new(ASL_TYPE_MSG); - asl_set(myInstance->log_msg, ASL_KEY_FACILITY, MY_BUNDLE_ID); - } - bundle = CFBundleGetBundleWithIdentifier(CFSTR(MY_BUNDLE_ID)); if (bundle != NULL) { CFStringRef action; @@ -1196,8 +1210,6 @@ watcher_remove(MyType *myInstance) myInstance->interfaces_known = NULL; } - asl_release(myInstance->log_msg); - myInstance->log_msg = NULL; return; } diff --git a/SystemConfiguration.fproj/BondConfiguration.c b/SystemConfiguration.fproj/BondConfiguration.c index 52f1e9c..2b8cc83 100644 --- a/SystemConfiguration.fproj/BondConfiguration.c +++ b/SystemConfiguration.fproj/BondConfiguration.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2015 Apple Inc. All rights reserved. + * Copyright (c) 2004-2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -35,11 +35,8 @@ #include #include -#include #include "SCNetworkConfigurationInternal.h" #include "SCPreferencesInternal.h" -#include -#include #include #include @@ -81,7 +78,7 @@ siocgifmedia(int s, const char * ifname, int * status, int * active) *status = 0; *active = 0; bzero(&ifmr, sizeof(ifmr)); - strncpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name)); + strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name)); if (ioctl(s, SIOCGIFMEDIA, &ifmr) == -1) { return (-1); } @@ -263,11 +260,9 @@ SCBondInterfaceCopyAll(SCPreferencesRef prefs) SCPreferencesRef ni_prefs; CFStringRef path; - if ((prefs == NULL) || - (__SCPreferencesUsingDefaultPrefs(prefs) == TRUE)) { + if (__SCPreferencesUsingDefaultPrefs(prefs)) { ni_prefs = NULL; - } - else { + } else { ni_prefs = __SCPreferencesCreateNIPrefsFromPrefs(prefs); } @@ -985,7 +980,7 @@ SCBondInterfaceSetMode(SCBondInterfaceRef bond, CFNumberRef mode) return FALSE; } - if (CFNumberGetValue(mode, kCFNumberIntType, &mode_num) == FALSE) { + if (!CFNumberGetValue(mode, kCFNumberIntType, &mode_num)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } @@ -1149,12 +1144,9 @@ __SCBondStatusCreatePrivate(CFAllocatorRef allocator, return NULL; } - /* establish the bond status */ - + /* initialize non-zero/NULL members */ statusPrivate->bond = CFRetain(bond); statusPrivate->status_bond = CFDictionaryCreateCopy(NULL, status_bond); - - statusPrivate->interfaces = NULL; statusPrivate->status_interfaces = CFDictionaryCreateCopy(NULL, status_interfaces); return (SCBondStatusRef)statusPrivate; @@ -1404,7 +1396,7 @@ __bond_set_mode(int s, CFStringRef bond_if, CFNumberRef mode) { struct if_bond_req breq; struct ifreq ifr; - int mode_num; + int mode_num; mode_num = IF_BOND_MODE_LACP; if (mode != NULL) { diff --git a/SystemConfiguration.fproj/BridgeConfiguration.c b/SystemConfiguration.fproj/BridgeConfiguration.c index 53a493f..6abafab 100644 --- a/SystemConfiguration.fproj/BridgeConfiguration.c +++ b/SystemConfiguration.fproj/BridgeConfiguration.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2015 Apple Inc. All rights reserved. + * Copyright (c) 2009-2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -32,11 +32,8 @@ #include #include -#include #include "SCNetworkConfigurationInternal.h" #include "SCPreferencesInternal.h" -#include -#include #include #include @@ -84,7 +81,7 @@ ifbifconf_copy(int s, const char * ifname) uint32_t len = sizeof(struct ifbreq) * 16; bzero(&ifd, sizeof(ifd)); - strncpy(ifd.ifd_name, ifname, sizeof(ifd.ifd_name)); + strlcpy(ifd.ifd_name, ifname, sizeof(ifd.ifd_name)); ifd.ifd_cmd = BRDGGIFS; buflen = sizeof(struct ifbifconf) + len; @@ -249,11 +246,9 @@ SCBridgeInterfaceCopyAll(SCPreferencesRef prefs) SCPreferencesRef ni_prefs; CFStringRef path; - if ((prefs == NULL) || - (__SCPreferencesUsingDefaultPrefs(prefs) == TRUE)) { + if (__SCPreferencesUsingDefaultPrefs(prefs)) { ni_prefs = NULL; - } - else { + } else { ni_prefs = __SCPreferencesCreateNIPrefsFromPrefs(prefs); } context.bridges = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); @@ -961,6 +956,7 @@ __bridge_add_interface(int s, CFStringRef bridge_if, CFStringRef interface_if) return FALSE; } + SC_log(LOG_INFO, "%@: added bridge member: %@", bridge_if, interface_if); return TRUE; } @@ -998,6 +994,41 @@ __bridge_remove_interface(int s, CFStringRef bridge_if, CFStringRef interface_if return FALSE; } + SC_log(LOG_INFO, "%@: removed bridge member: %@", bridge_if, interface_if); + return TRUE; +} + + +static Boolean +__bridge_set_mac(int s, CFStringRef bridge_if, CFDataRef macAddr) +{ + struct ifreq ifr; + + bzero(&ifr, sizeof(ifr)); + (void) _SC_cfstring_to_cstring(bridge_if, + ifr.ifr_name, + sizeof(ifr.ifr_name), + kCFStringEncodingASCII); + ifr.ifr_addr.sa_len = CFDataGetLength(macAddr); + if (ifr.ifr_addr.sa_len > sizeof(ifr.ifr_addr.sa_data)) { + _SCErrorSet(kSCStatusInvalidArgument); + SC_log(LOG_ERR, "%@: maformed MAC address (%d > %lu)", + bridge_if, + ifr.ifr_addr.sa_len, + sizeof(ifr.ifr_addr.sa_data)); + return FALSE; + } + CFDataGetBytes(macAddr, CFRangeMake(0, ifr.ifr_addr.sa_len), (UInt8 *)ifr.ifr_addr.sa_data); + + if (ioctl(s, SIOCSIFLLADDR, &ifr) == -1) { + _SCErrorSet(errno); + SC_log(LOG_ERR, "%@: could not set MAC address: %s", + bridge_if, + strerror(errno)); + return FALSE; + } + + SC_log(LOG_INFO, "%@: updated MAC address: %{ private }@", bridge_if, macAddr); return TRUE; } #endif // IFT_BRIDGE @@ -1030,7 +1061,7 @@ _SCBridgeInterfaceUpdateConfiguration(SCPreferencesRef prefs) /* * remove any no-longer-configured bridge interfaces and - * any devices associated with a bridge that are no longer + * any members associated with a bridge that are no longer * associated with a bridge. */ for (i = 0; i < nActive; i++) { @@ -1072,7 +1103,7 @@ _SCBridgeInterfaceUpdateConfiguration(SCPreferencesRef prefs) CFRangeMake(0, c_count), a_interface)) { /* - * if this device is no longer part + * if this member is no longer part * of the bridge. */ if (s == -1) { @@ -1118,7 +1149,7 @@ _SCBridgeInterfaceUpdateConfiguration(SCPreferencesRef prefs) /* * add any newly-configured bridge interfaces and add any - * devices that should now be associated with the bridge. + * members that should now be associated with the bridge. */ for (i = 0; i < nConfig; i++) { SCBridgeInterfaceRef c_bridge; @@ -1127,6 +1158,7 @@ _SCBridgeInterfaceUpdateConfiguration(SCPreferencesRef prefs) CFIndex c_count; Boolean found = FALSE; CFIndex j; + Boolean setMAC = FALSE; c_bridge = CFArrayGetValueAtIndex(config, i); c_bridge_if = SCNetworkInterfaceGetBSDName(c_bridge); @@ -1146,16 +1178,13 @@ _SCBridgeInterfaceUpdateConfiguration(SCPreferencesRef prefs) if (CFEqual(c_bridge_if, a_bridge_if)) { CFIndex c; - Boolean if_list_change = FALSE; found = TRUE; - if (!_SC_CFEqual(c_bridge_interfaces, a_bridge_interfaces)) { - if_list_change = TRUE; - } - if (!if_list_change) { + if (_SC_CFEqual(c_bridge_interfaces, a_bridge_interfaces)) { break; // if no change } + if (s == -1) { s = inet_dgram_socket(); if (s == -1) { @@ -1164,13 +1193,10 @@ _SCBridgeInterfaceUpdateConfiguration(SCPreferencesRef prefs) goto done; } } - if (!if_list_change) { - break; // no if list changes - } /* - * ensure that the first device of the bridge matches, if - * not then we remove all current devices and add them + * ensure that the first member of the bridge matches, if + * not then we remove all current members and add them * back in the preferred order. */ if ((c_count > 0) && @@ -1196,11 +1222,15 @@ _SCBridgeInterfaceUpdateConfiguration(SCPreferencesRef prefs) } } - a_count = 0; // all active devices have been removed + a_count = 0; // all active members have been removed + } + + if (a_count == 0) { + setMAC = TRUE; } /* - * add any devices which are not currently associated + * add any members which are not currently associated * with the bridge interface. */ for (c = 0; c < c_count; c++) { @@ -1223,7 +1253,22 @@ _SCBridgeInterfaceUpdateConfiguration(SCPreferencesRef prefs) } /* - * if this member interface is not currently part of the bridge. + * if this is the first member interface, set the MAC address + * of the bridge. + */ + if (setMAC) { + CFDataRef macAddr; + + macAddr = _SCNetworkInterfaceGetHardwareAddress(c_interface); + if (!__bridge_set_mac(s, c_bridge_if, macAddr)) { + // if bridge MAC could not be set + ok = FALSE; + } + setMAC = FALSE; + } + + /* + * add the member interface to the bridge. */ c_interface_if = SCNetworkInterfaceGetBSDName(c_interface); if (!__bridge_add_interface(s, c_bridge_if, c_interface_if)) { @@ -1258,6 +1303,8 @@ _SCBridgeInterfaceUpdateConfiguration(SCPreferencesRef prefs) continue; } + setMAC = TRUE; + /* * add the member interfaces */ @@ -1273,6 +1320,24 @@ _SCBridgeInterfaceUpdateConfiguration(SCPreferencesRef prefs) continue; } + /* + * if this is the first member interface, set the MAC address + * of the bridge. + */ + if (setMAC) { + CFDataRef macAddr; + + macAddr = _SCNetworkInterfaceGetHardwareAddress(c_interface); + if (!__bridge_set_mac(s, c_bridge_if, macAddr)) { + // if bridge MAC could not be set + ok = FALSE; + } + setMAC = FALSE; + } + + /* + * add the member interface to the bridge. + */ c_interface_if = SCNetworkInterfaceGetBSDName(c_interface); if (!__bridge_add_interface(s, c_bridge_if, c_interface_if)) { // if member could not be added @@ -1280,7 +1345,6 @@ _SCBridgeInterfaceUpdateConfiguration(SCPreferencesRef prefs) } } } - } done : diff --git a/SystemConfiguration.fproj/CaptiveNetwork.c b/SystemConfiguration.fproj/CaptiveNetwork.c index 94577fe..8ed2fd4 100644 --- a/SystemConfiguration.fproj/CaptiveNetwork.c +++ b/SystemConfiguration.fproj/CaptiveNetwork.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, 2012, 2013 Apple Inc. All rights reserved. + * Copyright (c) 2009, 2010, 2012, 2013, 2015 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -28,6 +28,7 @@ #include #include +#include #pragma mark - @@ -43,22 +44,14 @@ const CFStringRef kCNNetworkInfoKeyBSSID = CFSTR("BSSID"); static void * __loadCaptiveNetwork(void) { - static void *image = NULL; - if (NULL == image) { - const char *framework = "/System/Library/PrivateFrameworks/CaptiveNetwork.framework/CaptiveNetwork"; - struct stat statbuf; - const char *suffix = getenv("DYLD_IMAGE_SUFFIX"); - char path[MAXPATHLEN]; - - strlcpy(path, framework, sizeof(path)); - if (suffix) strlcat(path, suffix, sizeof(path)); - if (0 <= stat(path, &statbuf)) { - image = dlopen(path, RTLD_LAZY | RTLD_LOCAL); - } else { - image = dlopen(framework, RTLD_LAZY | RTLD_LOCAL); - } - } - return (void *)image; + static void *image = NULL; + static dispatch_once_t once; + + dispatch_once(&once, ^{ + image = _SC_dlopen("/System/Library/PrivateFrameworks/CaptiveNetwork.framework/CaptiveNetwork"); + }); + + return image; } diff --git a/SystemConfiguration.fproj/CaptiveNetwork.h b/SystemConfiguration.fproj/CaptiveNetwork.h index 4ab9655..b7ffb27 100644 --- a/SystemConfiguration.fproj/CaptiveNetwork.h +++ b/SystemConfiguration.fproj/CaptiveNetwork.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2015 Apple Inc. All rights reserved. + * Copyright (c) 2009-2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -51,22 +51,8 @@ CF_ASSUME_NONNULL_BEGIN These APIs are treated as advisory only. There is no guarantee or contract that the operating system will take the intended action. - - @note IMPORTANT: This API is deprecated starting in iOS 9. - For captive network applications, this has been completely - replaced by . - For other applications, there is no direct replacement. - Please file a bug describing your use of this API so that - we can consider your requirements as this situation evolves. */ -#define CN_DEPRECATION_NOTICE \ - "For captive network applications, this has been completely " \ - "replaced by . " \ - "For other applications, there is no direct replacement. " \ - "Please file a bug describing your use of this API to that " \ - "we can consider your requirements as this situation evolves." - __BEGIN_DECLS /*! @@ -129,37 +115,25 @@ CNMarkPortalOffline (CFStringRef interfaceName) You MUST release the returned value. */ CFArrayRef __nullable -CNCopySupportedInterfaces (void) - __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_8, __MAC_NA, - __IPHONE_4_1, __IPHONE_9_0, - CN_DEPRECATION_NOTICE); +CNCopySupportedInterfaces (void) __OSX_AVAILABLE_STARTING(__MAC_10_8,__IPHONE_4_1); /*! @constant kCNNetworkInfoKeySSIDData @discussion NetworkInfo Dictionary key for SSID in CFData format */ -extern const CFStringRef kCNNetworkInfoKeySSIDData - __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_NA, __MAC_NA, - __IPHONE_4_1, __IPHONE_9_0, - CN_DEPRECATION_NOTICE); +extern const CFStringRef kCNNetworkInfoKeySSIDData __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_1); /*! @constant kCNNetworkInfoKeySSID @discussion NetworkInfo Dictionary key for SSID in CFString format */ -extern const CFStringRef kCNNetworkInfoKeySSID - __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_NA, __MAC_NA, - __IPHONE_4_1, __IPHONE_9_0, - CN_DEPRECATION_NOTICE); +extern const CFStringRef kCNNetworkInfoKeySSID __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_1); /*! @constant kCNNetworkInfoKeyBSSID @discussion NetworkInfo Dictionary key for BSSID in CFString format */ -extern const CFStringRef kCNNetworkInfoKeyBSSID - __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_NA, __MAC_NA, - __IPHONE_4_1, __IPHONE_9_0, - CN_DEPRECATION_NOTICE); +extern const CFStringRef kCNNetworkInfoKeyBSSID __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_1); /*! @function CNCopyCurrentNetworkInfo @@ -181,10 +155,7 @@ extern const CFStringRef kCNNetworkInfoKeyBSSID You MUST release the returned value. */ CFDictionaryRef __nullable -CNCopyCurrentNetworkInfo (CFStringRef interfaceName) - __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_NA, __MAC_NA, - __IPHONE_4_1, __IPHONE_9_0, - CN_DEPRECATION_NOTICE); +CNCopyCurrentNetworkInfo (CFStringRef interfaceName) __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_1); __END_DECLS diff --git a/SystemConfiguration.fproj/DHCP.c b/SystemConfiguration.fproj/DHCP.c index d192415..11d8302 100644 --- a/SystemConfiguration.fproj/DHCP.c +++ b/SystemConfiguration.fproj/DHCP.c @@ -514,7 +514,7 @@ main(int argc, char * argv[]) printed = FALSE; } } - if (printed == FALSE) { + if (!printed) { print_data((void *)CFDataGetBytePtr(option), len); } if (serviceID) @@ -598,8 +598,7 @@ main(int argc, char * argv[]) } app_id = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), argv[2]); - if (DHCPClientPreferencesSetApplicationOptions(app_id, options, - count) == FALSE) { + if (!DHCPClientPreferencesSetApplicationOptions(app_id, options, count) { printf("operation failed\n"); } if (options) { diff --git a/SystemConfiguration.fproj/DeviceOnHold.c b/SystemConfiguration.fproj/DeviceOnHold.c deleted file mode 100644 index 5b1f437..0000000 --- a/SystemConfiguration.fproj/DeviceOnHold.c +++ /dev/null @@ -1,369 +0,0 @@ -/* - * Copyright (c) 2002-2005 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* - * Modification History - * - * May 29, 2002 Roger Smith - * - initial revision - */ - -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include -#include "dy_framework.h" - -#include "moh_msg.h" -#include "moh.h" -#include "DeviceOnHold.h" - - -#define kIODeviceSupportsHoldKey "V92Modem" - - -typedef struct { - - /* base CFType information */ - CFRuntimeBase cfBase; - - /* device name (e.g. "modem") */ - CFStringRef name; - - int sock; - -} DeviceOnHoldPrivate, *DeviceOnHoldPrivateRef; - - -static CFStringRef -__DeviceOnHoldCopyDescription(CFTypeRef cf) -{ - CFAllocatorRef allocator = CFGetAllocator(cf); - CFMutableStringRef result; - - result = CFStringCreateMutable(allocator, 0); - CFStringAppendFormat(result, NULL, CFSTR(" {\n"), cf, allocator); - CFStringAppendFormat(result, NULL, CFSTR("}")); - - return result; -} - - -static void -__DeviceOnHoldDeallocate(CFTypeRef cf) -{ - DeviceOnHoldPrivateRef DeviceOnHoldPrivate = (DeviceOnHoldPrivateRef)cf; - - /* release resources */ - if (DeviceOnHoldPrivate->name) CFRelease(DeviceOnHoldPrivate->name); - if (DeviceOnHoldPrivate->sock != -1) { - - } - - return; -} - - -static CFTypeID __kDeviceOnHoldTypeID = _kCFRuntimeNotATypeID; - - -static const CFRuntimeClass __DeviceOnHoldClass = { - 0, // version - "DeviceOnHold", // className - NULL, // init - NULL, // copy - __DeviceOnHoldDeallocate, // dealloc - NULL, // equal - NULL, // hash - NULL, // copyFormattingDesc - __DeviceOnHoldCopyDescription // copyDebugDesc -}; - - -static pthread_once_t initialized = PTHREAD_ONCE_INIT; - -static void -__DeviceOnHoldInitialize(void) -{ - __kDeviceOnHoldTypeID = _CFRuntimeRegisterClass(&__DeviceOnHoldClass); - return; -} - - -static DeviceOnHoldPrivateRef -__DeviceOnHoldCreatePrivate(CFAllocatorRef allocator) -{ - DeviceOnHoldPrivateRef devicePrivate; - uint32_t size; - - /* initialize runtime */ - pthread_once(&initialized, __DeviceOnHoldInitialize); - - /* allocate session */ - size = sizeof(DeviceOnHoldPrivate) - sizeof(CFRuntimeBase); - devicePrivate = (DeviceOnHoldPrivateRef)_CFRuntimeCreateInstance(allocator, - __kDeviceOnHoldTypeID, - size, - NULL); - if (!devicePrivate) { - return NULL; - } - - devicePrivate->name = NULL; - devicePrivate->sock = -1; - - return devicePrivate; -} - - -CFTypeID -DeviceOnHoldGetTypeID(void) { - pthread_once(&initialized, __DeviceOnHoldInitialize); /* initialize runtime */ - return __kDeviceOnHoldTypeID; -} - - -/* - * TBD: We determine whether a device supports on hold capability by looking at - * the numeric property DeviceSupportsHold (1 - yes, 0 or no property - no). For - * the Apple Dash II internal modem we also use the property V92Modem to track - * this same capability. - */ - -Boolean -IsDeviceOnHoldSupported(CFStringRef deviceName, // "modem" - CFDictionaryRef options) -{ - CFMutableDictionaryRef deviceToMatch; - uint32_t deviceSupportsHoldValue; - kern_return_t kr; - static mach_port_t masterPort = MACH_PORT_NULL; - io_iterator_t matchingServices; - CFNumberRef num; - CFMutableDictionaryRef properties; - Boolean result = FALSE; - io_service_t service; - - if (CFStringCompare(deviceName, CFSTR("modem"), 0) == kCFCompareEqualTo) { - if (masterPort == MACH_PORT_NULL) { - kr = IOMasterPort(MACH_PORT_NULL, &masterPort); - if (kr != KERN_SUCCESS) { - return FALSE; - } - } - - deviceToMatch = IOServiceMatching("InternalModemSupport"); - if (deviceToMatch == NULL) { - return FALSE; - } - - kr = IOServiceGetMatchingServices(masterPort, deviceToMatch, &matchingServices); - if (kr != KERN_SUCCESS) { - return FALSE; - } - - for ( ; (service = IOIteratorNext(matchingServices)) ; IOObjectRelease(service)) { - io_string_t path; - - kr = IORegistryEntryGetPath(service, kIOServicePlane, path); - assert( kr == KERN_SUCCESS ); - - // grab a copy of the properties - kr = IORegistryEntryCreateCFProperties(service, &properties, kCFAllocatorDefault, kNilOptions); - assert( kr == KERN_SUCCESS ); - - num = CFDictionaryGetValue(properties, CFSTR(kIODeviceSupportsHoldKey)); - if (isA_CFNumber(num)) { - CFNumberGetValue(num, kCFNumberSInt32Type, &deviceSupportsHoldValue); - if (deviceSupportsHoldValue == 1) { - result = TRUE; - } - } - - CFRelease(properties); - } - - IOObjectRelease(matchingServices); - } - - // Note: The issue for the general case is how to go from the SystemConfiguration - // dynamic store to the actual driver. The devicesupportshold property is not - // copied the either of the setup/state descriptions so the caller would need - // to know the exact driver they are searching for. - - return result; -} - - -DeviceOnHoldRef -DeviceOnHoldCreate(CFAllocatorRef allocator, - CFStringRef deviceName, // "modem" - CFDictionaryRef options) -{ - DeviceOnHoldPrivateRef devicePrivate; - int status; - - if (CFStringCompare(deviceName, CFSTR("modem"), 0) != kCFCompareEqualTo) { - return NULL; - } - - devicePrivate = __DeviceOnHoldCreatePrivate(allocator); - if (!devicePrivate) { - return NULL; - } - - status = MOHInit(&devicePrivate->sock, deviceName); - if (status != 0) { - CFRelease(devicePrivate); - return NULL; - } - - devicePrivate->name = CFStringCreateCopy(NULL, deviceName); - - return (DeviceOnHoldRef)devicePrivate; -} - - - -int32_t -DeviceOnHoldGetStatus(DeviceOnHoldRef device) -{ - DeviceOnHoldPrivateRef devicePrivate = (DeviceOnHoldPrivateRef)device; - int err; - uint32_t link = 1; - void *replyBuf; - size_t replyBufLen; - int32_t result = -1; - - if (!device) { - return -1; - } - - if (devicePrivate->sock == -1) { - return -1; - } - - err = MOHExec(devicePrivate->sock, - link, - MOH_SESSION_GET_STATUS, - NULL, - 0, - &replyBuf, - &replyBufLen); - - if (err != 0) { - return -1; - } - - if (replyBufLen == sizeof(result)) { - result = *(int32_t *)replyBuf; - } - - if (replyBuf) CFAllocatorDeallocate(NULL, replyBuf); - return result; -} - - -Boolean -DeviceOnHoldSuspend(DeviceOnHoldRef device) -{ - DeviceOnHoldPrivateRef devicePrivate = (DeviceOnHoldPrivateRef)device; - int err; - uint32_t link = 1; - void *replyBuf; - size_t replyBufLen; - Boolean result = FALSE; - - if (!device) { - return FALSE; - } - - if (devicePrivate->sock == -1) { - return FALSE; - } - - err = MOHExec(devicePrivate->sock, - link, - MOH_PUT_SESSION_ON_HOLD, - NULL, - 0, - &replyBuf, - &replyBufLen); - - if (err != 0) { - return -1; - } - - if (replyBufLen == sizeof(result)) { - result = (*(int32_t *)replyBuf) ? TRUE : FALSE; - } - - if (replyBuf) CFAllocatorDeallocate(NULL, replyBuf); - return result; -} - - -Boolean -DeviceOnHoldResume(DeviceOnHoldRef device) -{ - DeviceOnHoldPrivateRef devicePrivate = (DeviceOnHoldPrivateRef)device; - int err; - uint32_t link = 1; - void *replyBuf; - size_t replyBufLen; - Boolean result = FALSE; - - if (!device) { - return FALSE; - } - - if (devicePrivate->sock == -1) { - return FALSE; - } - - err = MOHExec(devicePrivate->sock, - link, - MOH_RESUME_SESSION_ON_HOLD,NULL, - 0, - &replyBuf, - &replyBufLen); - - if (err != 0) { - return -1; - } - - if (replyBufLen == sizeof(result)) { - result = (*(int32_t *)replyBuf) ? TRUE : FALSE; - } - - if (replyBuf) CFAllocatorDeallocate(NULL, replyBuf); - return result; -} diff --git a/SystemConfiguration.fproj/DeviceOnHold.h b/SystemConfiguration.fproj/DeviceOnHold.h deleted file mode 100644 index 9577bc6..0000000 --- a/SystemConfiguration.fproj/DeviceOnHold.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (c) 2002, 2004, 2005 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -#ifndef _DEVICEONHOLD_H -#define _DEVICEONHOLD_H - -#include -#include - - -/*! - @header DeviceOnHold - */ - - -/*! - @enum - @discussion Returned status codes from DeviceOnHoldGetStatus() - - @constant kDeviceIdle - @constant kDeviceConnecting - @constant kDeviceDataConnectionActive - @constant kDeviceDataConnectionOnHold - @constant kDeviceDisconnecting -*/ -enum -{ - kDeviceIdle = 0, - kDeviceConnecting, - kDeviceDataConnectionActive, - kDeviceDataConnectionOnHold, - kDeviceDisconnecting -}; - - -/*! - @typedef DeviceOnHoldRef - @discussion This is the handle to a specific device - which is used by the DeviceOnHold APIs. - */ -typedef const struct CF_BRIDGED_TYPE(id) __DeviceOnHoldRef * DeviceOnHoldRef; - - -__BEGIN_DECLS - - -/*! - @function IsDeviceOnHoldSupported - @discussion Determines whether a device has the capability to have - a connection placed "on hold". - - This function determines whether the device specified supports - the "on hold" capabality. - - @param devname A CFStringRef that represents the device being queried. - @param options A CFDictionaryRef of various options for the device. - @result TRUE if device supports "on hold". - - */ -Boolean -IsDeviceOnHoldSupported ( - CFStringRef devname, // e.g. "modem" - CFDictionaryRef options - ); - -/*! - @function DeviceOnHoldCreate - @discussion Creates a DeviceOnHoldRef for the specified device supports. - - This function creates a DeviceOnHoldRef handle which will be used - in all subsequent calls to the "on hold" API's. - - @param allocator A CFAllocatorRef. - @param devname A CFStringRef that represents the device being queried. - @param options A CFDictionaryRef of various options for the device. - @result DeviceOnHoldRef to pass to subsequent device hold api's. - - */ -DeviceOnHoldRef -DeviceOnHoldCreate ( - CFAllocatorRef allocator, - CFStringRef devname, // e.g. "modem" - CFDictionaryRef options - ); - - -/*! - @function DeviceOnHoldGetStatus - @discussion Returns the "on hold" status of the device. - - @param deviceRef A DeviceOnHoldRef. - @result The status of device. - - */ -int32_t -DeviceOnHoldGetStatus ( - DeviceOnHoldRef deviceRef - ); - - -/*! - @function DeviceOnHoldSuspend - @discussion Tells the device to go "on hold". - - This function will signal the deviceRef to suspend operations - - @param deviceRef A DeviceOnHoldRef. - @result Boolean if call succeeded. - - */ -Boolean -DeviceOnHoldSuspend ( - DeviceOnHoldRef deviceRef - ); - -/*! - @function DeviceOnHoldResume - @discussion Tells the device to resume. - - This function will signal the deviceRef to resume operations - - @param deviceRef A DeviceOnHoldRef. - @result Boolean if call succeeded. - - */ -Boolean -DeviceOnHoldResume ( - DeviceOnHoldRef deviceRef - ); - -__END_DECLS - -#endif /* _DEVICEONHOLD_H */ - diff --git a/SystemConfiguration.fproj/Info-Embedded.plist b/SystemConfiguration.fproj/Info-Embedded.plist index b4571b9..1f27296 100644 --- a/SystemConfiguration.fproj/Info-Embedded.plist +++ b/SystemConfiguration.fproj/Info-Embedded.plist @@ -9,7 +9,7 @@ CFBundleGetInfoString 1.14 CFBundleIdentifier - com.apple.SystemConfiguration + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/SystemConfiguration.fproj/Info.plist b/SystemConfiguration.fproj/Info.plist index b4571b9..1f27296 100644 --- a/SystemConfiguration.fproj/Info.plist +++ b/SystemConfiguration.fproj/Info.plist @@ -9,7 +9,7 @@ CFBundleGetInfoString 1.14 CFBundleIdentifier - com.apple.SystemConfiguration + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/SystemConfiguration.fproj/LinkConfiguration.c b/SystemConfiguration.fproj/LinkConfiguration.c index 4b92ea0..dc4ef3f 100644 --- a/SystemConfiguration.fproj/LinkConfiguration.c +++ b/SystemConfiguration.fproj/LinkConfiguration.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2007, 2010, 2011, 2013, 2015 Apple Inc. All rights reserved. + * Copyright (c) 2002-2007, 2010, 2011, 2013, 2015, 2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -42,10 +42,7 @@ #include #include // for IPV6_MMTU -#include -#include // for SCLog() #include "SCNetworkConfigurationInternal.h" // for __SCNetworkInterfaceCreatePrivate -#include #include #include @@ -905,9 +902,9 @@ _SCNetworkInterfaceIsPhysicalEthernet(SCNetworkInterfaceRef interface) } static Boolean -__getMTULimits(char ifr_name[IFNAMSIZ], - int *mtu_min, - int *mtu_max) +__getIOMTULimits(char ifr_name[IFNAMSIZ], + int *mtu_min, + int *mtu_max) { int ifType = 0; io_iterator_t io_iter = 0; @@ -1056,7 +1053,40 @@ SCNetworkInterfaceCopyMTU(SCNetworkInterfaceRef interface, *mtu_max = devmtu_p->ifdm_max; } } else { - (void)__getMTULimits(ifr.ifr_name, mtu_min, mtu_max); + ok = __getIOMTULimits(ifr.ifr_name, mtu_min, mtu_max); + if (!ok) { + CFStringRef interfaceType; + + interfaceType = SCNetworkInterfaceGetInterfaceType(interface); + if (CFEqual(interfaceType, kSCNetworkInterfaceTypeBridge)) { + CFIndex i; + CFArrayRef members; + CFIndex n; + + members = SCBridgeInterfaceGetMemberInterfaces(interface); + n = (members != NULL) ? CFArrayGetCount(members) : 0; + if (n > 1) { + if (mtu_min) *mtu_min = IF_MINMTU; + if (mtu_max) *mtu_max = IF_MAXMTU; + } + for (i = 0; i < n; i++) { + SCNetworkInterfaceRef member; + int member_mtu_min; + int member_mtu_max; + + member = CFArrayGetValueAtIndex(members, i); + ok = SCNetworkInterfaceCopyMTU(member, NULL, &member_mtu_min, &member_mtu_max); + if (ok) { + if ((mtu_min != NULL) && (*mtu_min < member_mtu_min)) { + *mtu_min = member_mtu_min; // min MTU needs to be higher + } + if ((mtu_max != NULL) && (*mtu_max > member_mtu_max)) { + *mtu_max = member_mtu_max; // max MTU needs to be lower + } + } + } + } + } } if (mtu_min != NULL) { diff --git a/SystemConfiguration.fproj/NetworkConfiguration.plist b/SystemConfiguration.fproj/NetworkConfiguration.plist index ab5faf3..8b9a638 100644 --- a/SystemConfiguration.fproj/NetworkConfiguration.plist +++ b/SystemConfiguration.fproj/NetworkConfiguration.plist @@ -317,51 +317,6 @@ VerboseLogging 0 - PPP-PPTP - - ACSPEnabled - 1 - CCPEnabled - 1 - CommDisplayTerminalWindow - 0 - CommRedialCount - 1 - CommRedialEnabled - 0 - CommRedialInterval - 5 - CommUseTerminalScript - 0 - DialOnDemand - 0 - DisconnectOnFastUserSwitch - 1 - DisconnectOnIdle - 0 - DisconnectOnIdleTimer - 600 - DisconnectOnLogout - 1 - DisconnectOnSleep - 0 - IPCPCompressionVJ - 0 - IdleReminder - 0 - IdleReminderTimer - 1800 - LCPEchoEnabled - 1 - LCPEchoFailure - 15 - LCPEchoInterval - 20 - Logfile - /var/log/ppp.log - VerboseLogging - 0 - PPP-Serial ACSPEnabled @@ -762,26 +717,6 @@ 1 - PPP-PPTP - - DNS - - IPv4 - - ConfigMethod - PPP - - IPv6 - - ConfigMethod - Automatic - - Proxies - - FTPPassive - 1 - - PPP-Serial DNS diff --git a/SystemConfiguration.fproj/SCD.c b/SystemConfiguration.fproj/SCD.c index 666a511..c9dfe7d 100644 --- a/SystemConfiguration.fproj/SCD.c +++ b/SystemConfiguration.fproj/SCD.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2008, 2010-2015 Apple Inc. All rights reserved. + * Copyright (c) 2000-2008, 2010-2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -37,11 +37,11 @@ #include #include #include +#include +#include -#include -#include -#include "SCD.h" #include "SCDynamicStoreInternal.h" +#include "SCD.h" #include "config.h" /* MiG generated file */ // asl logging @@ -394,13 +394,72 @@ _SC_isInstallEnvironment() { return is_install; } + +os_log_t +_SC_LOG_DEFAULT() +{ + static os_log_t log = NULL; + + if (log == NULL) { + log = os_log_create("com.apple.SystemConfiguration", ""); + } + + return log; +} + + +os_log_type_t +_SC_syslog_os_log_mapping(int level) +{ + if (level < 0) { + level = ~level; + } + + switch (level) { + case LOG_EMERG : + case LOG_ALERT : + case LOG_CRIT : + return OS_LOG_TYPE_ERROR; + + case LOG_ERR : + case LOG_WARNING : + case LOG_NOTICE : + return OS_LOG_TYPE_DEFAULT; + + case LOG_INFO : + return OS_LOG_TYPE_INFO; + + case LOG_DEBUG : + return OS_LOG_TYPE_DEBUG; + } + + return OS_LOG_TYPE_DEFAULT; +}; + static void -__SCLog(asl_object_t asl, asl_object_t msg, int level, CFStringRef formatString, va_list formatArguments) +__SCLog(asl_object_t asl, asl_object_t msg, int level, void *ret_addr, CFStringRef formatString, va_list formatArguments) { - CFDataRef line; + char *line; CFArrayRef lines; CFStringRef str; + if ((asl == NULL) && (level >= 0)) { + const char *__format; + + __format = CFStringGetCStringPtr(formatString, kCFStringEncodingUTF8); + if (__format != NULL) { + os_log_type_t __type; + + __type = _SC_syslog_os_log_mapping(level); + os_log_with_args(_SC_LOG_DEFAULT(), + __type, + __format, + formatArguments, + ret_addr); + return; + } + } + if (asl == NULL) { __SCThreadSpecificDataRef tsd; @@ -432,26 +491,26 @@ __SCLog(asl_object_t asl, asl_object_t msg, int level, CFStringRef formatString, CFIndex n = CFArrayGetCount(lines); for (i = 0; i < n; i++) { - line = CFStringCreateExternalRepresentation(NULL, - CFArrayGetValueAtIndex(lines, i), - kCFStringEncodingUTF8, - (UInt8)'?'); - if (line) { - asl_log(asl, msg, level, "%.*s", (int)CFDataGetLength(line), CFDataGetBytePtr(line)); - CFRelease(line); - } + line =_SC_cfstring_to_cstring_ext(CFArrayGetValueAtIndex(lines, i), + NULL, + 0, + kCFStringEncodingUTF8, + (UInt8)'?', + NULL); + asl_log(asl, msg, level, "%s", line); + CFAllocatorDeallocate(NULL, line); } CFRelease(lines); } } else { - line = CFStringCreateExternalRepresentation(NULL, - str, - kCFStringEncodingUTF8, - (UInt8)'?'); - if (line) { - asl_log(asl, msg, ~level, "%.*s", (int)CFDataGetLength(line), CFDataGetBytePtr(line)); - CFRelease(line); - } + line =_SC_cfstring_to_cstring_ext(str, + NULL, + 0, + kCFStringEncodingUTF8, + (UInt8)'?', + NULL); + asl_log(asl, msg, ~level, "%s", line); + CFAllocatorDeallocate(NULL, line); } CFRelease(str); return; @@ -461,8 +520,9 @@ __SCLog(asl_object_t asl, asl_object_t msg, int level, CFStringRef formatString, static void __SCPrint(FILE *stream, CFStringRef formatString, va_list formatArguments, Boolean trace, Boolean addNL) { - CFDataRef line; + char *line; CFStringRef str; + CFIndex usedBufLen; #ifdef ENABLE_SC_FORMATTING str = _CFStringCreateWithFormatAndArgumentsAux(NULL, @@ -477,10 +537,12 @@ __SCPrint(FILE *stream, CFStringRef formatString, va_list formatArguments, Boole formatArguments); #endif /* !ENABLE_SC_FORMATTING */ - line = CFStringCreateExternalRepresentation(NULL, - str, - kCFStringEncodingUTF8, - (UInt8)'?'); + line =_SC_cfstring_to_cstring_ext(str, + NULL, + 0, + kCFStringEncodingUTF8, + (UInt8)'?', + &usedBufLen); CFRelease(str); if (!line) { return; @@ -496,13 +558,13 @@ __SCPrint(FILE *stream, CFStringRef formatString, va_list formatArguments, Boole (void)fprintf(stream, "%2d:%02d:%02d.%03d ", tm_now.tm_hour, tm_now.tm_min, tm_now.tm_sec, tv_now.tv_usec / 1000); } - (void)fwrite((const void *)CFDataGetBytePtr(line), (size_t)CFDataGetLength(line), 1, stream); + (void)fwrite((const void *)line, usedBufLen, 1, stream); if (addNL) { (void)fputc('\n', stream); } fflush (stream); pthread_mutex_unlock(&lock); - CFRelease(line); + CFAllocatorDeallocate(NULL, line); return; } @@ -542,7 +604,7 @@ SCLog(Boolean condition, int level, CFStringRef formatString, ...) } if (log) { - __SCLog(NULL, NULL, level, formatString, formatArguments); + __SCLog(NULL, NULL, level, __builtin_return_address(0), formatString, formatArguments); va_end(formatArguments); } @@ -559,6 +621,68 @@ SCLog(Boolean condition, int level, CFStringRef formatString, ...) } +void +__SC_Log(int level, CFStringRef format_CF, os_log_t log, os_log_type_t type, const char *format, ...) +{ + Boolean do_log = FALSE; + Boolean do_print = FALSE; + va_list args_log; + va_list args_print; + + /* + * Note: The following are the expected values for _sc_log + * + * 0 if SC messages should be written to stdout/stderr + * 1 if SC messages should be logged w/asl(3) + * 2 if SC messages should be written to stdout/stderr AND logged + */ + + if (_sc_log > 0) { + log = TRUE; // log requested + va_start(args_log, format); + + if (_sc_log > 1) { + do_print = TRUE; // log AND print requested + va_copy(args_print, args_log); + } + } else { + do_print = TRUE; // print requested + va_start(args_print, format); + } + + if (do_log) { + if (level >= 0) { + os_log_with_args(log, + type, + format, + args_log, + __builtin_return_address(0)); + } else { + // if we need to break apart a multi-line message + __SCLog(NULL, + NULL, + level, + __builtin_return_address(0), + format_CF, + args_log); + } + va_end(args_log); + } + + if (do_print) { + __SCPrint(stdout, + format_CF, + args_print, + (_sc_log > 0), // trace + TRUE); // add newline + va_end(args_print); + } + + return; + +} + + void SCLOG(asl_object_t asl, asl_object_t msg, int level, CFStringRef formatString, ...) { @@ -589,7 +713,7 @@ SCLOG(asl_object_t asl, asl_object_t msg, int level, CFStringRef formatString, . } if (log) { - __SCLog(asl, msg, level, formatString, formatArguments); + __SCLog(asl, msg, level, __builtin_return_address(0), formatString, formatArguments); va_end(formatArguments); } @@ -626,21 +750,6 @@ SCPrint(Boolean condition, FILE *stream, CFStringRef formatString, ...) } -void -SCTrace(FILE *stream, CFStringRef formatString, ...) -{ - va_list formatArguments; - - va_start(formatArguments, formatString); - if (stream != NULL) { - __SCPrint(stream, formatString, formatArguments, TRUE, FALSE); - } - va_end(formatArguments); - - return; -} - - #pragma mark - #pragma mark ASL Functions @@ -723,7 +832,6 @@ __SCLoggerAllocate(CFAllocatorRef allocator) __kSCLoggerTypeID, size, NULL); - bzero((void*)state + sizeof(CFRuntimeBase), size); return (state); } @@ -942,9 +1050,9 @@ SCLoggerGetDefaultLogger() return defaultLogger; } -void -SCLoggerVLog(SCLoggerRef logger, int loglevel, CFStringRef formatString, - va_list args) +static void +SCLoggerVLogInternal(SCLoggerRef logger, int loglevel, void *ret_addr, + CFStringRef formatString, va_list args) { asl_object_t aslc; asl_object_t aslm; @@ -960,7 +1068,7 @@ SCLoggerVLog(SCLoggerRef logger, int loglevel, CFStringRef formatString, } aslc = logger->aslc; aslm = logger->aslm; - __SCLog(aslc, aslm, loglevel, formatString, args); + __SCLog(aslc, aslm, loglevel, ret_addr, formatString, args); pthread_mutex_unlock(&(logger->lock)); return; } @@ -971,12 +1079,19 @@ SCLoggerLog(SCLoggerRef logger, int loglevel, CFStringRef formatString, ...) va_list args; va_start(args, formatString); - SCLoggerVLog(logger, loglevel, formatString, args); + SCLoggerVLogInternal(logger, loglevel, __builtin_return_address(0), formatString, args); va_end(args); return; } +void +SCLoggerVLog(SCLoggerRef logger, int loglevel, CFStringRef formatString, va_list args) +{ + SCLoggerVLogInternal(logger, loglevel, __builtin_return_address(0), formatString, args); + return; +} + #pragma mark - #pragma mark SC error handling / logging diff --git a/SystemConfiguration.fproj/SCD.h b/SystemConfiguration.fproj/SCD.h index 78a3c35..747030b 100644 --- a/SystemConfiguration.fproj/SCD.h +++ b/SystemConfiguration.fproj/SCD.h @@ -1,15 +1,15 @@ /* - * Copyright (c) 2011 Apple Inc. All rights reserved. + * Copyright (c) 2011, 2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,7 +17,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ */ @@ -38,12 +38,61 @@ typedef struct { } __SCThreadSpecificData, *__SCThreadSpecificDataRef; - __BEGIN_DECLS + +#pragma mark - +#pragma mark [p]thread specific data + + __SCThreadSpecificDataRef __SCGetThreadSpecificData (void); + +#pragma mark - +#pragma mark ScheduleWithRunLoop/UnscheduleFromRunLoop + + +/* + * object / CFRunLoop management + */ +void +_SC_signalRunLoop (CFTypeRef obj, + CFRunLoopSourceRef rls, + CFArrayRef rlList); + +Boolean +_SC_isScheduled (CFTypeRef obj, + CFRunLoopRef runLoop, + CFStringRef runLoopMode, + CFMutableArrayRef rlList); + +void +_SC_schedule (CFTypeRef obj, + CFRunLoopRef runLoop, + CFStringRef runLoopMode, + CFMutableArrayRef rlList); + +Boolean +_SC_unschedule (CFTypeRef obj, + CFRunLoopRef runLoop, + CFStringRef runLoopMode, + CFMutableArrayRef rlList, + Boolean all); + + +#pragma mark - +#pragma mark Misc + + +char * +_SC_cfstring_to_cstring_ext (CFStringRef cfstr, + char *buf, + CFIndex bufLen, + CFStringEncoding encoding, + UInt8 lossByte, + CFIndex *usedBufLen); + __END_DECLS #endif /* _SCD_H */ diff --git a/SystemConfiguration.fproj/SCDAdd.c b/SystemConfiguration.fproj/SCDAdd.c index 6225492..3142f66 100644 --- a/SystemConfiguration.fproj/SCDAdd.c +++ b/SystemConfiguration.fproj/SCDAdd.c @@ -1,15 +1,15 @@ /* - * Copyright (c) 2000-2005, 2009-2011, 2013 Apple Inc. All rights reserved. + * Copyright (c) 2000-2005, 2009-2011, 2013, 2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,7 +17,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ */ @@ -31,11 +31,6 @@ * - initial revision */ -#include -#include - -#include -#include #include "SCDynamicStoreInternal.h" #include "config.h" /* MiG generated file */ @@ -78,6 +73,8 @@ SCDynamicStoreAddTemporaryValue(SCDynamicStoreRef store, CFStringRef key, CFProp return FALSE; } + os_activity_scope(storePrivate->activity); + retry : /* send the key & data to the server */ @@ -151,6 +148,8 @@ SCDynamicStoreAddValue(SCDynamicStoreRef store, CFStringRef key, CFPropertyListR return FALSE; } + os_activity_scope(storePrivate->activity); + retry : /* send the key & data to the server */ diff --git a/SystemConfiguration.fproj/SCDConsoleUser.c b/SystemConfiguration.fproj/SCDConsoleUser.c index 58cb1c6..35a2cc5 100644 --- a/SystemConfiguration.fproj/SCDConsoleUser.c +++ b/SystemConfiguration.fproj/SCDConsoleUser.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2005, 2009, 2011 Apple Inc. All rights reserved. + * Copyright (c) 2000-2005, 2009, 2011, 2015 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -152,7 +152,7 @@ SCDynamicStoreCopyConsoleInformation(SCDynamicStoreRef store) info = CFDictionaryGetValue(dict, kSCPropUsersConsoleSessionInfo); info = isA_CFArray(info); - if (!info) { + if (info == NULL) { _SCErrorSet(kSCStatusNoKey); goto done; } diff --git a/SystemConfiguration.fproj/SCDGet.c b/SystemConfiguration.fproj/SCDGet.c index 0636050..19d67c5 100644 --- a/SystemConfiguration.fproj/SCDGet.c +++ b/SystemConfiguration.fproj/SCDGet.c @@ -1,15 +1,15 @@ /* - * Copyright (c) 2000-2005, 2009-2011, 2013 Apple Inc. All rights reserved. + * Copyright (c) 2000-2005, 2009-2011, 2013, 2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,7 +17,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ */ @@ -31,11 +31,6 @@ * - initial revision */ -#include -#include - -#include -#include #include "SCDynamicStoreInternal.h" #include "config.h" /* MiG generated file */ @@ -91,6 +86,8 @@ SCDynamicStoreCopyMultiple(SCDynamicStoreRef store, } } + os_activity_scope(storePrivate->activity); + retry : /* send the keys and patterns, fetch the associated result from the server */ @@ -170,6 +167,8 @@ SCDynamicStoreCopyValue(SCDynamicStoreRef store, CFStringRef key) return NULL; } + os_activity_scope(storePrivate->activity); + retry : /* send the key & fetch the associated data from the server */ diff --git a/SystemConfiguration.fproj/SCDHostName.c b/SystemConfiguration.fproj/SCDHostName.c index 5e032b1..193d835 100644 --- a/SystemConfiguration.fproj/SCDHostName.c +++ b/SystemConfiguration.fproj/SCDHostName.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2008, 2011, 2013, 2014 Apple Inc. All rights reserved. + * Copyright (c) 2000-2008, 2011, 2013-2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -34,15 +34,31 @@ #include #include // for __CFStringGetUserDefaultEncoding -#include -#include -#include +#include "SCPreferencesInternal.h" #include "dy_framework.h" #pragma mark ComputerName +static CFStringEncoding +getNameEncoding(CFDictionaryRef dict) +{ + CFStringEncoding encoding; + CFNumberRef num; + + if (!CFDictionaryGetValueIfPresent(dict, + kSCPropSystemComputerNameEncoding, + (const void **)&num) || + !isA_CFNumber(num) || + !CFNumberGetValue(num, kCFNumberSInt32Type, &encoding)) { + encoding = CFStringGetSystemEncoding(); + } + + return encoding; +} + + CFStringRef _SCPreferencesCopyComputerName(SCPreferencesRef prefs, CFStringEncoding *nameEncoding) @@ -78,15 +94,7 @@ _SCPreferencesCopyComputerName(SCPreferencesRef prefs, } if (nameEncoding != NULL) { - CFNumberRef num; - - num = CFDictionaryGetValue(dict, - kSCPropSystemComputerNameEncoding); - if (isA_CFNumber(num)) { - CFNumberGetValue(num, kCFNumberIntType, nameEncoding); - } else { - *nameEncoding = CFStringGetSystemEncoding(); - } + *nameEncoding = getNameEncoding(dict); } } @@ -140,15 +148,7 @@ SCDynamicStoreCopyComputerName(SCDynamicStoreRef store, CFRetain(name); if (nameEncoding != NULL) { - CFNumberRef num; - - num = CFDictionaryGetValue(dict, - kSCPropSystemComputerNameEncoding); - if (isA_CFNumber(num)) { - CFNumberGetValue(num, kCFNumberIntType, nameEncoding); - } else { - *nameEncoding = CFStringGetSystemEncoding(); - } + *nameEncoding = getNameEncoding(dict); } _SCErrorSet(kSCStatusOK); @@ -232,7 +232,7 @@ SCPreferencesSetComputerName(SCPreferencesRef prefs, } else { ok = SCPreferencesPathRemoveValue(prefs, path); } - + if (ok) { if (name != NULL) { SC_log(LOG_NOTICE, "attempting to set the computer name to \"%@\"", name); @@ -332,7 +332,7 @@ SCPreferencesSetHostName(SCPreferencesRef prefs, } else { ok = SCPreferencesPathRemoveValue(prefs, path); } - + if (ok) { if (name != NULL) { SC_log(LOG_NOTICE, "attempting to set the host name to \"%@\"", name); @@ -475,10 +475,7 @@ _SC_stringIsValidDNSName(const char *name) } else if (isalnum(ch) == 0) { switch (ch) { case '.': - if (prev == '.') { - /* no empty labels */ - return FALSE; - } + /* a label separator */ break; case '-': /* hyphens are OK within a label */ @@ -579,7 +576,7 @@ SCPreferencesSetLocalHostName(SCPreferencesRef prefs, } else { ok = SCPreferencesPathRemoveValue(prefs, path); } - + if (ok) { if (name != NULL) { SC_log(LOG_NOTICE, "attempting to set the local host name to \"%@\"", name); diff --git a/SystemConfiguration.fproj/SCDList.c b/SystemConfiguration.fproj/SCDList.c index 154c935..3c631a4 100644 --- a/SystemConfiguration.fproj/SCDList.c +++ b/SystemConfiguration.fproj/SCDList.c @@ -1,15 +1,15 @@ /* - * Copyright (c) 2000-2005, 2009-2011, 2013 Apple Inc. All rights reserved. + * Copyright (c) 2000-2005, 2009-2011, 2013, 2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,7 +17,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ */ @@ -31,11 +31,6 @@ * - initial revision */ -#include -#include - -#include -#include #include "SCDynamicStoreInternal.h" #include "config.h" /* MiG generated file */ @@ -73,6 +68,8 @@ SCDynamicStoreCopyKeyList(SCDynamicStoreRef store, CFStringRef pattern) return NULL; } + os_activity_scope(storePrivate->activity); + retry : /* send the pattern & fetch the associated data from the server */ diff --git a/SystemConfiguration.fproj/SCDNotifierAdd.c b/SystemConfiguration.fproj/SCDNotifierAdd.c index beb1364..b48c02f 100644 --- a/SystemConfiguration.fproj/SCDNotifierAdd.c +++ b/SystemConfiguration.fproj/SCDNotifierAdd.c @@ -1,15 +1,15 @@ /* - * Copyright (c) 2000-2005, 2009-2011, 2013 Apple Inc. All rights reserved. + * Copyright (c) 2000-2005, 2009-2011, 2013, 2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,7 +17,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ */ @@ -31,11 +31,6 @@ * - initial revision */ -#include -#include - -#include -#include #include "SCDynamicStoreInternal.h" #include "config.h" /* MiG generated file */ @@ -80,6 +75,8 @@ SCDynamicStoreAddWatchedKey(SCDynamicStoreRef store, CFStringRef key, Boolean is return FALSE; } + os_activity_scope(storePrivate->activity); + retry : /* send the key to the server */ diff --git a/SystemConfiguration.fproj/SCDNotifierCancel.c b/SystemConfiguration.fproj/SCDNotifierCancel.c index 840f649..fff2d32 100644 --- a/SystemConfiguration.fproj/SCDNotifierCancel.c +++ b/SystemConfiguration.fproj/SCDNotifierCancel.c @@ -1,15 +1,15 @@ /* - * Copyright (c) 2000-2005, 2008-2011, 2015 Apple Inc. All rights reserved. + * Copyright (c) 2000-2005, 2008-2011, 2015, 2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,7 +17,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ */ @@ -31,20 +31,16 @@ * - initial revision */ -#include -#include - -#include -#include #include "SCDynamicStoreInternal.h" #include "config.h" /* MiG generated file */ Boolean SCDynamicStoreNotifyCancel(SCDynamicStoreRef store) { - SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store; - kern_return_t status; - int sc_status; + struct os_activity_scope_state_s activity_state; + SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store; + kern_return_t status; + int sc_status; if (store == NULL) { /* sorry, you must provide a session */ @@ -58,8 +54,13 @@ SCDynamicStoreNotifyCancel(SCDynamicStoreRef store) return TRUE; case Using_NotifierInformViaRunLoop : if (storePrivate->rls != NULL) { - CFRunLoopSourceInvalidate(storePrivate->rls); + CFRunLoopSourceRef rls; + + rls = storePrivate->rls; storePrivate->rls = NULL; + + CFRunLoopSourceInvalidate(rls); + CFRelease(rls); } return TRUE; case Using_NotifierInformViaDispatch : @@ -75,6 +76,8 @@ SCDynamicStoreNotifyCancel(SCDynamicStoreRef store) goto done; } + os_activity_scope_enter(storePrivate->activity, &activity_state); + status = notifycancel(storePrivate->server, (int *)&sc_status); if (__SCDynamicStoreCheckRetryAndHandleError(store, @@ -84,10 +87,9 @@ SCDynamicStoreNotifyCancel(SCDynamicStoreRef store) sc_status = kSCStatusOK; } - done : + os_activity_scope_leave(&activity_state); - /* set notifier inactive */ - storePrivate->notifyStatus = NotifierNotRegistered; + done : if (sc_status != kSCStatusOK) { _SCErrorSet(sc_status); diff --git a/SystemConfiguration.fproj/SCDNotifierGetChanges.c b/SystemConfiguration.fproj/SCDNotifierGetChanges.c index cb8b7cc..5f70d1b 100644 --- a/SystemConfiguration.fproj/SCDNotifierGetChanges.c +++ b/SystemConfiguration.fproj/SCDNotifierGetChanges.c @@ -1,15 +1,15 @@ /* - * Copyright (c) 2000, 2001, 2003-2005, 2009-2011 Apple Inc. All rights reserved. + * Copyright (c) 2000, 2001, 2003-2005, 2009-2011, 2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,7 +17,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ */ @@ -31,11 +31,6 @@ * - initial revision */ -#include -#include - -#include -#include #include "SCDynamicStoreInternal.h" #include "config.h" /* MiG generated file */ @@ -60,6 +55,8 @@ SCDynamicStoreCopyNotifiedKeys(SCDynamicStoreRef store) return NULL; } + os_activity_scope(storePrivate->activity); + retry : /* send the key & fetch the associated data from the server */ diff --git a/SystemConfiguration.fproj/SCDNotifierInformViaCallback.c b/SystemConfiguration.fproj/SCDNotifierInformViaCallback.c index ff1e055..a0e5f44 100644 --- a/SystemConfiguration.fproj/SCDNotifierInformViaCallback.c +++ b/SystemConfiguration.fproj/SCDNotifierInformViaCallback.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2005, 2008-2015 Apple Inc. All rights reserved. + * Copyright (c) 2000-2005, 2008-2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -31,19 +31,11 @@ * - initial revision */ -#include -#include -#include -#include -#include -#include - -#include -#include #include "SCDynamicStoreInternal.h" #include "config.h" /* MiG generated file */ +#include "SCD.h" -#if !TARGET_IPHONE_SIMULATOR || (defined(IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED) && (IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED >= 1090)) +#if !TARGET_OS_SIMULATOR || (defined(IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED) && (IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED >= 1090)) #define HAVE_MACHPORT_GUARDS #endif @@ -63,15 +55,11 @@ notifyMPCopyDescription(const void *info) static void rlsCallback(CFMachPortRef port, void *msg, CFIndex size, void *info) { - os_activity_t activity_id; mach_no_senders_notification_t *buf = msg; mach_msg_id_t msgid = buf->not_header.msgh_id; SCDynamicStoreRef store = (SCDynamicStoreRef)info; SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store; - activity_id = os_activity_start("processing SCDynamicStore notification", - OS_ACTIVITY_FLAG_DEFAULT); - if (msgid == MACH_NOTIFY_NO_SENDERS) { /* the server died, disable additional callbacks */ #ifdef DEBUG @@ -97,8 +85,6 @@ rlsCallback(CFMachPortRef port, void *msg, CFIndex size, void *info) CFRunLoopSourceSignal(storePrivate->rls); } - os_activity_end(activity_id); - return; } @@ -114,7 +100,7 @@ rlsSchedule(void *info, CFRunLoopRef rl, CFStringRef mode) (rl != NULL) ? mode : CFSTR("libdispatch")); #endif /* DEBUG */ - if (storePrivate->rlList == NULL) { + if (storePrivate->rlsNotifyPort == NULL) { CFMachPortContext context = { 0 , (void *)store , CFRetain @@ -194,6 +180,12 @@ rlsSchedule(void *info, CFRunLoopRef rl, CFStringRef mode) SC_log(LOG_NOTICE, "oldNotify != MACH_PORT_NULL"); } +#ifdef DEBUG + SC_log(LOG_DEBUG, " establish notification request with SCDynamicStore server"); +#endif /* DEBUG */ + + os_activity_scope(storePrivate->activity); + retry : __MACH_PORT_DEBUG(TRUE, "*** rlsSchedule", port); @@ -236,12 +228,17 @@ rlsSchedule(void *info, CFRunLoopRef rl, CFStringRef mode) port, rlsCallback, &context); - storePrivate->rlsNotifyRLS = CFMachPortCreateRunLoopSource(NULL, storePrivate->rlsNotifyPort, 0); - storePrivate->rlList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + if (rl != NULL) { + storePrivate->rlsNotifyRLS = CFMachPortCreateRunLoopSource(NULL, storePrivate->rlsNotifyPort, 0); + storePrivate->rlList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + } } if ((rl != NULL) && (storePrivate->rlsNotifyRLS != NULL)) { + /* set notifier active */ + storePrivate->notifyStatus = Using_NotifierInformViaRunLoop; + if (!_SC_isScheduled(store, rl, mode, storePrivate->rlList)) { /* * if we are not already scheduled with this runLoop / runLoopMode @@ -296,6 +293,13 @@ rlsCancel(void *info, CFRunLoopRef rl, CFStringRef mode) "*** rlsCancel", CFMachPortGetPort(storePrivate->rlsNotifyPort)); + if (storePrivate->rls != NULL) { + // Remove the reference we took on the rls. We do not invalidate + // the runloop source and let the client do it when appropriate. + CFRelease(storePrivate->rls); + storePrivate->rls = NULL; + } + if (storePrivate->rlList != NULL) { CFRelease(storePrivate->rlList); storePrivate->rlList = NULL; @@ -329,6 +333,12 @@ rlsCancel(void *info, CFRunLoopRef rl, CFStringRef mode) #endif // HAVE_MACHPORT_GUARDS } +#ifdef DEBUG + SC_log(LOG_DEBUG, " cancel notification request with SCDynamicStore server"); +#endif /* DEBUG */ + + os_activity_scope(storePrivate->activity); + if (storePrivate->server != MACH_PORT_NULL) { kr = notifycancel(storePrivate->server, (int *)&sc_status); @@ -341,6 +351,9 @@ rlsCancel(void *info, CFRunLoopRef rl, CFStringRef mode) return; } } + + /* set notifier inactive */ + storePrivate->notifyStatus = NotifierNotRegistered; } return; @@ -350,7 +363,6 @@ rlsCancel(void *info, CFRunLoopRef rl, CFStringRef mode) static void rlsPerform(void *info) { - os_activity_t activity_id; CFArrayRef changedKeys = NULL; void *context_info; void (*context_release)(const void *); @@ -358,9 +370,6 @@ rlsPerform(void *info) SCDynamicStoreRef store = (SCDynamicStoreRef)info; SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store; - activity_id = os_activity_start("processing SCDynamicStore notification", - OS_ACTIVITY_FLAG_DEFAULT); - #ifdef DEBUG SC_log(LOG_DEBUG, " executing notification function"); #endif /* DEBUG */ @@ -386,6 +395,7 @@ rlsPerform(void *info) context_release = NULL; } if (rlsFunction != NULL) { + SC_log(LOG_DEBUG, "exec SCDynamicStore callout"); (*rlsFunction)(store, changedKeys, context_info); } if (context_release != NULL) { @@ -394,62 +404,14 @@ rlsPerform(void *info) done : +#ifdef DEBUG + SC_log(LOG_DEBUG, " done!"); +#endif /* DEBUG */ + if (changedKeys != NULL) { CFRelease(changedKeys); } - os_activity_end(activity_id); - - return; -} - - -static CFTypeRef -rlsRetain(CFTypeRef cf) -{ - SCDynamicStoreRef store = (SCDynamicStoreRef)cf; - SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store; - - switch (storePrivate->notifyStatus) { - case NotifierNotRegistered : - /* mark RLS active */ - storePrivate->notifyStatus = Using_NotifierInformViaRunLoop; - /* keep a reference to the store */ - CFRetain(store); - break; - case Using_NotifierInformViaRunLoop : - break; - default : - SC_log(LOG_NOTICE, "unexpected notify status=%d", storePrivate->notifyStatus); - break; - } - - return cf; -} - - -static void -rlsRelease(CFTypeRef cf) -{ - SCDynamicStoreRef store = (SCDynamicStoreRef)cf; - SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store; - - switch (storePrivate->notifyStatus) { - case NotifierNotRegistered : - break; - case Using_NotifierInformViaRunLoop : - /* mark RLS inactive */ - storePrivate->notifyStatus = NotifierNotRegistered; - storePrivate->rls = NULL; - - /* release our reference to the store */ - CFRelease(store); - break; - default : - SC_log(LOG_NOTICE, "unexpected notify status=%d", storePrivate->notifyStatus); - break; - } - return; } @@ -517,13 +479,11 @@ SCDynamicStoreCreateRunLoopSource(CFAllocatorRef allocator, return NULL; } - if (storePrivate->rls != NULL) { - CFRetain(storePrivate->rls); - } else { + if (storePrivate->rls == NULL) { CFRunLoopSourceContext context = { 0 // version , (void *)store // info - , rlsRetain // retain - , rlsRelease // release + , CFRetain // retain + , CFRelease // release , rlsCopyDescription // copyDescription , CFEqual // equal , CFHash // hash @@ -538,6 +498,10 @@ SCDynamicStoreCreateRunLoopSource(CFAllocatorRef allocator, } } + if (storePrivate->rls != NULL) { + CFRetain(storePrivate->rls); + } + return storePrivate->rls; } @@ -650,6 +614,10 @@ SCDynamicStoreSetDispatchQueue(SCDynamicStoreRef store, dispatch_queue_t queue) msgid = notify_msg.msg.header.msgh_id; +#ifdef DEBUG + SC_log(LOG_DEBUG, "dispatch source callback, queue rlsPerform"); +#endif /* DEBUG */ + CFRetain(store); dispatch_group_async(group, queue, ^{ if (msgid == MACH_NOTIFY_NO_SENDERS) { @@ -685,7 +653,7 @@ SCDynamicStoreSetDispatchQueue(SCDynamicStoreRef store, dispatch_queue_t queue) rlsCancel((void*)store, NULL, NULL); - if (drainGroup != NULL) { + if ((drainGroup != NULL) && (drainQueue != NULL)) { dispatch_group_notify(drainGroup, drainQueue, ^{ // release group/queue references dispatch_release(drainQueue); diff --git a/SystemConfiguration.fproj/SCDNotifierInformViaFD.c b/SystemConfiguration.fproj/SCDNotifierInformViaFD.c index 77a7611..05f5165 100644 --- a/SystemConfiguration.fproj/SCDNotifierInformViaFD.c +++ b/SystemConfiguration.fproj/SCDNotifierInformViaFD.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2001, 2003-2005, 2008-2011, 2013, 2015 Apple Inc. All rights reserved. + * Copyright (c) 2000, 2001, 2003-2005, 2008-2011, 2013, 2015, 2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -31,11 +31,6 @@ * - initial revision */ -#include -#include - -#include -#include #include "SCDynamicStoreInternal.h" #include "config.h" /* MiG generated file */ @@ -50,12 +45,13 @@ SCDynamicStoreNotifyFileDescriptor(SCDynamicStoreRef store, int32_t identifier, int *fd) { - int fildes[2] = { -1, -1 }; - fileport_t fileport = MACH_PORT_NULL; - int ret; - int sc_status; - SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store; - kern_return_t status; + struct os_activity_scope_state_s activity_state; + int fildes[2] = { -1, -1 }; + fileport_t fileport = MACH_PORT_NULL; + int ret; + int sc_status; + SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store; + kern_return_t status; if (store == NULL) { /* sorry, you must provide a session */ @@ -95,6 +91,8 @@ SCDynamicStoreNotifyFileDescriptor(SCDynamicStoreRef store, goto fail; } + os_activity_scope_enter(storePrivate->activity, &activity_state); + retry : status = notifyviafd(storePrivate->server, @@ -109,6 +107,8 @@ SCDynamicStoreNotifyFileDescriptor(SCDynamicStoreRef store, goto retry; } + os_activity_scope_leave(&activity_state); + if (status != KERN_SUCCESS) { _SCErrorSet(status); goto fail; diff --git a/SystemConfiguration.fproj/SCDNotifierInformViaSignal.c b/SystemConfiguration.fproj/SCDNotifierInformViaSignal.c index 66fc49b..c4aa6ef 100644 --- a/SystemConfiguration.fproj/SCDNotifierInformViaSignal.c +++ b/SystemConfiguration.fproj/SCDNotifierInformViaSignal.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2001, 2004, 2005, 2009-2011, 2015 Apple Inc. All rights reserved. + * Copyright (c) 2000, 2001, 2004, 2005, 2009-2011, 2015, 2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -31,11 +31,6 @@ * - initial revision */ -#include -#include - -#include -#include #include "SCDynamicStoreInternal.h" #include "config.h" /* MiG generated file */ @@ -72,6 +67,8 @@ SCDynamicStoreNotifySignal(SCDynamicStoreRef store, pid_t pid, int sig) return FALSE; } + os_activity_scope(storePrivate->activity); + retry : status = notifyviasignal(storePrivate->server, task, sig, (int *)&sc_status); diff --git a/SystemConfiguration.fproj/SCDNotifierRemove.c b/SystemConfiguration.fproj/SCDNotifierRemove.c index 20cc423..d538274 100644 --- a/SystemConfiguration.fproj/SCDNotifierRemove.c +++ b/SystemConfiguration.fproj/SCDNotifierRemove.c @@ -1,15 +1,15 @@ /* - * Copyright (c) 2000-2005, 2009-2011, 2013 Apple Inc. All rights reserved. + * Copyright (c) 2000-2005, 2009-2011, 2013, 2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,7 +17,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ */ @@ -31,11 +31,6 @@ * - initial revision */ -#include -#include - -#include -#include #include "SCDynamicStoreInternal.h" #include "config.h" /* MiG generated file */ @@ -90,6 +85,8 @@ SCDynamicStoreRemoveWatchedKey(SCDynamicStoreRef store, CFStringRef key, Boolean return FALSE; } + os_activity_scope(storePrivate->activity); + retry : /* send the key to the server */ diff --git a/SystemConfiguration.fproj/SCDNotifierSetKeys.c b/SystemConfiguration.fproj/SCDNotifierSetKeys.c index 76222d1..ff71643 100644 --- a/SystemConfiguration.fproj/SCDNotifierSetKeys.c +++ b/SystemConfiguration.fproj/SCDNotifierSetKeys.c @@ -1,15 +1,15 @@ /* - * Copyright (c) 2000, 2001, 2003-2005, 2009-2011, 2013 Apple Inc. All rights reserved. + * Copyright (c) 2000, 2001, 2003-2005, 2009-2011, 2013, 2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,7 +17,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ */ @@ -28,15 +28,9 @@ * - initial revision */ -#include -#include - -#include -#include #include "SCDynamicStoreInternal.h" #include "config.h" /* MiG generated file */ - Boolean SCDynamicStoreSetNotificationKeys(SCDynamicStoreRef store, CFArrayRef keys, @@ -81,6 +75,8 @@ SCDynamicStoreSetNotificationKeys(SCDynamicStoreRef store, } } + os_activity_scope(storePrivate->activity); + retry : /* send the keys and patterns, fetch the associated result from the server */ diff --git a/SystemConfiguration.fproj/SCDNotifierWait.c b/SystemConfiguration.fproj/SCDNotifierWait.c index 5ea1ba3..62f92fb 100644 --- a/SystemConfiguration.fproj/SCDNotifierWait.c +++ b/SystemConfiguration.fproj/SCDNotifierWait.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2001, 2004, 2006, 2009-2011, 2015 Apple Inc. All rights reserved. + * Copyright (c) 2000, 2001, 2004, 2006, 2009-2011, 2015, 2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -31,13 +31,10 @@ * - initial revision */ -#include -#include - -#include -#include #include "SCDynamicStoreInternal.h" #include "config.h" /* MiG generated file */ +#include + static mach_msg_id_t waitForMachMessage(mach_port_t port) @@ -138,6 +135,8 @@ SCDynamicStoreNotifyWait(SCDynamicStoreRef store) SC_log(LOG_NOTICE, "oldNotify != MACH_PORT_NULL"); } + os_activity_scope(storePrivate->activity); + retry : status = notifyviaport(storePrivate->server, @@ -194,6 +193,8 @@ SCDynamicStoreNotifyWait(SCDynamicStoreRef store) return FALSE; } + os_activity_scope(storePrivate->activity); + // something changed, cancelling notification request status = notifycancel(storePrivate->server, (int *)&sc_status); diff --git a/SystemConfiguration.fproj/SCDNotify.c b/SystemConfiguration.fproj/SCDNotify.c index 2b21178..6850959 100644 --- a/SystemConfiguration.fproj/SCDNotify.c +++ b/SystemConfiguration.fproj/SCDNotify.c @@ -1,15 +1,15 @@ /* - * Copyright (c) 2000-2005, 2009-2011, 2013 Apple Inc. All rights reserved. + * Copyright (c) 2000-2005, 2009-2011, 2013, 2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,7 +17,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ */ @@ -28,11 +28,6 @@ * - initial revision */ -#include -#include - -#include -#include #include "SCDynamicStoreInternal.h" #include "config.h" /* MiG generated file */ @@ -69,6 +64,8 @@ SCDynamicStoreNotifyValue(SCDynamicStoreRef store, return FALSE; } + os_activity_scope(storePrivate->activity); + retry : /* send the key to the server */ diff --git a/SystemConfiguration.fproj/SCDOpen.c b/SystemConfiguration.fproj/SCDOpen.c index e0864b1..f377070 100644 --- a/SystemConfiguration.fproj/SCDOpen.c +++ b/SystemConfiguration.fproj/SCDOpen.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2006, 2008-2015 Apple Inc. All rights reserved. + * Copyright (c) 2000-2006, 2008-2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -40,12 +40,9 @@ #include #include -#include -#include -#include "SCD.h" #include "SCDynamicStoreInternal.h" #include "config.h" /* MiG generated file */ - +#include "SCD.h" static CFStringRef _sc_bundleID = NULL; static pthread_mutex_t _sc_lock = PTHREAD_MUTEX_INITIALIZER; @@ -64,6 +61,19 @@ static const char *notifyType[] = { }; +__private_extern__ os_log_t +__log_SCDynamicStore() +{ + static os_log_t log = NULL; + + if (log == NULL) { + log = os_log_create("com.apple.SystemConfiguration", "SCDynamicStore"); + } + + return log; +} + + static CFStringRef __SCDynamicStoreCopyDescription(CFTypeRef cf) { CFAllocatorRef allocator = CFGetAllocator(cf); @@ -166,6 +176,9 @@ __SCDynamicStoreDeallocate(CFTypeRef cf) if (storePrivate->name != NULL) CFRelease(storePrivate->name); if (storePrivate->options != NULL) CFRelease(storePrivate->options); + /* release activity tracing */ + if (storePrivate->activity != NULL) os_release(storePrivate->activity); + return; } @@ -245,20 +258,31 @@ __SCDynamicStoreServerPort(SCDynamicStorePrivateRef storePrivate, kern_return_t server_name = getenv("SCD_SERVER"); +#ifndef DEBUG + /* + * only allow the SCDynamicStore server bootstrap name to be changed with + * DEBUG builds. For RELEASE builds, assume that no server is available. + */ + if (server_name != NULL) { + *status = BOOTSTRAP_UNKNOWN_SERVICE; + return MACH_PORT_NULL; + } +#endif /* DEBUG */ + if (server_name == NULL) { server_name = SCD_SERVER; } -#if defined(BOOTSTRAP_PRIVILEGED_SERVER) && !TARGET_IPHONE_SIMULATOR +#if defined(BOOTSTRAP_PRIVILEGED_SERVER) && !TARGET_OS_SIMULATOR *status = bootstrap_look_up2(bootstrap_port, server_name, &server, 0, BOOTSTRAP_PRIVILEGED_SERVER); -#else // defined(BOOTSTRAP_PRIVILEGED_SERVER) && !TARGET_IPHONE_SIMULATOR +#else // defined(BOOTSTRAP_PRIVILEGED_SERVER) && !TARGET_OS_SIMULATOR *status = bootstrap_look_up(bootstrap_port, server_name, &server); -#endif // defined(BOOTSTRAP_PRIVILEGED_SERVER) && !TARGET_IPHONE_SIMULATOR +#endif // defined(BOOTSTRAP_PRIVILEGED_SERVER) && !TARGET_OS_SIMULATOR switch (*status) { case BOOTSTRAP_SUCCESS : @@ -294,7 +318,6 @@ __SCDynamicStoreCreatePrivate(CFAllocatorRef allocator, /* initialize runtime */ pthread_once(&initialized, __SCDynamicStoreInitialize); - /* allocate session */ size = sizeof(SCDynamicStorePrivate) - sizeof(CFRuntimeBase); storePrivate = (SCDynamicStorePrivateRef)_CFRuntimeCreateInstance(allocator, @@ -306,61 +329,30 @@ __SCDynamicStoreCreatePrivate(CFAllocatorRef allocator, return NULL; } + /* initialize non-zero/NULL members */ + /* client side of the "configd" session */ storePrivate->name = (name != NULL) ? CFRetain(name) : NULL; - storePrivate->options = NULL; - /* server side of the "configd" session */ - storePrivate->server = MACH_PORT_NULL; - storePrivate->serverNullSession = FALSE; - - /* flags */ - storePrivate->useSessionKeys = FALSE; + /* "client" activity tracing */ + storePrivate->activity = os_activity_create("accessing SCDynamicStore", + OS_ACTIVITY_CURRENT, + OS_ACTIVITY_FLAG_DEFAULT); /* Notification status */ storePrivate->notifyStatus = NotifierNotRegistered; /* "client" information associated with SCDynamicStoreCreateRunLoopSource() */ - storePrivate->rlList = NULL; - storePrivate->rls = NULL; storePrivate->rlsFunction = callout; - storePrivate->rlsContext.info = NULL; - storePrivate->rlsContext.retain = NULL; - storePrivate->rlsContext.release = NULL; - storePrivate->rlsContext.copyDescription = NULL; - if (context) { + if (context != NULL) { bcopy(context, &storePrivate->rlsContext, sizeof(SCDynamicStoreContext)); if (context->retain != NULL) { storePrivate->rlsContext.info = (void *)(*context->retain)(context->info); } } - storePrivate->rlsNotifyPort = NULL; - storePrivate->rlsNotifyRLS = NULL; - - /* "client" information associated with SCDynamicStoreSetDispatchQueue() */ - storePrivate->dispatchGroup = NULL; - storePrivate->dispatchQueue = NULL; - storePrivate->dispatchSource = NULL; - - /* "client" information associated with SCDynamicStoreSetDisconnectCallBack() */ - storePrivate->disconnectFunction = NULL; - storePrivate->disconnectForceCallBack = FALSE; - - /* "server" information associated with SCDynamicStoreSetNotificationKeys() */ - storePrivate->keys = NULL; - storePrivate->patterns = NULL; - - /* "server" information associated with SCDynamicStoreNotifyMachPort(); */ - storePrivate->notifyPort = MACH_PORT_NULL; - storePrivate->notifyPortIdentifier = 0; /* "server" information associated with SCDynamicStoreNotifyFileDescriptor(); */ storePrivate->notifyFile = -1; - storePrivate->notifyFileIdentifier = 0; - - /* "server" information associated with SCDynamicStoreNotifySignal(); */ - storePrivate->notifySignal = 0; - storePrivate->notifySignalTask = TASK_NULL; return storePrivate; } @@ -397,15 +389,16 @@ updateServerPort(SCDynamicStorePrivateRef storePrivate, mach_port_t *server, int static Boolean __SCDynamicStoreAddSession(SCDynamicStorePrivateRef storePrivate) { - kern_return_t kr = KERN_SUCCESS; - CFDataRef myName; /* serialized name */ - xmlData_t myNameRef; - CFIndex myNameLen; - CFDataRef myOptions = NULL; /* serialized options */ - xmlData_t myOptionsRef = NULL; - CFIndex myOptionsLen = 0; - int sc_status = kSCStatusFailed; - mach_port_t server; + struct os_activity_scope_state_s activity_state; + kern_return_t kr = KERN_SUCCESS; + CFDataRef myName; /* serialized name */ + xmlData_t myNameRef; + CFIndex myNameLen; + CFDataRef myOptions = NULL; /* serialized options */ + xmlData_t myOptionsRef = NULL; + CFIndex myOptionsLen = 0; + int sc_status = kSCStatusFailed; + mach_port_t server; if (!_SCSerializeString(storePrivate->name, &myName, (void **)&myNameRef, &myNameLen)) { goto done; @@ -426,6 +419,8 @@ __SCDynamicStoreAddSession(SCDynamicStorePrivateRef storePrivate) updateServerPort(storePrivate, &server, &sc_status); + os_activity_scope_enter(storePrivate->activity, &activity_state); + while (server != MACH_PORT_NULL) { // if SCDynamicStore server available @@ -472,6 +467,8 @@ __SCDynamicStoreAddSession(SCDynamicStorePrivateRef storePrivate) } __MACH_PORT_DEBUG(TRUE, "*** SCDynamicStoreAddSession", storePrivate->server); + os_activity_scope_leave(&activity_state); + // clean up CFRelease(myName); if (myOptions != NULL) CFRelease(myOptions); @@ -592,6 +589,7 @@ pushDisconnect(SCDynamicStoreRef store) context_info = storePrivate->rlsContext.info; context_release = NULL; } + SC_log(LOG_DEBUG, "exec SCDynamicStore disconnect callout"); (*disconnectFunction)(store, context_info); if (context_release) { context_release(context_info); @@ -622,6 +620,7 @@ __SCDynamicStoreReconnectNotifications(SCDynamicStoreRef store) if (storePrivate->rlList != NULL) { rlList = CFArrayCreateCopy(NULL, storePrivate->rlList); } + break; case Using_NotifierInformViaDispatch : dispatchQueue = storePrivate->dispatchQueue; if (dispatchQueue != NULL) dispatch_retain(dispatchQueue); diff --git a/SystemConfiguration.fproj/SCDPlugin.c b/SystemConfiguration.fproj/SCDPlugin.c index 926500f..54e3f5d 100644 --- a/SystemConfiguration.fproj/SCDPlugin.c +++ b/SystemConfiguration.fproj/SCDPlugin.c @@ -1,15 +1,15 @@ /* - * Copyright (c) 2002-2006, 2013 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2002-2006, 2013, 2015 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -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@ */ @@ -316,17 +316,28 @@ _SCDPluginExecCommand2(SCDPluginExecCallBack callout, gid_t egid; uid_t euid; - int i; int status; if (setup != NULL) { (setup)(pid, setupContext); } else { + int fd; + int i; + /* close any open FDs */ for (i = getdtablesize()-1; i>=0; i--) close(i); - open(_PATH_DEVNULL, O_RDWR, 0); - dup(0); - dup(0); + + /* stdin, stdout, stderr */ + fd = open(_PATH_DEVNULL, O_RDWR, 0); + if (fd != -1) { + (void) dup2(fd, STDIN_FILENO); + (void) dup2(fd, STDOUT_FILENO); + (void) dup2(fd, STDERR_FILENO); + if ((fd != STDIN_FILENO) && (fd != STDOUT_FILENO) && (fd != STDERR_FILENO)) { + (void) close(fd); + } + + } } egid = getegid(); diff --git a/SystemConfiguration.fproj/SCDPrivate.c b/SystemConfiguration.fproj/SCDPrivate.c index 398b0ef..818967f 100644 --- a/SystemConfiguration.fproj/SCDPrivate.c +++ b/SystemConfiguration.fproj/SCDPrivate.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2015 Apple Inc. All rights reserved. + * Copyright (c) 2000-2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -34,6 +34,7 @@ //#define DO_NOT_CRASH //#define DO_NOT_INFORM +#define SC_LOG_HANDLE _SC_LOG_DEFAULT() #include #include #include @@ -70,8 +71,8 @@ #pragma mark Miscellaneous -char * -_SC_cfstring_to_cstring(CFStringRef cfstr, char *buf, CFIndex bufLen, CFStringEncoding encoding) +__private_extern__ char * +_SC_cfstring_to_cstring_ext(CFStringRef cfstr, char *buf, CFIndex bufLen, CFStringEncoding encoding, UInt8 lossByte, CFIndex *usedBufLen) { CFIndex converted; CFIndex last = 0; @@ -86,7 +87,7 @@ _SC_cfstring_to_cstring(CFStringRef cfstr, char *buf, CFIndex bufLen, CFStringEn converted = CFStringGetBytes(cfstr, CFRangeMake(0, len), encoding, - 0, + lossByte, FALSE, NULL, 0, @@ -117,17 +118,29 @@ _SC_cfstring_to_cstring(CFStringRef cfstr, char *buf, CFIndex bufLen, CFStringEn (void)CFStringGetBytes(cfstr, CFRangeMake(0, len), encoding, - 0, + lossByte, FALSE, (UInt8 *)buf, bufLen, &last); buf[last] = '\0'; + if (usedBufLen != NULL) { + *usedBufLen = last; + } + return buf; } +char * +_SC_cfstring_to_cstring(CFStringRef cfstr, char *buf, CFIndex bufLen, CFStringEncoding encoding) +{ + return _SC_cfstring_to_cstring_ext(cfstr, buf, bufLen, encoding, 0, NULL); + +} + + void _SC_sockaddr_to_string(const struct sockaddr *address, char *buf, size_t bufLen) { @@ -206,7 +219,7 @@ _SC_string_to_sockaddr(const char *str, sa_family_t af, void *buf, size_t bufLen addr.sin6->sin6_len = sizeof(struct sockaddr_in6); addr.sin6->sin6_family = AF_INET6; - p = strchr(buf, '%'); + p = strchr(str, '%'); if (p != NULL) { addr.sin6->sin6_scope_id = if_nametoindex(p + 1); } @@ -693,6 +706,64 @@ _SCUnserializeMultiple(CFDictionaryRef dict) } +#pragma mark - + + +CFPropertyListRef +_SCCreatePropertyListFromResource(CFURLRef url) +{ + CFDictionaryRef dict = NULL; + SInt64 fileLen = 0; + Boolean ok; + CFReadStreamRef readStream; + CFNumberRef val = NULL; + + if (!CFURLCopyResourcePropertyForKey(url, kCFURLFileSizeKey, &val, NULL) || + (val == NULL)) { + // if size not available + SC_log(LOG_NOTICE, "CFURLCopyResourcePropertyForKey() size not available: %@", url); + return NULL; + } + + ok = CFNumberGetValue(val, kCFNumberSInt64Type, &fileLen); + CFRelease(val); + if (!ok || (fileLen == 0)) { + // if empty or size too large + SC_log(LOG_INFO, "_SCCreatePropertyListFromResource() improper size: %@", url); + return NULL; + } + + readStream = CFReadStreamCreateWithFile(NULL, url); + if (readStream != NULL) { + if (CFReadStreamOpen(readStream)) { + UInt8 *buffer; + CFIndex dataLen; + + buffer = CFAllocatorAllocate(NULL, (CFIndex)fileLen, 0); + dataLen = CFReadStreamRead(readStream, buffer, (CFIndex)fileLen); + if (dataLen == (CFIndex)fileLen) { + CFDataRef data; + + data = CFDataCreateWithBytesNoCopy(NULL, buffer, (CFIndex)fileLen, kCFAllocatorNull); + if (data != NULL) { + dict = CFPropertyListCreateWithData(NULL, + data, + kCFPropertyListImmutable, + NULL, + NULL); + CFRelease(data); + } + } + CFAllocatorDeallocate(NULL, buffer); + CFReadStreamClose(readStream); + } + CFRelease(readStream); + } + + return dict; +} + + #pragma mark - #pragma mark CFRunLoop scheduling @@ -886,9 +957,9 @@ _SC_CFBundleGet(void) env = getenv("DYLD_FRAMEWORK_PATH"); len = (env != NULL) ? strlen(env) : 0; - + if (len > 0) { /* We are debugging */ - + // trim any trailing slashes while (len > 1) { if (env[len - 1] != '/') { @@ -896,17 +967,17 @@ _SC_CFBundleGet(void) } len--; } - + // if DYLD_FRAMEWORK_PATH is ".../xxx~sym" than try ".../xxx~dst" if ((len > SUFFIX_SYM_LEN) && (strncmp(&env[len - SUFFIX_SYM_LEN], SUFFIX_SYM, SUFFIX_SYM_LEN) == 0) && ((len + SYSTEMCONFIGURATION_FRAMEWORK_PATH_LEN) < MAXPATHLEN)) { char path[MAXPATHLEN]; - + strlcpy(path, env, sizeof(path)); strlcpy(&path[len - SUFFIX_SYM_LEN], SUFFIX_DST, sizeof(path) - (len - SUFFIX_SYM_LEN)); strlcat(&path[len], SYSTEMCONFIGURATION_FRAMEWORK_PATH, sizeof(path) - len); - + url = CFURLCreateFromFileSystemRepresentation(NULL, (UInt8 *)path, len + SYSTEMCONFIGURATION_FRAMEWORK_PATH_LEN, @@ -915,18 +986,18 @@ _SC_CFBundleGet(void) CFRelease(url); } } - + if (bundle == NULL) { /* Try a more "direct" route to get the bundle */ - + url = CFURLCreateWithFileSystemPath(NULL, CFSTR(SYSTEMCONFIGURATION_FRAMEWORK_PATH), kCFURLPOSIXPathStyle, TRUE); - + bundle = CFBundleCreate(NULL, url); CFRelease(url); } - + if (bundle == NULL) { SC_log(LOG_ERR, "could not get CFBundle for \"%@\"", SYSTEMCONFIGURATION_BUNDLE_ID); } @@ -939,14 +1010,14 @@ done: CFStringRef _SC_CFBundleCopyNonLocalizedString(CFBundleRef bundle, CFStringRef key, CFStringRef value, CFStringRef tableName) { - CFDataRef data = NULL; - SInt32 errCode = 0; - Boolean ok; CFURLRef resourcesURL; CFStringRef str = NULL; + CFDictionaryRef table = NULL; CFURLRef url; - if ((tableName == NULL) || CFEqual(tableName, CFSTR(""))) tableName = CFSTR("Localizable"); + if ((tableName == NULL) || CFEqual(tableName, CFSTR(""))) { + tableName = CFSTR("Localizable"); + } /* * First, try getting the requested string using a manually constructed @@ -961,83 +1032,46 @@ _SC_CFBundleCopyNonLocalizedString(CFBundleRef bundle, CFStringRef key, CFString */ resourcesURL = CFBundleCopyResourcesDirectoryURL(bundle); if (resourcesURL != NULL) { - CFStringRef fileName = CFStringCreateWithFormat( - NULL, NULL, CFSTR("%@.strings"), tableName); - CFURLRef enlproj = CFURLCreateCopyAppendingPathComponent( - NULL, resourcesURL, CFSTR("English.lproj"), true); - url = CFURLCreateCopyAppendingPathComponent( - NULL, enlproj, fileName, false); - CFRelease(enlproj); + CFURLRef en_lproj; + CFStringRef fileName; + + en_lproj = CFURLCreateCopyAppendingPathComponent(NULL, + resourcesURL, + CFSTR("English.lproj"), + TRUE); + fileName = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@.strings"), tableName); + url = CFURLCreateCopyAppendingPathComponent(NULL, en_lproj, fileName, FALSE); + CFRelease(en_lproj); CFRelease(fileName); CFRelease(resourcesURL); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated" - ok = CFURLCreateDataAndPropertiesFromResource(NULL, - url, - &data, - NULL, - NULL, - &errCode); -#pragma GCC diagnostic pop - if (!ok) { - /* - * Failed to get the data using a manually-constructed URL - * for the given strings table. Fall back to using - * CFBundleCopyResourceURLForLocalization() below. - */ - SC_log(LOG_NOTICE, "%s: failed to create data properties from resource (error=%ld)", __FUNCTION__ , (long)errCode); - data = NULL; - } + table = _SCCreatePropertyListFromResource(url); CFRelease(url); } - if (data == NULL) { + if (table == NULL) { url = CFBundleCopyResourceURLForLocalization(bundle, tableName, CFSTR("strings"), NULL, CFSTR("English")); if (url != NULL) { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated" - ok = CFURLCreateDataAndPropertiesFromResource(NULL, - url, - &data, - NULL, - NULL, - &errCode); -#pragma GCC diagnostic pop - if (!ok) { - SC_log(LOG_NOTICE, "%s: failed to create data properties from resource (error=%ld)", __FUNCTION__ , (long)errCode); - data = NULL; - } + table = _SCCreatePropertyListFromResource(url); CFRelease(url); } else { - SC_log(LOG_ERR, "%s: failed to get resource url: {bundle:%@, table: %@}", __FUNCTION__,bundle, tableName); + SC_log(LOG_ERR, "failed to get resource url: {bundle:%@, table: %@}", bundle, tableName); } } - if (data != NULL) { - CFDictionaryRef table; - - table = CFPropertyListCreateWithData(NULL, - data, - kCFPropertyListImmutable, - NULL, - NULL); - if (table != NULL) { - if (isA_CFDictionary(table)) { - str = CFDictionaryGetValue(table, key); - if (str != NULL) { - CFRetain(str); - } + if (table != NULL) { + if (isA_CFDictionary(table)) { + str = CFDictionaryGetValue(table, key); + if (str != NULL) { + CFRetain(str); } - - CFRelease(table); } - CFRelease(data); + CFRelease(table); } if (str == NULL) { @@ -1419,30 +1453,17 @@ _SC_SimulateCrash(const char *crash_info, CFStringRef notifyHeader, CFStringRef { Boolean ok = FALSE; -#if ! TARGET_IPHONE_SIMULATOR - static bool (*dyfunc_SimulateCrash)(pid_t, mach_exception_data_type_t, CFStringRef) = NULL; - static void *image = NULL; - - if ((dyfunc_SimulateCrash == NULL) && (image == NULL)) { - const char *framework = "/System/Library/PrivateFrameworks/CrashReporterSupport.framework/CrashReporterSupport"; - struct stat statbuf; - const char *suffix = getenv("DYLD_IMAGE_SUFFIX"); - char path[MAXPATHLEN]; - - strlcpy(path, framework, sizeof(path)); - if (suffix) strlcat(path, suffix, sizeof(path)); - if (0 <= stat(path, &statbuf)) { - image = dlopen(path, RTLD_LAZY | RTLD_LOCAL); - } else { - image = dlopen(framework, RTLD_LAZY | RTLD_LOCAL); - } +#if !TARGET_OS_SIMULATOR + static bool (*dyfunc_SimulateCrash)(pid_t, mach_exception_data_type_t, CFStringRef) = NULL; + static void *image = NULL; + static dispatch_once_t once; + dispatch_once(&once, ^{ + image = _SC_dlopen("/System/Library/PrivateFrameworks/CrashReporterSupport.framework/CrashReporterSupport"); if (image != NULL) { dyfunc_SimulateCrash = dlsym(image, "SimulateCrash"); - } else { - image = (void *)0x1; // to ensure that we only dlopen() once } - } + }); if (dyfunc_SimulateCrash != NULL) { CFStringRef str; @@ -1476,7 +1497,7 @@ _SC_SimulateCrash(const char *crash_info, CFStringRef notifyHeader, CFStringRef } } #endif // TARGET_OS_EMBEDDED && !defined(DO_NOT_INFORM) -#endif /* ! TARGET_IPHONE_SIMULATOR */ +#endif // !TARGET_OS_SIMULATOR return ok; } diff --git a/SystemConfiguration.fproj/SCDRemove.c b/SystemConfiguration.fproj/SCDRemove.c index 8f95d37..50355d3 100644 --- a/SystemConfiguration.fproj/SCDRemove.c +++ b/SystemConfiguration.fproj/SCDRemove.c @@ -1,15 +1,15 @@ /* - * Copyright (c) 2000-2005, 2009-2011, 2013 Apple Inc. All rights reserved. + * Copyright (c) 2000-2005, 2009-2011, 2013, 2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,7 +17,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ */ @@ -31,10 +31,6 @@ * - initial revision */ -#include -#include -#include -#include #include "SCDynamicStoreInternal.h" #include "config.h" /* MiG generated file */ @@ -71,6 +67,8 @@ SCDynamicStoreRemoveValue(SCDynamicStoreRef store, CFStringRef key) return FALSE; } + os_activity_scope(storePrivate->activity); + retry : /* send the key to the server */ diff --git a/SystemConfiguration.fproj/SCDSet.c b/SystemConfiguration.fproj/SCDSet.c index 9eec2e8..75a567b 100644 --- a/SystemConfiguration.fproj/SCDSet.c +++ b/SystemConfiguration.fproj/SCDSet.c @@ -1,15 +1,15 @@ /* - * Copyright (c) 2000-2006, 2009-2011, 2013 Apple Inc. All rights reserved. + * Copyright (c) 2000-2006, 2009-2011, 2013, 2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,7 +17,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ */ @@ -31,11 +31,6 @@ * - initial revision */ -#include -#include - -#include -#include #include "SCDynamicStoreInternal.h" #include "config.h" /* MiG generated file */ @@ -112,6 +107,8 @@ SCDynamicStoreSetMultiple(SCDynamicStoreRef store, } } + os_activity_scope(storePrivate->activity); + retry : /* send the keys and patterns, fetch the associated result from the server */ @@ -187,6 +184,8 @@ SCDynamicStoreSetValue(SCDynamicStoreRef store, CFStringRef key, CFPropertyListR return FALSE; } + os_activity_scope(storePrivate->activity); + retry : /* send the key & data to the server, get new instance id */ diff --git a/SystemConfiguration.fproj/SCDSnapshot.c b/SystemConfiguration.fproj/SCDSnapshot.c index 3c8ac05..bc08c9f 100644 --- a/SystemConfiguration.fproj/SCDSnapshot.c +++ b/SystemConfiguration.fproj/SCDSnapshot.c @@ -1,15 +1,15 @@ /* - * Copyright (c) 2000, 2001, 2004, 2005, 2009-2011 Apple Inc. All rights reserved. + * Copyright (c) 2000, 2001, 2004, 2005, 2009-2011, 2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,7 +17,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ */ @@ -31,11 +31,6 @@ * - initial revision */ -#include -#include - -#include -#include #include "SCDynamicStoreInternal.h" #include "config.h" /* MiG generated file */ @@ -62,6 +57,8 @@ SCDynamicStoreSnapshot(SCDynamicStoreRef store) return FALSE; } + os_activity_scope(storePrivate->activity); + retry : status = snapshot(storePrivate->server, (int *)&sc_status); diff --git a/SystemConfiguration.fproj/SCDynamicStoreInternal.h b/SystemConfiguration.fproj/SCDynamicStoreInternal.h index b81fbfc..01e6490 100644 --- a/SystemConfiguration.fproj/SCDynamicStoreInternal.h +++ b/SystemConfiguration.fproj/SCDynamicStoreInternal.h @@ -1,15 +1,15 @@ /* - * Copyright (c) 2000-2004, 2006, 2009-2011, 2013 Apple Inc. All rights reserved. + * Copyright (c) 2000-2004, 2006, 2009-2011, 2013, 2015, 2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,7 +17,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ */ @@ -32,9 +32,17 @@ #include #include #include +#include +#include #include #include -#include + +#ifndef SC_LOG_HANDLE +#define SC_LOG_HANDLE __log_SCDynamicStore() +#endif // SC_LOG_HANDLE +#include +#include +#include /* Define the status of any registered notification. */ @@ -58,6 +66,9 @@ typedef struct { CFStringRef name; CFDictionaryRef options; + /* activity tracing */ + os_activity_t activity; + /* server side of the "configd" session */ mach_port_t server; Boolean serverNullSession; @@ -106,6 +117,9 @@ typedef struct { __BEGIN_DECLS +os_log_t +__log_SCDynamicStore (); + SCDynamicStorePrivateRef __SCDynamicStoreCreatePrivate (CFAllocatorRef allocator, const CFStringRef name, diff --git a/SystemConfiguration.fproj/SCDynamicStorePrivate.h b/SystemConfiguration.fproj/SCDynamicStorePrivate.h index 40acd63..fa8b010 100644 --- a/SystemConfiguration.fproj/SCDynamicStorePrivate.h +++ b/SystemConfiguration.fproj/SCDynamicStorePrivate.h @@ -1,15 +1,15 @@ /* - * Copyright (c) 2000, 2001, 2004, 2005, 2010, 2011, 2013 Apple Inc. All rights reserved. + * Copyright (c) 2000, 2001, 2004, 2005, 2010, 2011, 2013, 2015 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@ */ diff --git a/SystemConfiguration.fproj/SCLocation.c b/SystemConfiguration.fproj/SCLocation.c index 41449cd..6d5a2ba 100644 --- a/SystemConfiguration.fproj/SCLocation.c +++ b/SystemConfiguration.fproj/SCLocation.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2004, 2006, 2010, 2011 Apple Inc. All rights reserved. + * Copyright (c) 2002, 2004, 2006, 2010, 2011, 2015 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -33,7 +33,6 @@ #include #include - CFStringRef SCDynamicStoreKeyCreateLocation(CFAllocatorRef allocator) { @@ -67,7 +66,6 @@ SCDynamicStoreCopyLocation(SCDynamicStoreRef store) done : - if (dict) CFRelease(dict); return location; diff --git a/SystemConfiguration.fproj/SCNetwork.h b/SystemConfiguration.fproj/SCNetwork.h index 6829818..0a0ba43 100644 --- a/SystemConfiguration.fproj/SCNetwork.h +++ b/SystemConfiguration.fproj/SCNetwork.h @@ -125,8 +125,8 @@ __BEGIN_DECLS Note: this API has been deprecated but you can get equivalent results with :
-	SCNetworkReachabiltyRef   target;
-	SCNetworkReachabiltyFlags flags = 0;
+	SCNetworkReachabilityRef   target;
+	SCNetworkReachabilityFlags flags = 0;
 	Boolean                   ok;
 
 	target = SCNetworkReachabilityCreateWithAddress(NULL, address);
diff --git a/SystemConfiguration.fproj/SCNetworkConfiguration.h b/SystemConfiguration.fproj/SCNetworkConfiguration.h
index 0b5dd20..0de6096 100644
--- a/SystemConfiguration.fproj/SCNetworkConfiguration.h
+++ b/SystemConfiguration.fproj/SCNetworkConfiguration.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2011, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2011, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -123,7 +123,7 @@ extern const CFStringRef kSCNetworkInterfaceTypePPP						__OSX_AVAILABLE_STARTIN
 /*!
 	@const kSCNetworkInterfaceTypePPTP
  */
-extern const CFStringRef kSCNetworkInterfaceTypePPTP						__OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0/*SPI*/);
+extern const CFStringRef kSCNetworkInterfaceTypePPTP						__OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4,__MAC_10_12,__IPHONE_2_0/*SPI*/,__IPHONE_10_0/*SPI*/);
 
 /*!
 	@const kSCNetworkInterfaceTypeSerial
@@ -237,11 +237,6 @@ typedef const struct CF_BRIDGED_TYPE(id) __SCNetworkProtocol * SCNetworkProtocol
 
 /* network "protocol" types */
 
-/*!
-	@const kSCNetworkProtocolTypeAppleTalk
- */
-extern const CFStringRef kSCNetworkProtocolTypeAppleTalk					__OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4,__MAC_10_6,__IPHONE_NA,__IPHONE_NA);
-
 /*!
 	@const kSCNetworkProtocolTypeDNS
  */
@@ -447,7 +442,7 @@ SCNetworkInterfaceGetLocalizedDisplayName	(SCNetworkInterfaceRef		interface)	__O
  */
 Boolean
 SCNetworkInterfaceSetConfiguration		(SCNetworkInterfaceRef		interface,
-						 CFDictionaryRef		config)		__OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0/*SPI*/);
+						 CFDictionaryRef __nullable	config)		__OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0/*SPI*/);
 
 /*!
 	@function SCNetworkInterfaceSetExtendedConfiguration
@@ -459,7 +454,7 @@ SCNetworkInterfaceSetConfiguration		(SCNetworkInterfaceRef		interface,
 Boolean
 SCNetworkInterfaceSetExtendedConfiguration	(SCNetworkInterfaceRef		interface,
 						 CFStringRef			extendedType,
-						 CFDictionaryRef		config)		__OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0/*SPI*/);
+						 CFDictionaryRef __nullable	config)		__OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0/*SPI*/);
 
 #pragma mark -
 
@@ -907,7 +902,7 @@ SCNetworkProtocolGetProtocolType		(SCNetworkProtocolRef		protocol)	__OSX_AVAILAB
  */
 Boolean
 SCNetworkProtocolSetConfiguration		(SCNetworkProtocolRef		protocol,
-						 CFDictionaryRef		config)		__OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0/*SPI*/);
+						 CFDictionaryRef __nullable	config)		__OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0/*SPI*/);
 
 /*!
 	@function SCNetworkProtocolSetEnabled
@@ -1107,7 +1102,7 @@ SCNetworkServiceSetEnabled			(SCNetworkServiceRef		service,
  */
 Boolean
 SCNetworkServiceSetName				(SCNetworkServiceRef		service,
-						 CFStringRef			name)		__OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0/*SPI*/);
+						 CFStringRef __nullable		name)		__OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0/*SPI*/);
 
 
 /* --------------------------------------------------------------------------------
@@ -1285,7 +1280,7 @@ SCNetworkSetSetCurrent				(SCNetworkSetRef		set)		__OSX_AVAILABLE_STARTING(__MAC
  */
 Boolean
 SCNetworkSetSetName				(SCNetworkSetRef		set,
-						 CFStringRef			name)		__OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0/*SPI*/);
+						 CFStringRef __nullable		name)		__OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0/*SPI*/);
 
 /*!
 	@function SCNetworkSetSetServiceOrder
diff --git a/SystemConfiguration.fproj/SCNetworkConfigurationInternal.c b/SystemConfiguration.fproj/SCNetworkConfigurationInternal.c
index 3da8a10..f1a5fc1 100644
--- a/SystemConfiguration.fproj/SCNetworkConfigurationInternal.c
+++ b/SystemConfiguration.fproj/SCNetworkConfigurationInternal.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2007, 2009, 2010-2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2007, 2009, 2010-2013, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -29,15 +29,25 @@
  */
 
 
-#include 
-#include 
-#include 
-#include 
+#include "SCNetworkConfigurationInternal.h"
 
 #include 
 #include 
 
 
+__private_extern__ os_log_t
+__log_SCNetworkConfiguration()
+{
+	static os_log_t	log	= NULL;
+
+	if (log == NULL) {
+		log = os_log_create("com.apple.SystemConfiguration", "SCNetworkConfiguration");
+	}
+
+	return log;
+}
+
+
 __private_extern__ CFDictionaryRef
 __getPrefsConfiguration(SCPreferencesRef prefs, CFStringRef path)
 {
@@ -202,12 +212,8 @@ static CFDictionaryRef
 __copyTemplates()
 {
 	CFBundleRef     bundle;
-	CFErrorRef	error		= NULL;
-	SInt32		errorCode;
-	Boolean		ok;
 	CFDictionaryRef templates;
 	CFURLRef	url;
-	CFDataRef       xmlTemplates    = NULL;
 
 	bundle = _SC_CFBundleGet();
 	if (bundle == NULL) {
@@ -223,7 +229,7 @@ __copyTemplates()
 							  NETWORKCONFIGURATION_RESOURCE_FILE),
 						    kCFURLPOSIXPathStyle,
 						    TRUE);
-		
+
 		if (url == NULL) {
 			SC_log(LOG_ERR, "failed to CREATE resource URL to \"%s\"", SYSTEMCONFIGURATION_RESOURCES_PATH
 										   "/"
@@ -232,28 +238,10 @@ __copyTemplates()
 		}
 	}
 
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated"
-	ok = CFURLCreateDataAndPropertiesFromResource(NULL, url, &xmlTemplates, NULL, NULL, &errorCode);
-#pragma GCC diagnostic pop
+	templates = _SCCreatePropertyListFromResource(url);
 	CFRelease(url);
-	if (!ok || (xmlTemplates == NULL)) {
-		SC_log(LOG_NOTICE, "%s: failed to create data properties from resource (error=%ld)", __FUNCTION__ , (long)errorCode);
-		return NULL;
-	}
-
-	// convert the XML data into a property list
-	templates = CFPropertyListCreateWithData(NULL, xmlTemplates, kCFPropertyListImmutable, NULL, &error);
-	CFRelease(xmlTemplates);
-	if (templates == NULL) {
-		if (error != NULL) {
-			SC_log(LOG_NOTICE, "could not load SCNetworkConfiguration templates: %@", error);
-			CFRelease(error);
-		}
-		return NULL;
-	}
 
-	if (!isA_CFDictionary(templates)) {
+	if ((templates != NULL) && !isA_CFDictionary(templates)) {
 		CFRelease(templates);
 		return NULL;
 	}
diff --git a/SystemConfiguration.fproj/SCNetworkConfigurationInternal.h b/SystemConfiguration.fproj/SCNetworkConfigurationInternal.h
index 7ea2b7b..fbc4a1e 100644
--- a/SystemConfiguration.fproj/SCNetworkConfigurationInternal.h
+++ b/SystemConfiguration.fproj/SCNetworkConfigurationInternal.h
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2004-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -17,25 +17,29 @@
  * 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@
  */
 
 #ifndef _SCNETWORKCONFIGURATIONINTERNAL_H
 #define _SCNETWORKCONFIGURATIONINTERNAL_H
 
-
 #include 
 #include 
 #include 
+
+#ifndef	SC_LOG_HANDLE
+#define	SC_LOG_HANDLE	__log_SCNetworkConfiguration()
+#endif	// SC_LOG_HANDLE
 #include 
+#include 
+#include 
 #include 
-#include 
 #include 
 
-#if	!TARGET_IPHONE_SIMULATOR
+#if	!TARGET_OS_SIMULATOR
 #include "IPMonitorControl.h"
-#endif	// !TARGET_IPHONE_SIMULATOR
+#endif	// !TARGET_OS_SIMULATOR
 
 
 typedef struct {
@@ -156,6 +160,8 @@ typedef struct {
 	CFStringRef		prefix;
 	CFNumberRef		type;
 	CFNumberRef		unit;
+	CFNumberRef		family;
+	CFNumberRef		subfamily;
 	struct {
 		CFStringRef	name;
 		CFNumberRef	vid;
@@ -188,10 +194,10 @@ typedef struct {
 		CFDictionaryRef		options;
 	} vlan;
 
-#if	!TARGET_IPHONE_SIMULATOR
+#if	!TARGET_OS_SIMULATOR
 	// for interface rank assertions
 	IPMonitorControlRef	IPMonitorControl;
-#endif	// !TARGET_IPHONE_SIMULATOR
+#endif	// !TARGET_OS_SIMULATOR
 } SCNetworkInterfacePrivate, *SCNetworkInterfacePrivateRef;
 
 
@@ -306,6 +312,10 @@ __SCNetworkInterfaceGetEntityType		(SCNetworkInterfaceRef interface);
 CFStringRef
 __SCNetworkInterfaceGetNonLocalizedDisplayName	(SCNetworkInterfaceRef	interface);
 
+Boolean
+__SCNetworkInterfaceSetDisableUntilNeededValue	(SCNetworkInterfaceRef	interface,
+						 CFTypeRef		disable);
+
 void
 __SCNetworkInterfaceSetUserDefinedName(SCNetworkInterfaceRef interface, CFStringRef name);
 
@@ -325,12 +335,15 @@ __SCNetworkInterfaceGetUserDefinedName(SCNetworkInterfaceRef interface);
  @result	TRUE if the interface configuration is active.
  */
 Boolean
-__SCNetworkInterfaceIsActive			(SCNetworkInterfaceRef		interface);
+__SCNetworkInterfaceIsActive			(SCNetworkInterfaceRef	interface);
 
 Boolean
 __SCNetworkInterfaceIsMember			(SCPreferencesRef	prefs,
 						 SCNetworkInterfaceRef	interface);
 
+Boolean
+__SCNetworkInterfaceEntityIsPPTP		(CFDictionaryRef	entity);
+
 Boolean
 __SCNetworkInterfaceIsValidExtendedConfigurationType
 						(SCNetworkInterfaceRef	interface,
@@ -378,7 +391,7 @@ __SCNetworkInterfaceSetDeepConfiguration	(SCNetworkSetRef	set,
  */
 void
 __SCNetworkInterfaceSetIOInterfaceUnit		(SCNetworkInterfaceRef interface,
-						 CFNumberRef unit);
+						 CFNumberRef		unit);
 
 Boolean
 __SCNetworkInterfaceSupportsVLAN		(CFStringRef		bsd_if);
@@ -437,6 +450,10 @@ __SCNetworkServiceCreate			(SCPreferencesRef	prefs,
 						 SCNetworkInterfaceRef	interface,
 						 CFStringRef		userDefinedName);
 
+Boolean
+__SCNetworkServiceIsPPTP			(SCNetworkServiceRef	service);
+
+
 SCPreferencesRef
 __SCNetworkCreateDefaultNIPrefs			(CFStringRef		prefsID);
 
@@ -449,11 +466,11 @@ __SCNetworkCreateDefaultNIPrefs			(CFStringRef		prefsID);
  @result TRUE if add service to prefs is successful
  */
 Boolean
-__SCNetworkServiceMigrateNew			(SCPreferencesRef		prefs,
-						 SCNetworkServiceRef		service,
-						 CFDictionaryRef		bsdMapping,
-						 CFDictionaryRef		setMapping,
-						 CFDictionaryRef		serviceSetMapping);
+__SCNetworkServiceMigrateNew			(SCPreferencesRef	prefs,
+						 SCNetworkServiceRef	service,
+						 CFDictionaryRef	bsdMapping,
+						 CFDictionaryRef	setMapping,
+						 CFDictionaryRef	serviceSetMapping);
 
 void
 __SCNetworkServiceAddProtocolToService		(SCNetworkServiceRef		service,
@@ -465,6 +482,14 @@ __SCNetworkServiceAddProtocolToService		(SCNetworkServiceRef		service,
 #pragma mark SCNetworkSet configuration (internal)
 
 
+#pragma mark -
+#pragma mark Logging
+
+
+os_log_t
+__log_SCNetworkConfiguration			();
+
+
 #pragma mark -
 #pragma mark Miscellaneous (internal)
 
diff --git a/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h b/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h
index 73cc02e..537bab5 100644
--- a/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h
+++ b/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2005-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -312,6 +312,26 @@ _SCNetworkInterfaceCopyInterfaceInfo			(SCNetworkInterfaceRef		interface)	__OSX_
 CFStringRef
 _SCNetworkInterfaceGetConfigurationAction		(SCNetworkInterfaceRef		interface)	__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_2_0);
 
+/*!
+	@function _SCNetworkInterfaceGetFamilyType
+	@discussion Returns the family type for the interface.
+	@param interface The network interface.
+	@result The family type (ift_family) associated with the interface;
+		NULL if no family type is available.
+ */
+CFNumberRef
+_SCNetworkInterfaceGetFamilyType			(SCNetworkInterfaceRef		interface)	__OSX_AVAILABLE_STARTING(__MAC_10_12,__IPHONE_10_0);
+
+/*!
+	@function _SCNetworkInterfaceGetFamilySubType
+	@discussion Returns the family subtype for the interface.
+	@param interface The network interface.
+	@result The family subtype (ift_subfamily) associated with the interface;
+		NULL if no family subtype is available.
+ */
+CFNumberRef
+_SCNetworkInterfaceGetFamilySubType			(SCNetworkInterfaceRef		interface)	__OSX_AVAILABLE_STARTING(__MAC_10_12,__IPHONE_10_0);
+
 /*!
 	@function _SCNetworkInterfaceGetHardwareAddress
 	@discussion Returns a link layer address for the interface.
@@ -470,7 +490,8 @@ _SCNetworkInterfaceForceConfigurationRefresh		(CFStringRef			ifName)		__OSX_AVAI
 		about the currently requested capabilities, the active capabilities,
 		and the capabilities which are available.
 	@param interface The desired network interface.
-	@param capability The desired capability.
+	@param capability The desired capability;
+		NULL to return a CFDictionary of all capabilities.
 	@result a CFTypeRef representing the current value of requested
 		capability;
 		NULL if the capability is not available for this
@@ -712,11 +733,19 @@ SCNetworkInterfaceSetPassword				(SCNetworkInterfaceRef		interface,
 
 
 Boolean
-SCNetworkInterfaceGetDisableUntilNeeded			(SCNetworkInterfaceRef interface) __OSX_AVAILABLE_STARTING(__MAC_10_11,__IPHONE_9_0);
+SCNetworkInterfaceGetDisableUntilNeeded			(SCNetworkInterfaceRef		interface)	__OSX_AVAILABLE_STARTING(__MAC_10_11,__IPHONE_9_0);
 
 Boolean
-SCNetworkInterfaceSetDisableUntilNeeded			(SCNetworkInterfaceRef interface,
-							 Boolean disable) __OSX_AVAILABLE_STARTING(__MAC_10_11,__IPHONE_9_0);
+SCNetworkInterfaceSetDisableUntilNeeded			(SCNetworkInterfaceRef		interface,
+							 Boolean			disable)	__OSX_AVAILABLE_STARTING(__MAC_10_11,__IPHONE_9_0);
+
+
+CFDictionaryRef
+SCNetworkInterfaceGetQoSMarkingPolicy			(SCNetworkInterfaceRef		interface)	__OSX_AVAILABLE_STARTING(__MAC_10_12,__IPHONE_10_0);
+
+Boolean
+SCNetworkInterfaceSetQoSMarkingPolicy			(SCNetworkInterfaceRef		interface,
+							 CFDictionaryRef		policy)		__OSX_AVAILABLE_STARTING(__MAC_10_12,__IPHONE_10_0);
 
 
 #pragma mark -
@@ -879,6 +908,16 @@ isA_SCNetworkSet(CFTypeRef obj)
 CFArrayRef
 SCNetworkSetCopyAvailableInterfaces			(SCNetworkSetRef		set)		__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/);
 
+/*!
+	@function _SCNetworkSetCreateDefault
+	@discussion Create a new [default] set in the configuration.
+	@param prefs The "preferences" session.
+	@result A reference to the new SCNetworkSet.
+		You must release the returned value.
+ */
+SCNetworkSetRef
+_SCNetworkSetCreateDefault				(SCPreferencesRef		prefs)		__OSX_AVAILABLE_STARTING(__MAC_10_12,__IPHONE_10_0/*SPI*/);
+
 /*!
 	@function SCNetworkSetEstablishDefaultConfiguration
 	@discussion Updates a network set by adding services for
@@ -1110,7 +1149,7 @@ _SCNetworkConfigurationCheckValidity(CFURLRef configDir,
  @param prefs	the preferences ref pointing to the said preferences.plist
  @param ni_prefs	the preferences ref pointing to the said NetworkInterfaces.plist
  @result	TRUE if the configurations are valid against each other
- 
+
  */
 
 Boolean
@@ -1146,12 +1185,12 @@ _SCNetworkMigrationAreConfigurationsIdentical (CFURLRef configurationURL,
  @param targetPaths	the CFArray returned by _SCNetworkConfigurationPerformMigration
  @param targetDir	the CFURL passed to _SCNetworkConfigurationPerformMigration
  @result	An array of CFURL's; NULL if no paths need to be removed from the target filesystem
- 
+
 */
 
 CFArrayRef	// of CFURLRef's
 _SCNetworkConfigurationCopyMigrationRemovePaths	(CFArrayRef	targetPaths,
-                                                 CFURLRef	targetDir)				__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0);
+						 CFURLRef	targetDir)				__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0);
 
 __END_DECLS
 #endif	/* _SCNETWORKCONFIGURATIONPRIVATE_H */
diff --git a/SystemConfiguration.fproj/SCNetworkConnection.c b/SystemConfiguration.fproj/SCNetworkConnection.c
index 061236f..1d3d0e1 100644
--- a/SystemConfiguration.fproj/SCNetworkConnection.c
+++ b/SystemConfiguration.fproj/SCNetworkConnection.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -39,12 +39,12 @@
 #include 
 #include 
 #include 
-#include 
-#include 
 #include 
-#include 
-#include 
-#include 
+
+#include "SCNetworkConnectionInternal.h"
+#include "SCNetworkConfigurationInternal.h"
+#include "SCD.h"
+
 #include 
 #include 
 
@@ -79,9 +79,6 @@
 #define	PPPCONTROLLER_SERVER_PRIV	PPPCONTROLLER_SERVER
 #endif	// !PPPCONTROLLER_SERVER_PRIV
 
-
-#include "SCNetworkConnectionInternal.h"
-
 static int		debug			= 0;
 static pthread_once_t	initialized		= PTHREAD_ONCE_INIT;
 static pthread_mutex_t	scnc_lock		= PTHREAD_MUTEX_INITIALIZER;
@@ -140,13 +137,26 @@ typedef struct {
 	/* Flow Divert support info */
 	CFDictionaryRef			flow_divert_token_params;
 
-#if !TARGET_IPHONE_SIMULATOR
+#if !TARGET_OS_SIMULATOR
 	/* NetworkExtension data structures */
 	ne_session_t			ne_session;
-#endif /* !TARGET_IPHONE_SIMULATOR */
+#endif /* !TARGET_OS_SIMULATOR */
 } SCNetworkConnectionPrivate, *SCNetworkConnectionPrivateRef;
 
 
+__private_extern__ os_log_t
+__log_SCNetworkConnection()
+{
+	static os_log_t	log	= NULL;
+
+	if (log == NULL) {
+		log = os_log_create("com.apple.SystemConfiguration", "SCNetworkConnection");
+	}
+
+	return log;
+}
+
+
 static __inline__ CFTypeRef
 isA_SCNetworkConnection(CFTypeRef obj)
 {
@@ -154,7 +164,7 @@ isA_SCNetworkConnection(CFTypeRef obj)
 }
 
 
-#if !TARGET_IPHONE_SIMULATOR
+#if !TARGET_OS_SIMULATOR
 Boolean
 __SCNetworkConnectionUseNetworkExtension(SCNetworkConnectionPrivateRef connectionPrivate)
 {
@@ -178,7 +188,12 @@ __SCNetworkConnectionUseNetworkExtension(SCNetworkConnectionPrivateRef connectio
 				if (isA_CFString(interfaceType)) {
 					if (CFEqual(interfaceType, kSCNetworkInterfaceTypePPP)) {
 						CFStringRef interfaceSubType = CFDictionaryGetValue(interfaceDict, kSCPropNetInterfaceSubType);
-						result = (isA_CFString(interfaceSubType) && (CFEqual(interfaceSubType, kSCValNetInterfaceSubTypePPTP) || CFEqual(interfaceSubType, kSCValNetInterfaceSubTypeL2TP)));
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
+						result = (isA_CFString(interfaceSubType) &&
+							  (CFEqual(interfaceSubType, kSCValNetInterfaceSubTypePPTP) ||
+							   CFEqual(interfaceSubType, kSCValNetInterfaceSubTypeL2TP)));
+#pragma GCC diagnostic pop
 					} else {
 						result = (CFEqual(interfaceType, kSCNetworkInterfaceTypeVPN) || CFEqual(interfaceType, kSCNetworkInterfaceTypeIPSec));
 					}
@@ -193,17 +208,17 @@ __SCNetworkConnectionUseNetworkExtension(SCNetworkConnectionPrivateRef connectio
 
 	return result;
 }
-#endif /* !TARGET_IPHONE_SIMULATOR */
+#endif /* !TARGET_OS_SIMULATOR */
 
 
 Boolean
 __SCNetworkConnectionUsingNetworkExtension(SCNetworkConnectionPrivateRef connectionPrivate)
 {
-#if !TARGET_IPHONE_SIMULATOR
+#if !TARGET_OS_SIMULATOR
     return (connectionPrivate->ne_session != NULL);
 #else
 	return FALSE;
-#endif /* !TARGET_IPHONE_SIMULATOR */
+#endif /* !TARGET_OS_SIMULATOR */
 }
 
 
@@ -299,12 +314,12 @@ __SCNetworkConnectionDeallocate(CFTypeRef cf)
 		CFRelease(connectionPrivate->flow_divert_token_params);
 	}
 
-#if !TARGET_IPHONE_SIMULATOR
+#if !TARGET_OS_SIMULATOR
 	if (connectionPrivate->ne_session != NULL) {
 		ne_session_set_event_handler(connectionPrivate->ne_session, NULL, NULL);
 		ne_session_release(connectionPrivate->ne_session);
 	}
-#endif /* !TARGET_IPHONE_SIMULATOR */
+#endif /* !TARGET_OS_SIMULATOR */
 
 	return;
 }
@@ -386,15 +401,19 @@ __SCNetworkConnectionNotify(SCNetworkConnectionRef	connection,
 			    void			(*context_release)(const void *),
 			    void			*context_info)
 {
-	os_activity_t	activity_id;
+	os_activity_t	activity;
+
+	activity = os_activity_create("processing SCHelper request",
+				      OS_ACTIVITY_CURRENT,
+				      OS_ACTIVITY_FLAG_DEFAULT);
+	os_activity_scope(activity);
 
-	activity_id = os_activity_start("processing SCNetworkConnection notification",
-					OS_ACTIVITY_FLAG_DEFAULT);
+	SC_log(LOG_DEBUG, "exec SCNetworkConnection callout");
 	(*rlsFunction)(connection, nc_status, context_info);
 	if ((context_release != NULL) && (context_info != NULL)) {
 		(*context_release)(context_info);
 	}
-	os_activity_end(activity_id);
+	os_release(activity);
 
 	return;
 }
@@ -472,7 +491,7 @@ __SCNetworkConnectionCallBack(void *connection)
 		context_release	= NULL;
 	}
 
-#if !TARGET_IPHONE_SIMULATOR
+#if !TARGET_OS_SIMULATOR
 	if (__SCNetworkConnectionUsingNetworkExtension(connectionPrivate)) {
 		pthread_mutex_unlock(&connectionPrivate->lock);
 
@@ -481,7 +500,7 @@ __SCNetworkConnectionCallBack(void *connection)
 		CFRelease(connection); /* This releases the reference that we took in the NESessionEventStatusChanged event handler */
 		return;
 	}
-#endif /* !TARGET_IPHONE_SIMULATOR */
+#endif /* !TARGET_OS_SIMULATOR */
 
 	// Do we need to spin a new thread? (either we are running on the main
 	// dispatch queue or main runloop)
@@ -585,7 +604,6 @@ __SCNetworkConnectionCreatePrivate(CFAllocatorRef		allocator,
 	SCNetworkConnectionPrivateRef	connectionPrivate	= NULL;
 	uint32_t			size;
 
-
 	/* initialize runtime */
 	pthread_once(&initialized, __SCNetworkConnectionInitialize);
 
@@ -596,36 +614,24 @@ __SCNetworkConnectionCreatePrivate(CFAllocatorRef		allocator,
 		goto fail;
 	}
 
-	/* zero the data structure */
-	bzero(((u_char*)connectionPrivate)+sizeof(CFRuntimeBase), size);
-
+	/* initialize non-zero/NULL members */
 	pthread_mutex_init(&connectionPrivate->lock, NULL);
-
-	/* save the service */
 	if (service != NULL) {
 		connectionPrivate->service = CFRetain(service);
 	}
-
-	connectionPrivate->client_audit_session = MACH_PORT_NULL;
-	connectionPrivate->client_bootstrap_port = MACH_PORT_NULL;
 	connectionPrivate->client_uid = geteuid();
 	connectionPrivate->client_gid = getegid();
 	connectionPrivate->client_pid = getpid();
-	connectionPrivate->client_bundle_id = NULL;
-	uuid_clear(connectionPrivate->client_uuid);
-
 	connectionPrivate->rlsFunction = callout;
-
 	if (context) {
 		bcopy(context, &connectionPrivate->rlsContext, sizeof(SCNetworkConnectionContext));
 		if (context->retain != NULL) {
 			connectionPrivate->rlsContext.info = (void *)(*context->retain)(context->info);
 		}
 	}
-
 	connectionPrivate->type = kSCNetworkConnectionTypeUnknown;
 
-#if !TARGET_IPHONE_SIMULATOR
+#if !TARGET_OS_SIMULATOR
 	if (__SCNetworkConnectionUseNetworkExtension(connectionPrivate)) {
 		CFStringRef serviceID = SCNetworkServiceGetServiceID(connectionPrivate->service);
 		if (serviceID != NULL) {
@@ -645,7 +651,7 @@ __SCNetworkConnectionCreatePrivate(CFAllocatorRef		allocator,
 			goto fail;
 		}
 	}
-#endif /* !TARGET_IPHONE_SIMULATOR */
+#endif /* !TARGET_OS_SIMULATOR */
 
 	/* success, return the connection reference */
 	return connectionPrivate;
@@ -729,12 +735,12 @@ __SCNetworkConnectionRefreshServerPort(mach_port_t current_server, int *mach_res
 	return new_server;
 }
 
-#if	((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 50000)) && (!TARGET_IPHONE_SIMULATOR || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 70000))
+#if	((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 50000)) && (!TARGET_OS_SIMULATOR || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 70000))
 #define	HAVE_PPPCONTROLLER_ATTACHWITHAUDITSESSION
 #endif
 
 
-#if	((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 50000)) && !TARGET_IPHONE_SIMULATOR
+#if	((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 50000)) && !TARGET_OS_SIMULATOR
 #define	HAVE_PPPCONTROLLER_ATTACHWITHPROXY
 #endif
 
@@ -1234,6 +1240,12 @@ SCNetworkConnectionCreateWithService(CFAllocatorRef			allocator,
 		return FALSE;
 	}
 
+	if (__SCNetworkServiceIsPPTP(service)) {
+		SC_log(LOG_INFO, "PPTP VPNs are no longer supported");
+		_SCErrorSet(kSCStatusConnectionIgnore);
+		return FALSE;
+	}
+
 	connectionPrivate = __SCNetworkConnectionCreatePrivate(allocator, service, callout, context);
 	return (SCNetworkConnectionRef)connectionPrivate;
 }
@@ -1419,7 +1431,7 @@ SCNetworkConnectionCopyStatistics(SCNetworkConnectionRef connection)
 
 	pthread_mutex_lock(&connectionPrivate->lock);
 
-#if !TARGET_IPHONE_SIMULATOR
+#if !TARGET_OS_SIMULATOR
 	if (__SCNetworkConnectionUsingNetworkExtension(connectionPrivate)) {
 		__block xpc_object_t xstats = NULL;
 		ne_session_t ne_session = connectionPrivate->ne_session;
@@ -1447,7 +1459,7 @@ SCNetworkConnectionCopyStatistics(SCNetworkConnectionRef connection)
 
 		return statistics;
 	}
-#endif /* !TARGET_IPHONE_SIMULATOR */
+#endif /* !TARGET_OS_SIMULATOR */
 
     retry :
 
@@ -1532,7 +1544,7 @@ SCNetworkConnectionGetStatus(SCNetworkConnectionRef connection)
 
 	pthread_mutex_lock(&connectionPrivate->lock);
 
-#if !TARGET_IPHONE_SIMULATOR
+#if !TARGET_OS_SIMULATOR
 	if (__SCNetworkConnectionUsingNetworkExtension(connectionPrivate)) {
 		__block ne_session_status_t ne_status;
 		ne_session_t ne_session = connectionPrivate->ne_session;
@@ -1551,7 +1563,7 @@ SCNetworkConnectionGetStatus(SCNetworkConnectionRef connection)
 
 		return SCNetworkConnectionGetStatusFromNEStatus(ne_status);
 	}
-#endif /* !TARGET_IPHONE_SIMULATOR */
+#endif /* !TARGET_OS_SIMULATOR */
 
     retry :
 
@@ -1623,7 +1635,7 @@ SCNetworkConnectionCopyExtendedStatus(SCNetworkConnectionRef connection)
 
 	pthread_mutex_lock(&connectionPrivate->lock);
 
-#if !TARGET_IPHONE_SIMULATOR
+#if !TARGET_OS_SIMULATOR
 	if (__SCNetworkConnectionUsingNetworkExtension(connectionPrivate)) {
 		__block CFDictionaryRef statusDictionary = NULL;
 		ne_session_t ne_session = connectionPrivate->ne_session;
@@ -1823,7 +1835,7 @@ SCNetworkConnectionStart(SCNetworkConnectionRef	connection,
 	    connectionPrivate->flow_divert_token_params = NULL;
 	}
 
-#if !TARGET_IPHONE_SIMULATOR
+#if !TARGET_OS_SIMULATOR
 	if (__SCNetworkConnectionUsingNetworkExtension(connectionPrivate)) {
 		xpc_object_t xuser_options = NULL;
 
@@ -1862,10 +1874,10 @@ SCNetworkConnectionStart(SCNetworkConnectionRef	connection,
 		ok = TRUE;
 		goto done;
 	}
-#endif /* !TARGET_IPHONE_SIMULATOR */
+#endif /* !TARGET_OS_SIMULATOR */
 
 	if (userOptions && !_SCSerialize(userOptions, &dataref, &data, &datalen)) {
-		return FALSE;
+		goto done;
 	}
 
     retry :
@@ -1929,7 +1941,7 @@ SCNetworkConnectionStop(SCNetworkConnectionRef	connection,
 
 	pthread_mutex_lock(&connectionPrivate->lock);
 
-#if !TARGET_IPHONE_SIMULATOR
+#if !TARGET_OS_SIMULATOR
 	if (__SCNetworkConnectionUsingNetworkExtension(connectionPrivate)) {
 		ne_session_stop(connectionPrivate->ne_session);
 		/* make sure the xpc_message goes through */
@@ -1937,7 +1949,7 @@ SCNetworkConnectionStop(SCNetworkConnectionRef	connection,
 		ok = TRUE;
 		goto done;
 	}
-#endif /* !TARGET_IPHONE_SIMULATOR */
+#endif /* !TARGET_OS_SIMULATOR */
 
     retry :
 
@@ -1993,13 +2005,13 @@ SCNetworkConnectionSuspend(SCNetworkConnectionRef connection)
 
 	pthread_mutex_lock(&connectionPrivate->lock);
 
-#if !!TARGET_IPHONE_SIMULATOR
+#if !!TARGET_OS_SIMULATOR
 	if (__SCNetworkConnectionUsingNetworkExtension(connectionPrivate)) {
 		/* Suspend only applies to PPPSerial and PPPoE */
 		ok = TRUE;
 		goto done;
 	}
-#endif /* !TARGET_IPHONE_SIMULATOR */
+#endif /* !TARGET_OS_SIMULATOR */
 
     retry :
 
@@ -2055,13 +2067,13 @@ SCNetworkConnectionResume(SCNetworkConnectionRef connection)
 
 	pthread_mutex_lock(&connectionPrivate->lock);
 
-#if !TARGET_IPHONE_SIMULATOR
+#if !TARGET_OS_SIMULATOR
 	if (__SCNetworkConnectionUsingNetworkExtension(connectionPrivate)) {
 		/* Resume only applies to PPPSerial and PPPoE */
 		ok = TRUE;
 		goto done;
 	}
-#endif /* !TARGET_IPHONE_SIMULATOR */
+#endif /* !TARGET_OS_SIMULATOR */
 
     retry :
 
@@ -2097,7 +2109,7 @@ SCNetworkConnectionResume(SCNetworkConnectionRef connection)
 }
 
 
-#if	!TARGET_IPHONE_SIMULATOR
+#if	!TARGET_OS_SIMULATOR
 Boolean
 SCNetworkConnectionRefreshOnDemandState(SCNetworkConnectionRef connection)
 {
@@ -2169,7 +2181,7 @@ SCNetworkConnectionRefreshOnDemandState(SCNetworkConnectionRef connection)
 	pthread_mutex_unlock(&connectionPrivate->lock);
 	return ok;
 }
-#endif	/* !TARGET_IPHONE_SIMULATOR */
+#endif	/* !TARGET_OS_SIMULATOR */
 
 
 CFDictionaryRef
@@ -2190,7 +2202,7 @@ SCNetworkConnectionCopyUserOptions(SCNetworkConnectionRef connection)
 
 	pthread_mutex_lock(&connectionPrivate->lock);
 
-#if !TARGET_IPHONE_SIMULATOR
+#if !TARGET_OS_SIMULATOR
 	if (__SCNetworkConnectionUsingNetworkExtension(connectionPrivate)) {
 		__block xpc_object_t config = NULL;
 		ne_session_t ne_session = connectionPrivate->ne_session;
@@ -2218,7 +2230,7 @@ SCNetworkConnectionCopyUserOptions(SCNetworkConnectionRef connection)
 		}
 		return userOptions;
 	}
-#endif /* !TARGET_IPHONE_SIMULATOR */
+#endif /* !TARGET_OS_SIMULATOR */
 
     retry :
 
@@ -2401,6 +2413,7 @@ __SCNetworkConnectionScheduleWithRunLoop(SCNetworkConnectionRef	connection,
 					      MACH_PORT_NULL);		// notify
 				if (kr != KERN_SUCCESS) {
 					SC_log(LOG_NOTICE, "SCDynamicStore notification handler, kr=0x%x", kr);
+					free(notify_msg);
 					return;
 				}
 
@@ -2436,7 +2449,7 @@ __SCNetworkConnectionScheduleWithRunLoop(SCNetworkConnectionRef	connection,
 		_SC_schedule(connection, runLoop, runLoopMode, connectionPrivate->rlList);
 	}
 
-#if !TARGET_IPHONE_SIMULATOR
+#if !TARGET_OS_SIMULATOR
 	if (__SCNetworkConnectionUsingNetworkExtension(connectionPrivate)) {
 		CFRetain(connection);
 		ne_session_set_event_handler(connectionPrivate->ne_session, __SCNetworkConnectionQueue(), ^(ne_session_event_t event, void *event_data) {
@@ -2458,7 +2471,7 @@ __SCNetworkConnectionScheduleWithRunLoop(SCNetworkConnectionRef	connection,
 			}
 		});
 	}
-#endif /* !TARGET_IPHONE_SIMULATOR */
+#endif /* !TARGET_OS_SIMULATOR */
 
 	ok = TRUE;
 
@@ -2548,9 +2561,9 @@ __SCNetworkConnectionUnscheduleFromRunLoop(SCNetworkConnectionRef	connection,
 		connectionPrivate->scheduled = FALSE;
 
 		if (__SCNetworkConnectionUsingNetworkExtension(connectionPrivate)) {
-#if !TARGET_IPHONE_SIMULATOR
+#if !TARGET_OS_SIMULATOR
 			ne_session_cancel(connectionPrivate->ne_session);
-#endif /* !TARGET_IPHONE_SIMULATOR */
+#endif /* !TARGET_OS_SIMULATOR */
 		} else {
 			mach_port_t session_port = __SCNetworkConnectionSessionPort(connectionPrivate);
 			if (session_port == MACH_PORT_NULL) {
@@ -2676,12 +2689,11 @@ SCNetworkConnectionTriggerOnDemandIfNeeded	(CFStringRef			hostName,
 						 int				timeout,
 						 int				trafficClass)
 {
-#if !TARGET_IPHONE_SIMULATOR
+#if !TARGET_OS_SIMULATOR
 	__block Boolean triggeredOnDemand = FALSE;
 	struct proc_uniqidentifierinfo procu;
 	void *policy_match = NULL;
 	char *hostname = NULL;
-	CFIndex hostnameSize = 0;
 	pid_t pid = getpid();
 	uid_t uid = geteuid();
 
@@ -2690,13 +2702,7 @@ SCNetworkConnectionTriggerOnDemandIfNeeded	(CFStringRef			hostName,
 		goto done;
 	}
 
-	hostnameSize = CFStringGetLength(hostName);
-	if (hostnameSize == 0) {
-		goto done;
-	}
-
-	hostname = malloc(hostnameSize + 1);
-	CFStringGetCString(hostName, hostname, hostnameSize + 1, kCFStringEncodingUTF8);
+	hostname = _SC_cfstring_to_cstring(hostName, NULL, 0, kCFStringEncodingUTF8);
 
 	if (proc_pidinfo(pid, PROC_PIDUNIQIDENTIFIERINFO, 1, &procu, sizeof(procu)) != sizeof(procu)) {
 		goto done;
@@ -2725,10 +2731,12 @@ SCNetworkConnectionTriggerOnDemandIfNeeded	(CFStringRef			hostName,
 								dispatch_retain(wait_for_session);
 								ne_session_set_event_handler(new_session, __SCNetworkConnectionQueue(),
 									^(ne_session_event_t event, void *event_data) {
-										os_activity_t	activity_id;
+										os_activity_t	activity;
 
-										activity_id = os_activity_start("processing ne_session notification",
-														OS_ACTIVITY_FLAG_DEFAULT);
+										activity = os_activity_create("processing ne_session notification",
+													      OS_ACTIVITY_CURRENT,
+													      OS_ACTIVITY_FLAG_DEFAULT);
+										os_activity_scope(activity);
 
 										if (event == NESessionEventStatusChanged) {
 											dispatch_retain(wait_for_session);
@@ -2747,7 +2755,7 @@ SCNetworkConnectionTriggerOnDemandIfNeeded	(CFStringRef			hostName,
 											dispatch_release(wait_for_session);
 										}
 
-										os_activity_end(activity_id);
+										os_release(activity);
 									});
 								ne_session_start_with_options(new_session, start_options);
 							} else {
@@ -2767,7 +2775,7 @@ SCNetworkConnectionTriggerOnDemandIfNeeded	(CFStringRef			hostName,
 	}
 done:
 	if (hostname) {
-		free(hostname);
+		CFAllocatorDeallocate(NULL, hostname);
 	}
 
 	if (policy_match) {
@@ -2932,7 +2940,7 @@ SCNetworkConnectionGetServiceIdentifier		(SCNetworkConnectionRef		connection)
 }
 
 
-#if !TARGET_IPHONE_SIMULATOR
+#if !TARGET_OS_SIMULATOR
 SCNetworkConnectionStatus
 SCNetworkConnectionGetStatusFromNEStatus(ne_session_status_t status)
 {
@@ -2952,7 +2960,7 @@ SCNetworkConnectionGetStatusFromNEStatus(ne_session_status_t status)
 
 	return kSCNetworkConnectionInvalid;
 }
-#endif /* !TARGET_IPHONE_SIMULATOR */
+#endif /* !TARGET_OS_SIMULATOR */
 
 
 #pragma mark -
@@ -3917,7 +3925,7 @@ __SCNetworkConnectionCopyUserPreferencesInternal(CFDictionaryRef	selectionOption
 				// (4) Get the default set of user options for this service
 				success = SCNetworkConnectionPrivateCopyDefaultUserOptionsFromArray((CFArrayRef)userServices,
 												    userOptions);
-				if(success && (userOptions != NULL)) {
+				if (success) {
 					addPasswordFromKeychain(*serviceID, userOptions);
 				}
 			} else {
@@ -3944,7 +3952,6 @@ SCNetworkConnectionCopyUserPreferences(CFDictionaryRef	selectionOptions,
 {
 	Boolean	success	= FALSE;
 
-
 	/* initialize runtime */
 	pthread_once(&initialized, __SCNetworkConnectionInitialize);
 
@@ -4368,18 +4375,23 @@ SCNetworkConnectionSelectServiceWithOptions(SCNetworkConnectionRef connection, C
 		if (isA_CFDictionary(configuration)) {
 			found_trigger = __SCNetworkConnectionCopyTriggerWithService(configuration, service_id);
 			if (found_trigger != NULL) {
-				CFNumberRef status_num = CFDictionaryGetValue(found_trigger, kSCNetworkConnectionOnDemandStatus);
-				if (isA_CFNumber(status_num)) {
-					CFNumberGetValue(status_num, kCFNumberIntType, &on_demand_status);
+				CFNumberRef status_num;
+
+				if (!CFDictionaryGetValueIfPresent(found_trigger,
+								   kSCNetworkConnectionOnDemandStatus,
+								   (const void **) &status_num) ||
+				    !isA_CFNumber(status_num) ||
+				    !CFNumberGetValue(status_num, kCFNumberSInt32Type, &on_demand_status)) {
+					on_demand_status = kSCNetworkConnectionInvalid;
 				}
+
 				/*
 				 * If the trigger should be ignored, still use App Layer VPN if it is already connected or
 				 * is in the process of connecting.
 				 */
 				if (__SCNetworkConnectionShouldIgnoreTrigger(found_trigger) &&
-				    on_demand_status != kSCNetworkConnectionConnecting &&
-				    on_demand_status != kSCNetworkConnectionConnected)
-				{
+				    (on_demand_status != kSCNetworkConnectionConnecting) &&
+				    (on_demand_status != kSCNetworkConnectionConnected)) {
 					use_app_layer = FALSE;
 				}
 			}
@@ -4483,9 +4495,14 @@ SCNetworkConnectionSelectServiceWithOptions(SCNetworkConnectionRef connection, C
 		CFRetain(connectionPrivate->on_demand_info);
 
 		if (on_demand_status == kSCNetworkConnectionInvalid) {
-			CFNumberRef status_num = CFDictionaryGetValue(found_trigger, kSCNetworkConnectionOnDemandStatus);
-			if (isA_CFNumber(status_num)) {
-				CFNumberGetValue(status_num, kCFNumberIntType, &on_demand_status);
+			CFNumberRef	status_num;
+
+			if (!CFDictionaryGetValueIfPresent(found_trigger,
+							   kSCNetworkConnectionOnDemandStatus,
+							   (const void **) &status_num) ||
+			    !isA_CFNumber(status_num) ||
+			    !CFNumberGetValue(status_num, kCFNumberSInt32Type, &on_demand_status)) {
+				on_demand_status = kSCNetworkConnectionInvalid;
 			}
 		}
 
@@ -4578,7 +4595,6 @@ SCNetworkConnectionPrivateCopyDefaultServiceIDForDial(CFStringRef *serviceID)
 	CFPropertyListRef	lastServiceSelectedInIC = NULL;
 
 
-
 	// we found the service the user last had open in IC
 	if (lastServiceSelectedInIC != NULL) {
 		// make sure its a PPP service
@@ -4924,12 +4940,11 @@ __private_extern__
 char *
 __SCNetworkConnectionGetControllerPortName(void)
 {
-#if	((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1090) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 70000)) && !TARGET_IPHONE_SIMULATOR
+#if	((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1090) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 70000)) && !TARGET_OS_SIMULATOR
 	if (scnc_server_name == NULL){
 		if (!(sandbox_check(getpid(), "mach-lookup", SANDBOX_FILTER_GLOBAL_NAME | SANDBOX_CHECK_NO_REPORT, PPPCONTROLLER_SERVER_PRIV))){
 			scnc_server_name = PPPCONTROLLER_SERVER_PRIV;
-		}
-		else{
+		} else {
 			scnc_server_name = PPPCONTROLLER_SERVER;
 		}
 	}
diff --git a/SystemConfiguration.fproj/SCNetworkConnectionInternal.h b/SystemConfiguration.fproj/SCNetworkConnectionInternal.h
index 9bef13b..08ccc60 100644
--- a/SystemConfiguration.fproj/SCNetworkConnectionInternal.h
+++ b/SystemConfiguration.fproj/SCNetworkConnectionInternal.h
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (c) 2012, 2013, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -26,9 +26,20 @@
 
 #include 
 
+#include 
+#include 
+
+#ifndef SC_LOG_HANDLE
+#define	SC_LOG_HANDLE	__log_SCNetworkConnection()
+#endif	// SC_LOG_HANDLE
+#include 
+#include 
+#include 
+
 
 __BEGIN_DECLS
 
+os_log_t	__log_SCNetworkConnection();
 void		__SCNetworkConnectionForceOnDemandConfigurationRefresh(void);
 char *		__SCNetworkConnectionGetControllerPortName(void);
 CFDictionaryRef	__SCNetworkConnectionCopyTokenParameters(SCNetworkConnectionRef connection);
diff --git a/SystemConfiguration.fproj/SCNetworkConnectionPrivate.c b/SystemConfiguration.fproj/SCNetworkConnectionPrivate.c
index 076261a..8f58c2f 100644
--- a/SystemConfiguration.fproj/SCNetworkConnectionPrivate.c
+++ b/SystemConfiguration.fproj/SCNetworkConnectionPrivate.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2012, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2006-2012, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -23,8 +23,6 @@
 
 #include 
 #include 
-#include 
-#include 		// for SCLog
 #include "SCNetworkConfigurationInternal.h"
 #include 
 #include 
@@ -158,6 +156,7 @@ __SCUserPreferencesCreatePrivate(CFAllocatorRef		allocator,
 		return NULL;
 	}
 
+	/* initialize non-zero/NULL members */
 	prefsPrivate->serviceID	= CFStringCreateCopy(NULL, serviceID);
 	prefsPrivate->prefsID	= CFStringCreateCopy(NULL, prefsID);
 
diff --git a/SystemConfiguration.fproj/SCNetworkConnectionPrivate.h b/SystemConfiguration.fproj/SCNetworkConnectionPrivate.h
index f5c3aeb..5160314 100644
--- a/SystemConfiguration.fproj/SCNetworkConnectionPrivate.h
+++ b/SystemConfiguration.fproj/SCNetworkConnectionPrivate.h
@@ -2,14 +2,14 @@
  * Copyright (c) 2006, 2008, 2009, 2011-2015 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@
  */
 
@@ -27,7 +27,7 @@
 #include 
 #include 
 #include 
-#if !TARGET_IPHONE_SIMULATOR
+#if !TARGET_OS_SIMULATOR
 #include 
 #endif
 #include 
@@ -488,10 +488,10 @@ __SCNetworkConnectionCopyOnDemandInfoWithName	(SCDynamicStoreRef		*storeP,
 						 SCNetworkConnectionStatus	*connectionStatus,
 						 CFStringRef			*vpnRemoteAddress)	__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_2_0);
 
-#if !TARGET_IPHONE_SIMULATOR
+#if !TARGET_OS_SIMULATOR
 SCNetworkConnectionStatus
 SCNetworkConnectionGetStatusFromNEStatus	(ne_session_status_t status)				__OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0);
-#endif /* !TARGET_IPHONE_SIMULATOR */
+#endif /* !TARGET_OS_SIMULATOR */
 
 #pragma mark -
 #pragma mark SCUserPreferences SPIs
diff --git a/SystemConfiguration.fproj/SCNetworkInterface.c b/SystemConfiguration.fproj/SCNetworkInterface.c
index 5f70eaf..6e0dace 100644
--- a/SystemConfiguration.fproj/SCNetworkInterface.c
+++ b/SystemConfiguration.fproj/SCNetworkInterface.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -37,10 +37,7 @@
 #include 
 #include 
 #include 
-#include 
 #include "SCNetworkConfigurationInternal.h"
-#include 
-#include 
 #include "SCPreferencesInternal.h"
 #include "SCHelper_client.h"
 
@@ -63,9 +60,9 @@
 #include 	// for kIOEthernetInterfaceClass
 #include 
 #include 
-#if	!TARGET_IPHONE_SIMULATOR
+#if	!TARGET_OS_SIMULATOR
 #include 
-#endif	// !TARGET_IPHONE_SIMULATOR
+#endif	// !TARGET_OS_SIMULATOR
 
 #include "dy_framework.h"
 
@@ -82,6 +79,7 @@
 #endif
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -95,7 +93,6 @@
 #include 
 #include 
 #include 
-#include 
 
 
 static CFStringRef	copy_interface_string				(CFBundleRef bundle, CFStringRef key, Boolean localized);
@@ -155,97 +152,15 @@ const CFStringRef kSCNetworkInterfaceTypeWWAN		= CFSTR("WWAN");
 const CFStringRef kSCNetworkInterfaceTypeIPv4		= CFSTR("IPv4");
 
 static SCNetworkInterfacePrivate __kSCNetworkInterfaceIPv4	= {
-	INIT_CFRUNTIME_BASE(),			// cfBase
-	NULL,					// interface type
-	FALSE,					// active
-	NULL,					// name
-	NULL,					// localized name
-	NULL,					// localization key
-	NULL,					// localization arg1
-	NULL,					// localization arg2
-	NULL,					// [layered] interface
-	NULL,					// prefs
-	NULL,					// store
-	NULL,					// serviceID
-	NULL,					// unsaved
-	NULL,					// entity_device
-	NULL,					// entity_device_unique
-	NULL,					// entity_type
-	NULL,					// entity_subtype
-	NULL,					// supported_interface_types
-	NULL,					// supported_protocol_types
-	NULL,					// address
-	NULL,					// addressString
-	FALSE,					// builtin
-	NULL,					// configurationAction
-	FALSE,					// hidden
-	NULL,					// location
-	NULL,					// path
-	0,					// entryID
-	NULL,					// overrides
-	FALSE,					// modemIsV92
-	NULL,					// name prefix
-	NULL,					// type
-	NULL,					// unit
-	{ NULL, 0, 0 },				// usb { name, vid, pid }
-	kSortUnknown,				// sort_order
-	FALSE,					// supportsBond
-	{ NULL, NULL, NULL },			// bond { interfaces, mode, options }
-	FALSE,					// supportsBridge
-	{ NULL, NULL },				// bridge { interfaces, options }
-	FALSE,					// supportsVLAN
-	{ NULL, NULL, NULL },			// vlan { interface, tag, options }
-#if	!TARGET_IPHONE_SIMULATOR
-	NULL,					// IPMonitorControl
-#endif	// !TARGET_IPHONE_SIMULATOR
+	.cfBase		= INIT_CFRUNTIME_BASE(),	// cfBase
+	.sort_order	= kSortUnknown,			// sort_order
 };
 
 const SCNetworkInterfaceRef kSCNetworkInterfaceIPv4	= (SCNetworkInterfaceRef)&__kSCNetworkInterfaceIPv4;
 
 static SCNetworkInterfacePrivate __kSCNetworkInterfaceLoopback	= {
-	INIT_CFRUNTIME_BASE(),			// cfBase
-	NULL,					// interface type
-	FALSE,					// active
-	NULL,					// name
-	NULL,					// localized name
-	NULL,					// localization key
-	NULL,					// localization arg1
-	NULL,					// localization arg2
-	NULL,					// [layered] interface
-	NULL,					// prefs
-	NULL,					// store
-	NULL,					// serviceID
-	NULL,					// unsaved
-	NULL,					// entity_device
-	NULL,					// entity_device_unique
-	NULL,					// entity_type
-	NULL,					// entity_subtype
-	NULL,					// supported_interface_types
-	NULL,					// supported_protocol_types
-	NULL,					// address
-	NULL,					// addressString
-	FALSE,					// builtin
-	NULL,					// configurationAction
-	FALSE,					// hidden
-	NULL,					// location
-	NULL,					// path
-	0,					// entryID
-	NULL,					// overrides
-	FALSE,					// modemIsV92
-	NULL,					// name prefix
-	NULL,					// type
-	NULL,					// unit
-	{ NULL, 0, 0 },				// usb { name, vid, pid }
-	kSortUnknown,				// sort_order
-	FALSE,					// supportsBond
-	{ NULL, NULL, NULL },			// bond { interfaces, mode, options }
-	FALSE,					// supportsBridge
-	{ NULL, NULL },				// bridge { interfaces, options }
-	FALSE,					// supportsVLAN
-	{ NULL, NULL, NULL },			// vlan { interface, tag, options }
-#if	!TARGET_IPHONE_SIMULATOR
-	NULL,					// IPMonitorControl
-#endif	// !TARGET_IPHONE_SIMULATOR
+	.cfBase		= INIT_CFRUNTIME_BASE(),	// cfBase
+	.sort_order	= kSortUnknown,			// sort_order
 };
 
 const SCNetworkInterfaceRef kSCNetworkInterfaceLoopback	= (SCNetworkInterfaceRef)&__kSCNetworkInterfaceLoopback;
@@ -296,7 +211,10 @@ static const struct {
 	{ &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					},
+#pragma GCC diagnostic pop
 	{ &kSCNetworkInterfaceTypeSerial	, &kSCEntNetModem     , FALSE,	doPPP,		&kSCValNetInterfaceSubTypePPPSerial,    doNone					},
 	{ &kSCNetworkInterfaceTypeVLAN		, &kSCEntNetEthernet  , TRUE ,	doNone,		NULL,					doDNS|doIPv4|doIPv6|doProxies|doSMB	},
 	{ &kSCNetworkInterfaceTypeVPN		, &kSCEntNetVPN       , FALSE,	doNone,		NULL,					doDNS|doIPv4|doIPv6|doProxies|doSMB	},
@@ -342,6 +260,7 @@ static const CFRuntimeClass __SCNetworkInterfaceClass = {
 
 static pthread_once_t		initialized	= PTHREAD_ONCE_INIT;
 static pthread_once_t		iokit_quiet	= PTHREAD_ONCE_INIT;
+static pthread_mutex_t		lock		= PTHREAD_MUTEX_INITIALIZER;
 
 
 static mach_port_t		masterPort	= MACH_PORT_NULL;
@@ -423,6 +342,12 @@ __SCNetworkInterfaceCopyFormattingDescription(CFTypeRef cf, CFDictionaryRef form
 	if (interfacePrivate->unit != NULL) {
 		CFStringAppendFormat(result, NULL, CFSTR(", unit = %@"), interfacePrivate->unit);
 	}
+	if (interfacePrivate->family != NULL) {
+		CFStringAppendFormat(result, NULL, CFSTR(", family = %@"), interfacePrivate->family);
+	}
+	if (interfacePrivate->subfamily != NULL) {
+		CFStringAppendFormat(result, NULL, CFSTR(", subfamily = %@"), interfacePrivate->subfamily);
+	}
 	if ((interfacePrivate->usb.vid != NULL) || (interfacePrivate->usb.pid != NULL)) {
 		int	pid	= 0;
 		int	vid	= 0;
@@ -609,6 +534,12 @@ __SCNetworkInterfaceDeallocate(CFTypeRef cf)
 	if (interfacePrivate->unit != NULL)
 		CFRelease(interfacePrivate->unit);
 
+	if (interfacePrivate->family != NULL)
+		CFRelease(interfacePrivate->family);
+
+	if (interfacePrivate->subfamily != NULL)
+		CFRelease(interfacePrivate->subfamily);
+
 	if (interfacePrivate->usb.name != NULL)
 		CFRelease(interfacePrivate->usb.name);
 
@@ -641,10 +572,10 @@ __SCNetworkInterfaceDeallocate(CFTypeRef cf)
 
 	if (interfacePrivate->vlan.options != NULL)
 		CFRelease(interfacePrivate->vlan.options);
-#if	!TARGET_IPHONE_SIMULATOR
+#if	!TARGET_OS_SIMULATOR
 	if (interfacePrivate->IPMonitorControl != NULL)
 		CFRelease(interfacePrivate->IPMonitorControl);
-#endif	// !TARGET_IPHONE_SIMULATOR
+#endif	// !TARGET_OS_SIMULATOR
 	return;
 }
 
@@ -793,55 +724,11 @@ __SCNetworkInterfaceCreatePrivate(CFAllocatorRef	allocator,
 		return NULL;
 	}
 
-	interfacePrivate->interface_type		= NULL;
-	interfacePrivate->active			= FALSE;
-	interfacePrivate->name				= NULL;
-	interfacePrivate->localized_name		= NULL;
-	interfacePrivate->localized_key			= NULL;
-	interfacePrivate->localized_arg1		= NULL;
-	interfacePrivate->localized_arg2		= NULL;
-	interfacePrivate->interface			= (interface != NULL) ? CFRetain(interface) : NULL;
-	interfacePrivate->prefs				= (prefs     != NULL) ? CFRetain(prefs)     : NULL;
-	interfacePrivate->store				= NULL;
-	interfacePrivate->serviceID			= (serviceID != NULL) ? CFRetain(serviceID) : NULL;
-	interfacePrivate->unsaved			= NULL;
-	interfacePrivate->entity_device			= NULL;
-	interfacePrivate->entity_device_unique		= NULL;
-	interfacePrivate->entity_type			= NULL;
-	interfacePrivate->entity_subtype		= NULL;
-	interfacePrivate->supported_interface_types     = NULL;
-	interfacePrivate->supported_protocol_types      = NULL;
-	interfacePrivate->address			= NULL;
-	interfacePrivate->addressString			= NULL;
-	interfacePrivate->builtin			= FALSE;
-	interfacePrivate->configurationAction		= NULL;
-	interfacePrivate->hidden			= FALSE;
-	interfacePrivate->location			= NULL;
-	interfacePrivate->path				= NULL;
-	interfacePrivate->entryID			= 0;
-	interfacePrivate->overrides			= NULL;
-	interfacePrivate->modemIsV92			= FALSE;
-	interfacePrivate->prefix			= NULL;
-	interfacePrivate->type				= NULL;
-	interfacePrivate->unit				= NULL;
-	interfacePrivate->usb.name			= NULL;
-	interfacePrivate->usb.vid			= NULL;
-	interfacePrivate->usb.pid			= NULL;
-	interfacePrivate->sort_order			= kSortUnknown;
-
-	interfacePrivate->supportsBond			= FALSE;
-	interfacePrivate->bond.interfaces		= NULL;
-	interfacePrivate->bond.mode			= NULL;
-	interfacePrivate->bond.options			= NULL;
-
-	interfacePrivate->supportsBridge		= FALSE;
-	interfacePrivate->bridge.interfaces		= NULL;
-	interfacePrivate->bridge.options		= NULL;
-
-	interfacePrivate->supportsVLAN			= FALSE;
-	interfacePrivate->vlan.interface		= NULL;
-	interfacePrivate->vlan.tag			= NULL;
-	interfacePrivate->vlan.options			= NULL;
+	/* initialize non-zero/NULL members */
+	interfacePrivate->interface	= (interface != NULL) ? CFRetain(interface) : NULL;
+	interfacePrivate->prefs		= (prefs     != NULL) ? CFRetain(prefs)     : NULL;
+	interfacePrivate->serviceID	= (serviceID != NULL) ? CFRetain(serviceID) : NULL;
+	interfacePrivate->sort_order	= kSortUnknown;
 
 	return interfacePrivate;
 }
@@ -1654,7 +1541,7 @@ isBluetoothBuiltin(Boolean *haveController)
 	hciController = IOIteratorNext(iter);
 	IOObjectRelease(iter);
 	if(hciController != MACH_PORT_NULL) {
-#if	!TARGET_IPHONE_SIMULATOR
+#if	!TARGET_OS_SIMULATOR
 		CFNumberRef	idVendor;
 
 		idVendor = IORegistryEntryCreateCFProperty(hciController, CFSTR(kUSBVendorID), NULL, 0);
@@ -1669,7 +1556,7 @@ isBluetoothBuiltin(Boolean *haveController)
 
 			CFRelease(idVendor);
 		}
-#endif	// !TARGET_IPHONE_SIMULATOR
+#endif	// !TARGET_OS_SIMULATOR
 
 		IOObjectRelease(hciController);
 	}
@@ -1706,7 +1593,7 @@ processUSBInterface(SCNetworkInterfacePrivateRef	interfacePrivate,
 		    io_registry_entry_t			bus,
 		    CFDictionaryRef			bus_dict)
 {
-#if	!TARGET_IPHONE_SIMULATOR
+#if	!TARGET_OS_SIMULATOR
 	// capture USB info
 	interfacePrivate->usb.name = IORegistryEntrySearchCFProperty(interface,
 								     kIOServicePlane,
@@ -1723,7 +1610,7 @@ processUSBInterface(SCNetworkInterfacePrivateRef	interfacePrivate,
 								     CFSTR(kUSBProductID),
 								     NULL,
 								     kIORegistryIterateRecursively | kIORegistryIterateParents);
-#endif	// !TARGET_IPHONE_SIMULATOR
+#endif	// !TARGET_OS_SIMULATOR
 
 	return;
 }
@@ -2037,7 +1924,7 @@ processNetworkInterface(SCNetworkInterfacePrivateRef	interfacePrivate,
 						io_registry_entry_t	node	= interface;
 
 						while (provider != NULL) {
-#if	!TARGET_IPHONE_SIMULATOR
+#if	!TARGET_OS_SIMULATOR
 							if (CFEqual(provider, CFSTR(kIOUSBDeviceClassName)) ||
 							    CFEqual(provider, CFSTR(kIOUSBInterfaceClassName))) {
 								// get USB info (if available)
@@ -2056,7 +1943,7 @@ processNetworkInterface(SCNetworkInterfacePrivateRef	interfacePrivate,
 								}
 								break;
 							}
-#endif	// !TARGET_IPHONE_SIMULATOR
+#endif	// !TARGET_OS_SIMULATOR
 
 							if (node == interface) {
 								node = controller;
@@ -2215,18 +2102,18 @@ set_connection_script(SCNetworkInterfacePrivateRef interfacePrivate, CFStringRef
 static Boolean
 is_valid_connection_script(CFStringRef script)
 {
-	char				ccl[MAXPATHLEN];
-	char				path[MAXPATHLEN];
-	NSSearchPathEnumerationState	state;
+	char					ccl[MAXPATHLEN];
+	char					path[MAXPATHLEN];
+	sysdir_search_path_enumeration_state	state;
 
 	(void) _SC_cfstring_to_cstring(script,
 				       ccl,
 				       sizeof(ccl),
 				       kCFStringEncodingUTF8);
 
-	state = NSStartSearchPathEnumeration(NSLibraryDirectory,
-					     NSLocalDomainMask|NSSystemDomainMask);
-	while ((state = NSGetNextSearchPathEnumeration(state, path))) {
+	state = sysdir_start_search_path_enumeration(SYSDIR_DIRECTORY_LIBRARY,
+						     SYSDIR_DOMAIN_MASK_LOCAL|SYSDIR_DOMAIN_MASK_SYSTEM);
+	while ((state = sysdir_get_next_search_path_enumeration(state, path))) {
 		size_t		n;
 		struct stat	statBuf;
 
@@ -2641,7 +2528,7 @@ createInterface(io_registry_entry_t interface, processInterface func,
 	CFTypeRef			val;
 
 	// Keys of interest
-#if	TARGET_IPHONE_SIMULATOR || 1	// while waiting for rdar://19431723
+#if	TARGET_OS_SIMULATOR || 1	// while waiting for rdar://19431723
 #else
 	const CFStringRef interface_dict_keys[] = {
 		CFSTR(kIOInterfaceType),
@@ -2655,7 +2542,7 @@ createInterface(io_registry_entry_t interface, processInterface func,
 		CFSTR(kIOSerialBSDTypeKey),
 		CFSTR(kIOLocation)
 	};
-#endif	// !TARGET_IPHONE_SIMULATOR
+#endif	// !TARGET_OS_SIMULATOR
 
 	const CFStringRef controller_dict_keys[] = {
 		CFSTR(kIOFeatures),
@@ -2679,7 +2566,7 @@ createInterface(io_registry_entry_t interface, processInterface func,
 		}
 	}
 
-#if	TARGET_IPHONE_SIMULATOR || 1	// while waiting for rdar://19431723
+#if	TARGET_OS_SIMULATOR || 1	// while waiting for rdar://19431723
 	// get the dictionary associated with the [interface] node
 	kr = IORegistryEntryCreateCFProperties(interface, &interface_dict, NULL, kNilOptions);
 	if (kr != kIOReturnSuccess) {
@@ -2690,7 +2577,7 @@ createInterface(io_registry_entry_t interface, processInterface func,
 	 interface_dict = copyIORegistryProperties(interface,
 						   interface_dict_keys,
 						   sizeof(interface_dict_keys)/sizeof(interface_dict_keys[0]));
-#endif	// !TARGET_IPHONE_SIMULATOR
+#endif	// !TARGET_OS_SIMULATOR
 
 	// get the controller node
 	kr = IORegistryEntryGetParentEntry(interface, kIOServicePlane, &controller);
@@ -2937,9 +2824,14 @@ __SCNetworkInterfaceIsValidExtendedConfigurationType(SCNetworkInterfaceRef	inter
 
 	/*
 	 * ???
-	 * Do we match specific/known extended configuration types (e.g. EAPOL)
-	 * and ensure that any non-standard extended configuration types be of
-	 * the form com.myCompany.myType?
+	 * Should we check/match and specifically allow known extended
+	 * configuration types (e.g. EAPOL)?
+	 *
+	 * Should we check/match and specifically block known internal
+	 * configuration types (e.g. QoSMarking)?
+	 *
+	 * Lastly, should we ensure that any non-standard extended configuration
+	 * types be of the form com.myCompany.myType?
 	 * ???
 	 */
 
@@ -2984,6 +2876,27 @@ __addExtendedConfigurationType(const void *key, const void *value, void *context
 }
 
 
+static CFIndex
+findPerInterfaceConfiguration(SCNetworkInterfaceRef interface)
+{
+	CFIndex				interfaceIndex;
+	SCNetworkInterfacePrivateRef 	interfacePrivate	= (SCNetworkInterfacePrivateRef)interface;
+
+	interfaceIndex = findConfiguration(interfacePrivate->interface_type);
+	if (interfaceIndex == kCFNotFound) {
+		// if per-service (not per interface) configuration
+		return kCFNotFound;
+	}
+
+	if (!configurations[interfaceIndex].per_interface_config) {
+		// if per-interface configuration not allowed
+		return kCFNotFound;
+	}
+
+	return interfaceIndex;
+}
+
+
 static CF_RETURNS_RETAINED CFArrayRef
 extendedConfigurationTypes(SCNetworkInterfaceRef interface)
 {
@@ -3008,15 +2921,9 @@ extendedConfigurationTypes(SCNetworkInterfaceRef interface)
 		goto done;
 	}
 
-	interfaceIndex = findConfiguration(interfacePrivate->interface_type);
+	interfaceIndex = findPerInterfaceConfiguration(interface);
 	if (interfaceIndex == kCFNotFound) {
-		// we don't allow per-service extended configurations
-		goto done;
-	}
-
-	if (!configurations[interfaceIndex].per_interface_config) {
-		// known interface type but we still don't allow
-		// per-service extended configurations
+		// if no per-interface configuration
 		goto done;
 	}
 
@@ -3140,9 +3047,9 @@ static CFArrayRef
 copyConfigurationPaths(SCNetworkInterfacePrivateRef	interfacePrivate,
 		       CFStringRef			extendedType)
 {
-	CFArrayRef			array;
-	CFIndex				interfaceIndex;
-	CFStringRef			path;
+	CFArrayRef	array		= NULL;
+	CFIndex		interfaceIndex;
+	CFStringRef	path;
 
 	interfaceIndex = findConfiguration(interfacePrivate->interface_type);
 	if (interfaceIndex == kCFNotFound) {
@@ -3162,9 +3069,11 @@ copyConfigurationPaths(SCNetworkInterfacePrivateRef	interfacePrivate,
 		array = stringCreateArray(path);
 		CFRelease(path);
 	}
-	else {
+
+	else if (interfacePrivate->serviceID != NULL) {
 		array = copyPerInterfaceConfigurationPaths(interfacePrivate, extendedType);
 	}
+
 	return (array);
 }
 
@@ -3589,7 +3498,7 @@ __SCNetworkInterfaceSetIOInterfacePrefix (SCNetworkInterfaceRef interface,
 
 __private_extern__
 void
-__SCNetworkInterfaceSetIOInterfaceUnit (SCNetworkInterfaceRef interface,
+__SCNetworkInterfaceSetIOInterfaceUnit(SCNetworkInterfaceRef interface,
 				       CFNumberRef unit)
 {
 	SCNetworkInterfacePrivateRef interfacePrivate;
@@ -3622,12 +3531,12 @@ __SCNetworkInterfaceSetIOInterfaceUnit (SCNetworkInterfaceRef interface,
 
 	// Update the BSD Name
 	if ((newBSDName == NULL) ||
-	    (__SCNetworkInterfaceUpdateBSDName(interface, oldBSDName, newBSDName) == FALSE)) {
+	    (!__SCNetworkInterfaceUpdateBSDName(interface, oldBSDName, newBSDName))) {
 		SC_log(LOG_INFO, "BSD name update failed");
 	}
 
 	// Update the path
-	if (__SCNetworkInterfaceUpdateIOPath(interface) == FALSE) {
+	if (!__SCNetworkInterfaceUpdateIOPath(interface)) {
 		SC_log(LOG_INFO, "IOPath update failed");
 	}
 
@@ -3662,48 +3571,48 @@ __SCNetworkInterfaceCopyStorageEntity(SCNetworkInterfaceRef interface)
 	CFDictionaryRef info = NULL;
 	CFStringRef type = NULL;
 
-	if (interfacePrivate->active == TRUE) {
+	if (interfacePrivate->active) {
 		active = kCFBooleanTrue;
 	}
 
 	bsdName = SCNetworkInterfaceGetBSDName(interface);
-	if (isA_CFString(bsdName) == NULL) {
+	if (!isA_CFString(bsdName)) {
 		goto done;
 	}
 
 	builtin = interfacePrivate->builtin ? kCFBooleanTrue : kCFBooleanFalse;
 	interfaceNamePrefix = _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface);
-	if (isA_CFString(interfaceNamePrefix) == NULL) {
+	if (!isA_CFString(interfaceNamePrefix)) {
 		goto done;
 	}
 
 	interfaceType = _SCNetworkInterfaceGetIOInterfaceType(interface);
-	if (isA_CFNumber(interfaceType) == NULL) {
+	if (!isA_CFNumber(interfaceType)) {
 		goto done;
 	}
 
 	interfaceUnit = _SCNetworkInterfaceGetIOInterfaceUnit(interface);
-	if (isA_CFNumber(interfaceUnit) == NULL) {
+	if (!isA_CFNumber(interfaceUnit)) {
 		goto done;
 	}
 
 	macAddress = _SCNetworkInterfaceGetHardwareAddress(interface);
-	if (isA_CFData(macAddress) == NULL) {
+	if (!isA_CFData(macAddress)) {
 		goto done;
 	}
 
 	pathMatch = _SCNetworkInterfaceGetIOPath(interface);
-	if (isA_CFString(pathMatch) == NULL) {
+	if (!isA_CFString(pathMatch)) {
 		goto done;
 	}
 
 	info = _SCNetworkInterfaceCopyInterfaceInfo(interface);
-	if (isA_CFDictionary(info) == NULL) {
+	if (!isA_CFDictionary(info)) {
 		goto done;
 	}
 
 	type = SCNetworkInterfaceGetInterfaceType(interface);
-	if (isA_CFString(type) == NULL) {
+	if (!isA_CFString(type)) {
 		goto done;
 	}
 
@@ -3769,7 +3678,7 @@ __SCNetworkInterfaceMatchesName(CFStringRef name, CFStringRef key)
 	CFStringRef	str;
 
 	if (bundle == NULL) {
-		SC_log(LOG_NOTICE, "%s: no bundle information to compare interface names", __FUNCTION__);
+		SC_log(LOG_NOTICE, "no bundle information to compare interface names");
 		return FALSE;
 	}
 
@@ -3864,7 +3773,7 @@ __SCNetworkInterfaceCreateWithStorageEntity (CFAllocatorRef allocator,
 		SC_log(LOG_INFO, "No IOInterfaceType");
 		goto done;
 	}
-	if (CFNumberGetValue(ioInterfaceType, kCFNumberIntType, &ioInterfaceTypeNum) == FALSE) {
+	if (!CFNumberGetValue(ioInterfaceType, kCFNumberIntType, &ioInterfaceTypeNum)) {
 		SC_log(LOG_NOTICE, "Count not extract value from ioInterfaceType");
 	}
 	ioInterfaceUnit = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceUnit));
@@ -3891,11 +3800,11 @@ __SCNetworkInterfaceCreateWithStorageEntity (CFAllocatorRef allocator,
 		goto done;
 	}
 	userDefinedName = CFDictionaryGetValue(SCNetworkInterfaceInfo, kSCPropUserDefinedName);
-#if	!TARGET_IPHONE_SIMULATOR
+#if	!TARGET_OS_SIMULATOR
 	usbProductName = CFDictionaryGetValue(SCNetworkInterfaceInfo, CFSTR(kUSBProductString));
 	idProduct = CFDictionaryGetValue(SCNetworkInterfaceInfo, CFSTR(kUSBProductID));
 	idVendor = CFDictionaryGetValue(SCNetworkInterfaceInfo, CFSTR(kUSBVendorID));
-#endif	// !TARGET_IPHONE_SIMULATOR
+#endif	// !TARGET_OS_SIMULATOR
 
 	type = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceType));
 	if (isA_CFString(type) == NULL) {
@@ -4085,9 +3994,12 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef		allocator,
 		} else if (CFEqual(ifSubType, kSCValNetInterfaceSubTypeL2TP)) {
 			interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4,
 													       kSCNetworkInterfaceTypeL2TP);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
 		} else if (CFEqual(ifSubType, kSCValNetInterfaceSubTypePPTP)) {
 			interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4,
 													       kSCNetworkInterfaceTypePPTP);
+#pragma GCC diagnostic pop
 		} else {
 			// XXX do we allow non-Apple variants of PPP??? XXX
 			interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4,
@@ -4231,11 +4143,11 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef		allocator,
 
     done :
 
-	if ((interfacePrivate == NULL) || (useSystemInterfaces == FALSE))  {
+	if ((interfacePrivate == NULL) || !useSystemInterfaces)  {
 		/*
 		 * if device not present on this system
 		 */
-		if (useSystemInterfaces == FALSE) {
+		if (!useSystemInterfaces) {
 			if (interfacePrivate != NULL) {
 				CFRelease(interfacePrivate);
 			}
@@ -4249,7 +4161,7 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef		allocator,
 
 		// Using UserDefinedName to check the validity of preferences file
 		// when useSystemInterfaces is FALSE
-		if (useSystemInterfaces == FALSE) {
+		if (!useSystemInterfaces) {
 			CFStringRef userDefinedName = CFDictionaryGetValue(interface_entity, kSCPropUserDefinedName);
 			if (isA_CFString(userDefinedName) != NULL) {
 				CFRetain(userDefinedName);
@@ -4270,7 +4182,7 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef		allocator,
 			CFStringRef	entity_hardware;
 			SCNetworkInterfaceRef virtualInterface;
 
-			if ((useSystemInterfaces == FALSE) &&
+			if (!useSystemInterfaces &&
 			    (((virtualInterface = findBridgeInterface(servicePref, ifDevice)) != NULL) ||
 #if	!TARGET_OS_IPHONE
 			    ((virtualInterface = findBondInterface(servicePref,  ifDevice)) != NULL) ||
@@ -4317,7 +4229,7 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef		allocator,
 		} else if (CFEqual(ifType, kSCValNetInterfaceTypeFireWire)) {
 			interfacePrivate->interface_type = kSCNetworkInterfaceTypeFireWire;
 			interfacePrivate->sort_order     = kSortFireWire;
-		} else if (CFEqual(ifType, kSCValNetInterfaceTypePPP)) {
+		} else if (CFEqual(ifType, kSCValNetInterfaceTypePPP) && (ifSubType != NULL)) {
 			if (CFEqual(ifSubType, kSCValNetInterfaceSubTypePPPoE)) {
 				CFStringRef	entity_hardware;
 
@@ -4354,7 +4266,7 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef		allocator,
 					return NULL;
 				}
 			}
-		} else if (CFEqual(ifType, kSCValNetInterfaceTypeVPN)) {
+		} else if (CFEqual(ifType, kSCValNetInterfaceTypeVPN) && (ifSubType != NULL)) {
 			SCNetworkInterfaceRef	child;
 			CFRelease(interfacePrivate);
 			child = SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4, ifSubType);
@@ -4378,12 +4290,13 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef		allocator,
 			interfacePrivate = __SCNetworkInterfaceCreateCopy(NULL, kSCNetworkInterfaceLoopback, NULL, NULL);
 		} else if (CFStringFind(ifType, CFSTR("."), 0).location != kCFNotFound) {
 			// if vendor interface
+			pthread_mutex_lock(&lock);
 			if (vendor_interface_types == NULL) {
 				vendor_interface_types = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
 			}
 			CFSetAddValue(vendor_interface_types, ifType);
-
 			interfacePrivate->interface_type = CFSetGetValue(vendor_interface_types, ifType);
+			pthread_mutex_unlock(&lock);
 		} else {
 			// if unknown interface
 			CFRelease(interfacePrivate);
@@ -4774,9 +4687,6 @@ SCNetworkInterfaceGetSupportedInterfaceTypes(SCNetworkInterfaceRef interface)
 			if (configurations[i].supported_interfaces & doPPP) {
 				CFArrayAppendValue(interfacePrivate->supported_interface_types, kSCNetworkInterfaceTypePPP);
 			}
-			if (configurations[i].supported_interfaces & doPPTP) {
-				CFArrayAppendValue(interfacePrivate->supported_interface_types, kSCNetworkInterfaceTypePPTP);
-			}
 			if (configurations[i].supported_interfaces & doIPSec) {
 				CFArrayAppendValue(interfacePrivate->supported_interface_types, kSCNetworkInterfaceTypeIPSec);
 			}
@@ -4909,6 +4819,8 @@ SCNetworkInterfaceCreateWithInterface(SCNetworkInterfaceRef child, CFStringRef i
 		parentPrivate->interface_type = kSCNetworkInterfaceTypeL2TP;
 		parentPrivate->localized_key  = CFSTR("l2tp");
 		parentPrivate->entity_type    = kSCEntNetL2TP;			// interface config goes into "L2TP"
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
 	} else if (CFEqual(interfaceType, kSCNetworkInterfaceTypePPTP)) {
 		if ((childIndex == kCFNotFound) ||
 		    ((configurations[childIndex].supported_interfaces & doPPTP) != doPPTP)) {
@@ -4918,6 +4830,7 @@ SCNetworkInterfaceCreateWithInterface(SCNetworkInterfaceRef child, CFStringRef i
 		parentPrivate->interface_type = kSCNetworkInterfaceTypePPTP;
 		parentPrivate->localized_key  = CFSTR("pptp");
 		parentPrivate->entity_type    = kSCEntNetPPTP;			// interface config goes into "PPTP"
+#pragma GCC diagnostic pop
 	} else if (CFEqual(interfaceType, kSCNetworkInterfaceType6to4)) {
 		if ((childIndex == kCFNotFound) ||
 		    ((configurations[childIndex].supported_interfaces & do6to4) != do6to4)) {
@@ -4985,12 +4898,14 @@ SCNetworkInterfaceCreateWithInterface(SCNetworkInterfaceRef child, CFStringRef i
 		}
 	} else if (CFStringFind(interfaceType, CFSTR("."), 0).location != kCFNotFound) {
 		// if custom interface type
+		pthread_mutex_lock(&lock);
 		if (vendor_interface_types == NULL) {
 			vendor_interface_types = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
 		}
 		CFSetAddValue(vendor_interface_types, interfaceType);
-
 		parentPrivate->interface_type = CFSetGetValue(vendor_interface_types, interfaceType);
+		pthread_mutex_unlock(&lock);
+
 		parentPrivate->entity_type    = parentPrivate->interface_type;	// interface config goes into a
 										// a dictionary with the same
 										// name as the interfaceType
@@ -5238,7 +5153,7 @@ SCNetworkInterfaceGetHardwareAddressString(SCNetworkInterfaceRef interface)
 		n  = CFDataGetLength(interfacePrivate->address) * 3;
 
 		if (n > sizeof(mac)) {
-			mac_p = CFAllocatorAllocate(NULL, 0, n);
+			mac_p = CFAllocatorAllocate(NULL, n, 0);
 		}
 
 		for (cp = mac_p; n > 0; n -= 3) {
@@ -5297,7 +5212,7 @@ copy_string_from_bundle(CFBundleRef bundle, CFStringRef key, Boolean localized)
 							 key,
 							 NETWORKINTERFACE_LOCALIZATIONS);
 	}
-	
+
 	return str;
 }
 
@@ -5309,18 +5224,18 @@ copy_interface_string(CFBundleRef bundle, CFStringRef key, Boolean localized)
 	CFStringRef	str	= NULL;
 
 	str = copy_string_from_bundle(bundle, key, localized);
-	
+
 	if (str == NULL) {
 		SC_log(LOG_ERR, "Received NULL string for the interface key: {Bundle: %@, key: %@, localized: %d}", bundle,
-			                                                                                            key,
-		                                                                                                    localized);
+														    key,
+														    localized);
 		goto done;
 	}
-	
+
 	if (CFEqual(str, key) && !reported) {
 		const CFStringRef knownStrKey = CFSTR("airport");
 		CFStringRef knownStrValue = NULL;
-		
+
 		knownStrValue = copy_string_from_bundle(bundle, knownStrKey, localized);
 		if (knownStrValue == NULL || CFEqual(knownStrValue, knownStrKey)) {
 			/* We are here because we requested for a localized/non-localized string
@@ -5337,7 +5252,7 @@ copy_interface_string(CFBundleRef bundle, CFStringRef key, Boolean localized)
 #endif //TARGET_OS_IPHONE
 			reported = TRUE;
 		}
-		
+
 		if (knownStrValue != NULL) {
 			CFRelease(knownStrValue);
 		}
@@ -5724,6 +5639,7 @@ Boolean
 SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface, CFDictionaryRef config)
 {
 	CFStringRef	defaultType;
+	Boolean		ok;
 
 	if (!isA_SCNetworkInterface(interface)) {
 		_SCErrorSet(kSCStatusInvalidArgument);
@@ -5735,7 +5651,14 @@ SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface, CFDictionary
 		return FALSE;
 	}
 
-	return __SCNetworkInterfaceSetConfiguration(interface, defaultType, config, FALSE);
+	ok = __SCNetworkInterfaceSetConfiguration(interface, defaultType, config, FALSE);
+	if (ok) {
+		SC_log(LOG_DEBUG, "SCNetworkInterfaceSetConfiguration(): %@ -> %@",
+		       interface,
+		       config != NULL ? config : (CFDictionaryRef)CFSTR("NULL"));
+	}
+
+	return ok;
 }
 
 
@@ -5744,6 +5667,8 @@ SCNetworkInterfaceSetExtendedConfiguration(SCNetworkInterfaceRef	interface,
 					   CFStringRef			extendedType,
 					   CFDictionaryRef		config)
 {
+	Boolean		ok;
+
 	if (!isA_SCNetworkInterface(interface)) {
 		_SCErrorSet(kSCStatusInvalidArgument);
 		return FALSE;
@@ -5753,7 +5678,14 @@ SCNetworkInterfaceSetExtendedConfiguration(SCNetworkInterfaceRef	interface,
 		return FALSE;
 	}
 
-	return __SCNetworkInterfaceSetConfiguration(interface, extendedType, config, FALSE);
+	ok = __SCNetworkInterfaceSetConfiguration(interface, extendedType, config, FALSE);
+	if (ok) {
+		SC_log(LOG_DEBUG, "SCNetworkInterfaceSetExtendedConfiguration(): %@ -> %@",
+		       interface,
+		       config != NULL ? config : (CFDictionaryRef)CFSTR("NULL"));
+	}
+
+	return ok;
 }
 
 
@@ -6978,7 +6910,7 @@ _SCNetworkInterfaceCopyInterfaceInfo(SCNetworkInterfaceRef interface)
 
 	// add USB info
 	if ((interfacePrivate->usb.vid != NULL) || (interfacePrivate->usb.pid != NULL)) {
-#if	!TARGET_IPHONE_SIMULATOR
+#if	!TARGET_OS_SIMULATOR
 		if (interfacePrivate->usb.name != NULL) {
 			CFDictionaryAddValue(info, CFSTR(kUSBProductString), interfacePrivate->usb.name);
 		}
@@ -6988,7 +6920,7 @@ _SCNetworkInterfaceCopyInterfaceInfo(SCNetworkInterfaceRef interface)
 		if (interfacePrivate->usb.pid != NULL) {
 			CFDictionaryAddValue(info, CFSTR(kUSBProductID), interfacePrivate->usb.pid);
 		}
-#endif	// !TARGET_IPHONE_SIMULATOR
+#endif	// !TARGET_OS_SIMULATOR
 	}
 
 	if (CFDictionaryGetCount(info) == 0) {
@@ -7064,6 +6996,72 @@ _SCNetworkInterfaceGetIOInterfaceUnit(SCNetworkInterfaceRef interface)
 }
 
 
+static void
+update_ift_family(SCNetworkInterfaceRef interface)
+{
+	SCNetworkInterfacePrivateRef	interfacePrivate	= (SCNetworkInterfacePrivateRef)interface;
+
+	// note: family/subfamily are not in IORegistry, fetch with ioctl()
+
+	if ((interfacePrivate->family == NULL) && (interfacePrivate->subfamily == NULL)) {
+		CFStringRef	bsdName	= SCNetworkInterfaceGetBSDName(interface);
+		struct ifreq	ifr;
+
+		bzero(&ifr, sizeof(ifr));
+		if ((bsdName != NULL) &&
+		    _SC_cfstring_to_cstring(bsdName, ifr.ifr_name, sizeof(ifr.ifr_name), kCFStringEncodingASCII) != NULL) {
+			int	s;
+
+			s = socket(AF_INET, SOCK_DGRAM, 0);
+			if (s != -1) {
+				if (ioctl(s, SIOCGIFTYPE, (caddr_t)&ifr) == -1) {
+					ifr.ifr_type.ift_family = 0;
+					ifr.ifr_type.ift_subfamily = 0;
+				}
+				close(s);
+			}
+		}
+
+		interfacePrivate->family = CFNumberCreate(NULL,
+							  kCFNumberSInt32Type,
+							  &ifr.ifr_type.ift_family);
+		interfacePrivate->subfamily = CFNumberCreate(NULL,
+							     kCFNumberSInt32Type,
+							     &ifr.ifr_type.ift_subfamily);
+	}
+}
+
+
+CFNumberRef
+_SCNetworkInterfaceGetFamilyType(SCNetworkInterfaceRef interface)
+{
+	SCNetworkInterfacePrivateRef	interfacePrivate	= (SCNetworkInterfacePrivateRef)interface;
+
+	// note: family not in IORegistry, fetch with ioctl()
+
+	if (interfacePrivate->family == NULL) {
+		update_ift_family(interface);
+	}
+
+	return interfacePrivate->family;
+}
+
+
+CFNumberRef
+_SCNetworkInterfaceGetFamilySubType(SCNetworkInterfaceRef interface)
+{
+	SCNetworkInterfacePrivateRef	interfacePrivate	= (SCNetworkInterfacePrivateRef)interface;
+
+	// note: subfamily not in IORegistry, fetch with ioctl()
+
+	if (interfacePrivate->subfamily == NULL) {
+		update_ift_family(interface);
+	}
+
+	return interfacePrivate->subfamily;
+}
+
+
 CFStringRef
 _SCNetworkInterfaceGetIOPath(SCNetworkInterfaceRef interface)
 {
@@ -7275,6 +7273,9 @@ _SCNetworkInterfaceCopySlashDevPath(SCNetworkInterfaceRef interface)
 }
 
 
+#pragma mark -
+
+
 Boolean
 _SCNetworkInterfaceIsBluetoothPAN(SCNetworkInterfaceRef interface)
 {
@@ -7371,6 +7372,48 @@ _SCNetworkInterfaceIsThunderbolt(SCNetworkInterfaceRef interface)
 }
 
 
+#pragma mark -
+
+
+CFDictionaryRef
+SCNetworkInterfaceGetQoSMarkingPolicy(SCNetworkInterfaceRef interface)
+{
+	CFDictionaryRef	policy;
+
+	if (!isA_SCNetworkInterface(interface)) {
+		_SCErrorSet(kSCStatusInvalidArgument);
+		return NULL;
+	}
+
+	policy = __SCNetworkInterfaceGetConfiguration(interface, kSCEntNetQoSMarkingPolicy);
+	if (policy == NULL) {
+		_SCErrorSet(kSCStatusOK);
+	}
+
+	return policy;
+}
+
+Boolean
+SCNetworkInterfaceSetQoSMarkingPolicy(SCNetworkInterfaceRef interface, CFDictionaryRef policy)
+{
+	Boolean		ok;
+
+	if (!isA_SCNetworkInterface(interface)) {
+		_SCErrorSet(kSCStatusInvalidArgument);
+		return FALSE;
+	}
+
+	ok = __SCNetworkInterfaceSetConfiguration(interface, kSCEntNetQoSMarkingPolicy, policy, FALSE);
+	if (ok) {
+		SC_log(LOG_DEBUG, "SCNetworkInterfaceSetQoSMarkingPolicy(): %@ -> %@",
+		       interface,
+		       policy != NULL ? policy : (CFDictionaryRef)CFSTR("NULL"));
+	}
+
+	return ok;
+}
+
+
 #pragma mark -
 #pragma mark SCNetworkInterface [internal] SPIs
 
@@ -7458,6 +7501,12 @@ __SCNetworkInterfaceCreateCopy(CFAllocatorRef		allocator,
 	if (oldPrivate->unit != NULL) {
 		newPrivate->unit		= CFRetain(oldPrivate->unit);
 	}
+	if (oldPrivate->family != NULL) {
+		newPrivate->family		= CFRetain(oldPrivate->family);
+	}
+	if (oldPrivate->subfamily != NULL) {
+		newPrivate->subfamily		= CFRetain(oldPrivate->subfamily);
+	}
 	if (oldPrivate->usb.name != NULL) {
 		newPrivate->usb.name		= CFRetain(oldPrivate->usb.name);
 	}
@@ -7622,6 +7671,7 @@ __SCNetworkInterfaceSetDeepConfiguration(SCNetworkSetRef set, SCNetworkInterface
 	for (i = 0; interface != NULL; i++) {
 		CFStringRef	defaultType;
 		CFDictionaryRef interfaceConfiguration;
+		Boolean		ok;
 
 		interfaceConfiguration = (configs != NULL) ? CFArrayGetValueAtIndex(configs, i) : NULL;
 
@@ -7637,18 +7687,20 @@ __SCNetworkInterfaceSetDeepConfiguration(SCNetworkSetRef set, SCNetworkInterface
 			}
 			if (set == NULL) {
 				// if service is not associated with the set
-				if (!__SCNetworkInterfaceSetConfiguration(interface, defaultType, config, TRUE)) {
-					SC_log(LOG_INFO, "__SCNetworkInterfaceSetConfiguration() failed, interface=%@, type=%@",
-					       interface,
-					       defaultType);
-				}
+				ok = __SCNetworkInterfaceSetConfiguration(interface, defaultType, config, TRUE);
 			} else {
 				// apply default configuration to this set
-				if (!__SCNetworkInterfaceSetDefaultConfiguration(set, interface, defaultType, config, TRUE)) {
-					SC_log(LOG_INFO, "__SCNetworkInterfaceSetDefaultConfiguration() failed, interface=%@, type=%@",
-					       interface,
-					       defaultType);
-				}
+				ok = __SCNetworkInterfaceSetDefaultConfiguration(set, interface, defaultType, config, TRUE);
+			}
+			if (ok) {
+				SC_log(LOG_DEBUG, "__SCNetworkInterfaceSetDeepConfiguration(): %@, %@ -> %@",
+				       interface,
+				       defaultType,
+				       config != NULL ? config : (CFDictionaryRef)CFSTR("NULL"));
+			} else {
+				SC_log(LOG_INFO, "__SCNetworkInterfaceSetDeepConfiguration() failed, interface=%@, type=%@",
+				       interface,
+				       defaultType);
 			}
 
 			extendedTypes = extendedConfigurationTypes(interface);
@@ -7662,14 +7714,20 @@ __SCNetworkInterfaceSetDeepConfiguration(SCNetworkSetRef set, SCNetworkInterface
 
 					extendedType = CFArrayGetValueAtIndex(extendedTypes, j);
 					config = (interfaceConfiguration != NULL) ? CFDictionaryGetValue(interfaceConfiguration, extendedType)
-					: NULL;
+										  : NULL;
 					if (config == (CFDictionaryRef)kCFNull) {
 						config = NULL;
 					}
-					if (!__SCNetworkInterfaceSetConfiguration(interface, extendedType, config, TRUE)) {
-						SC_log(LOG_INFO, "__SCNetworkInterfaceSetConfiguration() failed, interface=%@, type=%@",
+					ok = __SCNetworkInterfaceSetConfiguration(interface, extendedType, config, TRUE);
+					if (ok) {
+						SC_log(LOG_DEBUG, "__SCNetworkInterfaceSetDeepConfiguration(): %@, %@ -> %@",
 						       interface,
-						       defaultType);
+						       extendedType,
+						       config != NULL ? config : (CFDictionaryRef)CFSTR("NULL"));
+					} else {
+						SC_log(LOG_INFO, "__SCNetworkInterfaceSetDeepConfiguration() failed, interface=%@, type=%@",
+						       interface,
+						       extendedType);
 					}
 				}
 
@@ -7706,7 +7764,7 @@ _SCNetworkInterfaceCopyActive(SCDynamicStoreRef store, CFStringRef bsdName)
 }
 
 
-#if	!TARGET_IPHONE_SIMULATOR
+#if	!TARGET_OS_SIMULATOR
 SCNetworkServicePrimaryRank
 SCNetworkInterfaceGetPrimaryRank(SCNetworkInterfaceRef interface)
 {
@@ -7759,21 +7817,6 @@ SCNetworkInterfaceSetPrimaryRank(SCNetworkInterfaceRef interface,
 						       newRank);
 }
 
-static CFIndex
-findPerInterfaceConfig(SCNetworkInterfaceRef interface)
-{
-	CFIndex				interfaceIndex;
-	SCNetworkInterfacePrivateRef 	interfacePrivate
-		= (SCNetworkInterfacePrivateRef)interface;
-
-	interfaceIndex = findConfiguration(interfacePrivate->interface_type);
-	if (interfaceIndex == kCFNotFound
-	    || !configurations[interfaceIndex].per_interface_config) {
-		return (kCFNotFound);
-	}
-	return (interfaceIndex);
-}
-
 Boolean
 SCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface)
 {
@@ -7788,7 +7831,7 @@ SCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface)
 		_SCErrorSet(kSCStatusInvalidArgument);
 		return (FALSE);
 	}
-	interfaceIndex = findPerInterfaceConfig(interface);
+	interfaceIndex = findPerInterfaceConfiguration(interface);
 	if (interfaceIndex == kCFNotFound) {
 		_SCErrorSet(kSCStatusInvalidArgument);
 		return (FALSE);
@@ -7825,7 +7868,7 @@ SCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface)
 }
 
 Boolean
-SCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface, Boolean disable)
+__SCNetworkInterfaceSetDisableUntilNeededValue(SCNetworkInterfaceRef interface, CFTypeRef disable)
 {
 	CFIndex				count;
 	CFIndex				i;
@@ -7839,7 +7882,11 @@ SCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface, Boolean
 		_SCErrorSet(kSCStatusInvalidArgument);
 		return (FALSE);
 	}
-	interfaceIndex = findPerInterfaceConfig(interface);
+	if ((disable != NULL) && !isA_CFNumber(disable)) {
+		_SCErrorSet(kSCStatusInvalidArgument);
+		return (FALSE);
+	}
+	interfaceIndex = findPerInterfaceConfiguration(interface);
 	if (interfaceIndex == kCFNotFound) {
 		_SCErrorSet(kSCStatusInvalidArgument);
 		return (FALSE);
@@ -7852,28 +7899,28 @@ SCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface, Boolean
 	count = CFArrayGetCount(path_list);
 	for (i = 0; i < count; i++) {
 		CFDictionaryRef		config;
-		CFNumberRef		disable_prop;
 		CFMutableDictionaryRef	new_config;
 		CFStringRef		path = CFArrayGetValueAtIndex(path_list, i);
-		int			intval;
 
 		config = __getPrefsConfiguration(interfacePrivate->prefs, path);
 		if (config != NULL) {
 			new_config
 				= CFDictionaryCreateMutableCopy(NULL, 0, config);
-		}
-		else {
+		} else {
 			new_config
 				= CFDictionaryCreateMutable(NULL, 0,
 							    &kCFTypeDictionaryKeyCallBacks,
 							    &kCFTypeDictionaryValueCallBacks);
 		}
-		intval = disable ? 1 : 0;
-		disable_prop = CFNumberCreate(NULL, kCFNumberIntType, &intval);
-		CFDictionarySetValue(new_config, kSCPropDisableUntilNeeded,
-				     disable_prop);
-		CFRelease(disable_prop);
-		ok = __setPrefsConfiguration(interfacePrivate->prefs, path, new_config, FALSE);
+		if (disable != NULL) {
+			CFDictionarySetValue(new_config, kSCPropDisableUntilNeeded, disable);
+		} else {
+			CFDictionaryRemoveValue(new_config, kSCPropDisableUntilNeeded);
+		}
+		ok = __setPrefsConfiguration(interfacePrivate->prefs,
+					     path,
+					     (CFDictionaryGetCount(new_config) > 0) ? new_config : NULL,
+					     FALSE);
 		CFRelease(new_config);
 		if (!ok) {
 			break;
@@ -7883,7 +7930,22 @@ SCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface, Boolean
 	return (ok);
 }
 
-#else 	// !TARGET_IPHONE_SIMULATOR
+Boolean
+SCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface, Boolean disable)
+{
+	Boolean		ok;
+	const int	one	= 1;
+	CFNumberRef     num;
+	const int	zero	= 0;
+
+	num = CFNumberCreate(NULL, kCFNumberIntType, disable ? &one : &zero);
+	ok = __SCNetworkInterfaceSetDisableUntilNeededValue(interface, num);
+	CFRelease(num);
+
+	return ok;
+}
+
+#else 	// !TARGET_OS_SIMULATOR
 
 SCNetworkServicePrimaryRank
 SCNetworkInterfaceGetPrimaryRank(SCNetworkInterfaceRef interface)
@@ -7899,21 +7961,26 @@ SCNetworkInterfaceSetPrimaryRank(SCNetworkInterfaceRef interface,
 	return (FALSE);
 }
 
-
 Boolean
 SCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface)
 {
-    return (FALSE);
+	return (FALSE);
+}
+
+Boolean
+__SCNetworkInterfaceSetDisableUntilNeededValue(SCNetworkInterfaceRef interface, CFTypeRef disable)
+{
+	return (FALSE);
 }
 
 Boolean
 SCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface, Boolean disable)
 {
-    _SCErrorSet(kSCStatusInvalidArgument);
-    return (FALSE);
+	_SCErrorSet(kSCStatusInvalidArgument);
+	return (FALSE);
 }
 
-#endif	// !TARGET_IPHONE_SIMULATOR
+#endif	// !TARGET_OS_SIMULATOR
 
 
 __private_extern__
@@ -7930,6 +7997,7 @@ __SCNetworkInterfaceCopyStoredWithPreferences (SCPreferencesRef ni_prefs)
 
 	if (ni_prefs == NULL) {
 		defaultNetworkInterfacePath = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@"), PREFS_DEFAULT_DIR, NETWORK_INTERFACES_PREFS);
+		assert(defaultNetworkInterfacePath != NULL);
 		ni_prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath);
 	}
 
@@ -7973,6 +8041,7 @@ __SCNetworkInterfaceSaveStoredWithPreferences(SCPreferencesRef prefs, CFArrayRef
 
 	if (prefs == NULL) {    // TODO: Get the default preferences on the system
 		defaultNetworkInterfacePath = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), PREFS_DEFAULT_DIR, NETWORK_INTERFACES_PREFS);
+		assert(defaultNetworkInterfacePath != NULL);
 		prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath);
 	}
 
@@ -8031,7 +8100,7 @@ __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(CFAllocatorRef allocator
 			if (tmp_bsdName == NULL) {
 				continue;
 			}
-			if (CFEqual(bsdName, tmp_bsdName) == TRUE) {
+			if (CFEqual(bsdName, tmp_bsdName)) {
 				interface = __SCNetworkInterfaceCreateWithStorageEntity(allocator, dict, ni_prefs);
 				break;
 			}
@@ -8076,3 +8145,23 @@ __SCNetworkInterfaceCreateMappingUsingBSDName(CFArrayRef interfaces)
 
 	return mappingBSDToInterface;
 }
+
+__private_extern__ Boolean
+__SCNetworkInterfaceEntityIsPPTP(CFDictionaryRef entity)
+{
+	CFStringRef intfSubtype;
+
+	if (entity == NULL) {
+		return FALSE;
+	}
+
+	intfSubtype = CFDictionaryGetValue(entity, kSCPropNetInterfaceSubType);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
+	if (intfSubtype != NULL && CFEqual(intfSubtype, kSCValNetInterfaceSubTypePPTP)) {
+		return TRUE;
+	}
+#pragma GCC diagnostic pop
+
+	return FALSE;
+}
diff --git a/SystemConfiguration.fproj/SCNetworkMigration.c b/SystemConfiguration.fproj/SCNetworkMigration.c
index 955562c..411c7e7 100644
--- a/SystemConfiguration.fproj/SCNetworkMigration.c
+++ b/SystemConfiguration.fproj/SCNetworkMigration.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2014-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -30,13 +30,10 @@
 
 #include 
 #include 
-#include 
-#include 
-#include 
+#include "SCNetworkConfigurationInternal.h"
 #include "SCPreferencesInternal.h"
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -81,8 +78,7 @@ _SCNetworkConfigurationCopyMigrationPathsWithBaseURL(CFURLRef baseURL, CFURLRef
 {
 	if (baseURL != NULL) {
 		CFRetain(baseURL);
-	}
-	else {
+	} else {
 		baseURL = CFURLCreateFromFileSystemRepresentation(NULL,
 								  (UInt8*)PREFS_DEFAULT_DIR_PLIST,
 								  sizeof(PREFS_DEFAULT_DIR_PLIST),
@@ -90,14 +86,16 @@ _SCNetworkConfigurationCopyMigrationPathsWithBaseURL(CFURLRef baseURL, CFURLRef
 	}
 
 	*prefs = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL,
-								      (UInt8*)PREFS_DEFAULT_CONFIG_PLIST,
-								      sizeof(PREFS_DEFAULT_CONFIG_PLIST) - 1,
-								      FALSE, baseURL);
+								       (UInt8*)PREFS_DEFAULT_CONFIG_PLIST,
+								       sizeof(PREFS_DEFAULT_CONFIG_PLIST) - 1,
+								       FALSE,
+								       baseURL);
 
 	*interfaces = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL,
-									   (UInt8*)NETWORK_INTERFACES_PREFS_PLIST,
-									   sizeof(NETWORK_INTERFACES_PREFS_PLIST) - 1,
-									   FALSE, baseURL);
+									    (UInt8*)NETWORK_INTERFACES_PREFS_PLIST,
+									    sizeof(NETWORK_INTERFACES_PREFS_PLIST) - 1,
+									    FALSE,
+									    baseURL);
 	CFRelease(baseURL);
 	return;
 }
@@ -231,7 +229,7 @@ SCNetworkConfigurationCopyConfigurationFiles(CFURLRef	configDir,
 		goto done;
 	}
 	copyfile_state_free(state);
-	chmod(targetPathString, mode);
+	(void)chmod(targetPathString, mode);
 
 	networkInterfacesState = copyfile_state_alloc();
 	if ((error = copyfile(networkInterfacesPathString, targetNetworkInterfacesPathString, networkInterfacesState, COPYFILE_ALL)) != 0) {
@@ -244,11 +242,11 @@ SCNetworkConfigurationCopyConfigurationFiles(CFURLRef	configDir,
 		goto done;
 	}
 	copyfile_state_free(networkInterfacesState);
-	chmod(targetNetworkInterfacesPathString, mode);
+	(void)chmod(targetNetworkInterfacesPathString, mode);
 
 	success = TRUE;
 done:
-	if (removeTargetFiles == TRUE) {
+	if (removeTargetFiles) {
 		_SCNetworkConfigurationRemoveConfigurationFiles(targetDir);
 	}
 	if (preferencesPathURL != NULL) {
@@ -291,19 +289,19 @@ _SCNetworkConfigurationMakePathIfNeeded(CFURLRef pathURL)
 
 	slen = strlen(path);
 
-	strlcpy( thepath, path, slen+1);
+	strlcpy(thepath, path, slen+1);
 	c = thepath;
-	if ( *c == '/' )
+	if (*c == '/')
 		c++;
-	for(  ; !success; c++){
-		if ( (*c == '/') || ( *c == '\0' )){
-			if ( *c == '\0' )
+	for(; !success; c++){
+		if ((*c == '/') || (*c == '\0')){
+			if (*c == '\0')
 				success = TRUE;
 			else
 				*c = '\0';
-			if ( mkdir( thepath, newmask) ){
-				if ( errno == EEXIST || errno == EISDIR){
-					if ( stat(thepath, &sb) < 0){
+			if (mkdir(thepath, newmask)){
+				if (errno == EEXIST || errno == EISDIR){
+					if (stat(thepath, &sb) < 0){
 						SC_log(LOG_ERR, "stat returned value < 0");
 						break;
 					}
@@ -332,22 +330,7 @@ __SCNetworkCreateDefaultPref(CFStringRef prefsID)
 
 	currentSet = SCNetworkSetCopyCurrent(prefs);
 	if (currentSet == NULL) {
-		CFBundleRef bundle;
-		CFStringRef setName = NULL;
-
-		currentSet = SCNetworkSetCreate(prefs);
-		bundle = _SC_CFBundleGet();
-		if (bundle != NULL) {
-			setName = CFBundleCopyLocalizedString(bundle,
-							      CFSTR("DEFAULT_SET_NAME"),
-							      CFSTR("Automatic"),
-							      NULL);
-		}
-		SCNetworkSetSetName(currentSet, (setName != NULL) ? setName : CFSTR("Automatic"));
-		SCNetworkSetSetCurrent(currentSet);
-		if (setName != NULL) {
-			CFRelease(setName);
-		}
+		currentSet = _SCNetworkSetCreateDefault(prefs);
 	}
 	SCNetworkSetEstablishDefaultConfiguration(currentSet);
 	CFRelease(currentSet);
@@ -505,13 +488,13 @@ _SCNetworkConfigurationPerformMigration(CFURLRef sourceDir, CFURLRef currentDir,
 		goto done;
 	}
 
-	if ((currentDirConfig == NULL) || (CFEqual(currentDirConfig, targetDirConfig) == FALSE)) {
-		if (_SCNetworkConfigurationMakePathIfNeeded(targetDirConfig) == FALSE) {
+	if ((currentDirConfig == NULL) || !CFEqual(currentDirConfig, targetDirConfig)) {
+		if (!_SCNetworkConfigurationMakePathIfNeeded(targetDirConfig)) {
 			SC_log(LOG_INFO, "Could not create target directory");
 			goto done;
 		}
 
-		if (SCNetworkConfigurationCopyConfigurationFiles(currentDirConfig, targetDirConfig) == FALSE) {
+		if (!SCNetworkConfigurationCopyConfigurationFiles(currentDirConfig, targetDirConfig)) {
 			SC_log(LOG_INFO, "Could not copy configuration files from \"%@\" to \"%@\"",
 			       currentDirConfig,
 			       targetDirConfig);
@@ -525,7 +508,7 @@ _SCNetworkConfigurationPerformMigration(CFURLRef sourceDir, CFURLRef currentDir,
 	}
 
 	// If both source and current configurations point to current system, then no migration needs to be done.
-	if ((currentDirConfig != NULL) && (CFEqual(sourceDirConfig, currentDirConfig) == TRUE)) {
+	if ((currentDirConfig != NULL) && CFEqual(sourceDirConfig, currentDirConfig)) {
 		SC_log(LOG_INFO, "No migration needed, source and current configurations point to same path");
 		migrationComplete = TRUE;
 	}
@@ -533,13 +516,13 @@ _SCNetworkConfigurationPerformMigration(CFURLRef sourceDir, CFURLRef currentDir,
 		migrationComplete = _SCNetworkConfigurationMigrateConfiguration(sourceDirConfig, targetDirConfig);
 	}
 	SC_log(LOG_NOTICE, "Migration %s", migrationComplete ? "complete" : "failed");
-	if (migrationComplete == TRUE) {
+	if (migrationComplete) {
 		paths = _SCNetworkConfigurationCopyMigrationPaths(NULL);
 	}
 	else {
 		// If migration fails, then remove configuration files from target config if they are
 		// copied from the current directory
-		if (removeTargetOnFailure == TRUE) {
+		if (removeTargetOnFailure) {
 			_SCNetworkConfigurationRemoveConfigurationFiles(targetDirConfig);
 		}
 	}
@@ -700,7 +683,7 @@ _SCNetworkInterfaceStorageCopyMaxUnitPerInterfaceType(SCPreferencesRef ni_prefs)
 			continue;
 		}
 
-		if (CFDictionaryContainsKey(interfaceTypeToMaxUnitMapping, type) == FALSE) {
+		if (!CFDictionaryContainsKey(interfaceTypeToMaxUnitMapping, type)) {
 			int temp = 0;
 			cfMaxUnit = CFNumberCreate(NULL, kCFNumberIntType, &temp);
 			CFDictionaryAddValue(interfaceTypeToMaxUnitMapping, type, cfMaxUnit);
@@ -758,7 +741,7 @@ _SCNetworkConfigurationCopyBuiltinMapping (SCPreferencesRef sourcePrefs, SCPrefe
 		for (CFIndex idx2 = 0; idx2 < targetBuiltinInterfaceCount; idx2++) {
 			targetInterface = CFArrayGetValueAtIndex(targetBuiltinInterfaces, idx2);
 
-			if (_SCNetworkConfigurationIsInterfaceNamerMappable(sourceInterface, targetInterface, FALSE) == TRUE) {
+			if (_SCNetworkConfigurationIsInterfaceNamerMappable(sourceInterface, targetInterface, FALSE)) {
 				if (builtinMapping == NULL) {
 					builtinMapping = CFDictionaryCreateMutable(NULL, 0,
 										   &kCFTypeDictionaryKeyCallBacks,
@@ -828,14 +811,14 @@ _SCNetworkConfigurationCopyExternalInterfaceMapping (SCPreferencesRef sourcePref
 		for (CFIndex idx2 = 0; idx2 < targetExternalInterfaceCount; idx2++) {
 			targetInterface = CFArrayGetValueAtIndex(targetExternalInterfaces, idx2);
 
-			if (_SCNetworkConfigurationIsInterfaceNamerMappable(sourceInterface, targetInterface, TRUE) == TRUE) {
+			if (_SCNetworkConfigurationIsInterfaceNamerMappable(sourceInterface, targetInterface, TRUE)) {
 				CFDictionaryAddValue(externalMapping, sourceInterface, targetInterface);
 				CFArrayRemoveValueAtIndex(targetExternalInterfaces, idx2);
 				break;
 			}
 		}
 
-		if (CFDictionaryContainsKey(externalMapping, sourceInterface) == FALSE) {
+		if (!CFDictionaryContainsKey(externalMapping, sourceInterface)) {
 			// Create new mappings for external source interfaces which don't exist in the target
 			type = _SCNetworkInterfaceGetIOInterfaceType(sourceInterface);
 
@@ -858,7 +841,7 @@ _SCNetworkConfigurationCopyExternalInterfaceMapping (SCPreferencesRef sourcePref
 			currentInterfaceUnit = _SCNetworkInterfaceGetIOInterfaceUnit(targetInterface);
 
 			if ((isA_CFNumber(currentInterfaceUnit) == NULL) ||
-			    (CFEqual(currentInterfaceUnit, cfMaxTargetUnit) == FALSE)) {
+			    !CFEqual(currentInterfaceUnit, cfMaxTargetUnit)) {
 				// Update the interface unit
 				__SCNetworkInterfaceSetIOInterfaceUnit(targetInterface, cfMaxTargetUnit);
 			}
@@ -922,20 +905,20 @@ _SCNetworkConfigurationIsInterfaceNamerMappable(SCNetworkInterfaceRef interface1
 		return FALSE;
 	}
 
-	if (_SC_CFEqual(interface1Type, interface2Type) == FALSE) {
+	if (!_SC_CFEqual(interface1Type, interface2Type)) {
 		return FALSE;
 	}
 
-	if (_SC_CFEqual(interface1Prefix, interface2Prefix) == FALSE) {
+	if (!_SC_CFEqual(interface1Prefix, interface2Prefix)) {
 		return FALSE;
 	}
 
-	if (_SC_CFEqual(interface1UserDefinedName, interface2UserDefinedName) == FALSE) {
+	if (!_SC_CFEqual(interface1UserDefinedName, interface2UserDefinedName)) {
 		// Checking if we have a mismatch because of the name Ethernet and Ethernet 1
 		// Checking if we have a mismatch because of the name Airport and WiFi
-		if ((interface1IsBuiltin == TRUE) &&
-		    (interface2IsBuiltin == TRUE) &&
-		    (__SCNetworkConfigurationInterfaceNameIsEquiv(interface1UserDefinedName, interface2UserDefinedName) == TRUE)) {
+		if (interface1IsBuiltin &&
+		    interface2IsBuiltin &&
+		    __SCNetworkConfigurationInterfaceNameIsEquiv(interface1UserDefinedName, interface2UserDefinedName)) {
 			    return TRUE;
 		}
 		return FALSE;
@@ -952,7 +935,7 @@ __SCNetworkConfigurationInterfaceNameIsEquiv(CFStringRef interfaceName1, CFStrin
 
 	if ((isA_CFString(interfaceName1) != NULL) &&
 	    (isA_CFString(interfaceName2) != NULL)) {
-		if (CFEqual(interfaceName1, interfaceName2) == FALSE) {
+		if (!CFEqual(interfaceName1, interfaceName2)) {
 			// Check if we are looking at the WiFi interface
 			if ((CFEqual(interfaceName1, CFSTR("AirPort")) ||
 			     (CFEqual(interfaceName1, CFSTR("Wi-Fi")))) &&
@@ -968,19 +951,19 @@ __SCNetworkConfigurationInterfaceNameIsEquiv(CFStringRef interfaceName1, CFStrin
 				return TRUE;
 			}
 
-			if (((CFStringHasSuffix(interfaceName1, portSuffix) == TRUE) &&
+			if ((CFStringHasSuffix(interfaceName1, portSuffix) &&
 			    (CFStringCompareWithOptions(interfaceName1, interfaceName2, CFRangeMake(0, (CFStringGetLength(interfaceName1) - CFStringGetLength(portSuffix))), 0) == kCFCompareEqualTo)) ||
-			    ((CFStringHasSuffix(interfaceName2, portSuffix) == TRUE) &&
+			    (CFStringHasSuffix(interfaceName2, portSuffix) &&
 			     (CFStringCompareWithOptions(interfaceName2, interfaceName1, CFRangeMake(0, (CFStringGetLength(interfaceName2) - CFStringGetLength(portSuffix))), 0) == kCFCompareEqualTo))) {
 				return TRUE;
 			}
 
 			for (CFIndex idx = 0; idx < interfaceCount; idx++) {
 				CFStringRef tempInterfaceName = interfaceArray[idx];
-				if ((CFEqual(interfaceName1, tempInterfaceName) == TRUE ||
-					__SCNetworkInterfaceMatchesName(interfaceName1, tempInterfaceName) == TRUE) &&
-				    (CFEqual(interfaceName2, tempInterfaceName) == TRUE  ||
-					__SCNetworkInterfaceMatchesName(interfaceName2, tempInterfaceName) == TRUE)) {
+				if ((CFEqual(interfaceName1, tempInterfaceName) ||
+				     __SCNetworkInterfaceMatchesName(interfaceName1, tempInterfaceName)) &&
+				    (CFEqual(interfaceName2, tempInterfaceName) ||
+				     __SCNetworkInterfaceMatchesName(interfaceName2, tempInterfaceName))) {
 					return TRUE;
 				}
 			}
@@ -1032,20 +1015,20 @@ _SCNetworkConfigurationValidateInterface (const void *key, const void *value, vo
 
 	// 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.
-	if ((*ctx->isValid == FALSE) && (repair == FALSE)) {
+	if ((*ctx->isValid == FALSE) && !repair) {
 		return;
 	}
 
 	// There is no interface present for the service
 	interface = CFDictionaryGetValue(interfaceMapping, bsdName);
 	if (interface == NULL) {
-		if ((((bsdNameToBridgeServices != NULL) && (CFDictionaryContainsKey(bsdNameToBridgeServices, bsdName) == FALSE))) &&
-		    (((bsdNameToBondServices != NULL) && (CFDictionaryContainsKey(bsdNameToBondServices, bsdName) == FALSE))) &&
-		    (((bsdNameToVLANServices != NULL) && (CFDictionaryContainsKey(bsdNameToVLANServices, bsdName) == FALSE)))) {
+		if ((((bsdNameToBridgeServices != NULL) && !CFDictionaryContainsKey(bsdNameToBridgeServices, bsdName))) &&
+		    (((bsdNameToBondServices != NULL) && !CFDictionaryContainsKey(bsdNameToBondServices, bsdName))) &&
+		    (((bsdNameToVLANServices != NULL) && !CFDictionaryContainsKey(bsdNameToVLANServices, bsdName)))) {
 			// Not a virtual interface
 			SC_log(LOG_INFO, "No real interface with BSD name (%@) for service", bsdName);
 
-			if (repair == TRUE) {
+			if (repair) {
 				CFArrayAppendValue(interfaceToBeRemoved, serviceInterface);
 			}
 			*ctx->isValid = FALSE;
@@ -1057,14 +1040,14 @@ _SCNetworkConfigurationValidateInterface (const void *key, const void *value, vo
 	interfaceUserDefinedName = __SCNetworkInterfaceGetUserDefinedName(interface);
 	serviceInterfaceUserDefinedName = __SCNetworkInterfaceGetUserDefinedName(serviceInterface);
 
-	if (__SCNetworkConfigurationInterfaceNameIsEquiv(interfaceUserDefinedName, serviceInterfaceUserDefinedName) == FALSE) {
+	if (!__SCNetworkConfigurationInterfaceNameIsEquiv(interfaceUserDefinedName, serviceInterfaceUserDefinedName)) {
 		SC_log(LOG_INFO, "Interface user defined name (%@) doesn't match service/interface user defined name: %@",
 		       interfaceUserDefinedName,
 		       serviceInterfaceUserDefinedName);
 		*ctx->isValid = FALSE;
 		// Check if the service interface name is set to localized key
 		if (isA_CFArray(interfacePreserveServiceInformation) != NULL &&
-		    __SCNetworkInterfaceMatchesName(interfaceUserDefinedName, serviceInterfaceUserDefinedName) == TRUE) {
+		    __SCNetworkInterfaceMatchesName(interfaceUserDefinedName, serviceInterfaceUserDefinedName)) {
 			SC_log(LOG_NOTICE, "serviceInterfaceUserDefinedName: %@ is the localized key for interface name: %@", serviceInterfaceUserDefinedName, interfaceUserDefinedName);
 			CFArrayAppendValue(interfacePreserveServiceInformation, serviceInterface);
 		}
@@ -1089,12 +1072,12 @@ _SCNetworkConfigurationCollectMissingService(const void *key, const void *value,
 	CFDictionaryRef serviceInterfaceMapping = ctx->interfaceMapping;
 
 	if ((isA_SCNetworkInterface(interface) == NULL) ||
-	    (_SCNetworkInterfaceIsBuiltin(interface) == FALSE)) {
+	    !_SCNetworkInterfaceIsBuiltin(interface)) {
 		return;
 	}
 
 	// Check if services have mapping for the BSD name of the interface
-	if (CFDictionaryContainsKey(serviceInterfaceMapping, bsdName) == FALSE) {
+	if (!CFDictionaryContainsKey(serviceInterfaceMapping, bsdName)) {
 		CFArrayAppendValue(interfacesMissingServices, interface); // Adding interface since the corresponding service seems to be missing
 	}
 }
@@ -1148,7 +1131,7 @@ _SCNetworkConfigurationCreateBuiltinInterfaceServices(SCPreferencesRef pref,
 	for (CFIndex idx = 0; idx < missingServiceCount; idx++) {
 		interface = CFArrayGetValueAtIndex(interfacesWithoutService, idx);
 
-		if (__SCNetworkServiceCreate(pref, interface, NULL) == FALSE) {
+		if (!__SCNetworkServiceCreate(pref, interface, NULL)) {
 			SC_log(LOG_INFO, "Could not add service for interface: %@", interface);
 			success = FALSE;
 		}
@@ -1189,7 +1172,7 @@ add_service(const void *value, void *context)
 		goto done;
 	}
 
-	if (SCNetworkServiceEstablishDefaultConfiguration(service) == FALSE) {
+	if (!SCNetworkServiceEstablishDefaultConfiguration(service)) {
 		SCNetworkServiceRemove(service);
 		SC_log(LOG_INFO, "SCNetworkServiceEstablishDefaultConfiguration() failed");
 		goto done;
@@ -1211,7 +1194,7 @@ add_service(const void *value, void *context)
 			__SCNetworkServiceAddProtocolToService(service, protocolType, configuration, enabled);
 		}
 	}
-	
+
 	// Add Service to current set
 	currentSet = SCNetworkSetCopyCurrent(prefs);
 	if (currentSet == NULL) {
@@ -1220,7 +1203,7 @@ add_service(const void *value, void *context)
 		goto done;
 	}
 
-	if (SCNetworkSetAddService(currentSet, service) == FALSE) {
+	if (!SCNetworkSetAddService(currentSet, service)) {
 		SCNetworkServiceRemove(service);
 		SC_log(LOG_INFO,  "Could not add service to current set");
 		goto done;
@@ -1319,8 +1302,8 @@ _SCNetworkConfigurationSaveOldConfiguration(SCPreferencesRef prefs)
 	currentCalendar = CFCalendarCopyCurrent();
 	absoluteTime = CFAbsoluteTimeGetCurrent();
 
-	if (CFCalendarDecomposeAbsoluteTime(currentCalendar, absoluteTime, "yMdHms",
-					    &year, &month, &day, &hour, &minute, &second) == FALSE) {
+	if (!CFCalendarDecomposeAbsoluteTime(currentCalendar, absoluteTime, "yMdHms",
+					     &year, &month, &day, &hour, &minute, &second)) {
 		SC_log(LOG_INFO, "CFCalendarDecomposeAbsoluteTime() failed");
 	}
 	keyListCount = (CFIndex)sizeof(keyList)/sizeof(CFStringRef);
@@ -1469,7 +1452,7 @@ validate_vlan(const void *value, void *context)
 	CFRelease(interface);
 
 done:
-	if (isValid == FALSE) {
+	if (!isValid) {
 		SC_log(LOG_INFO, "Removing invalid VLAN configuration: %@", vlan);
 		SCVLANInterfaceRemove(vlan);
 	}
@@ -1507,7 +1490,7 @@ _SCNetworkConfigurationCheckValidityWithPreferences(SCPreferencesRef prefs,
 			repairConfiguration = CFBooleanGetValue(repair);
 		}
 	}
-	if (__SCPreferencesGetLimitSCNetworkConfiguration(prefs) == FALSE) {
+	if (!__SCPreferencesGetLimitSCNetworkConfiguration(prefs)) {
 		__SCPreferencesSetLimitSCNetworkConfiguration(prefs, TRUE);
 		revertLimitNetworkConfiguration = TRUE;
 	}
@@ -1584,15 +1567,15 @@ _SCNetworkConfigurationCheckValidityWithPreferences(SCPreferencesRef prefs,
 
 	CFDictionaryApplyFunction(mappingServiceBSDNameToInterface, _SCNetworkConfigurationValidateInterface, &context);
 
-	if (isValid == FALSE) {
+	if (!isValid) {
 		SC_log(LOG_INFO, "mismatch between interface names in NetworkInterfaces.plist and preferences.plist");
 		if (repairConfiguration) {
 			isValid = _SCNetworkConfigurationRepairUsingPreferences(prefs, &context);
-			if (isValid == FALSE) {
+			if (!isValid) {
 				goto done;
 			}
 			// Save the changes if repair fixed an invalid configuration
-			if (SCPreferencesCommitChanges(prefs) == FALSE) {
+			if (!SCPreferencesCommitChanges(prefs)) {
 				SC_log(LOG_INFO, "SCPreferencesCommitChanges() failed");
 			}
 		}
@@ -1633,13 +1616,13 @@ _SCNetworkConfigurationCheckValidityWithPreferences(SCPreferencesRef prefs,
 		for (CFIndex idx2 = 0; idx2 < CFArrayGetCount(setServices); idx2++) {
 			SCNetworkServiceRef service = CFArrayGetValueAtIndex(setServices, idx2);
 
-			if (CFArrayContainsValue(allServices, CFRangeMake(0, CFArrayGetCount(allServices)), service) == FALSE) {
+			if (!CFArrayContainsValue(allServices, CFRangeMake(0, CFArrayGetCount(allServices)), service)) {
 				isValid = FALSE;
 				SC_log(LOG_INFO, "All network services in the network set are not present in SCNetworkService array");
 				break;
 			}
 		}
-		if (isValid == FALSE) {
+		if (!isValid) {
 			break;
 		}
 
@@ -1650,8 +1633,8 @@ _SCNetworkConfigurationCheckValidityWithPreferences(SCPreferencesRef prefs,
 		if (setServiceOrder != NULL) {
 			for (CFIndex idx2 = 0; idx2 < CFArrayGetCount(setServiceOrder); idx2++) {
 				SCNetworkServiceRef service = CFArrayGetValueAtIndex(setServiceOrder, idx2);
-				if ((CFArrayContainsValue(setServiceOrder, CFRangeMake(0, CFArrayGetCount(setServiceOrder)), service) == FALSE) &&
-				    (CFArrayContainsValue(allServices, CFRangeMake(0, CFArrayGetCount(allServices)), service) == FALSE)) {
+				if (!CFArrayContainsValue(setServiceOrder, CFRangeMake(0, CFArrayGetCount(setServiceOrder)), service) &&
+				    !CFArrayContainsValue(allServices, CFRangeMake(0, CFArrayGetCount(allServices)), service)) {
 					SC_log(LOG_INFO, "Service: %@ is not present in the service order for set %@", service, set);
 					break;
 				}
@@ -1698,6 +1681,7 @@ done:
 	if (allSets != NULL) {
 		CFRelease(allSets);
 	}
+#if	!TARGET_OS_IPHONE
 	if (bsdNameToBridgeServices != NULL) {
 		CFRelease(bsdNameToBridgeServices);
 	}
@@ -1707,6 +1691,7 @@ done:
 	if (bsdNameToVLANServices != NULL) {
 		CFRelease(bsdNameToVLANServices);
 	}
+#endif
 	if (setServices != NULL) {
 		CFRelease(setServices);
 	}
@@ -1722,7 +1707,7 @@ done:
 	if (bsdNameServiceProtocolPreserveMapping != NULL) {
 		CFRelease(bsdNameServiceProtocolPreserveMapping);
 	}
-	if (revertLimitNetworkConfiguration ) {
+	if (revertLimitNetworkConfiguration) {
 		__SCPreferencesSetLimitSCNetworkConfiguration(prefs, FALSE);
 	}
 	return isValid;
@@ -1738,7 +1723,6 @@ _SCNetworkConfigurationCheckValidity(CFURLRef configDir, CFDictionaryRef options
 	SCPreferencesRef configPref = NULL;
 	CFURLRef configPreferenceFile = NULL;
 	CFStringRef configPreferencesFileString = NULL;
-	CFArrayRef configurationFiles = NULL;
 	Boolean isValid = FALSE;
 	char networkInterfaceStr[PATH_MAX];
 	char prefsStr[PATH_MAX];
@@ -1785,9 +1769,6 @@ done:
 	if (baseURL != NULL) {
 		CFRelease(baseURL);
 	}
-	if (configurationFiles != NULL) {
-		CFRelease(configurationFiles);
-	}
 	if (configPreferencesFileString != NULL) {
 		CFRelease(configPreferencesFileString);
 	}
@@ -1823,7 +1804,7 @@ _SCNetworkConfigurationCollectInterfaceStorageEntity(const void *key, const void
 	CFDictionaryRef interface_entity = NULL;
 	SCNetworkInterfaceRef targetInterface = (SCNetworkInterfaceRef)value;
 
-	if (CFArrayContainsValue(ctx->externalInterfaceList, CFRangeMake(0, CFArrayGetCount(ctx->externalInterfaceList)), targetInterface) == TRUE) {
+	if (CFArrayContainsValue(ctx->externalInterfaceList, CFRangeMake(0, CFArrayGetCount(ctx->externalInterfaceList)), targetInterface)) {
 		SC_log(LOG_INFO, "Target interface (%@) already exists, not adding to NetworkInterfaces.plist", targetInterface);
 		return; // If the target interface already exists then do not add it to NetworkInterfaces.plist
 	}
@@ -1911,7 +1892,7 @@ SCNetworkMigrationMapSourceToTargetName(const void *key, const void *value, void
 		return;
 	}
 
-	if (CFDictionaryContainsKey(mapping, sourceBSDName) == FALSE) {
+	if (!CFDictionaryContainsKey(mapping, sourceBSDName)) {
 		CFDictionaryAddValue(mapping, sourceBSDName, targetBSDName);
 	}
 	return;
@@ -1963,7 +1944,7 @@ _SCNetworkMigrationCreateServiceSetMapping(SCPreferencesRef prefs)
 	for (CFIndex idx = 0; idx < CFArrayGetCount(services); idx++) {
 		service = CFArrayGetValueAtIndex(services, idx);
 
-		if (CFDictionaryContainsKey(serviceSetMapping, service) == FALSE) {
+		if (!CFDictionaryContainsKey(serviceSetMapping, service)) {
 			setList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
 			CFDictionaryAddValue(serviceSetMapping, service, setList);
 			CFRelease(setList);
@@ -2046,7 +2027,7 @@ _SCNetworkMigrationCreateSetMapping(SCPreferencesRef sourcePrefs,
 	for (CFIndex idx = 0; idx < CFArrayGetCount(sourceSets); idx++) {
 		SCNetworkSetRef sourceSet = CFArrayGetValueAtIndex(sourceSets, idx);
 
-		if ((currentSourceSet != NULL) && (CFEqual(sourceSet, currentSourceSet) == TRUE)) {
+		if ((currentSourceSet != NULL) && CFEqual(sourceSet, currentSourceSet)) {
 			continue;
 		}
 
@@ -2151,22 +2132,22 @@ _SCNetworkMigrationCreateServiceMappingUsingBSDMapping(SCPreferencesRef sourcePr
 
 		sourceInterfaceType = __SCNetworkInterfaceGetEntityType(sourceInterface);
 		if ((isA_CFString(sourceInterfaceType) != NULL) &&
-		    ((CFEqual(sourceInterfaceType, kSCValNetInterfaceTypeVPN) == TRUE) ||
-		     (CFEqual(sourceInterfaceType, kSCValNetInterfaceTypePPP) == TRUE))) {
+		    (CFEqual(sourceInterfaceType, kSCValNetInterfaceTypeVPN) ||
+		     CFEqual(sourceInterfaceType, kSCValNetInterfaceTypePPP))) {
 			    sourceInterfaceSubType = __SCNetworkInterfaceGetEntitySubType(sourceInterface);
 			    if (isA_CFString(sourceInterfaceSubType) == NULL) {
 				    SC_log(LOG_INFO, "No source interface SubType");
 				    continue;
 			    }
 		}
-		else if (((isA_CFString(sourceInterfaceType) != NULL) &&
-			 (CFEqual(sourceInterfaceType, kSCValNetInterfaceTypeIPSec) == FALSE) &&
-			  (CFEqual(sourceInterfaceType, kSCValNetInterfaceType6to4) == FALSE) &&
-			  (CFEqual(sourceInterfaceType, kSCValNetInterfaceTypeLoopback) == FALSE)) ||
-			 (isA_CFString(sourceInterfaceType) == NULL)) {
+		else if ((isA_CFString(sourceInterfaceType) &&
+			  !CFEqual(sourceInterfaceType, kSCValNetInterfaceTypeIPSec) &&
+			  !CFEqual(sourceInterfaceType, kSCValNetInterfaceType6to4) &&
+			  !CFEqual(sourceInterfaceType, kSCValNetInterfaceTypeLoopback)) ||
+			 !isA_CFString(sourceInterfaceType)) {
 			sourceBSDName = SCNetworkInterfaceGetBSDName(sourceInterface);
-			if ((isA_CFString(sourceBSDName) == NULL) ||
-			    (CFDictionaryContainsKey(bsdNameMapping, sourceBSDName)) == FALSE) {
+			if (!isA_CFString(sourceBSDName) ||
+			    !CFDictionaryContainsKey(bsdNameMapping, sourceBSDName)) {
 				SC_log(LOG_INFO, "No BSD name mapping for %@",
 				       (sourceBSDName == NULL) ? CFSTR("NULL") : sourceBSDName);
 				continue;
@@ -2201,7 +2182,7 @@ _SCNetworkMigrationCreateServiceMappingUsingBSDMapping(SCPreferencesRef sourcePr
 					continue;
 				}
 
-				if (CFEqual(targetBSDName, bsdNameMapTarget) == TRUE) {
+				if (CFEqual(targetBSDName, bsdNameMapTarget)) {
 					SC_log(LOG_INFO, "Removing target BSD name: %@", targetBSDName);
 					CFDictionaryAddValue(serviceMapping, sourceService, targetService);
 					CFArrayRemoveValueAtIndex(targetSCNetworkServicesMutable, idx2);
@@ -2212,8 +2193,8 @@ _SCNetworkMigrationCreateServiceMappingUsingBSDMapping(SCPreferencesRef sourcePr
 				// Source Interface Type should be VPN
 				targetInterfaceType = __SCNetworkInterfaceGetEntityType(targetInterface);
 				if ((isA_CFString(targetInterfaceType) == NULL) ||
-				    ((CFEqual(targetInterfaceType, kSCValNetInterfaceTypeVPN) == FALSE) &&
-				     (CFEqual(targetInterfaceType, kSCValNetInterfaceTypePPP) == FALSE))) {
+				    (!CFEqual(targetInterfaceType, kSCValNetInterfaceTypeVPN) &&
+				     !CFEqual(targetInterfaceType, kSCValNetInterfaceTypePPP))) {
 					    SC_log(LOG_INFO, "Unexpected target interface type: %@",
 						   (targetInterfaceType != NULL) ? targetInterfaceType : CFSTR("NULL"));
 					    continue;
@@ -2225,8 +2206,8 @@ _SCNetworkMigrationCreateServiceMappingUsingBSDMapping(SCPreferencesRef sourcePr
 				}
 
 				// Check if the target interface type and the target interface sub type match
-				if ((CFEqual(targetInterfaceType, sourceInterfaceType) == TRUE) &&
-				    (CFEqual(targetInterfaceSubType, sourceInterfaceSubType) == TRUE)) {
+				if (CFEqual(targetInterfaceType, sourceInterfaceType) &&
+				    CFEqual(targetInterfaceSubType, sourceInterfaceSubType)) {
 					SC_log(LOG_INFO, "Removing target BSD Name: %@ for VPN", targetBSDName);
 					CFDictionaryAddValue(serviceMapping, sourceService, targetService);
 					CFArrayRemoveValueAtIndex(targetSCNetworkServicesMutable, idx2);
@@ -2236,7 +2217,7 @@ _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) == FALSE) {
+		if (!CFDictionaryContainsKey(serviceMapping, sourceService)) {
 			SC_log(LOG_INFO, "Service needs to be added: %@", sourceService);
 			CFDictionaryAddValue(serviceMapping, sourceService, kCFBooleanFalse);
 		}
@@ -2458,7 +2439,7 @@ add_target_bridge(const void *key, const void *value, void *context)
 
 	newBridge = SCBridgeInterfaceCreate(prefs);
 
-	if (__SCBridgeInterfaceSetMemberInterfaces(newBridge, newInterfaceList) == FALSE) {
+	if (!__SCBridgeInterfaceSetMemberInterfaces(newBridge, newInterfaceList)) {
 		SC_log(LOG_INFO, "__SCBridgeInterfaceSetMemberInterfaces() failed");
 	}
 	CFRelease(newInterfaceList);
@@ -2486,7 +2467,7 @@ add_target_bridge(const void *key, const void *value, void *context)
 
 	for (CFIndex idx = 0; idx < CFArrayGetCount(oldServiceList); idx++) {
 		SCNetworkServiceRef oldService = CFArrayGetValueAtIndex(oldServiceList, idx);
-		if (__SCNetworkServiceMigrateNew(prefs, oldService, bridgeBSDNameMapping, setMapping, serviceSetMapping) == FALSE) {
+		if (!__SCNetworkServiceMigrateNew(prefs, oldService, bridgeBSDNameMapping, setMapping, serviceSetMapping)) {
 			SC_log(LOG_INFO, "Could not migrate Bridge service: %@", oldService);
 		}
 	}
@@ -2528,7 +2509,7 @@ _SCNetworkMigrationCopyMappingBSDNameToBridgeServices(SCPreferencesRef prefs)
 		if ((bsdName != NULL) &&
 		SCNetworkInterfaceGetInterfaceType(interface) == kSCNetworkInterfaceTypeBridge) {
 			CFMutableArrayRef serviceList;
-			if (CFDictionaryContainsKey(bridgeServices, bsdName) == FALSE) {
+			if (!CFDictionaryContainsKey(bridgeServices, bsdName)) {
 				serviceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
 				CFDictionaryAddValue(bridgeServices, bsdName, serviceList);
 				CFRelease(serviceList);
@@ -2583,7 +2564,7 @@ _SCNetworkMigrationDoBridgeMigration (SCPreferencesRef sourcePrefs,
 			interface = CFArrayGetValueAtIndex(bridgeMembers, idx2);
 			interfaceName = SCNetworkInterfaceGetBSDName(interface);
 
-			if (CFDictionaryContainsKey(bsdMapping, interfaceName) == TRUE) {
+			if (CFDictionaryContainsKey(bsdMapping, interfaceName)) {
 				CFStringRef bridgeNewName = CFStringCreateWithFormat(NULL, NULL, CFSTR("bridge%ld"), count);
 				CFDictionaryAddValue(bridgeMapping, interfaceName, bridgeNewName);
 				CFArrayAppendValue(interfaceList, interfaceName);
@@ -2602,7 +2583,7 @@ _SCNetworkMigrationDoBridgeMigration (SCPreferencesRef sourcePrefs,
 	// Remove Target Bridges
 	for (CFIndex idx = 0; idx < CFArrayGetCount(allTargetBridges); idx++) {
 		bridge = CFArrayGetValueAtIndex(allTargetBridges, idx);
-		if (SCBridgeInterfaceRemove(bridge) == FALSE) {
+		if (!SCBridgeInterfaceRemove(bridge)) {
 			SC_log(LOG_INFO, "SCBridgeInterfaceRemove() failed: %@", bridge);
 			goto done;
 		}
@@ -2659,7 +2640,7 @@ add_target_bond(const void *key, const void *value, void *context)
 	CFArrayApplyFunction(oldInterfaceList, CFRangeMake(0, CFArrayGetCount(oldInterfaceList)), add_virtual_interface, &memberListContext);
 
 	newBond = SCBondInterfaceCreate(prefs);
-	if (__SCBondInterfaceSetMemberInterfaces(newBond, newInterfaceList) == FALSE) {
+	if (!__SCBondInterfaceSetMemberInterfaces(newBond, newInterfaceList)) {
 		SC_log(LOG_INFO, "__SCBondInterfaceSetMemberInterfaces() failed");
 	}
 	CFRelease(newInterfaceList);
@@ -2690,7 +2671,7 @@ add_target_bond(const void *key, const void *value, void *context)
 
 	for (CFIndex idx = 0; idx < CFArrayGetCount(oldServiceList); idx++) {
 		SCNetworkServiceRef oldService = CFArrayGetValueAtIndex(oldServiceList, idx);
-		if (__SCNetworkServiceMigrateNew(prefs, oldService, bondBSDNameMapping, setMapping, serviceSetMapping) == FALSE) {
+		if (!__SCNetworkServiceMigrateNew(prefs, oldService, bondBSDNameMapping, setMapping, serviceSetMapping)) {
 			SC_log(LOG_INFO, "Could not migrate Bond service: %@", oldService);
 		}
 	}
@@ -2731,7 +2712,7 @@ _SCNetworkMigrationCopyMappingBSDNameToBondServices(SCPreferencesRef prefs)
 		if ((bsdName != NULL) &&
 		SCNetworkInterfaceGetInterfaceType(interface) == kSCNetworkInterfaceTypeBond) {
 			CFMutableArrayRef serviceList;
-			if (CFDictionaryContainsKey(bondServices, bsdName) == FALSE) {
+			if (!CFDictionaryContainsKey(bondServices, bsdName)) {
 				serviceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
 				CFDictionaryAddValue(bondServices, bsdName, serviceList);
 				CFRelease(serviceList);
@@ -2785,7 +2766,7 @@ _SCNetworkMigrationDoBondMigration (SCPreferencesRef sourcePrefs,
 			interface = CFArrayGetValueAtIndex(bondMembers, idx2);
 			interfaceName = SCNetworkInterfaceGetBSDName(interface);
 
-			if (CFDictionaryContainsKey(bsdMapping, interfaceName) == TRUE) {
+			if (CFDictionaryContainsKey(bsdMapping, interfaceName)) {
 				CFStringRef bondNewName = CFStringCreateWithFormat(NULL, NULL, CFSTR("bond%ld"), count);
 				CFDictionaryAddValue(bondMapping, interfaceName, bondNewName);
 				CFArrayAppendValue(interfaceList, interfaceName);
@@ -2804,7 +2785,7 @@ _SCNetworkMigrationDoBondMigration (SCPreferencesRef sourcePrefs,
 	// Remove Target Bonds
 	for (CFIndex idx = 0; idx < CFArrayGetCount(allTargetBonds); idx++) {
 		bond = CFArrayGetValueAtIndex(allTargetBonds, idx);
-		if (SCBondInterfaceRemove(bond) == FALSE) {
+		if (!SCBondInterfaceRemove(bond)) {
 			SC_log(LOG_INFO, "SCBondInterfaceRemove() failed: %@", bond);
 			goto done;
 		}
@@ -2888,6 +2869,7 @@ add_target_vlan(const void *value, void *context)
 	newVLAN = SCVLANInterfaceCreate(prefs, newPhysicalInterface, vlanTag);
 	if (newVLAN == NULL) {
 		SC_log(LOG_INFO, "Could not create new VLAN interface");
+		goto done;
 	}
 
 	vlanName = SCNetworkInterfaceGetLocalizedDisplayName(oldVLAN);
@@ -2912,7 +2894,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) == FALSE) {
+		if (!__SCNetworkServiceMigrateNew(prefs, oldService, vlanBSDMapping, setMapping, serviceSetMapping)) {
 			SC_log(LOG_INFO, "Could not migrate VLAN service: %@", oldService);
 		}
 	}
@@ -2960,7 +2942,7 @@ _SCNetworkMigrationCopyMappingBSDNameToVLANServices(SCPreferencesRef prefs)
 		if ((bsdName != NULL) &&
 		    SCNetworkInterfaceGetInterfaceType(interface) == kSCNetworkInterfaceTypeVLAN) {
 			CFMutableArrayRef serviceList;
-			if (CFDictionaryContainsKey(vlanServices, bsdName) == FALSE) {
+			if (!CFDictionaryContainsKey(vlanServices, bsdName)) {
 				serviceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
 				CFDictionaryAddValue(vlanServices, bsdName, serviceList);
 				CFRelease(serviceList);
@@ -3012,7 +2994,7 @@ _SCNetworkMigrationDoVLANMigration (SCPreferencesRef sourcePrefs,
 		SC_log(LOG_DEBUG, "physical VLAN interface name: %@", physicalInterfaceName);
 
 		// Add VLAN to be migrated if the mapping between interfaces exists
-		if (CFDictionaryContainsKey(bsdMapping, physicalInterfaceName) == TRUE) {
+		if (CFDictionaryContainsKey(bsdMapping, physicalInterfaceName)) {
 			CFStringRef vlanNewName = CFStringCreateWithFormat(NULL, NULL, CFSTR("vlan%ld"), count);
 			CFDictionaryAddValue(vlanMapping, vlanBSDName, vlanNewName);
 			CFArrayAppendValue(vlanList, vlan);
@@ -3026,7 +3008,7 @@ _SCNetworkMigrationDoVLANMigration (SCPreferencesRef sourcePrefs,
 	// Remove Target VLANs
 	for (CFIndex idx = 0; idx < CFArrayGetCount(allTargetVLAN); idx++) {
 		vlan = CFArrayGetValueAtIndex(allTargetVLAN, idx);
-		if (SCVLANInterfaceRemove(vlan) == FALSE) {
+		if (!SCVLANInterfaceRemove(vlan)) {
 			SC_log(LOG_INFO, "SCVLANInterfaceRemove() failed: %@", vlan);
 			goto done;
 		}
@@ -3063,23 +3045,23 @@ _SCNetworkMigrationDoVirtualNetworkInterfaceMigration(SCPreferencesRef sourcePre
 						      CFDictionaryRef serviceSetMapping)
 {
 	// Handle Bridges
-	if (_SCNetworkMigrationDoBridgeMigration(sourcePrefs, sourceNIPrefs,
+	if (!_SCNetworkMigrationDoBridgeMigration(sourcePrefs, sourceNIPrefs,
 						 targetPrefs, targetNIPrefs,
-						 bsdMapping, setMapping, serviceSetMapping) == FALSE) {
+						 bsdMapping, setMapping, serviceSetMapping)) {
 		SC_log(LOG_INFO, "Bridge migration failed");
 	}
 
 	// Handle Bonds
-	if (_SCNetworkMigrationDoBondMigration(sourcePrefs, sourceNIPrefs,
+	if (!_SCNetworkMigrationDoBondMigration(sourcePrefs, sourceNIPrefs,
 					       targetPrefs, targetNIPrefs,
-					       bsdMapping, setMapping, serviceSetMapping) == FALSE) {
+					       bsdMapping, setMapping, serviceSetMapping)) {
 		SC_log(LOG_INFO, "Bond migration failed");
 	}
 
 	// Handle VLANs
-	if (_SCNetworkMigrationDoVLANMigration(sourcePrefs, sourceNIPrefs,
+	if (!_SCNetworkMigrationDoVLANMigration(sourcePrefs, sourceNIPrefs,
 					       targetPrefs, targetNIPrefs,
-					       bsdMapping, setMapping, serviceSetMapping) == FALSE) {
+					       bsdMapping, setMapping, serviceSetMapping)) {
 		SC_log(LOG_INFO, "VLAN migration failed");
 	}
 	return TRUE;
@@ -3109,7 +3091,7 @@ create_migrated_order(const void *value, void *context)
 	// which were migrated into the target configuration
 	for (CFIndex idx = 0; idx < CFArrayGetCount(targetServiceOrder); idx++) {
 		CFStringRef targetServiceID = CFArrayGetValueAtIndex(targetServiceOrder, idx);
-		if (CFEqual(migratedServiceID, targetServiceID) == TRUE) {
+		if (CFEqual(migratedServiceID, targetServiceID)) {
 			CFArrayAppendValue(migratedServiceOrder, migratedServiceID);
 			return;
 		}
@@ -3134,7 +3116,7 @@ create_non_migrated_service_list(const void *value, void *context)
 	for (CFIndex idx = 0; idx < CFArrayGetCount(migratedServiceOrder); idx++) {
 		CFStringRef migratedServiceID = CFArrayGetValueAtIndex(migratedServiceOrder, idx);
 
-		if (CFEqual(targetServiceID, migratedServiceID) == TRUE) {
+		if (CFEqual(targetServiceID, migratedServiceID)) {
 			return;
 		}
 	}
@@ -3186,7 +3168,7 @@ preserve_service_order(const void *key, const void *value, void *context)
 	// while maintaining the service order or the source set
 	CFArrayApplyFunction(sourceServiceOrder, CFRangeMake(0, CFArrayGetCount(sourceServiceOrder)), create_migrated_order, &migrated_context);
 
-	if (success == FALSE) {
+	if (*success == FALSE) {
 		goto done;
 	}
 
@@ -3210,7 +3192,7 @@ preserve_service_order(const void *key, const void *value, void *context)
 	// Add non migrated services
 	for (CFIndex idx = 0; idx < CFArrayGetCount(nonMigratedServices); idx++) {
 		SCNetworkServiceRef service = CFArrayGetValueAtIndex(nonMigratedServices, idx);
-		SCNetworkSetAddService(targetSet, service);
+		(void)SCNetworkSetAddService(targetSet, service);
 	}
 
 done:
@@ -3277,7 +3259,7 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD
 	CFMutableDictionaryRef validityOptions = NULL;
 
 	// Check if configuration files exist in sourceDir
-	if (__SCNetworkConfigurationMigrateConfigurationFilesPresent(sourceDir, &sourceConfigurationFiles) == FALSE) {
+	if (!__SCNetworkConfigurationMigrateConfigurationFilesPresent(sourceDir, &sourceConfigurationFiles)) {
 		SC_log(LOG_INFO, "sourceDir: (%@) doesn't contain configuration files", sourceDir);
 		goto done;
 	}
@@ -3303,7 +3285,8 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD
 		goto done;
 	}
 
-	if ((targetConfigurationFilesPresent = __SCNetworkConfigurationMigrateConfigurationFilesPresent(targetDir, &targetConfigurationFiles)) == FALSE) {
+	targetConfigurationFilesPresent = __SCNetworkConfigurationMigrateConfigurationFilesPresent(targetDir, &targetConfigurationFiles);
+	if (!targetConfigurationFilesPresent) {
 		if (targetConfigurationFiles == NULL) {
 			SC_log(LOG_DEBUG, "targetConfigurationFiles is NULL");
 			goto done;
@@ -3325,7 +3308,7 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD
 	targetPreferencesFileString = CFStringCreateWithCString(NULL, targetPreferencesFileStr, kCFStringEncodingUTF8);
 	targetNetworkInterfaceFileString = CFStringCreateWithCString(NULL, targetNetworkInterfaceFileStr, kCFStringEncodingUTF8);
 
-	if (targetConfigurationFilesPresent == TRUE) {
+	if (targetConfigurationFilesPresent) {
 		targetPrefs = SCPreferencesCreate(NULL, PLUGIN_ID, targetPreferencesFileString);
 		targetNetworkInterfacePrefs = SCPreferencesCreate(NULL, PLUGIN_ID, targetNetworkInterfaceFileString);
 		if ((targetPrefs == NULL) || (targetNetworkInterfacePrefs == NULL)) {
@@ -3368,19 +3351,19 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD
 	// Create services for builtin interfaces at source if they don't exist
 	(void)_SCNetworkConfigurationCreateBuiltinInterfaceServices(sourcePrefs, sourceNetworkInterfacePrefs);
 	// Checking validity of the source and destination preferences before continuing
-	if (_SCNetworkConfigurationCheckValidityWithPreferences(sourcePrefs,
+	if (!_SCNetworkConfigurationCheckValidityWithPreferences(sourcePrefs,
 								 sourceNetworkInterfacePrefs,
-								 validityOptions) == FALSE) {
+								 validityOptions)) {
 		SC_log(LOG_INFO, "Source configuration not valid");
 		goto skipServiceMigration;
 	}
 	// Only call this function if configuration files were not created by default
-	if (targetConfigurationFilesPresent == TRUE) {
+	if (targetConfigurationFilesPresent) {
 		// Create services for builtin interfaces at target if they don't exist
 		(void)_SCNetworkConfigurationCreateBuiltinInterfaceServices(targetPrefs, targetNetworkInterfacePrefs);
-		if (_SCNetworkConfigurationCheckValidityWithPreferences(targetPrefs,
+		if (!_SCNetworkConfigurationCheckValidityWithPreferences(targetPrefs,
 									 targetNetworkInterfacePrefs,
-									 validityOptions) == FALSE) {
+									 validityOptions)) {
 			SC_log(LOG_INFO, "Target configuration not valid");
 			goto skipServiceMigration;
 		}
@@ -3416,12 +3399,15 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD
 		if (foundNewInterface) {
 			if (isA_CFArray(newTargetNetworkInterfaceEntity) == NULL) {
 				SC_log(LOG_INFO, "newTargetNetworkInterfaceEntity is NULL or not of correct type");
+				CFRelease(upgradeSourcePrefs);
+				CFRelease(upgradeSourceNIPrefs);
 				goto done;
 			}
 			// Write new interface mapping to NetworkInterfaces.plist
-			if (__SCNetworkInterfaceSaveStoredWithPreferences(targetNetworkInterfacePrefs, newTargetNetworkInterfaceEntity) == FALSE)
-			{
+			if (!__SCNetworkInterfaceSaveStoredWithPreferences(targetNetworkInterfacePrefs, newTargetNetworkInterfaceEntity)) {
 				SC_log(LOG_INFO, "SCNetworkInterfaceSaveStoreWithPreferences: failed to update NetworkInterfaces.plist");
+				CFRelease(upgradeSourcePrefs);
+				CFRelease(upgradeSourceNIPrefs);
 				goto done;
 			}
 
@@ -3447,8 +3433,7 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD
 			goto done;
 		}
 		// Write new interface mapping to NetworkInterfaces.plist
-		if (__SCNetworkInterfaceSaveStoredWithPreferences(targetNetworkInterfacePrefs, newTargetNetworkInterfaceEntity) == FALSE)
-		{
+		if (!__SCNetworkInterfaceSaveStoredWithPreferences(targetNetworkInterfacePrefs, newTargetNetworkInterfaceEntity)) {
 			SC_log(LOG_INFO, "SCNetworkInterfaceSaveStoreWithPreferences: failed to update NetworkInterfaces.plist");
 			goto done;
 		}
@@ -3472,44 +3457,44 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD
 		sourceServiceSetMapping = _SCNetworkMigrationCreateServiceSetMapping(sourcePrefs);
 
 		// Perform the migration of services
-		if (_SCNetworkMigrationDoServiceMigration(sourcePrefs, targetPrefs,
+		if (!_SCNetworkMigrationDoServiceMigration(sourcePrefs, targetPrefs,
 							  serviceMapping, bsdNameMapping,
-							  setMapping, sourceServiceSetMapping) == FALSE) {
+							  setMapping, sourceServiceSetMapping)) {
 			SC_log(LOG_INFO, "SCNetworkMigrationDoServiceMigration: failed to complete successfully");
 			goto done;
 		}
 
 #if	!TARGET_OS_IPHONE
 		// Migrating Virtual Network Interface
-		if (_SCNetworkMigrationDoVirtualNetworkInterfaceMigration(sourcePrefs, sourceNetworkInterfacePrefs,
+		if (!_SCNetworkMigrationDoVirtualNetworkInterfaceMigration(sourcePrefs, sourceNetworkInterfacePrefs,
 									  targetPrefs, targetNetworkInterfacePrefs,
-									  bsdNameMapping, setMapping, sourceServiceSetMapping) == FALSE) {
+									  bsdNameMapping, setMapping, sourceServiceSetMapping)) {
 			SC_log(LOG_INFO, "_SCNetworkMigrationDoVirtualNetworkInterfaceMigration: failed to complete successfully");
 		}
 #endif
 		// Migrate Service Order
-		if (_SCNetworkMigrationDoServiceOrderMigration(sourcePrefs, targetPrefs, setMapping) == FALSE) {
+		if (!_SCNetworkMigrationDoServiceOrderMigration(sourcePrefs, targetPrefs, setMapping)) {
 			SC_log(LOG_INFO, "_SCNetworkMigrationDoServiceOrderMigration: failed to complete successfully");
 		}
 	}
 
 skipServiceMigration:
 	// Migrating System Information
-	if (isUpgradeScenario == FALSE) {
-		if (_SCNetworkMigrationDoSystemMigration(sourcePrefs, targetPrefs) == FALSE) {
+	if (!isUpgradeScenario) {
+		if (!_SCNetworkMigrationDoSystemMigration(sourcePrefs, targetPrefs)) {
 			SC_log(LOG_INFO, "_SCNetworkMigrationDoSystemMigration: failed to complete successfully");
 		}
 	}
-	if (_SCNetworkConfigurationCheckValidityWithPreferences(targetPrefs, targetNetworkInterfacePrefs, validityOptions) == FALSE) {
+	if (!_SCNetworkConfigurationCheckValidityWithPreferences(targetPrefs, targetNetworkInterfacePrefs, validityOptions)) {
 		SC_log(LOG_INFO, "Migrated configuration not valid");
 		goto done;
 	}
-	if (SCPreferencesCommitChanges(targetPrefs) == FALSE) {
+	if (!SCPreferencesCommitChanges(targetPrefs)) {
 		SC_log(LOG_INFO, "SCPreferencesCommitChanges(target preferences.plist) failed: %s", SCErrorString(SCError()));
 		goto done;
 	}
 
-	if (SCPreferencesCommitChanges(targetNetworkInterfacePrefs) == FALSE) {
+	if (!SCPreferencesCommitChanges(targetNetworkInterfacePrefs)) {
 		SC_log(LOG_INFO, "SCPreferencesCommitChanges(target NetworkInterfaces.plist) failed: %s", SCErrorString(SCError()));
 		goto done;
 	}
@@ -3576,7 +3561,7 @@ done:
 #define N_QUICK 64
 
 static Boolean
-_SCNetworkMigrationAreServicesIdentical( SCPreferencesRef configPref, SCPreferencesRef expectedConfigPref)
+_SCNetworkMigrationAreServicesIdentical(SCPreferencesRef configPref, SCPreferencesRef expectedConfigPref)
 {
 	const void * expected_vals_q[N_QUICK];
 	const void ** expected_vals = expected_vals_q;
@@ -3620,7 +3605,7 @@ _SCNetworkMigrationAreServicesIdentical( SCPreferencesRef configPref, SCPreferen
 
 	for (CFIndex idx=0; idx < serviceDictCount; idx++) {
 		serviceEntity = vals[idx];
-		if (isA_CFDictionary(serviceEntity) == FALSE) {
+		if (!isA_CFDictionary(serviceEntity)) {
 			continue;
 		}
 		CFArrayAppendValue(serviceArray, serviceEntity);
@@ -3637,8 +3622,7 @@ _SCNetworkMigrationAreServicesIdentical( SCPreferencesRef configPref, SCPreferen
 
 	for (CFIndex idx = 0; idx < expectedServiceDictCount; idx++) {
 		serviceEntity = expected_vals[idx];
-
-		if (isA_CFDictionary(serviceEntity) == FALSE) {
+		if (!isA_CFDictionary(serviceEntity)) {
 			continue;
 		}
 		CFArrayAppendValue(expectedServiceArray, serviceEntity);
@@ -3657,13 +3641,13 @@ _SCNetworkMigrationAreServicesIdentical( SCPreferencesRef configPref, SCPreferen
 		for (CFIndex idx2 = 0; idx2 < serviceArrayCount; idx2++) {
 			serviceEntity = CFArrayGetValueAtIndex(serviceArray, idx2);
 
-			if (CFEqual(expectedServiceEntity, serviceEntity) == TRUE) {
+			if (CFEqual(expectedServiceEntity, serviceEntity)) {
 				foundMatch = TRUE;
 				break;
 			}
 		}
 
-		if (foundMatch == FALSE) {
+		if (!foundMatch) {
 			break;
 		}
 	}
@@ -3716,12 +3700,12 @@ _SCNetworkMigrationAreNetworkInterfaceConfigurationsIdentical (SCPreferencesRef
 
 		for (CFIndex idx2 = 0; idx2 < interfaceListCount; idx2++) {
 			interfaceEntity = CFArrayGetValueAtIndex(interfaceList, idx2);
-			if (CFEqual(expectedInterfaceEntity, interfaceEntity) == TRUE) {
+			if (CFEqual(expectedInterfaceEntity, interfaceEntity)) {
 				foundMatch = TRUE;
 				break;
 			}
 		}
-		if (foundMatch == FALSE) {
+		if (!foundMatch) {
 			break;
 		}
 	}
@@ -3766,14 +3750,14 @@ _SCNetworkMigrationAreConfigurationsIdentical (CFURLRef configurationURL,
 	baseConfigURL = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE, kCFURLPOSIXPathStyle, TRUE, configurationURL);
 	configPreferencesURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*) PREFS_DEFAULT_CONFIG_PLIST, sizeof(PREFS_DEFAULT_CONFIG_PLIST), FALSE, baseConfigURL);
 
-	if (CFURLResourceIsReachable(configPreferencesURL, NULL) == FALSE) {
+	if (!CFURLResourceIsReachable(configPreferencesURL, NULL)) {
 		SC_log(LOG_INFO, "No preferences.plist file");
 		goto done;
 	}
 
 	configNetworkInterfacesURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)NETWORK_INTERFACES_PREFS_PLIST, sizeof(NETWORK_INTERFACES_PREFS_PLIST), FALSE, baseConfigURL);
 
-	if (CFURLResourceIsReachable(configNetworkInterfacesURL, NULL) == FALSE) {
+	if (!CFURLResourceIsReachable(configNetworkInterfacesURL, NULL)) {
 		SC_log(LOG_INFO, "No NetworkInterfaces.plist file");
 		goto done;
 	}
@@ -3790,14 +3774,14 @@ _SCNetworkMigrationAreConfigurationsIdentical (CFURLRef configurationURL,
 	baseExpectedConfigURL = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE, kCFURLPOSIXPathStyle, TRUE, expectedConfigurationURL);
 	expectedPreferencesURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)PREFS_DEFAULT_CONFIG_PLIST, sizeof(PREFS_DEFAULT_CONFIG_PLIST), FALSE, baseExpectedConfigURL);
 
-	if (CFURLResourceIsReachable(expectedPreferencesURL, NULL) == FALSE) {
+	if (!CFURLResourceIsReachable(expectedPreferencesURL, NULL)) {
 		SC_log(LOG_INFO, "No expected preferences.plist file");
 		goto done;
 	}
 
 	expectedNetworkInterfaceURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)NETWORK_INTERFACES_PREFS_PLIST, sizeof(NETWORK_INTERFACES_PREFS_PLIST), FALSE, baseExpectedConfigURL);
 
-	if (CFURLResourceIsReachable(expectedNetworkInterfaceURL, NULL) == FALSE) {
+	if (!CFURLResourceIsReachable(expectedNetworkInterfaceURL, NULL)) {
 		SC_log(LOG_INFO, "No expected NetworkInterfaces.plist file");
 		goto done;
 	}
@@ -3896,7 +3880,7 @@ _SCNetworkConfigurationCopyMigrationRemovePaths	(CFArrayRef	targetPaths,
 		targetFile = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)filePath,
 		strnlen(filePath, sizeof(filePath)), FALSE, targetDir);
 
-		if (CFURLResourceIsReachable(targetFile, NULL) == FALSE) {
+		if (!CFURLResourceIsReachable(targetFile, NULL)) {
 			CFArrayAppendValue(toBeRemoved, affectedURL);
 		}
 		CFRelease(targetFile);
diff --git a/SystemConfiguration.fproj/SCNetworkProtocol.c b/SystemConfiguration.fproj/SCNetworkProtocol.c
index 921908a..33bf633 100644
--- a/SystemConfiguration.fproj/SCNetworkProtocol.c
+++ b/SystemConfiguration.fproj/SCNetworkProtocol.c
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2004-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2008, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -31,10 +31,7 @@
 
 #include 
 #include 
-#include 
 #include "SCNetworkConfigurationInternal.h"
-#include 
-#include 
 
 #include 
 
@@ -45,9 +42,6 @@ static Boolean		__SCNetworkProtocolEqual		(CFTypeRef cf1, CFTypeRef cf2);
 static CFHashCode	__SCNetworkProtocolHash			(CFTypeRef cf);
 
 
-#if	!TARGET_OS_IPHONE
-const CFStringRef kSCNetworkProtocolTypeAppleTalk       = CFSTR("AppleTalk");
-#endif	// !TARGET_OS_IPHONE
 const CFStringRef kSCNetworkProtocolTypeDNS		= CFSTR("DNS");
 const CFStringRef kSCNetworkProtocolTypeIPv4		= CFSTR("IPv4");
 const CFStringRef kSCNetworkProtocolTypeIPv6		= CFSTR("IPv6");
@@ -169,7 +163,8 @@ __SCNetworkProtocolCreatePrivate(CFAllocatorRef		allocator,
 		return NULL;
 	}
 
-	protocolPrivate->entityID       = CFStringCreateCopy(NULL, entityID);
+	/* initialize non-zero/NULL members */
+	protocolPrivate->entityID	= CFStringCreateCopy(NULL, entityID);
 	protocolPrivate->service	= CFRetain(service);
 
 	return protocolPrivate;
@@ -181,9 +176,6 @@ __SCNetworkProtocolIsValidType(CFStringRef protocolType)
 {
 	int				i;
 	static const CFStringRef	*valid_types[]   = {
-#if	!TARGET_OS_IPHONE
-		&kSCNetworkProtocolTypeAppleTalk,
-#endif	// !TARGET_OS_IPHONE
 		&kSCNetworkProtocolTypeDNS,
 		&kSCNetworkProtocolTypeIPv4,
 		&kSCNetworkProtocolTypeIPv6,
@@ -312,6 +304,12 @@ SCNetworkProtocolSetConfiguration(SCNetworkProtocolRef protocol, CFDictionaryRef
 	ok = __setPrefsConfiguration(servicePrivate->prefs, path, config, TRUE);
 	CFRelease(path);
 
+	if (ok) {
+		SC_log(LOG_DEBUG, "SCNetworkProtocolSetConfiguration(): %@ --> %@",
+		       protocol,
+		       config != NULL ? config : (CFDictionaryRef)CFSTR("NULL"));
+	}
+
 	return ok;
 }
 
@@ -333,5 +331,11 @@ SCNetworkProtocolSetEnabled(SCNetworkProtocolRef protocol, Boolean enabled)
 	ok = __setPrefsEnabled(servicePrivate->prefs, path, enabled);
 	CFRelease(path);
 
+	if (ok) {
+		SC_log(LOG_DEBUG, "SCNetworkProtocolSetEnabled(): %@ -> %s",
+		       protocol,
+		       enabled ? "Enabled" : "Disabled");
+	}
+
 	return ok;
 }
diff --git a/SystemConfiguration.fproj/SCNetworkReachability.c b/SystemConfiguration.fproj/SCNetworkReachability.c
index eb1dd24..76afb7f 100644
--- a/SystemConfiguration.fproj/SCNetworkReachability.c
+++ b/SystemConfiguration.fproj/SCNetworkReachability.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -39,14 +39,8 @@
 #include 
 #include 
 #include 
-#include 
-#include 
-#include 
-#include 
-#include 
 #include 
 #include 
-
 #include 
 #include 
 #include 
@@ -61,10 +55,15 @@
 #include 
 #include 
 
-#include "SCNetworkReachabilityInternal.h"
-
-#include 
+#include 
+#include 
 
+#define	SC_LOG_HANDLE	__log_SCNetworkReachability()
+#include 
+#include 
+#include 
+#include "SCD.h"
+#include "SCNetworkReachabilityInternal.h"
 
 
 
@@ -122,8 +121,10 @@ __SCNetworkReachabilityGetFlagsFromPath(nw_path_t			path,
 					nw_array_t			resolvedEndpoints,
 					Boolean				resolvedEndpointUseFlags,
 					SCNetworkReachabilityFlags	resolvedEndpointFlags);
-static Boolean __SCNetworkReachabilitySetDispatchQueue(SCNetworkReachabilityPrivateRef	targetPrivate,
-						       dispatch_queue_t			queue);
+
+static Boolean
+__SCNetworkReachabilitySetDispatchQueue(SCNetworkReachabilityPrivateRef	targetPrivate,
+					dispatch_queue_t		queue);
 
 static CFTypeID __kSCNetworkReachabilityTypeID	= _kCFRuntimeNotATypeID;
 
@@ -156,6 +157,19 @@ _callback_queue()
 	return q;
 }
 
+static os_log_t
+__log_SCNetworkReachability()
+{
+	static os_log_t	log	= NULL;
+
+	if (log == NULL) {
+		log = os_log_create("com.apple.SystemConfiguration", "SCNetworkReachability");
+	}
+
+	return log;
+}
+
+
 #pragma mark -
 #pragma mark SCNetworkReachability APIs
 
@@ -209,6 +223,15 @@ _SCNetworkReachabilityCopyTargetDescription(SCNetworkReachabilityRef target)
 		}
 	}
 
+	if (targetPrivate->parameters != NULL) {
+		unsigned int	if_index;
+
+		if_index = nw_parameters_get_required_interface_index(targetPrivate->parameters);
+		if (if_index != 0) {
+			CFStringAppendFormat(str, NULL, CFSTR(", if_index = %u"), if_index);
+		}
+	}
+
 	return str;
 }
 
@@ -223,8 +246,14 @@ _SCNetworkReachabilityCopyTargetFlags(SCNetworkReachabilityRef target)
 	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));
+				       __SCNetworkReachabilityGetFlagsFromPath(targetPrivate->lastPath,
+									       targetPrivate->type,
+									       targetPrivate->lastResolverStatus,
+									       targetPrivate->lastResolvedEndpoints,
+									       targetPrivate->lastResolvedEndpointHasFlags,
+									       targetPrivate->lastResolvedEndpointFlags),
+				       targetPrivate->lastResolvedEndpointHasFlags ? targetPrivate->lastResolvedEndpointInterfaceIndex
+										   : nw_path_get_interface_index(targetPrivate->lastPath));
 	return str;
 }
 
@@ -257,13 +286,16 @@ __SCNetworkReachabilityCopyDescription(CFTypeRef cf)
 			if (nw_array_get_count(targetPrivate->lastResolvedEndpoints) > 0) {
 				nw_array_apply(targetPrivate->lastResolvedEndpoints, ^bool(size_t index, nw_object_t object) {
 					nw_endpoint_t endpoint = (nw_endpoint_t)object;
-					if (nw_endpoint_get_type(endpoint) == nw_endpoint_type_address) {
+					nw_endpoint_type_t endpoint_type = nw_endpoint_get_type(endpoint);
+					if (endpoint_type == nw_endpoint_type_address) {
 						char buf[64];
 						const struct sockaddr	*sa = nw_endpoint_get_address(endpoint);
 						_SC_sockaddr_to_string(sa, buf, sizeof(buf));
 						CFStringAppendFormat(result, NULL, CFSTR(", %s"), buf);
-					} else if (nw_endpoint_get_type(endpoint) == nw_endpoint_type_host) {
+					} else if (endpoint_type == nw_endpoint_type_host) {
 						CFStringAppendFormat(result, NULL, CFSTR(", %s"), nw_endpoint_get_hostname(endpoint));
+					} else {
+						CFStringAppendFormat(result, NULL, CFSTR(", unexpected nw_endpoint type: %d"), endpoint_type);
 					}
 					return TRUE;
 				});
@@ -299,9 +331,7 @@ __SCNetworkReachabilityDeallocate(CFTypeRef cf)
 	SCNetworkReachabilityRef	target		= (SCNetworkReachabilityRef)cf;
 	SCNetworkReachabilityPrivateRef	targetPrivate	= (SCNetworkReachabilityPrivateRef)target;
 
-	if (_sc_debug && (_sc_log > 0)) {
-		SC_log(LOG_INFO, "%srelease", targetPrivate->log_prefix);
-	}
+	SC_log(LOG_DEBUG, "%srelease", targetPrivate->log_prefix);
 
 	/* release resources */
 	MUTEX_LOCK(&targetPrivate->lock);
@@ -353,15 +383,6 @@ __SCNetworkReachabilityInitialize(void)
 {
 	__kSCNetworkReachabilityTypeID = _CFRuntimeRegisterClass(&__SCNetworkReachabilityClass);
 
-	// provide a way to enable SCNetworkReachability logging without
-	// having to set _sc_debug=1.
-	if ((getenv("REACH_LOGGING") != NULL) ||
-	    (CFPreferencesGetAppBooleanValue(CFSTR("com.apple.SCNetworkReachability.debug"),
-					     kCFPreferencesCurrentApplication,
-					     NULL))) {
-		_sc_debug = TRUE;
-	}
-
 	pthread_mutexattr_init(&lock_attr);
 	pthread_mutexattr_settype(&lock_attr, PTHREAD_MUTEX_ERRORCHECK);
 
@@ -387,14 +408,8 @@ __SCNetworkReachabilityCreatePrivate(CFAllocatorRef	allocator)
 		return NULL;
 	}
 
-	bzero((void *)targetPrivate + sizeof(CFRuntimeBase), size);
-
+	/* initialize non-zero/NULL members */
 	MUTEX_INIT(&targetPrivate->lock);
-
-	targetPrivate->pathEvaluator = NULL;
-	targetPrivate->resolver = NULL;
-
-	targetPrivate->log_prefix[0] = '\0';
 	if (_sc_log > 0) {
 		snprintf(targetPrivate->log_prefix,
 			 sizeof(targetPrivate->log_prefix),
@@ -420,7 +435,7 @@ is_valid_address(const struct sockaddr *address)
 					valid = address;
 				} else {
 					if (!warned) {
-						SC_log(LOG_NOTICE, "SCNetworkReachabilityCreateWithAddress[Pair] called with \"struct sockaddr *\" len %d < %zu",
+						SC_log(LOG_WARNING, "SCNetworkReachabilityCreateWithAddress[Pair] called with \"struct sockaddr *\" len %d < %zu",
 						      address->sa_len,
 						      sizeof(struct sockaddr_in));
 						warned = TRUE;
@@ -431,7 +446,7 @@ is_valid_address(const struct sockaddr *address)
 				if (address->sa_len >= sizeof(struct sockaddr_in6)) {
 					valid = address;
 				} else if (!warned) {
-					SC_log(LOG_NOTICE, "SCNetworkReachabilityCreateWithAddress[Pair] called with \"struct sockaddr *\" len %d < %zu",
+					SC_log(LOG_WARNING, "SCNetworkReachabilityCreateWithAddress[Pair] called with \"struct sockaddr *\" len %d < %zu",
 					      address->sa_len,
 					      sizeof(struct sockaddr_in6));
 					warned = TRUE;
@@ -439,7 +454,7 @@ is_valid_address(const struct sockaddr *address)
 				break;
 			default :
 				if (!warned) {
-					SC_log(LOG_NOTICE, "SCNetworkReachabilityCreateWithAddress[Pair] called with invalid address family %d",
+					SC_log(LOG_WARNING, "SCNetworkReachabilityCreateWithAddress[Pair] called with invalid address family %d",
 					      address->sa_family);
 					warned = TRUE;
 				}
@@ -469,10 +484,11 @@ SCNetworkReachabilityRef
 SCNetworkReachabilityCreateWithAddress(CFAllocatorRef		allocator,
 				       const struct sockaddr	*address)
 {
+	const struct sockaddr		*targetAddress;
 	SCNetworkReachabilityPrivateRef	targetPrivate;
 
-	address = is_valid_address(address);
-	if (address == NULL) {
+	targetAddress = is_valid_address(address);
+	if (targetAddress == NULL) {
 		_SCErrorSet(kSCStatusInvalidArgument);
 		return NULL;
 	}
@@ -484,21 +500,36 @@ SCNetworkReachabilityCreateWithAddress(CFAllocatorRef		allocator,
 
 	targetPrivate->type = reachabilityTypeAddress;
 
-	if (!__SCNetworkReachabilityAddressIsEmpty(address)) {
-		targetPrivate->remoteAddressEndpoint = nw_endpoint_create_address(address);
+	if (!__SCNetworkReachabilityAddressIsEmpty(targetAddress)) {
+		targetPrivate->remoteAddressEndpoint = nw_endpoint_create_address(targetAddress);
 	}
 
-	if (_sc_debug && (_sc_log > 0)) {
-		SC_log(LOG_INFO, "%s%s %@",
-		       targetPrivate->log_prefix,
-		       DEBUG_REACHABILITY_TYPE_ADDRESS,
-		       targetPrivate);
-	}
+	SC_log(LOG_DEBUG, "%s%s %@",
+	       targetPrivate->log_prefix,
+	       DEBUG_REACHABILITY_TYPE_ADDRESS,
+	       targetPrivate);
 
 	return (SCNetworkReachabilityRef)targetPrivate;
 }
 
 
+static Boolean
+is_ipv4_loopback(const struct sockaddr *sa)
+{
+	uint32_t		addr;
+	struct sockaddr_in	*sin	= (struct sockaddr_in *)(void *)sa;
+
+	if ((sa == NULL) ||
+	    (sa->sa_len < sizeof(struct sockaddr_in)) ||
+	    (sa->sa_family != AF_INET)) {
+		return FALSE;
+	}
+
+	addr = ntohl(sin->sin_addr.s_addr);
+	return IN_LOOPBACK(addr) ? TRUE : FALSE;
+}
+
+
 static Boolean
 is_same_address(const struct sockaddr *a, const struct sockaddr *b)
 {
@@ -578,6 +609,24 @@ SCNetworkReachabilityCreateWithAddressPair(CFAllocatorRef		allocator,
 		}
 	}
 
+#if	!TARGET_OS_IPHONE
+	// Check/fix for loopback IP --> remote IP (rdar://26561383)
+	if ((localAddress != NULL) && (remoteAddress != NULL) &&
+	    is_ipv4_loopback(localAddress) && !is_ipv4_loopback(remoteAddress)) {
+		static Boolean	warned	= FALSE;
+
+		if (!warned) {
+			SC_log(LOG_WARNING, "BUG: SCNetworkReachabilityCreateWithAddressPair() called with local ");
+			SC_log(LOG_WARNING, "address and remote  address. To return the expected (but actually");
+			SC_log(LOG_WARNING, "incorrect) result, switched to SCNetworkReachabilityCreateWithAddress() with");
+			SC_log(LOG_WARNING, "the remote address.");
+			warned = TRUE;
+		}
+
+		return SCNetworkReachabilityCreateWithAddress(allocator, remoteAddress);
+	}
+#endif	// !TARGET_OS_IPHONE
+
 	targetPrivate = __SCNetworkReachabilityCreatePrivate(allocator);
 	if (targetPrivate == NULL) {
 		return NULL;
@@ -600,12 +649,10 @@ SCNetworkReachabilityCreateWithAddressPair(CFAllocatorRef		allocator,
 	targetPrivate->parameters = nw_parameters_create();
 	nw_parameters_set_local_address(targetPrivate->parameters, targetPrivate->localAddressEndpoint);
 
-	if (_sc_debug && (_sc_log > 0)) {
-		SC_log(LOG_INFO, "%s%s %@",
-		       targetPrivate->log_prefix,
-		       DEBUG_REACHABILITY_TYPE_ADDRESSPAIR,
-		       targetPrivate);
-	}
+	SC_log(LOG_DEBUG, "%s%s %@",
+	       targetPrivate->log_prefix,
+	       DEBUG_REACHABILITY_TYPE_ADDRESSPAIR,
+	       targetPrivate);
 
 	return (SCNetworkReachabilityRef)targetPrivate;
 }
@@ -648,12 +695,10 @@ SCNetworkReachabilityCreateWithName(CFAllocatorRef	allocator,
 
 	targetPrivate->hostnameEndpoint = nw_endpoint_create_host(nodename, "0");
 
-	if (_sc_debug && (_sc_log > 0)) {
-		SC_log(LOG_INFO, "%s%s %@",
-		       targetPrivate->log_prefix,
-		       DEBUG_REACHABILITY_TYPE_NAME,
-		       targetPrivate);
-	}
+	SC_log(LOG_DEBUG, "%s%s %@",
+	       targetPrivate->log_prefix,
+	       DEBUG_REACHABILITY_TYPE_NAME,
+	       targetPrivate);
 
 	return (SCNetworkReachabilityRef)targetPrivate;
 }
@@ -683,12 +728,10 @@ __SCNetworkReachabilityCreateWithPTR(CFAllocatorRef		allocator,
 	targetPrivate->parameters = nw_parameters_create();
 	nw_parameters_set_resolve_ptr(targetPrivate->parameters, TRUE);
 
-	if (_sc_debug && (_sc_log > 0)) {
-		SC_log(LOG_INFO, "%s%s %@",
-		       targetPrivate->log_prefix,
-		       DEBUG_REACHABILITY_TYPE_PTR,
-		       targetPrivate);
-	}
+	SC_log(LOG_DEBUG, "%s%s %@",
+	       targetPrivate->log_prefix,
+	       DEBUG_REACHABILITY_TYPE_PTR,
+	       targetPrivate);
 
 	return (SCNetworkReachabilityRef)targetPrivate;
 }
@@ -701,6 +744,7 @@ SCNetworkReachabilityCreateWithOptions(CFAllocatorRef	allocator,
 	const struct sockaddr		*addr_p		= NULL;
 	const struct sockaddr		*addr_r		= NULL;
 	CFDataRef			data;
+	Boolean				haveOpt		= FALSE;
 	CFStringRef			interface	= NULL;
 	CFStringRef			nodename;
 	CFBooleanRef			resolverBypass;
@@ -814,13 +858,15 @@ SCNetworkReachabilityCreateWithOptions(CFAllocatorRef	allocator,
 		nw_interface_t interfaceObject = nw_interface_create_with_index(if_index);
 		nw_parameters_require_interface(targetPrivate->parameters, interfaceObject);
 		network_release(interfaceObject);
+		haveOpt = TRUE;
 	}
 
 	if (resolverBypass != NULL) {
 		targetPrivate->resolverBypass = CFBooleanGetValue(resolverBypass);
+		haveOpt = TRUE;
 	}
 
-	if (_sc_debug && (_sc_log > 0)) {
+	if (haveOpt) {
 		const char	*opt	= "???";
 
 		switch (targetPrivate->type) {
@@ -838,10 +884,10 @@ SCNetworkReachabilityCreateWithOptions(CFAllocatorRef	allocator,
 				break;
 		}
 
-		SC_log(LOG_INFO, "%s%s %@",
-		      targetPrivate->log_prefix,
-		      opt,
-		      targetPrivate);
+		SC_log(LOG_DEBUG, "%s%s %@",
+		       targetPrivate->log_prefix,
+		       opt,
+		       targetPrivate);
 	}
 
 	return (SCNetworkReachabilityRef)targetPrivate;
@@ -860,6 +906,7 @@ CFArrayRef	/* CFArray[CFData], where each CFData is a (struct sockaddr *) */
 SCNetworkReachabilityCopyResolvedAddress(SCNetworkReachabilityRef	target,
 					 int				*error_num)
 {
+	CFMutableArrayRef		array		= NULL;
 	SCNetworkReachabilityPrivateRef	targetPrivate	= (SCNetworkReachabilityPrivateRef)target;
 
 	if (!isA_SCNetworkReachability(target)) {
@@ -879,60 +926,50 @@ SCNetworkReachabilityCopyResolvedAddress(SCNetworkReachabilityRef	target,
 	MUTEX_LOCK(&targetPrivate->lock);
 
 	if (nw_array_get_count(targetPrivate->lastResolvedEndpoints) > 0) {
-		CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
-		if (array != NULL) {
-			nw_array_apply(targetPrivate->lastResolvedEndpoints, ^bool(size_t index, nw_object_t object) {
-				if (nw_endpoint_get_type((nw_endpoint_t)object) == nw_endpoint_type_address) {
-					const struct sockaddr *address = nw_endpoint_get_address((nw_endpoint_t)object);
-					if (address != NULL) {
-						CFDataRef addressData = CFDataCreate(kCFAllocatorDefault, (const uint8_t *)address, address->sa_len);
-						if (addressData != NULL) {
-							CFArrayAppendValue(array, addressData);
-							CFRelease(addressData);
-						}
-					}
-				} else if (nw_endpoint_get_type((nw_endpoint_t)object) == nw_endpoint_type_host) {
-					CFStringRef string = CFStringCreateWithCString(kCFAllocatorDefault, nw_endpoint_get_hostname((nw_endpoint_t)object), kCFStringEncodingASCII);
-					if (string != NULL) {
-						if (CFStringHasPrefix(string,  CFSTR(".")) || CFStringHasSuffix(string,  CFSTR("."))) {
-							CFMutableStringRef mutableString = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, string);
-							if (mutableString != NULL) {
-								CFRelease(string);
-								string = mutableString;
-								CFStringTrim(mutableString, CFSTR("."));
-							}
-						}
-						CFArrayAppendValue(array, string);
-						CFRelease(string);
-					}
+		array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+		nw_array_apply(targetPrivate->lastResolvedEndpoints, ^bool(size_t index, nw_object_t object) {
+			nw_endpoint_type_t endpoint_type = nw_endpoint_get_type((nw_endpoint_t)object);
+			if (endpoint_type == nw_endpoint_type_address) {
+				const struct sockaddr *address = nw_endpoint_get_address((nw_endpoint_t)object);
+				if (address == NULL) {
+					SC_log(LOG_ERR, "nw_endpoint_type_address w/no address");
+					return TRUE;
 				}
-				return TRUE;
-			});
-			MUTEX_UNLOCK(&targetPrivate->lock);
-			return array;
-		}
-	}
 
-	MUTEX_UNLOCK(&targetPrivate->lock);
+				CFDataRef addressData = CFDataCreate(kCFAllocatorDefault, (const uint8_t *)address, address->sa_len);
+				CFArrayAppendValue(array, addressData);
+				CFRelease(addressData);
+			} else if (endpoint_type == nw_endpoint_type_host) {
+				const char *host = nw_endpoint_get_hostname((nw_endpoint_t)object);
+				if (host == NULL) {
+					SC_log(LOG_ERR, "nw_endpoint_type_host w/no host");
+					return TRUE;
+				}
 
-	_SCErrorSet(kSCStatusOK);
-	return NULL;
-}
+				CFStringRef string = CFStringCreateWithCString(kCFAllocatorDefault, host, kCFStringEncodingASCII);
+				if (string == NULL) {
+					SC_log(LOG_ERR, "nw_endpoint_type_host w/non-ASCII host");
+					return TRUE;
+				}
 
-/*
- * rankReachability()
- *   Not reachable       == 0
- *   Connection Required == 1
- *   Reachable           == 2
- */
-static int
-rankReachability(SCNetworkReachabilityFlags flags)
-{
-	int	rank = 0;
+				if (CFStringHasPrefix(string,  CFSTR(".")) || CFStringHasSuffix(string,  CFSTR("."))) {
+					CFMutableStringRef mutableString = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, string);
+					CFRelease(string);
+					string = mutableString;
+					CFStringTrim(mutableString, CFSTR("."));
+				}
+				CFArrayAppendValue(array, string);
+				CFRelease(string);
+			} else {
+				SC_log(LOG_ERR, "unexpected nw_endpoint type: %d", endpoint_type);
+			}
+			return TRUE;
+		});
+	}
 
-	if (flags & kSCNetworkReachabilityFlagsReachable)		rank = 2;
-	if (flags & kSCNetworkReachabilityFlagsConnectionRequired)	rank = 1;
-	return rank;
+	MUTEX_UNLOCK(&targetPrivate->lock);
+	_SCErrorSet(kSCStatusOK);
+	return array;
 }
 
 #pragma mark -
@@ -965,6 +1002,42 @@ __SCNetworkReachabilityGetAgentVPNFlags(xpc_object_t dictionary, Boolean *vpn, B
 	}
 }
 
+static bool
+nw_path_is_linklocal_direct(nw_path_t path)
+{
+	bool is_linklocal_direct = false;
+
+	nw_endpoint_t endpoint = nw_path_copy_endpoint(path);
+	if (endpoint == NULL) {
+		return false;
+	}
+
+	if (nw_endpoint_get_type(endpoint) == nw_endpoint_type_address) {
+		const struct sockaddr_in *sin;
+
+		sin = (const struct sockaddr_in *)(void *)nw_endpoint_get_address(endpoint);;
+		if ((sin != NULL) &&
+		    (sin->sin_family == AF_INET) &&
+		    IN_LINKLOCAL(ntohl(sin->sin_addr.s_addr))) {
+			nw_interface_t interface = nw_path_copy_interface(path);
+
+			if (interface != NULL) {
+				nw_interface_type_t type = nw_interface_get_type(interface);
+				if ((type == nw_interface_type_wired) ||
+				    ((type == nw_interface_type_wifi) &&
+				     (nw_interface_get_subtype(interface) != nw_interface_subtype_wifi_awdl))) {
+					is_linklocal_direct = true;
+				}
+
+				network_release(interface);
+			}
+		}
+	}
+
+	network_release(endpoint);
+	return is_linklocal_direct;
+}
+
 static SCNetworkReachabilityFlags
 __SCNetworkReachabilityGetFlagsFromPath(nw_path_t			path,
 					ReachabilityAddressType		type,
@@ -974,14 +1047,17 @@ __SCNetworkReachabilityGetFlagsFromPath(nw_path_t			path,
 					SCNetworkReachabilityFlags	resolvedEndpointFlags)
 {
 	__block SCNetworkReachabilityFlags flags = kSCNetworkReachabilityFlagsReachable;
+	__block const char *why = "???";
 	if (path != NULL) {
 		nw_path_status_t status = nw_path_get_status(path);
 		if (status == nw_path_status_satisfied) {
 			__block bool checkDNSFlags = TRUE;
 			flags = kSCNetworkReachabilityFlagsReachable;
-#if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
+			why = "nw_path_status_satisfied";
+#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR
 			if (nw_path_uses_interface_type(path, nw_interface_type_cellular)) {
 				flags |= (kSCNetworkReachabilityFlagsTransientConnection | kSCNetworkReachabilityFlagsIsWWAN);
+				why = "nw_path_status_satisfied, cellular";
 			}
 #endif
 			xpc_object_t agent_dictionary = nw_path_copy_netagent_dictionary(path);
@@ -994,6 +1070,7 @@ __SCNetworkReachabilityGetFlagsFromPath(nw_path_t			path,
 						if (vpn) {
 							// VPN flows are transient
 							flags |= kSCNetworkReachabilityFlagsTransientConnection;
+							why = "nw_path_status_satisfied, VPN";
 						}
 						if (onDemand &&
 						    type == reachabilityTypeName &&
@@ -1001,6 +1078,7 @@ __SCNetworkReachabilityGetFlagsFromPath(nw_path_t			path,
 						    nw_array_get_count(resolvedEndpoints) == 0) {
 							// On Demand by hostname, when no address has been resolved
 							flags |= (kSCNetworkReachabilityFlagsConnectionRequired | kSCNetworkReachabilityFlagsConnectionOnDemand);
+							why = "nw_path_status_satisfied, OnDemand";
 							checkDNSFlags = FALSE;
 						}
 						return TRUE;
@@ -1015,33 +1093,48 @@ __SCNetworkReachabilityGetFlagsFromPath(nw_path_t			path,
 					    nw_array_get_count(resolvedEndpoints) == 0) {
 						// DNS didn't resolve, as a final answer for now. Not reachable!
 						flags = 0;
+						why = "nw_path_status_satisfied, DNS not reachable";
 					} else if (resolvedEndpointUseFlags) {
 						flags = resolvedEndpointFlags;
+						why = "nw_path_status_satisfied, resolved endpoint flags";
 					}
 				}
 			} else {
-				if (nw_path_is_direct(path)) {
+				if (nw_path_is_direct(path) || nw_path_is_linklocal_direct(path)) {
 					flags |= kSCNetworkReachabilityFlagsIsDirect;
+					why = "nw_path_status_satisfied, by address, direct";
 				}
 				if (nw_path_is_local(path)) {
 					flags |= kSCNetworkReachabilityFlagsIsLocalAddress;
+					why = "nw_path_status_satisfied, by address, local";
 				}
 			}
 		} else if (status == nw_path_status_unsatisfied) {
 			flags = 0;
+			why = "nw_path_status_unsatisfied";
+#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR
+			if (nw_path_uses_interface_type(path, nw_interface_type_cellular)) {
+				flags |= kSCNetworkReachabilityFlagsIsWWAN;
+				why = "nw_path_status_unsatisfied, WWAN";
+			}
+#endif
 		} else if (status == nw_path_status_satisfiable) {
 			flags = (kSCNetworkReachabilityFlagsReachable | kSCNetworkReachabilityFlagsConnectionRequired | kSCNetworkReachabilityFlagsTransientConnection);
+			why = "nw_path_status_satisfiable";
 			uuid_t vpn_uuid;
 			if (nw_path_get_vpn_config_id(path, &vpn_uuid)) {
 				flags |= kSCNetworkReachabilityFlagsConnectionOnDemand;
+				why = "nw_path_status_satisfiable, OnDemand";
 			}
-#if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
+#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR
 			else if (nw_path_uses_interface_type(path, nw_interface_type_cellular)) {
-				flags |= (kSCNetworkReachabilityFlagsIsWWAN);
+				flags |= kSCNetworkReachabilityFlagsIsWWAN;
+				why = "nw_path_status_satisfiable, WWAN";
 			}
 #endif
 		}
 	}
+	SC_log(LOG_DEBUG, "__SCNetworkReachabilityGetFlagsFromPath, flags = 0x%08x, %s", flags, why);
 	return (flags & kSCNetworkReachabilityFlagsMask);
 }
 
@@ -1073,11 +1166,16 @@ SCNetworkReachabilityGetInterfaceIndex(SCNetworkReachabilityRef target)
 
 	MUTEX_LOCK(&targetPrivate->lock);
 
-	flags = __SCNetworkReachabilityGetFlagsFromPath(targetPrivate->lastPath, targetPrivate->type, nw_resolver_status_invalid, NULL, targetPrivate->lastResolvedEndpointHasFlags, targetPrivate->lastResolvedEndpointFlags);
+	flags = __SCNetworkReachabilityGetFlagsFromPath(targetPrivate->lastPath,
+							targetPrivate->type,
+							nw_resolver_status_invalid,
+							NULL,
+							targetPrivate->lastResolvedEndpointHasFlags,
+							targetPrivate->lastResolvedEndpointFlags);
 
 	/* Only return the if_index if the connection is reachable not for reachable connection
 	 * required etc ... */
-	if (ok && rankReachability(flags) == 2) {
+	if (ok && __SCNetworkReachabilityRank(flags) == ReachabilityRankReachable) {
 		if (targetPrivate->lastResolvedEndpointHasFlags) {
 			if_index = targetPrivate->lastResolvedEndpointInterfaceIndex;
 		} else {
@@ -1089,11 +1187,98 @@ SCNetworkReachabilityGetInterfaceIndex(SCNetworkReachabilityRef target)
 	return if_index;
 }
 
+// CrazyIvan46 is the feature that allows connections to IPv4 literals on IPv6-only (NAT64+DNS64) networks to work
+// This function replaces the path when the initial one isn't satisfied and our target is an IPv4 literal
+// It tries IPv6 reachability instead in case we could synthesize another address to connect to
+static OS_OBJECT_RETURNS_RETAINED nw_path_t
+__SCNetworkReachabilityCreateCrazyIvan46Path(nw_path_t path, nw_endpoint_t endpoint,
+					     nw_parameters_t parameters, Boolean allow_resolution)
+{
+	nw_path_t retPath = NULL;
+	const struct sockaddr *sa;
+
+	if ((nw_path_get_status(path) != nw_path_status_unsatisfied) ||
+	    (NULL == endpoint) || (nw_endpoint_get_type(endpoint) != nw_endpoint_type_address)) {
+		return NULL;
+	}
+
+	sa = nw_endpoint_get_address(endpoint);
+
+	if (sa->sa_family != AF_INET) {
+		return NULL;
+	}
+
+	if (allow_resolution) {
+		uint32_t ifIndex = 0;
+		int32_t numPrefixes;
+		nw_nat64_prefix_t *prefixes = NULL;
+		struct sockaddr_in sin;
+
+		memcpy(&sin, sa, MIN(sizeof(sin), sa->sa_len));
+		if (NULL != parameters) {
+			ifIndex = nw_parameters_get_required_interface_index(parameters);
+		}
+		numPrefixes = nw_nat64_copy_prefixes(&ifIndex, &prefixes);
+		if (numPrefixes > 0) {
+			struct sockaddr_in6 synthesizedAddress = {
+				.sin6_len = sizeof(struct sockaddr_in6),
+				.sin6_family = AF_INET6,
+				.sin6_port = nw_endpoint_get_port(endpoint),
+				.sin6_flowinfo = 0,
+				.sin6_scope_id = 0
+			};
+			nw_endpoint_t synthesizedEndpoint;
+			nw_path_evaluator_t synthesizedEvaluator;
+			nw_path_t synthesizedPath;
+
+			nw_nat64_synthesize_v6(&prefixes[0], &sin.sin_addr, &synthesizedAddress.sin6_addr);
+			synthesizedEndpoint = nw_endpoint_create_address((const struct sockaddr *)&synthesizedAddress);
+			synthesizedEvaluator = nw_path_create_evaluator_for_endpoint(synthesizedEndpoint, parameters);
+			synthesizedPath = nw_path_evaluator_copy_path(synthesizedEvaluator);
+			if (nw_path_get_status(synthesizedPath) != nw_path_status_unsatisfied) {
+				retPath = synthesizedPath;
+				SC_log(LOG_INFO, "Using CrazyIvan46 synthesized reachability result");
+			} else {
+				network_release(synthesizedPath);
+			}
+			network_release(synthesizedEvaluator);
+			network_release(synthesizedEndpoint);
+		}
+	} else {
+		// Don't synthesize in non-scheduled mode to avoid generating DNS traffic
+		nw_path_t v6Path;
+		nw_path_evaluator_t v6PathEvaluator;
+		nw_parameters_t v6Parameters;
+
+		if (NULL != parameters) {
+			v6Parameters = nw_parameters_copy(parameters);
+		} else {
+			v6Parameters = nw_parameters_create();
+		}
+		nw_parameters_set_required_address_family(v6Parameters, AF_INET6);
+		v6PathEvaluator = nw_path_create_evaluator_for_endpoint(NULL, v6Parameters);
+		v6Path = nw_path_evaluator_copy_path(v6PathEvaluator);
+		if (nw_path_get_status(v6Path) != nw_path_status_unsatisfied) {
+			retPath = v6Path;
+			SC_log(LOG_INFO, "Using CrazyIvan46 simple reachability result");
+		} else {
+			network_release(v6Path);
+		}
+		network_release(v6PathEvaluator);
+		network_release(v6Parameters);
+	}
+	return retPath;
+}
+
 Boolean
 SCNetworkReachabilityGetFlags(SCNetworkReachabilityRef		target,
 			      SCNetworkReachabilityFlags	*flags)
 {
+	nw_path_t			crazyIvanPath;
+	nw_endpoint_t			endpoint;
 	Boolean				ok		= TRUE;
+	nw_path_t			path;
+	nw_path_evaluator_t		pathEvaluator;
 	SCNetworkReachabilityPrivateRef	targetPrivate	= (SCNetworkReachabilityPrivateRef)target;
 
 	if (!isA_SCNetworkReachability(target)) {
@@ -1105,18 +1290,31 @@ SCNetworkReachabilityGetFlags(SCNetworkReachabilityRef		target,
 
 	if (targetPrivate->scheduled) {
 		// if being watched, return the last known (and what should be current) status
-		*flags = __SCNetworkReachabilityGetFlagsFromPath(targetPrivate->lastPath, targetPrivate->type, targetPrivate->lastResolverStatus, targetPrivate->lastResolvedEndpoints, targetPrivate->lastResolvedEndpointHasFlags, targetPrivate->lastResolvedEndpointFlags);
+		*flags = __SCNetworkReachabilityGetFlagsFromPath(targetPrivate->lastPath,
+								 targetPrivate->type,
+								 targetPrivate->lastResolverStatus,
+								 targetPrivate->lastResolvedEndpoints,
+								 targetPrivate->lastResolvedEndpointHasFlags,
+								 targetPrivate->lastResolvedEndpointFlags);
 		// because we have synchronously captured the current status, we no longer
 		// need our by-name required callback
 		targetPrivate->sentFirstUpdate = TRUE;
 		goto done;
 	}
 
-
 	// Not being watched, so run a one-shot path evaluator
-	// We don't care about DNS resolution in this case, since we only need to have the DNS resolution to support clients watching reachability to get updates
-	nw_path_evaluator_t pathEvaluator = nw_path_create_evaluator_for_endpoint(__SCNetworkReachabilityGetPrimaryEndpoint(targetPrivate), targetPrivate->parameters);
-	nw_path_t path = nw_path_evaluator_copy_path(pathEvaluator);
+	// We don't care about DNS resolution in this case, since we only need to have the
+	// DNS resolution to support clients watching reachability to get updates
+	endpoint = __SCNetworkReachabilityGetPrimaryEndpoint(targetPrivate);
+	pathEvaluator = nw_path_create_evaluator_for_endpoint(endpoint, targetPrivate->parameters);
+	path = nw_path_evaluator_copy_path(pathEvaluator);
+
+	crazyIvanPath = __SCNetworkReachabilityCreateCrazyIvan46Path(path, endpoint, targetPrivate->parameters, FALSE);
+	if (NULL != crazyIvanPath) {
+		network_release(path);
+		path = crazyIvanPath;
+	}
+
 	*flags = __SCNetworkReachabilityGetFlagsFromPath(path, 0, nw_resolver_status_invalid, NULL, FALSE, 0);
 	network_release(path);
 	network_release(pathEvaluator);
@@ -1134,14 +1332,16 @@ SCNetworkReachabilityGetFlags(SCNetworkReachabilityRef		target,
 static void
 reachPerformAndUnlock(SCNetworkReachabilityPrivateRef targetPrivate)
 {
-	os_activity_t			activity_id;
+	os_activity_t			activity;
 	void				*context_info;
 	void				(*context_release)(const void *);
 	SCNetworkReachabilityCallBack	rlsFunction;
 	SCNetworkReachabilityFlags	flags		= 0;
 
-	activity_id = os_activity_start("processing SCNetworkReachability notification",
-					OS_ACTIVITY_FLAG_DEFAULT);
+	activity = os_activity_create("processing SCNetworkReachability notification",
+				      OS_ACTIVITY_CURRENT,
+				      OS_ACTIVITY_FLAG_DEFAULT);
+	os_activity_scope(activity);
 
 	if (!targetPrivate->scheduled) {
 		// if no longer scheduled
@@ -1161,11 +1361,19 @@ reachPerformAndUnlock(SCNetworkReachabilityPrivateRef targetPrivate)
 		context_release	= NULL;
 	}
 
-	flags = __SCNetworkReachabilityGetFlagsFromPath(targetPrivate->lastPath, targetPrivate->type, targetPrivate->lastResolverStatus, targetPrivate->lastResolvedEndpoints, targetPrivate->lastResolvedEndpointHasFlags, targetPrivate->lastResolvedEndpointFlags);
+	flags = __SCNetworkReachabilityGetFlagsFromPath(targetPrivate->lastPath,
+							targetPrivate->type,
+							targetPrivate->lastResolverStatus,
+							targetPrivate->lastResolvedEndpoints,
+							targetPrivate->lastResolvedEndpointHasFlags,
+							targetPrivate->lastResolvedEndpointFlags);
 
 	MUTEX_UNLOCK(&targetPrivate->lock);
 
 	if (rlsFunction != NULL) {
+		SC_log(LOG_DEBUG, "%sexec SCNetworkReachability callout w/flags = 0x%08x",
+		       targetPrivate->log_prefix,
+		       flags);
 		(*rlsFunction)((SCNetworkReachabilityRef)targetPrivate,
 			       flags,
 			       context_info);
@@ -1177,7 +1385,7 @@ reachPerformAndUnlock(SCNetworkReachabilityPrivateRef targetPrivate)
 
     done :
 
-	os_activity_end(activity_id);
+	os_release(activity);
 
 	return;
 }
@@ -1342,6 +1550,7 @@ SCNetworkReachabilityUnscheduleFromRunLoop(SCNetworkReachabilityRef	target,
 	Boolean				success = FALSE;
 	Boolean				unscheduleDispatchQueue = FALSE;
 	SCNetworkReachabilityPrivateRef	targetPrivate	= (SCNetworkReachabilityPrivateRef)target;
+
 	if (!isA_SCNetworkReachability(target) || (runLoop == NULL) || (runLoopMode == NULL)) {
 		_SCErrorSet(kSCStatusInvalidArgument);
 		return FALSE;
@@ -1385,7 +1594,12 @@ static __inline__ void
 __SCNetworkReachabilityCopyPathStatus(SCNetworkReachabilityPrivateRef targetPrivate, SCNetworkReachabilityFlags *flags, uint *ifIndex, size_t *endpointCount)
 {
 	if (flags) {
-		*flags = __SCNetworkReachabilityGetFlagsFromPath(targetPrivate->lastPath, targetPrivate->type, targetPrivate->lastResolverStatus, targetPrivate->lastResolvedEndpoints, targetPrivate->lastResolvedEndpointHasFlags, targetPrivate->lastResolvedEndpointFlags);
+		*flags = __SCNetworkReachabilityGetFlagsFromPath(targetPrivate->lastPath,
+								 targetPrivate->type,
+								 targetPrivate->lastResolverStatus,
+								 targetPrivate->lastResolvedEndpoints,
+								 targetPrivate->lastResolvedEndpointHasFlags,
+								 targetPrivate->lastResolvedEndpointFlags);
 	}
 	if (ifIndex) {
 		*ifIndex = nw_path_get_interface_index(targetPrivate->lastPath);
@@ -1415,8 +1629,10 @@ __SCNetworkReachabilityRestartResolver(SCNetworkReachabilityPrivateRef targetPri
 	if (targetPrivate &&
 	    !targetPrivate->resolverBypass &&
 	    isReachabilityTypeName(targetPrivate->type)) {
-		targetPrivate = (SCNetworkReachabilityPrivateRef)CFRetain(targetPrivate);
-		nw_resolver_cancel(targetPrivate->resolver);
+		CFRetain(targetPrivate);
+		if (NULL != targetPrivate->resolver) {
+			nw_resolver_cancel(targetPrivate->resolver);
+		}
 		nw_resolver_t resolver = nw_resolver_create_with_endpoint(__SCNetworkReachabilityGetPrimaryEndpoint(targetPrivate), targetPrivate->lastPathParameters ? targetPrivate->lastPathParameters : targetPrivate->parameters);
 		targetPrivate->resolver = resolver;
 		nw_resolver_set_cancel_handler(resolver, ^(void) {
@@ -1448,6 +1664,7 @@ __SCNetworkReachabilityRestartResolver(SCNetworkReachabilityPrivateRef targetPri
 				nw_array_apply(targetPrivate->lastResolvedEndpoints, ^bool(size_t index, nw_object_t object) {
 					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);
@@ -1459,11 +1676,12 @@ __SCNetworkReachabilityRestartResolver(SCNetworkReachabilityPrivateRef targetPri
 					network_release(path);
 					network_release(pathEvaluator);
 
-					if (rankReachability(flags) > rankReachability(targetPrivate->lastResolvedEndpointFlags)) {
+					rank = __SCNetworkReachabilityRank(flags);
+					if (rank > __SCNetworkReachabilityRank(targetPrivate->lastResolvedEndpointFlags)) {
 						// Return the best case result
 						targetPrivate->lastResolvedEndpointFlags = flags;
 						targetPrivate->lastResolvedEndpointInterfaceIndex = interfaceIndex;
-						if (rankReachability(flags) == 2) {
+						if (rank == ReachabilityRankReachable) {
 							// Can't get any better than REACHABLE
 							return FALSE;
 						}
@@ -1495,16 +1713,23 @@ __SCNetworkReachabilitySetDispatchQueue(SCNetworkReachabilityPrivateRef	targetPr
 	Boolean	ok	= FALSE;
 
 	if (queue != NULL) {
+		nw_path_t		crazyIvanPath;
+		nw_endpoint_t		endpoint;
+		nw_path_evaluator_t	pathEvaluator;
+
 		if ((targetPrivate->dispatchQueue != NULL) ||		// if we are already scheduled with a dispatch queue
 		    ((queue != NULL) && targetPrivate->scheduled)) {	// if we are already scheduled on a CFRunLoop
 			_SCErrorSet(kSCStatusInvalidArgument);
 			goto done;
 		}
 
+		SC_log(LOG_DEBUG, "%sscheduled", targetPrivate->log_prefix);
+
 		// retain dispatch queue
 		dispatch_retain(queue);
 		nw_path_evaluator_cancel(targetPrivate->pathEvaluator);
-		nw_path_evaluator_t pathEvaluator = nw_path_create_evaluator_for_endpoint(__SCNetworkReachabilityGetPrimaryEndpoint(targetPrivate), targetPrivate->parameters);
+		endpoint = __SCNetworkReachabilityGetPrimaryEndpoint(targetPrivate);
+		pathEvaluator = nw_path_create_evaluator_for_endpoint(endpoint, targetPrivate->parameters);
 		targetPrivate->pathEvaluator = pathEvaluator;
 		targetPrivate->dispatchQueue = queue;
 		targetPrivate->scheduled = TRUE;
@@ -1518,6 +1743,13 @@ __SCNetworkReachabilitySetDispatchQueue(SCNetworkReachabilityPrivateRef	targetPr
 		network_release(targetPrivate->lastPath);
 		targetPrivate->lastPath = nw_path_evaluator_copy_path(pathEvaluator);
 
+		crazyIvanPath = __SCNetworkReachabilityCreateCrazyIvan46Path(targetPrivate->lastPath, endpoint,
+									     targetPrivate->parameters, FALSE);
+		if (NULL != crazyIvanPath) {
+			network_release(targetPrivate->lastPath);
+			targetPrivate->lastPath = crazyIvanPath;
+		}
+
 		network_release(targetPrivate->lastPathParameters);
 		targetPrivate->lastPathParameters = nw_path_copy_derived_parameters(targetPrivate->lastPath);
 
@@ -1526,7 +1758,7 @@ __SCNetworkReachabilitySetDispatchQueue(SCNetworkReachabilityPrivateRef	targetPr
 		targetPrivate->lastResolvedEndpoints = NULL;
 		__SCNetworkReachabilityRestartResolver(targetPrivate);
 
-		targetPrivate = (SCNetworkReachabilityPrivateRef)CFRetain(targetPrivate);
+		CFRetain(targetPrivate);
 		nw_path_evaluator_set_cancel_handler(pathEvaluator, ^(void) {
 			MUTEX_LOCK(&targetPrivate->lock);
 			if (pathEvaluator == targetPrivate->pathEvaluator) {
@@ -1540,6 +1772,7 @@ __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;
@@ -1547,6 +1780,16 @@ __SCNetworkReachabilitySetDispatchQueue(SCNetworkReachabilityPrivateRef	targetPr
 
 				network_release(targetPrivate->lastPath);
 				targetPrivate->lastPath = network_retain(path);
+
+				crazyIvanPath = __SCNetworkReachabilityCreateCrazyIvan46Path(targetPrivate->lastPath,
+											     endpoint,
+											     targetPrivate->parameters,
+											     TRUE);
+				if (NULL != crazyIvanPath) {
+					network_release(targetPrivate->lastPath);
+					targetPrivate->lastPath = crazyIvanPath;
+				}
+
 				if (targetPrivate->lastResolverStatus == nw_resolver_status_complete) {
 					targetPrivate->lastResolverStatus = nw_resolver_status_invalid;
 					__SCNetworkReachabilityRestartResolver(targetPrivate);
@@ -1577,7 +1820,6 @@ __SCNetworkReachabilitySetDispatchQueue(SCNetworkReachabilityPrivateRef	targetPr
 			goto done;
 		}
 
-
 		targetPrivate->scheduled = FALSE;
 		targetPrivate->sentFirstUpdate = FALSE;
 		nw_path_evaluator_cancel(targetPrivate->pathEvaluator);
@@ -1588,12 +1830,16 @@ __SCNetworkReachabilitySetDispatchQueue(SCNetworkReachabilityPrivateRef	targetPr
 		targetPrivate->lastPathParameters = NULL;
 		network_release(targetPrivate->lastResolvedEndpoints);
 		targetPrivate->lastResolvedEndpoints = NULL;
-		nw_resolver_cancel(targetPrivate->resolver);
-		targetPrivate->resolver = NULL;
+		if (NULL != targetPrivate->resolver) {
+			nw_resolver_cancel(targetPrivate->resolver);
+			targetPrivate->resolver = NULL;
+		}
 		if (targetPrivate->dispatchQueue != NULL) {
 			dispatch_release(targetPrivate->dispatchQueue);
 			targetPrivate->dispatchQueue = NULL;
 		}
+
+		SC_log(LOG_DEBUG, "%sunscheduled", targetPrivate->log_prefix);
 	}
 	ok = TRUE;
 done:
diff --git a/SystemConfiguration.fproj/SCNetworkReachability.h b/SystemConfiguration.fproj/SCNetworkReachability.h
index 7024fc1..0dc6266 100644
--- a/SystemConfiguration.fproj/SCNetworkReachability.h
+++ b/SystemConfiguration.fproj/SCNetworkReachability.h
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2003-2005, 2008-2010, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2005, 2008-2010, 2015-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -49,6 +49,22 @@ CF_ASSUME_NONNULL_BEGIN
 		computer.
 		Note that reachability does not guarantee that the data
 		packet will actually be received by the host.
+ 
+		When reachability is used without scheduling updates on a runloop
+		or dispatch queue, the system will not generate DNS traffic and
+		will be optimistic about its reply - it will assume that the target
+		is reachable if there is a default route but a DNS query is
+		needed to learn the address. When scheduled, the first callback
+		will behave like an unscheduled call but subsequent calls will
+		leverage DNS results.
+ 
+		When used on IPv6-only (NAT64+DNS64) networks, reachability checks
+		for IPv4 address literals (either a struct sockaddr_in * or textual
+		representations such as "192.0.2.1") will automatically give the
+		result for the corresponding synthesized IPv6 address.
+		On those networks, creating a CFSocketStream or NSURLSession
+		to that address will send packets but trying to connect using
+		BSD socket APIs will fail.
  */
 
 /*!
@@ -323,12 +339,13 @@ SCNetworkReachabilityUnscheduleFromRunLoop	(
 
 /*!
 	@function SCNetworkReachabilitySetDispatchQueue
-	@discussion Schedules callbacks for the given target on the given
+	@discussion Schedule or unschedule callbacks for the given target on the given
 		dispatch queue.
 	@param target The address or name that is set up for asynchronous
 		notifications.  Must be non-NULL.
-	@param queue A libdispatch queue to run the callback on. Pass NULL to disable notifications, and release queue.
-	@result Returns TRUE if the target is unscheduled successfully;
+	@param queue A libdispatch queue to run the callback on. 
+		Pass NULL to unschedule callbacks.
+	@result Returns TRUE if the target is scheduled or unscheduled successfully;
 		FALSE otherwise.
  */
 Boolean
diff --git a/SystemConfiguration.fproj/SCNetworkReachabilityInternal.h b/SystemConfiguration.fproj/SCNetworkReachabilityInternal.h
index f3ef568..5e354f1 100644
--- a/SystemConfiguration.fproj/SCNetworkReachabilityInternal.h
+++ b/SystemConfiguration.fproj/SCNetworkReachabilityInternal.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -33,7 +33,6 @@
 #include 
 #include 
 
-#include 
 #include 
 #include 
 #include 
@@ -53,6 +52,11 @@ typedef	enum {
 	UNKNOWN
 } lazyBoolean;
 
+typedef enum {
+	ReachabilityRankNone			= 0,
+	ReachabilityRankConnectionRequired	= 1,
+	ReachabilityRankReachable		= 2
+} ReachabilityRankType;
 
 typedef enum {
 	// by-address SCNetworkReachability targets
@@ -127,11 +131,11 @@ __SCNetworkReachabilityCopyFlags(SCNetworkReachabilityFlags flags, CFStringRef p
 {
 	CFMutableStringRef	str	= CFStringCreateMutable(NULL, 0);
 
+	if (prefix != NULL) {
+		CFStringAppend(str, prefix);
+	}
+
 	if (debug) {
-		if (prefix != NULL) {
-			CFStringAppend(str, prefix);
-		}
-		
 		CFStringAppendFormat(str, NULL, CFSTR("0x%08x ("), flags);
 	}
 
@@ -195,6 +199,20 @@ __SCNetworkReachabilityCopyFlags(SCNetworkReachabilityFlags flags, CFStringRef p
 	return str;
 }
 
+static __inline__ ReachabilityRankType
+__SCNetworkReachabilityRank(SCNetworkReachabilityFlags flags)
+{
+	ReachabilityRankType	rank = ReachabilityRankNone;
+
+	if ((flags & kSCNetworkReachabilityFlagsReachable) != 0) {
+		rank = ReachabilityRankReachable;
+		if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0) {
+			rank = ReachabilityRankConnectionRequired;
+		}
+	}
+	return rank;
+}
+
 
 __END_DECLS
 
diff --git a/SystemConfiguration.fproj/SCNetworkService.c b/SystemConfiguration.fproj/SCNetworkService.c
index fe257c4..4034ee2 100644
--- a/SystemConfiguration.fproj/SCNetworkService.c
+++ b/SystemConfiguration.fproj/SCNetworkService.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -31,10 +31,7 @@
 
 #include 
 #include 
-#include 
 #include "SCNetworkConfigurationInternal.h"
-#include 
-#include 
 #include "SCPreferencesInternal.h"
 
 #include 
@@ -166,10 +163,10 @@ __SCNetworkServiceCreatePrivate(CFAllocatorRef		allocator,
 		return NULL;
 	}
 
+	/* initialize non-zero/NULL members */
 	servicePrivate->prefs		= (prefs != NULL) ? CFRetain(prefs): NULL;
 	servicePrivate->serviceID	= CFStringCreateCopy(NULL, serviceID);
 	servicePrivate->interface       = (interface != NULL) ? CFRetain(interface) : NULL;
-	servicePrivate->name		= NULL;
 
 	return servicePrivate;
 }
@@ -417,6 +414,10 @@ SCNetworkServiceAddProtocolType(SCNetworkServiceRef service, CFStringRef protoco
 
     done :
 
+	if (ok) {
+		SC_log(LOG_DEBUG, "SCNetworkServiceAddProtocolType(): %@, %@", service, protocolType);
+	}
+
 	CFRelease(path);
 	return ok;
 }
@@ -471,6 +472,11 @@ SCNetworkServiceCopyAll(SCPreferencesRef prefs)
 				continue;
 			}
 
+			if (__SCNetworkInterfaceEntityIsPPTP(entity)) {
+				SC_log(LOG_INFO, "PPTP services are no longer supported");
+				continue;
+			}
+
 			servicePrivate = __SCNetworkServiceCreatePrivate(NULL, prefs, keys[i], NULL);
 			assert(servicePrivate != NULL);
 			CFArrayAppendValue(array, (SCNetworkServiceRef)servicePrivate);
@@ -605,6 +611,12 @@ SCNetworkServiceCopy(SCPreferencesRef prefs, CFStringRef serviceID)
 		return NULL;
 	}
 
+	if (__SCNetworkInterfaceEntityIsPPTP(entity)) {
+		SC_log(LOG_INFO, "PPTP services are no longer supported");
+		_SCErrorSet(kSCStatusNoKey);
+		return NULL;
+	}
+
 	servicePrivate = __SCNetworkServiceCreatePrivate(NULL, prefs, serviceID, NULL);
 	return (SCNetworkServiceRef)servicePrivate;
 }
@@ -931,6 +943,8 @@ SCNetworkServiceCreate(SCPreferencesRef prefs, SCNetworkInterfaceRef interface)
 					       interface_name);
 	}
 
+	SC_log(LOG_DEBUG, "SCNetworkServiceCreate(): %@", servicePrivate);
+
 	return (SCNetworkServiceRef)servicePrivate;
 }
 
@@ -1083,7 +1097,7 @@ SCNetworkServiceGetName(SCNetworkServiceRef service)
 		name = CFDictionaryGetValue(entity, kSCPropUserDefinedName);
 		if (isA_CFString(name)) {
 			servicePrivate->name = CFRetain(name);
-			if (useSystemInterfaces == FALSE) {
+			if (!useSystemInterfaces) {
 				return servicePrivate->name;
 			}
 		}
@@ -1147,9 +1161,10 @@ SCNetworkServiceGetName(SCNetworkServiceRef service)
 					// compare the older "Built-in XXX" non-localized name
 					interface_name = __SCNetworkInterfaceCopyXNonLocalizedDisplayName(interface);
 					break;
-#endif	// !TARGET_OS_IPHONE
+#else	// !TARGET_OS_IPHONE
 				default :
 					continue;
+#endif	// !TARGET_OS_IPHONE
 			}
 
 			if (interface_name != NULL) {
@@ -1266,6 +1281,10 @@ SCNetworkServiceRemove(SCNetworkServiceRef service)
 	ok = SCPreferencesPathRemoveValue(servicePrivate->prefs, path);
 	CFRelease(path);
 
+	if (ok) {
+		SC_log(LOG_DEBUG, "SCNetworkServiceRemove(): %@", service);
+	}
+
 	return ok;
 }
 
@@ -1303,6 +1322,10 @@ SCNetworkServiceRemoveProtocolType(SCNetworkServiceRef service, CFStringRef prot
 
     done :
 
+	if (ok) {
+		SC_log(LOG_DEBUG, "SCNetworkServiceRemoveProtocolType(): %@, %@", service, protocolType);
+	}
+
 	CFRelease(path);
 	return ok;
 }
@@ -1339,6 +1362,12 @@ SCNetworkServiceSetEnabled(SCNetworkServiceRef service, Boolean enabled)
 	ok = __setPrefsEnabled(servicePrivate->prefs, path, enabled);
 	CFRelease(path);
 
+	if (ok) {
+		SC_log(LOG_DEBUG, "SCNetworkServiceSetEnabled(): %@ -> %s",
+		       service,
+		       enabled ? "Enabled" : "Disabled");
+	}
+
 	return ok;
 }
 
@@ -1514,6 +1543,10 @@ SCNetworkServiceSetName(SCNetworkServiceRef service, CFStringRef name)
 	if (name != NULL) CFRetain(name);
 	servicePrivate->name = name;
 
+	if (ok) {
+		SC_log(LOG_DEBUG, "SCNetworkServiceSetName(): %@", service);
+	}
+
 	return ok;
 }
 
@@ -1709,9 +1742,12 @@ _SCNetworkServiceIsVPN(SCNetworkServiceRef service)
 		if (CFEqual(interfaceType, kSCNetworkInterfaceTypeL2TP)) {
 			return TRUE;
 		}
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
 		if (CFEqual(interfaceType, kSCNetworkInterfaceTypePPTP)) {
 			return TRUE;
 		}
+#pragma GCC diagnostic pop
 	} else if (CFEqual(interfaceType, kSCNetworkInterfaceTypeVPN)) {
 		return TRUE;
 	} else if (CFEqual(interfaceType, kSCNetworkInterfaceTypeIPSec)) {
@@ -1725,11 +1761,11 @@ _SCNetworkServiceIsVPN(SCNetworkServiceRef service)
 Boolean
 SCNetworkServiceSetExternalID(SCNetworkServiceRef service, CFStringRef identifierDomain, CFStringRef identifier)
 {
-	CFStringRef					prefs_path;
-	CFDictionaryRef				service_dictionary;
+	CFStringRef			prefs_path;
+	CFDictionaryRef			service_dictionary;
 	SCNetworkServicePrivateRef	service_private		= (SCNetworkServicePrivateRef)service;
-	Boolean						success				= FALSE;
-	CFStringRef					prefixed_domain;
+	Boolean				success			= FALSE;
+	CFStringRef			prefixed_domain;
 
 	if (!isA_SCNetworkService(service) || (service_private->prefs == NULL) || !isA_CFString(identifierDomain)) {
 		_SCErrorSet(kSCStatusInvalidArgument);
@@ -1774,8 +1810,8 @@ SCNetworkServiceSetExternalID(SCNetworkServiceRef service, CFStringRef identifie
 	    if (service_private->externalIDs == NULL) {
 			service_private->externalIDs = CFDictionaryCreateMutable(NULL,
 										 0,
-																	 &kCFTypeDictionaryKeyCallBacks,
-																	 &kCFTypeDictionaryValueCallBacks);
+										 &kCFTypeDictionaryKeyCallBacks,
+										 &kCFTypeDictionaryValueCallBacks);
 	    }
 	    CFDictionarySetValue(service_private->externalIDs, prefixed_domain, identifier);
 	} else {
@@ -1797,9 +1833,9 @@ SCNetworkServiceSetExternalID(SCNetworkServiceRef service, CFStringRef identifie
 CFStringRef
 SCNetworkServiceCopyExternalID(SCNetworkServiceRef service, CFStringRef identifierDomain)
 {
+	CFStringRef			identifier		= NULL;
+	CFStringRef			prefixed_domain;
 	SCNetworkServicePrivateRef	service_private		= (SCNetworkServicePrivateRef)service;
-	CFStringRef					identifier			= NULL;
-	CFStringRef					prefixed_domain;
 
 	if (!isA_SCNetworkService(service) || (service_private->prefs == NULL) || !isA_CFString(identifierDomain)) {
 		_SCErrorSet(kSCStatusInvalidArgument);
@@ -1816,7 +1852,7 @@ SCNetworkServiceCopyExternalID(SCNetworkServiceRef service, CFStringRef identifi
 	}
 
 	if (identifier == NULL) {
-		CFStringRef			prefs_path;
+		CFStringRef		prefs_path;
 		CFDictionaryRef		service_dictionary;
 
 		prefs_path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL,
@@ -1871,9 +1907,9 @@ replaceServiceID(const void *value, void *context)
 	// update service order
 	serviceOrder = SCNetworkSetGetServiceOrder(set);
 	if ((isA_CFArray(serviceOrder) != NULL) &&
-	    (CFArrayContainsValue(serviceOrder,
+	    CFArrayContainsValue(serviceOrder,
 				  CFRangeMake(0, CFArrayGetCount(serviceOrder)),
-				  service_context->oldServiceID) == TRUE)) {
+				  service_context->oldServiceID)) {
 		CFIndex	count;
 		CFIndex	serviceOrderIndex;
 
@@ -2006,6 +2042,8 @@ _SCNetworkServiceSetServiceID(SCNetworkServiceRef service, CFStringRef newServic
 		servicePrivate->interface = newInterface;
 	}
 
+	SC_log(LOG_DEBUG, "_SCNetworkServiceSetServiceID(): %@ --> %@", service, newServiceID);
+
 	// replace serviceID with new one
 	CFRetain(newServiceID);
 	CFRelease(servicePrivate->serviceID);
@@ -2022,6 +2060,7 @@ _SCNetworkServiceSetServiceID(SCNetworkServiceRef service, CFStringRef newServic
 	if (allSets != NULL) {
 		CFRelease(allSets);
 	}
+
 	return ok;
 }
 
@@ -2051,7 +2090,7 @@ copyInterfaceConfiguration(SCNetworkServiceRef oldService, SCNetworkServiceRef n
 
 		if ((configuration != NULL) ||
 		    (SCError() == kSCStatusOK)) {
-			if (SCNetworkInterfaceSetConfiguration(newInterface, configuration) == FALSE) {
+			if (!SCNetworkInterfaceSetConfiguration(newInterface, configuration)) {
 				SC_log(LOG_INFO, "problem setting interface configuration");
 			}
 
@@ -2072,7 +2111,7 @@ copyInterfaceConfiguration(SCNetworkServiceRef oldService, SCNetworkServiceRef n
 					configuration = SCNetworkInterfaceGetExtendedConfiguration(oldInterface, kSCEntNetIPSec);
 					if ((configuration != NULL) ||
 					    (SCError() == kSCStatusOK)) {
-						if (SCNetworkInterfaceSetExtendedConfiguration(newInterface, kSCEntNetIPSec, configuration) == FALSE) {
+						if (!SCNetworkInterfaceSetExtendedConfiguration(newInterface, kSCEntNetIPSec, configuration)) {
 							SC_log(LOG_INFO, "problem setting child interface configuration");
 						}
 					}
@@ -2169,7 +2208,6 @@ __SCNetworkServiceMigrateNew(SCPreferencesRef		prefs,
 	SCNetworkServiceRef newService = NULL;
 	CFStringRef serviceID = NULL;
 	SCNetworkServicePrivateRef servicePrivate = (SCNetworkServicePrivateRef) service;
-	CFMutableDictionaryRef servicesMutable = NULL;
 	CFArrayRef setList = NULL;
 	Boolean success = FALSE;
 	CFStringRef targetDeviceName = NULL;
@@ -2238,9 +2276,13 @@ __SCNetworkServiceMigrateNew(SCPreferencesRef		prefs,
 	}
 
 	enabled = SCNetworkServiceGetEnabled(service);
-	SCNetworkServiceSetEnabled(newService, enabled);
+	if (!SCNetworkServiceSetEnabled(newService, enabled)) {
+		SCNetworkServiceRemove(newService);
+		SC_log(LOG_INFO, "SCNetworkServiceSetEnabled() failed");
+		goto done;
+	}
 
-	if (SCNetworkServiceEstablishDefaultConfiguration(newService) == FALSE) {
+	if (!SCNetworkServiceEstablishDefaultConfiguration(newService)) {
 		SCNetworkServiceRemove(newService);
 		SC_log(LOG_INFO, "SCNetworkServiceEstablishDefaultConfiguration() failed");
 		goto done;
@@ -2250,8 +2292,8 @@ __SCNetworkServiceMigrateNew(SCPreferencesRef		prefs,
 	_SCNetworkServiceSetServiceID(newService, serviceID);
 
 	userDefinedName = SCNetworkServiceGetName(service);
-	if (userDefinedName != NULL &&
-	    SCNetworkServiceSetName(newService, userDefinedName) == FALSE) {
+	if ((userDefinedName != NULL) &&
+	    !SCNetworkServiceSetName(newService, userDefinedName)) {
 		SC_log(LOG_INFO, "SCNetworkServiceSetName(, %@) failed", userDefinedName);
 	}
 
@@ -2263,13 +2305,12 @@ __SCNetworkServiceMigrateNew(SCPreferencesRef		prefs,
 			for (CFIndex idx = 0; idx < CFArrayGetCount(setList); idx++) {
 				oldSet = CFArrayGetValueAtIndex(setList, idx);
 				newSet = CFDictionaryGetValue(setMapping, oldSet);
-
 				if (newSet == NULL) {
 					continue;
 				}
-				if (SCNetworkSetAddService(newSet, newService) == FALSE) {
+
+				if (!SCNetworkSetAddService(newSet, newService)) {
 					SC_log(LOG_INFO, "SCNetworkSetAddService() failed");
-					continue;
 				}
 			}
 		}
@@ -2304,9 +2345,6 @@ done:
 	if (newService != NULL) {
 		CFRelease(newService);
 	}
-	if (servicesMutable != NULL) {
-		CFRelease(servicesMutable);
-	}
 	if (ni_prefs != NULL) {
 		CFRelease(ni_prefs);
 	}
@@ -2343,14 +2381,14 @@ __SCNetworkServiceCreate(SCPreferencesRef	prefs,
 		SC_log(LOG_INFO, "SCNetworkServiceCreate() failed: %s", SCErrorString(SCError()));
 	} else {
 		ok = SCNetworkServiceSetName(service, userDefinedName);
-		if (ok == FALSE) {
+		if (!ok) {
 			SC_log(LOG_INFO, "SCNetworkServiceSetName() failed: %s", SCErrorString(SCError()));
 			SCNetworkServiceRemove(service);
 			goto done;
 		}
 
 		ok = SCNetworkServiceEstablishDefaultConfiguration(service);
-		if (ok == FALSE) {
+		if (!ok) {
 			SC_log(LOG_INFO, "SCNetworkServiceEstablishDefaultConfiguration() failed: %s", SCErrorString(SCError()));
 			SCNetworkServiceRemove(service);
 			goto done;
@@ -2366,7 +2404,7 @@ __SCNetworkServiceCreate(SCPreferencesRef	prefs,
 	}
 	if (service != NULL) {
 		ok = SCNetworkSetAddService(currentSet, service);
-		if (ok == FALSE) {
+		if (!ok) {
 			SC_log(LOG_INFO, "Could not add service to the current set");
 			SCNetworkServiceRemove(service);
 			goto done;
@@ -2382,3 +2420,28 @@ __SCNetworkServiceCreate(SCPreferencesRef	prefs,
 	}
 	return ok;
 }
+
+__private_extern__ Boolean
+__SCNetworkServiceIsPPTP(SCNetworkServiceRef	service)
+{
+	CFStringRef intfSubtype;
+	SCNetworkServicePrivateRef servicePrivate = (SCNetworkServicePrivateRef)service;
+
+	if (servicePrivate == NULL || servicePrivate->interface == NULL) {
+		return FALSE;
+	}
+
+	intfSubtype = __SCNetworkInterfaceGetEntitySubType(servicePrivate->interface);
+	if (intfSubtype == NULL) {
+		return FALSE;
+	}
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
+	if (CFEqual(intfSubtype, kSCValNetInterfaceSubTypePPTP)) {
+		return TRUE;
+	}
+#pragma GCC diagnostic pop
+
+	return FALSE;
+}
diff --git a/SystemConfiguration.fproj/SCNetworkSet.c b/SystemConfiguration.fproj/SCNetworkSet.c
index 3a2ff97..a9ae4e4 100644
--- a/SystemConfiguration.fproj/SCNetworkSet.c
+++ b/SystemConfiguration.fproj/SCNetworkSet.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -31,10 +31,7 @@
 
 #include 
 #include 
-#include 
 #include "SCNetworkConfigurationInternal.h"
-#include 
-#include 
 
 #include 
 
@@ -157,10 +154,9 @@ __SCNetworkSetCreatePrivate(CFAllocatorRef      allocator,
 		return NULL;
 	}
 
+	/* initialize non-zero/NULL members */
 	setPrivate->setID       = CFStringCreateCopy(NULL, setID);
 	setPrivate->prefs       = CFRetain(prefs);
-	setPrivate->name	= NULL;
-	setPrivate->established	= FALSE;	// "new" (not yet established) set
 
 	return setPrivate;
 }
@@ -498,6 +494,10 @@ SCNetworkSetAddService(SCNetworkSetRef set, SCNetworkServiceRef service)
 
     done :
 
+	if (ok) {
+		SC_log(LOG_DEBUG, "SCNetworkSetAddService(): %@, %@", set, service);
+	}
+
 	if (interface_config != NULL)	CFRelease(interface_config);
 	return ok;
 }
@@ -777,14 +777,31 @@ SCNetworkSetCopyServices(SCNetworkSetRef set)
 										      serviceID,	// service
 										      NULL);		// entity
 				if (CFEqual(path, link)) {
-					SCNetworkServicePrivateRef	servicePrivate;
-
-					servicePrivate = __SCNetworkServiceCreatePrivate(NULL,
-											 setPrivate->prefs,
-											 serviceID,
-											 NULL);
-					CFArrayAppendValue(array, (SCNetworkServiceRef)servicePrivate);
-					CFRelease(servicePrivate);
+					CFDictionaryRef	entity;
+					CFStringRef	interfacePath;
+					Boolean		skip		= FALSE;
+
+					interfacePath = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL,			// allocator
+												       serviceID,		// service
+												       kSCEntNetInterface);	// entity
+					entity = SCPreferencesPathGetValue(setPrivate->prefs, interfacePath);
+					CFRelease(interfacePath);
+
+					if (__SCNetworkInterfaceEntityIsPPTP(entity)) {
+						SC_log(LOG_INFO, "PPTP services are no longer supported");
+						skip = TRUE;
+					}
+
+					if (!skip) {
+						SCNetworkServicePrivateRef	servicePrivate;
+
+						servicePrivate = __SCNetworkServiceCreatePrivate(NULL,
+												 setPrivate->prefs,
+												 serviceID,
+												 NULL);
+						CFArrayAppendValue(array, (SCNetworkServiceRef)servicePrivate);
+						CFRelease(servicePrivate);
+					}
 				}
 				CFRelease(path);
 			}
@@ -840,10 +857,74 @@ SCNetworkSetCreate(SCPreferencesRef prefs)
 		setPrivate = NULL;
 	}
 
+	if (setPrivate != NULL) {
+		SC_log(LOG_DEBUG, "SCNetworkSetCreate(): %@", setPrivate);
+	}
+
 	return (SCNetworkSetRef)setPrivate;
 }
 
 
+SCNetworkSetRef
+_SCNetworkSetCreateDefault(SCPreferencesRef prefs)
+{
+	CFBundleRef	bundle;
+	Boolean		ok		= TRUE;
+	SCNetworkSetRef	set;
+	CFStringRef	setName		= NULL;
+
+	set = SCNetworkSetCopyCurrent(prefs);
+	if (set != NULL) {
+		SC_log(LOG_NOTICE, "creating default set w/already existing set");
+		CFRelease(set);
+		_SCErrorSet(kSCStatusKeyExists);
+		return NULL;
+	}
+
+	// create a new ("Automatic") set
+	set = SCNetworkSetCreate(prefs);
+	if (set == NULL) {
+		SC_log(LOG_NOTICE, "could not create \"new\" set: %s",
+		       SCErrorString(SCError()));
+		goto done;
+	}
+
+	bundle = _SC_CFBundleGet();
+	if (bundle != NULL) {
+		setName = CFBundleCopyLocalizedString(bundle,
+						      CFSTR("DEFAULT_SET_NAME"),
+						      CFSTR("Automatic"),
+						      NULL);
+	}
+
+	ok = SCNetworkSetSetName(set, (setName != NULL) ? setName : CFSTR("Automatic"));
+	if (!ok) {
+		// if we could not save the new set's "name"
+		SC_log(LOG_NOTICE, "could not save the new set's name: %s",
+		       SCErrorString(SCError()));
+		goto done;
+	}
+
+	ok = SCNetworkSetSetCurrent(set);
+	if (!ok) {
+		// if we could not make this the "current" set
+		SC_log(LOG_NOTICE, "could not establish new set as current: %s",
+		       SCErrorString(SCError()));
+//		goto done;
+	}
+
+    done :
+
+	if (!ok && (set != NULL)) {
+		SCNetworkSetRemove(set);
+		CFRelease(set);
+		set = NULL;
+	}
+	if (setName != NULL) CFRelease(setName);
+	return set;
+}
+
+
 CFStringRef
 SCNetworkSetGetSetID(SCNetworkSetRef set)
 {
@@ -978,10 +1059,15 @@ SCNetworkSetRemove(SCNetworkSetRef set)
 	if (!isA_CFString(currentPath) || !CFEqual(currentPath, path)) {
 		ok = SCPreferencesPathRemoveValue(setPrivate->prefs, path);
 	} else {
+		SC_log(LOG_DEBUG, "SCNetworkSetRemove() failed, currently active: %@", setPrivate->setID);
 		_SCErrorSet(kSCStatusInvalidArgument);
 	}
 	CFRelease(path);
 
+	if (ok) {
+		SC_log(LOG_DEBUG, "SCNetworkSetRemove(): %@", set);
+	}
+
 	return ok;
 }
 
@@ -1034,12 +1120,15 @@ SCNetworkSetRemoveService(SCNetworkSetRef set, SCNetworkServiceRef service)
 	// push the [deep] interface configuration [back] into all sets which contain the service.
 	if (interface_config != NULL) {
 		__SCNetworkInterfaceSetDeepConfiguration(set, interface, interface_config);
+		CFRelease(interface_config);
 	}
 
-	if (interface_config != NULL)     CFRelease(interface_config);
-	if (!ok) {
+	if (ok) {
+		SC_log(LOG_DEBUG, "SCNetworkSetRemoveService(): %@, %@", set, service);
+	} else {
 		_SCErrorSet(sc_status);
 	}
+
 	return ok;
 }
 
@@ -1059,6 +1148,11 @@ SCNetworkSetSetCurrent(SCNetworkSetRef set)
 	path = SCPreferencesPathKeyCreateSet(NULL, setPrivate->setID);
 	ok = SCPreferencesSetValue(setPrivate->prefs, kSCPrefCurrentSet, path);
 	CFRelease(path);
+
+	if (ok) {
+		SC_log(LOG_DEBUG, "SCNetworkSetSetCurrent(): %@", set);
+	}
+
 	return ok;
 }
 
@@ -1188,6 +1282,10 @@ SCNetworkSetSetName(SCNetworkSetRef set, CFStringRef name)
 
     done :
 
+	if (ok) {
+		SC_log(LOG_DEBUG, "SCNetworkSetSetName(): %@", set);
+	}
+
 	if (localized != NULL)		CFRelease(localized);
 	if (non_localized != NULL)	CFRelease(non_localized);
 	return ok;
@@ -1463,7 +1561,9 @@ __SCNetworkSetEstablishDefaultConfigurationForInterfaces(SCNetworkSetRef set, CF
 	CFArrayRef		services;
 	SCNetworkSetPrivateRef	setPrivate	= (SCNetworkSetPrivateRef)set;
 	Boolean			updated		= FALSE;
+#if	!TARGET_OS_IPHONE
 	Boolean			updatedIFs	= FALSE;
+#endif	// !TARGET_OS_IPHONE
 
 #if	TARGET_OS_IPHONE
 	CFArrayRef		orphans		= NULL;
@@ -1667,7 +1767,9 @@ __SCNetworkSetEstablishDefaultConfigurationForInterfaces(SCNetworkSetRef set, CF
 		}
 		CFRelease(interface_list);
 	}
+#if	!TARGET_OS_IPHONE
 	if (updatedIFs)		CFRelease(interfaces);
+#endif	// !TARGET_OS_IPHONE
 	if (services != NULL)	CFRelease(services);
 	if (excluded != NULL)	CFRelease(excluded);
 
@@ -1960,9 +2062,11 @@ _SCNetworkSetSetSetID(SCNetworkSetRef set, CFStringRef newSetID)
 		CFRelease(currentSet);
 	}
 
+	SC_log(LOG_DEBUG, "_SCNetworkSetSetID(): %@ --> %@", set, newSetID);
+
+	// replace setID with new one
 	CFRetain(newSetID);
 	CFRelease(setPrivate->setID);
-
 	setPrivate->setID = newSetID;
 
 	if (updateCurrentSet) {
diff --git a/SystemConfiguration.fproj/SCNetworkSignature.c b/SystemConfiguration.fproj/SCNetworkSignature.c
index b5bebd6..31e3df7 100644
--- a/SystemConfiguration.fproj/SCNetworkSignature.c
+++ b/SystemConfiguration.fproj/SCNetworkSignature.c
@@ -316,8 +316,7 @@ SCNetworkSignatureCopyActiveIdentifiers(CFAllocatorRef alloc)
 			/* Does this service have a signature? */
 			if (isA_CFDictionary(service_info) != NULL) {
 				network_sig = CFDictionaryGetValue(service_info, kStoreKeyNetworkSignature);
-				if (isA_CFString(network_sig) != NULL
-				    && CFArrayContainsValue(active, range, network_sig) == FALSE) {
+				if (isA_CFString(network_sig) && !CFArrayContainsValue(active, range, network_sig)) {
 					CFArrayAppendValue(active, network_sig);
 					network_sig = NULL;
 					range.length++;
@@ -350,8 +349,7 @@ SCNetworkSignatureCopyActiveIdentifiers(CFAllocatorRef alloc)
 		network_sig = CFDictionaryGetValue(service_dict,
 						   kStoreKeyNetworkSignature);
 		/* Does this service have a signature? */
-		if (isA_CFString(network_sig) != NULL
-		    && CFArrayContainsValue(active, range, network_sig) == FALSE) {
+		if (isA_CFString(network_sig) && !CFArrayContainsValue(active, range, network_sig)) {
 			CFArrayAppendValue(active, network_sig);
 			range.length++;
 			network_sig = NULL;
diff --git a/SystemConfiguration.fproj/SCP.c b/SystemConfiguration.fproj/SCP.c
index b48b1a2..9c0d541 100644
--- a/SystemConfiguration.fproj/SCP.c
+++ b/SystemConfiguration.fproj/SCP.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2001, 2003-2005, 2007-2009, 2011, 2014, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003-2005, 2007-2009, 2011, 2014-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -31,8 +31,6 @@
  * - initial revision
  */
 
-#include 
-#include 
 #include "SCPreferencesInternal.h"
 #include "SCNetworkConfigurationInternal.h"
 
@@ -109,7 +107,7 @@ __SCPreferencesPath(CFAllocatorRef	allocator,
 
 		pathLen = CFStringGetMaximumSizeOfFileSystemRepresentation(path);
 		pathStr = CFAllocatorAllocate(NULL, pathLen, 0);
-		if (CFStringGetFileSystemRepresentation(path, pathStr, pathLen) == FALSE) {
+		if (!CFStringGetFileSystemRepresentation(path, pathStr, pathLen)) {
 			SC_log(LOG_INFO, "could not convert path to C string");
 			CFAllocatorDeallocate(NULL, pathStr);
 			pathStr = NULL;
@@ -179,7 +177,7 @@ __SCPreferencesCreateNIPrefsFromPrefs(SCPreferencesRef prefs)
 			       kCFCompareBackwards);
 
 	newURL = CFURLCreateWithFileSystemPath(NULL, newPath, kCFURLPOSIXPathStyle, FALSE);
-	if (CFURLResourceIsReachable(newURL, NULL) == FALSE) {
+	if (!CFURLResourceIsReachable(newURL, NULL)) {
 		ni_prefs = __SCNetworkCreateDefaultNIPrefs(newPath);
 	}
 	else {
diff --git a/SystemConfiguration.fproj/SCPAdd.c b/SystemConfiguration.fproj/SCPAdd.c
index 2168f50..438e7e8 100644
--- a/SystemConfiguration.fproj/SCPAdd.c
+++ b/SystemConfiguration.fproj/SCPAdd.c
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2000, 2001, 2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2004, 2016 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -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@
  */
 
@@ -31,8 +31,6 @@
  * - initial revision
  */
 
-#include 
-#include 
 #include "SCPreferencesInternal.h"
 
 Boolean
diff --git a/SystemConfiguration.fproj/SCPApply.c b/SystemConfiguration.fproj/SCPApply.c
index 0c39499..6bef941 100644
--- a/SystemConfiguration.fproj/SCPApply.c
+++ b/SystemConfiguration.fproj/SCPApply.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2001, 2004-2006, 2010, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2004-2006, 2010, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -31,8 +31,6 @@
  * - initial revision
  */
 
-#include 
-#include 
 #include "SCPreferencesInternal.h"
 #include "SCHelper_client.h"
 
@@ -113,6 +111,9 @@ SCPreferencesApplyChanges(SCPreferencesRef prefs)
 		goto done;
 	}
 
+	SC_log(LOG_INFO, "SCPreferences() apply: %s",
+	       prefsPrivate->newPath ? prefsPrivate->newPath : prefsPrivate->path);
+
 	/* post notification */
 	ok = SCDynamicStoreNotifyValue(NULL, prefsPrivate->sessionKeyApply);
 	if (!ok) {
diff --git a/SystemConfiguration.fproj/SCPCommit.c b/SystemConfiguration.fproj/SCPCommit.c
index 8a3107c..3d17b53 100644
--- a/SystemConfiguration.fproj/SCPCommit.c
+++ b/SystemConfiguration.fproj/SCPCommit.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2008, 2010-2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2008, 2010-2013, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -32,8 +32,6 @@
  */
 
 #include 
-#include 
-#include 
 #include "SCPreferencesInternal.h"
 #include "SCHelper_client.h"
 
@@ -312,6 +310,9 @@ SCPreferencesCommitChanges(SCPreferencesRef prefs)
 
     committed :
 
+	SC_log(LOG_INFO, "SCPreferences() commit: %s",
+	       prefsPrivate->newPath ? prefsPrivate->newPath : prefsPrivate->path);
+
 	/* post notification */
 	ok = SCDynamicStoreNotifyValue(NULL, prefsPrivate->sessionKeyCommit);
 	if (!ok) {
diff --git a/SystemConfiguration.fproj/SCPGet.c b/SystemConfiguration.fproj/SCPGet.c
index f83471c..1500f09 100644
--- a/SystemConfiguration.fproj/SCPGet.c
+++ b/SystemConfiguration.fproj/SCPGet.c
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2000, 2001, 2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2004, 2016 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -35,8 +35,6 @@
 #include 
 #include 
 
-#include 
-#include 
 #include "SCPreferencesInternal.h"
 
 CFPropertyListRef
diff --git a/SystemConfiguration.fproj/SCPList.c b/SystemConfiguration.fproj/SCPList.c
index fa5437d..d6fa5aa 100644
--- a/SystemConfiguration.fproj/SCPList.c
+++ b/SystemConfiguration.fproj/SCPList.c
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2005, 2016 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -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@
  */
 
@@ -31,8 +31,6 @@
  * - initial revision
  */
 
-#include 
-#include 
 #include "SCPreferencesInternal.h"
 
 CFArrayRef
diff --git a/SystemConfiguration.fproj/SCPLock.c b/SystemConfiguration.fproj/SCPLock.c
index b0e69fd..21f20bb 100644
--- a/SystemConfiguration.fproj/SCPLock.c
+++ b/SystemConfiguration.fproj/SCPLock.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2010, 2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2010, 2013, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -31,9 +31,6 @@
  * - initial revision
  */
 
-#include 
-#include 
-#include 
 #include "SCPreferencesInternal.h"
 #include "SCHelper_client.h"
 
@@ -47,8 +44,6 @@
 #include 
 #include 
 
-
-
 static Boolean
 __SCPreferencesLock_helper(SCPreferencesRef prefs, Boolean wait)
 {
@@ -187,30 +182,15 @@ createParentDirectory(const char *path)
 static void
 reportDelay(SCPreferencesRef prefs, struct timeval *delay, Boolean isStale)
 {
-	asl_object_t		m;
 	SCPreferencesPrivateRef	prefsPrivate	= (SCPreferencesPrivateRef)prefs;
-	char			str[256];
-
-	m = asl_new(ASL_TYPE_MSG);
-	asl_set(m, "com.apple.message.domain", "com.apple.SystemConfiguration.SCPreferencesLock");
-	(void) _SC_cfstring_to_cstring(prefsPrivate->name, str, sizeof(str), kCFStringEncodingUTF8);
-	asl_set(m, "com.apple.message.signature", str);
-	(void) _SC_cfstring_to_cstring(prefsPrivate->prefsID, str, sizeof(str), kCFStringEncodingUTF8);
-	asl_set(m, "com.apple.message.signature2", str);
-	(void) snprintf(str, sizeof(str),
-			"%d.%3.3d",
-			(int)delay->tv_sec,
-			delay->tv_usec / 1000);
-	asl_set(m, "com.apple.message.value", str);
-	SCLOG(NULL, m, ASL_LEVEL_DEBUG,
-	      CFSTR("SCPreferences(%@:%@) lock delayed for %d.%3.3d seconds%s"),
-	      prefsPrivate->name,
-	      prefsPrivate->prefsID,
-	      (int)delay->tv_sec,
-	      delay->tv_usec / 1000,
-	      isStale ? " (stale)" : "");
-	asl_release(m);
 
+	SC_log(LOG_ERR,
+	       "SCPreferences(%@:%@) lock delayed for %d.%3.3d seconds%s",
+	       prefsPrivate->name,
+	       prefsPrivate->prefsID,
+	       (int)delay->tv_sec,
+	       delay->tv_usec / 1000,
+	       isStale ? " (stale)" : "");
 	return;
 }
 
@@ -395,7 +375,6 @@ SCPreferencesLock(SCPreferencesRef prefs, Boolean wait)
 		return FALSE;
 	}
 
-
 	pthread_mutex_lock(&prefsPrivate->lock);
 
 	__SCPreferencesAddSessionKeys(prefs);
@@ -483,7 +462,7 @@ SCPreferencesLock(SCPreferencesRef prefs, Boolean wait)
 	// we have the lock
 
 	snprintf(buf, sizeof(buf), "%d\n", getpid());
-	write(prefsPrivate->lockFD, buf, strlen(buf));
+	(void) write(prefsPrivate->lockFD, buf, strlen(buf));
 
     locked :
 
@@ -533,6 +512,9 @@ SCPreferencesLock(SCPreferencesRef prefs, Boolean wait)
 		reportDelay(prefs, &lockElapsed, FALSE);
 	}
 
+	SC_log(LOG_DEBUG, "SCPreferences() lock: %s",
+	       prefsPrivate->newPath ? prefsPrivate->newPath : prefsPrivate->path);
+
 	prefsPrivate->locked = TRUE;
 	pthread_mutex_unlock(&prefsPrivate->lock);
 	return TRUE;
diff --git a/SystemConfiguration.fproj/SCPOpen.c b/SystemConfiguration.fproj/SCPOpen.c
index 17e44aa..ec6f0ff 100644
--- a/SystemConfiguration.fproj/SCPOpen.c
+++ b/SystemConfiguration.fproj/SCPOpen.c
@@ -1,5 +1,5 @@
 /*
- * Copyright(c) 2000-2015 Apple Inc. All rights reserved.
+ * Copyright(c) 2000-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -36,26 +36,36 @@
 
 #include 
 #include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include "SCPreferencesInternal.h"
-#include "SCHelper_client.h"
-
-#include "dy_framework.h"
-
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
+#include 
+
+#include "SCPreferencesInternal.h"
+#include "SCD.h"
+#include "SCHelper_client.h"
+#include "dy_framework.h"
 
 
 const AuthorizationRef	kSCPreferencesUseEntitlementAuthorization	= (AuthorizationRef)CFSTR("UseEntitlement");
 
 
+__private_extern__ os_log_t
+__log_SCPreferences()
+{
+	static os_log_t	log	= NULL;
+
+	if (log == NULL) {
+		log = os_log_create("com.apple.SystemConfiguration", "SCPreferences");
+	}
+
+	return log;
+}
+
+
 static __inline__ CFTypeRef
 isA_SCPreferences(CFTypeRef obj)
 {
@@ -159,6 +169,7 @@ static pthread_once_t initialized	= PTHREAD_ONCE_INIT;
 
 static void
 __SCPreferencesInitialize(void) {
+	/* register with CoreFoundation */
 	__kSCPreferencesTypeID = _CFRuntimeRegisterClass(&__SCPreferencesClass);
 	return;
 }
@@ -183,39 +194,10 @@ __SCPreferencesCreatePrivate(CFAllocatorRef	allocator)
 		return NULL;
 	}
 
+	/* initialize non-zero/NULL members */
 	pthread_mutex_init(&prefsPrivate->lock, NULL);
-
-	prefsPrivate->name				= NULL;
-	prefsPrivate->prefsID				= NULL;
-	prefsPrivate->options				= NULL;
-	prefsPrivate->path				= NULL;
-	prefsPrivate->newPath				= NULL;		// new prefs path
-	prefsPrivate->locked				= FALSE;
 	prefsPrivate->lockFD				= -1;
-	prefsPrivate->lockPath				= NULL;
-	prefsPrivate->signature				= NULL;
-	prefsPrivate->session				= NULL;
-	prefsPrivate->sessionNoO_EXLOCK			= NULL;
-	prefsPrivate->sessionRefcnt			= 0;
-	prefsPrivate->sessionKeyLock			= NULL;
-	prefsPrivate->sessionKeyCommit			= NULL;
-	prefsPrivate->sessionKeyApply			= NULL;
-	prefsPrivate->scheduled				= FALSE;
-	prefsPrivate->rls				= NULL;
-	prefsPrivate->rlsFunction			= NULL;
-	prefsPrivate->rlsContext.info			= NULL;
-	prefsPrivate->rlsContext.retain			= NULL;
-	prefsPrivate->rlsContext.release		= NULL;
-	prefsPrivate->rlsContext.copyDescription	= NULL;
-	prefsPrivate->rlList				= NULL;
-	prefsPrivate->dispatchQueue			= NULL;
-	prefsPrivate->prefs				= NULL;
-	prefsPrivate->accessed				= FALSE;
-	prefsPrivate->changed				= FALSE;
 	prefsPrivate->isRoot				= (geteuid() == 0);
-	prefsPrivate->limit_SCNetworkConfiguration	= FALSE;
-	prefsPrivate->authorizationData			= NULL;
-	prefsPrivate->helper_port			= MACH_PORT_NULL;
 
 	return prefsPrivate;
 }
@@ -608,6 +590,9 @@ __SCPreferencesAccess(SCPreferencesRef	prefs)
 		prefsPrivate->changed = TRUE;
 	}
 
+	SC_log(LOG_DEBUG, "SCPreferences() access: %s",
+	       prefsPrivate->newPath ? prefsPrivate->newPath : prefsPrivate->path);
+
 	prefsPrivate->accessed = TRUE;
 	return;
 }
@@ -726,10 +711,10 @@ SCPreferencesCreateWithOptions(CFAllocatorRef	allocator,
 		CFRelease(bundleID);
 
 		if (authorizationDict != NULL) {
-			_SCSerialize((CFPropertyListRef)authorizationDict,
-				     &authorizationData,
-				     NULL,
-				     NULL);
+			(void) _SCSerialize((CFPropertyListRef)authorizationDict,
+					    &authorizationData,
+					    NULL,
+					    NULL);
 			CFRelease(authorizationDict);
 		}
 	}
@@ -795,6 +780,10 @@ prefsNotify(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info)
 	pthread_mutex_unlock(&prefsPrivate->lock);
 
 	if (rlsFunction != NULL) {
+		SC_log(LOG_DEBUG, "exec SCPreferences callout: %s%s%s",
+		       ((notify & kSCPreferencesNotificationCommit) != 0) ? "commit" : "",
+		       ((notify & kSCPreferencesNotificationCommit|kSCPreferencesNotificationApply) != 0) ? ", " : "",
+		       ((notify & kSCPreferencesNotificationApply)  != 0) ? "apply"  : "");
 		(*rlsFunction)(prefs, notify, context_info);
 	}
 
@@ -938,6 +927,7 @@ __SCPreferencesScheduleWithRunLoop(SCPreferencesRef	prefs,
 			if (!ok) {
 				goto done;
 			}
+			assert(prefsPrivate->session != NULL);
 		}
 
 		// add SCDynamicStore "keys"
@@ -1159,6 +1149,9 @@ SCPreferencesSynchronize(SCPreferencesRef prefs)
 		return;
 	}
 
+	SC_log(LOG_DEBUG, "SCPreferences() synchronize: %s",
+	       prefsPrivate->newPath ? prefsPrivate->newPath : prefsPrivate->path);
+
 	if (prefsPrivate->authorizationData != NULL) {
 		__SCPreferencesSynchronize_helper(prefs);
 	}
diff --git a/SystemConfiguration.fproj/SCPPath.c b/SystemConfiguration.fproj/SCPPath.c
index a9489ff..eef1ac2 100644
--- a/SystemConfiguration.fproj/SCPPath.c
+++ b/SystemConfiguration.fproj/SCPPath.c
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2000-2006, 2008, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2006, 2008, 2011, 2012, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -31,9 +31,6 @@
  * - initial revision
  */
 
-#include 
-#include 
-#include 
 #include "SCPreferencesInternal.h"
 
 #define	MAXLINKS	8
diff --git a/SystemConfiguration.fproj/SCPRemove.c b/SystemConfiguration.fproj/SCPRemove.c
index fa2b1b5..76aac0e 100644
--- a/SystemConfiguration.fproj/SCPRemove.c
+++ b/SystemConfiguration.fproj/SCPRemove.c
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2000, 2001, 2004, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2004, 2011, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -31,8 +31,6 @@
  * - initial revision
  */
 
-#include 
-#include 
 #include "SCPreferencesInternal.h"
 
 Boolean
diff --git a/SystemConfiguration.fproj/SCPSet.c b/SystemConfiguration.fproj/SCPSet.c
index ae82d19..d89880c 100644
--- a/SystemConfiguration.fproj/SCPSet.c
+++ b/SystemConfiguration.fproj/SCPSet.c
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2000, 2001, 2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2004, 2016 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -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@
  */
 
@@ -31,8 +31,6 @@
  * - initial revision
  */
 
-#include 
-#include 
 #include "SCPreferencesInternal.h"
 
 Boolean
diff --git a/SystemConfiguration.fproj/SCPUnlock.c b/SystemConfiguration.fproj/SCPUnlock.c
index 76da3a0..8af8040 100644
--- a/SystemConfiguration.fproj/SCPUnlock.c
+++ b/SystemConfiguration.fproj/SCPUnlock.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2001, 2004-2010, 2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2004-2010, 2013, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -31,8 +31,6 @@
  * - initial revision
  */
 
-#include 
-#include 
 #include "SCPreferencesInternal.h"
 #include "SCHelper_client.h"
 
@@ -89,29 +87,14 @@ __SCPreferencesUnlock_helper(SCPreferencesRef prefs)
 static void
 reportDelay(SCPreferencesRef prefs, struct timeval *delay)
 {
-	asl_object_t		m;
 	SCPreferencesPrivateRef	prefsPrivate	= (SCPreferencesPrivateRef)prefs;
-	char			str[256];
-
-	m = asl_new(ASL_TYPE_MSG);
-	asl_set(m, "com.apple.message.domain", "com.apple.SystemConfiguration.SCPreferencesUnlock");
-	(void) _SC_cfstring_to_cstring(prefsPrivate->name, str, sizeof(str), kCFStringEncodingUTF8);
-	asl_set(m, "com.apple.message.signature", str);
-	(void) _SC_cfstring_to_cstring(prefsPrivate->prefsID, str, sizeof(str), kCFStringEncodingUTF8);
-	asl_set(m, "com.apple.message.signature2", str);
-	(void) snprintf(str, sizeof(str),
-			"%d.%3.3d",
-			(int)delay->tv_sec,
-			delay->tv_usec / 1000);
-	asl_set(m, "com.apple.message.value", str);
-	SCLOG(NULL, m, ASL_LEVEL_DEBUG,
-	      CFSTR("SCPreferences(%@:%@) lock held for %d.%3.3d seconds"),
-	      prefsPrivate->name,
-	      prefsPrivate->prefsID,
-	      (int)delay->tv_sec,
-	      delay->tv_usec / 1000);
-	asl_release(m);
 
+	SC_log(LOG_ERR,
+	       "SCPreferences(%@:%@) lock held for %d.%3.3d seconds",
+	       prefsPrivate->name,
+	       prefsPrivate->prefsID,
+	       (int)delay->tv_sec,
+	       delay->tv_usec / 1000);
 	return;
 }
 
@@ -162,6 +145,9 @@ SCPreferencesUnlock(SCPreferencesRef prefs)
 		reportDelay(prefs, &lockElapsed);
 	}
 
+	SC_log(LOG_DEBUG, "SCPreferences() unlock: %s",
+	       prefsPrivate->newPath ? prefsPrivate->newPath : prefsPrivate->path);
+
 	prefsPrivate->locked = FALSE;
 
 	pthread_mutex_unlock(&prefsPrivate->lock);
diff --git a/SystemConfiguration.fproj/SCPreferencesInternal.h b/SystemConfiguration.fproj/SCPreferencesInternal.h
index 608eb9e..22e6c44 100644
--- a/SystemConfiguration.fproj/SCPreferencesInternal.h
+++ b/SystemConfiguration.fproj/SCPreferencesInternal.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2001, 2003-2005, 2007-2011, 2013-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003-2005, 2007-2011, 2013-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -24,14 +24,23 @@
 #ifndef _SCPREFERENCESINTERNAL_H
 #define _SCPREFERENCESINTERNAL_H
 
+#include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
+
+#ifndef	SC_LOG_HANDLE
+#define	SC_LOG_HANDLE	__log_SCPreferences()
+#endif	// SC_LOG_HANDLE
+#include 
+#include 
+#include 
+
 #include 
 #include 
-#include 
 
 
 #define	PREFS_DEFAULT_DIR		CFSTR("/Library/Preferences/SystemConfiguration")
@@ -123,6 +132,9 @@ typedef struct {
 
 __BEGIN_DECLS
 
+os_log_t
+__log_SCPreferences			();
+
 Boolean
 __SCPreferencesCreate_helper		(SCPreferencesRef	prefs);
 
diff --git a/SystemConfiguration.fproj/SCPreferencesKeychainPrivate.c b/SystemConfiguration.fproj/SCPreferencesKeychainPrivate.c
index 36dd87b..5970514 100644
--- a/SystemConfiguration.fproj/SCPreferencesKeychainPrivate.c
+++ b/SystemConfiguration.fproj/SCPreferencesKeychainPrivate.c
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2006, 2007, 2010, 2014 Apple Inc. All rights reserved.
+ * Copyright (c) 2006, 2007, 2010, 2014, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -36,7 +36,6 @@
 #include 
 #include 
 #include 	// for _CFBundleCopyMainBundleExecutableURL
-#include 	// for _SCErrorSet
 #include "dy_framework.h"
 
 #include "SCPreferencesInternal.h"
@@ -192,7 +191,6 @@ _SCSecAccessCreateForExecutables(CFStringRef	label,
 				 CFArrayRef	executableURLs)
 {
 	SecAccessRef			access			= NULL;
-	CFArrayRef			aclList			= NULL;
 	CFIndex				i;
 	CFIndex				n;
 	OSStatus			status;
@@ -240,7 +238,6 @@ _SCSecAccessCreateForExecutables(CFStringRef	label,
 
     done :
 
-	if (aclList != NULL)	CFRelease(aclList);
 	CFRelease(trustedApplications);
 
 	return	access;
diff --git a/SystemConfiguration.fproj/SCPreferencesSetSpecific.h b/SystemConfiguration.fproj/SCPreferencesSetSpecific.h
index 7c87bef..647c808 100644
--- a/SystemConfiguration.fproj/SCPreferencesSetSpecific.h
+++ b/SystemConfiguration.fproj/SCPreferencesSetSpecific.h
@@ -65,7 +65,7 @@ __BEGIN_DECLS
 Boolean
 SCPreferencesSetComputerName		(
 					SCPreferencesRef	prefs,
-					CFStringRef		name,
+					CFStringRef __nullable	name,
 					CFStringEncoding	nameEncoding
 					)			__OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_2_0/*SPI*/);
 
@@ -87,7 +87,7 @@ SCPreferencesSetComputerName		(
 Boolean
 SCPreferencesSetLocalHostName		(
 					SCPreferencesRef	prefs,
-					CFStringRef		name
+					CFStringRef __nullable	name
 					)			__OSX_AVAILABLE_STARTING(__MAC_10_2,__IPHONE_2_0/*SPI*/);
 
 __END_DECLS
diff --git a/SystemConfiguration.fproj/SCPrivate.h b/SystemConfiguration.fproj/SCPrivate.h
index b336bcb..94b2c9c 100644
--- a/SystemConfiguration.fproj/SCPrivate.h
+++ b/SystemConfiguration.fproj/SCPrivate.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -64,11 +64,11 @@
 
 
 /* "server" defines */
-#if	!TARGET_IPHONE_SIMULATOR
+#if	!TARGET_OS_SIMULATOR
 #define _SC_SERVER_PROG			"configd"
-#else	// !TARGET_IPHONE_SIMULATOR
+#else	// !TARGET_OS_SIMULATOR
 #define _SC_SERVER_PROG			"configd_sim"
-#endif	// !TARGET_IPHONE_SIMULATOR
+#endif	// !TARGET_OS_SIMULATOR
 
 
 /* atomic operations */
@@ -79,12 +79,21 @@
 
 
 /* framework path */
-#if !TARGET_OS_WATCH
+#if	!TARGET_OS_WATCH
 #define	SYSTEMCONFIGURATION_FRAMEWORK_PATH	"/System/Library/Frameworks/SystemConfiguration.framework"
 #else
 #define	SYSTEMCONFIGURATION_FRAMEWORK_PATH	"/System/Library/PrivateFrameworks/SystemConfiguration.framework"
 #endif
 
+
+/* get-network-info script path */
+#if	!TARGET_OS_EMBEDDED
+#define SYSTEMCONFIGURATION_GET_NETWORK_INFO_PATH	SYSTEMCONFIGURATION_FRAMEWORK_PATH "/Resources/get-network-info"
+#else
+#define SYSTEMCONFIGURATION_GET_NETWORK_INFO_PATH	SYSTEMCONFIGURATION_FRAMEWORK_PATH "/get-network-info"
+#endif
+
+
 /* framework variables */
 extern int	_sc_debug;	/* non-zero if debugging enabled */
 extern int	_sc_verbose;	/* non-zero if verbose logging enabled */
@@ -308,6 +317,19 @@ CF_RETURNS_RETAINED
 CFDictionaryRef	_SCUnserializeMultiple		(CFDictionaryRef	dict);
 
 
+#pragma mark -
+
+
+/*!
+	@function _SCCreatePropertyListFromResource
+	@discussion Reads a property list referenced by a file URL.
+	@param url The file URL.
+	@result The CFPropertyList content of the URL.
+ */
+CFPropertyListRef
+_SCCreatePropertyListFromResource		(CFURLRef		url);
+
+
 #pragma mark -
 #pragma mark String conversion
 
@@ -390,6 +412,24 @@ void		_SC_sendMachMessage		(mach_port_t		port,
 #pragma mark Logging
 
 
+/*!
+	@function _SC_LOG_DEFAULT
+	@discussion Maps a syslog/asl logging level to an os_log level.
+	@param level The syslog/asl logging level
+	@result The os_log level
+ */
+os_log_t	_SC_LOG_DEFAULT			();
+
+
+/*!
+	@function _SC_syslog_os_log_mapping
+	@discussion Maps a syslog/asl logging level to an os_log level.
+	@param level The syslog/asl logging level
+	@result The os_log level
+ */
+os_log_type_t	_SC_syslog_os_log_mapping	(int			level);
+
+
 /*!
 	@function _SCCopyDescription
 	@discussion Returns a formatted textual description of a CF object.
@@ -488,15 +528,81 @@ void		SCLOG				(asl_object_t		asl,
 
 /*!
 	@function SC_log
-	@discussion Issue a log message.
-	@param level The asl(3) logging priority. Passing the complement of a logging
-		priority (e.g. ~ASL_LEVEL_NOTICE) will result in log message lines
-		NOT being split by a "\n".
+	@discussion Issue an os_log() message.
+
+	Note:	By default, the log messages will be associated with the
+		"com.apple.SystemConfiguration" subsystem.  This behavior
+		can be overwritten by #define'ing SC_LOG_HANDLE with the name
+		of an os_log_t global (or a function that returns an os_log_t)
+		*BEFORE* this header is #include'd. In that case, the noted
+		log handle will be used.
+
+		Also, by #define'ing SC_LOG_OR_PRINT, we will check the "_sc_log"
+		global to see if the messages should [also] be directed to stdout/stderr.
+
+	@param level The syslog(3 logging priority.
 	@param __string The format string
 	@result The specified message will be written to the unified logging system.
  */
-#define SC_log(__level, __string, ...)	\
-	SCLog(TRUE, __level, CFSTR( __string ), ## __VA_ARGS__)
+#ifndef SC_log
+
+#ifndef	SC_LOG_HANDLE
+#define	SC_LOG_HANDLE	_SC_LOG_DEFAULT()	// use [SC] default os_log handle
+
+#ifndef	SC_LOG_OR_PRINT
+#define	USE_SC_LOG_OR_PRINT			// use '_sc_log' to control os_log, printf
+#endif	// !SC_LOG_OR_PRINT
+
+#endif	// !SC_LOG_HANDLE
+
+#ifdef	USE_SC_LOG_OR_PRINT
+
+#define	SC_log(__level, __format, ...)							\
+	do {										\
+		os_log_t	__handle = SC_LOG_HANDLE;				\
+		os_log_type_t	__type   = _SC_syslog_os_log_mapping(__level);		\
+											\
+		if ((_sc_log != 1) || os_log_type_enabled(__handle, __type)) {		\
+			__SC_Log(__level,						\
+				 CFSTR( __format ),					\
+				 __handle,						\
+				 __type,						\
+				 __format,						\
+				 ## __VA_ARGS__);					\
+		}									\
+	} while (0)
+
+#else	// USE_SC_LOG_OR_PRINT
+
+#define	SC_log(__level, __format, ...)							\
+	do {										\
+		os_log_type_t	__type = _SC_syslog_os_log_mapping(__level);		\
+		os_log_with_type(SC_LOG_HANDLE, __type, __format, ## __VA_ARGS__);	\
+	} while (0)
+
+#endif	// USE_SC_LOG_OR_PRINT
+
+#endif	// !SC_log
+
+
+/*!
+	@function __SC_Log
+	@discussion Issue a log message w/os_log(3) or printf(3).
+	@param level A syslog(3) logging priority. If less than 0, log message is multi-line
+	@param format_CF The format string (as a CFString for stdout/stderr)
+	@param log The os_log_t handle (for logging)
+	@param type The os_log_type_t type (for logging)
+	@param format The format string (for logging)
+	@result The specified message will be written to the system message
+		logger.
+ stream.
+ */
+void		__SC_Log			(int		level,
+						 CFStringRef	format_CF,
+						 os_log_t	log,
+						 os_log_type_t	type,
+						 const char	*format,
+						 ...)	CF_FORMAT_FUNCTION(2, 6) __attribute__((format(os_log, 5, 6)));
 
 
 /*!
@@ -515,30 +621,6 @@ void		SCPrint				(Boolean		condition,
 
 
 
-/*!
-	@function SCTrace
-	@discussion Write a debug message with a time stamp.
-	@param stream The output stream for the log message.
-	@param formatString The format string
-	@result The message will be written to the specified stream
-		stream.
- */
-void		SCTrace				(FILE			*stream,
-						 CFStringRef		formatString,
-						 ...)	CF_FORMAT_FUNCTION(2, 3);
-
-/*!
-	@function SC_trace
-	@discussion Issue a debug message / write with a time stamp
-	@param stream The output stream for the log message.
-	@param formatString The format string
-	@result The message will be written to the specified stream
-		stream.
- */
-#define SC_trace(__stream, __string, ...)	\
-	SCTrace(__stream, CFSTR( __string ), ## __VA_ARGS__)
-
-
 /*!
 	@function SCLoggerCreate
 	@discussion Create a reference to logger which stores information like verbose mode or not, loggerID, etc.
@@ -761,37 +843,6 @@ _SC_dos_encoding_and_codepage			(CFStringEncoding	macEncoding,
 						 UInt32			*dosCodepage);
 #endif	// !TARGET_OS_IPHONE
 
-#pragma mark -
-#pragma mark ScheduleWithRunLoop/UnscheduleFromRunLoop
-
-
-/*
- * object / CFRunLoop  management
- */
-void
-_SC_signalRunLoop				(CFTypeRef		obj,
-						 CFRunLoopSourceRef     rls,
-						 CFArrayRef		rlList);
-
-Boolean
-_SC_isScheduled					(CFTypeRef		obj,
-						 CFRunLoopRef		runLoop,
-						 CFStringRef		runLoopMode,
-						 CFMutableArrayRef      rlList);
-
-void
-_SC_schedule					(CFTypeRef		obj,
-						 CFRunLoopRef		runLoop,
-						 CFStringRef		runLoopMode,
-						 CFMutableArrayRef      rlList);
-
-Boolean
-_SC_unschedule					(CFTypeRef		obj,
-						 CFRunLoopRef		runLoop,
-						 CFStringRef		runLoopMode,
-						 CFMutableArrayRef      rlList,
-						 Boolean		all);
-
 #pragma mark -
 #pragma mark Bundle
 
@@ -860,6 +911,9 @@ _SC_isInstallEnvironment			(void);
 CFStringRef
 _SC_hw_model					(Boolean		trim);
 
+void *
+_SC_dlopen					(const char		*framework);
+
 /*
  * debugging
  */
diff --git a/SystemConfiguration.fproj/SCProxies.c b/SystemConfiguration.fproj/SCProxies.c
index 6870719..4c6a60b 100644
--- a/SystemConfiguration.fproj/SCProxies.c
+++ b/SystemConfiguration.fproj/SCProxies.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2004, 2006-2013 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2004, 2006-2013, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -39,9 +39,6 @@
 #include 
 #endif	// !TARGET_OS_SIMULATOR
 
-
-
-
 CFStringRef
 SCDynamicStoreKeyCreateProxies(CFAllocatorRef allocator)
 {
@@ -78,7 +75,8 @@ validate_proxy_content(CFMutableDictionaryRef	proxies,
 			goto disable;		// if not enabled, remove provided key/value
 		}
 
-		if ((enabled != 0) && !isA_CFString(host)) {
+		if ((enabled != 0) &&
+		    (!isA_CFString(host) || (CFStringGetLength(host) == 0))) {
 			goto disable;		// if enabled, not provided (or not valid)
 		}
 	}
@@ -268,7 +266,7 @@ __SCNetworkProxiesCopyNormalized(CFDictionaryRef proxy)
 			CFStringRef	str;
 
 			str = CFArrayGetValueAtIndex(array, i);
-			if (!isA_CFString(str)) {
+			if (!isA_CFString(str) || (CFStringGetLength(str) == 0)) {
 				// if we don't like the array contents
 				n = 0;
 				break;
@@ -369,12 +367,12 @@ normalize_scoped_proxy(const void *key, const void *value, void *context)
 static void
 normalize_services_proxy(const void *key, const void *value, void *context)
 {
-	CFStringRef		serviceID	= (CFStringRef)key;
+	CFNumberRef		serviceIndex	= (CFNumberRef)key;
 	CFDictionaryRef		proxy		= (CFDictionaryRef)value;
 	CFMutableDictionaryRef	newServices	= (CFMutableDictionaryRef)context;
 
 	proxy = __SCNetworkProxiesCopyNormalized(proxy);
-	CFDictionarySetValue(newServices, serviceID, proxy);
+	CFDictionarySetValue(newServices, serviceIndex, proxy);
 	CFRelease(proxy);
 
 	return;
@@ -459,7 +457,6 @@ SCDynamicStoreCopyProxiesWithOptions(SCDynamicStoreRef store, CFDictionaryRef op
 					     &kCFTypeDictionaryValueCallBacks);
 	}
 
-
 	return proxies;
 }
 
@@ -497,7 +494,6 @@ _SCNetworkProxiesCopyMatchingInternal(CFDictionaryRef	globalConfiguration,
 
 		euuid = CFDictionaryGetValue(options, kSCProxiesMatchExecutableUUID);
 		euuid = isA_CFType(euuid, CFUUIDGetTypeID());
-
 		if (euuid != NULL) {
 			CFUUIDBytes uuid_bytes = CFUUIDGetUUIDBytes(euuid);
 			uuid_copy(match_uuid, (const uint8_t *)&uuid_bytes);
@@ -667,11 +663,17 @@ _SCNetworkProxiesCopyMatchingInternal(CFDictionaryRef	globalConfiguration,
     done :
 
 	if (sc_status != kSCStatusOK) {
-		if (proxies != NULL) {
-			CFRelease(proxies);
-			proxies = NULL;
-		}
 		_SCErrorSet(sc_status);
+
+//		Note: if we are returning an error then we must
+//		      return w/proxies==NULL.  At present, there
+//		      is no code (above) that would get here with
+//		      proxies!=NULL so we don't need to take any
+//		      action but future coder's should beware :-)
+//		if (proxies != NULL) {
+//			CFRelease(proxies);
+//			proxies = NULL;
+//		}
 	}
 	if (trimmed != NULL) CFRelease(trimmed);
 
diff --git a/SystemConfiguration.fproj/SCSchemaDefinitions.c b/SystemConfiguration.fproj/SCSchemaDefinitions.c
index af94876..a357970 100644
--- a/SystemConfiguration.fproj/SCSchemaDefinitions.c
+++ b/SystemConfiguration.fproj/SCSchemaDefinitions.c
@@ -74,6 +74,7 @@ const CFStringRef kSCEntNetLinkIssues                              = CFSTR("Link
 const CFStringRef kSCEntNetLinkQuality                             = CFSTR("LinkQuality");
 const CFStringRef kSCEntNetLoopback                                = CFSTR("Loopback");
 const CFStringRef kSCEntNetOnDemand                                = CFSTR("OnDemand");
+const CFStringRef kSCEntNetQoSMarkingPolicy                        = CFSTR("QoSMarkingPolicy");
 const CFStringRef kSCEntNetService                                 = CFSTR("__SERVICE__");
 const CFStringRef kSCEntNetVPN                                     = CFSTR("VPN");
 const CFStringRef kSCPropNetOverridePrimary                        = CFSTR("OverridePrimary");
@@ -96,18 +97,11 @@ const CFStringRef kSCValNetAirPortJoinModeStrongest                = CFSTR("Stro
 const CFStringRef kSCValNetAirPortAuthPasswordEncryptionKeychain   = CFSTR("Keychain");
 
 #if	!TARGET_OS_IPHONE
-const CFStringRef kSCPropNetAppleTalkComputerName                  = CFSTR("ComputerName");
-const CFStringRef kSCPropNetAppleTalkComputerNameEncoding          = CFSTR("ComputerNameEncoding");
 const CFStringRef kSCPropNetAppleTalkConfigMethod                  = CFSTR("ConfigMethod");
 const CFStringRef kSCPropNetAppleTalkDefaultZone                   = CFSTR("DefaultZone");
 const CFStringRef kSCPropNetAppleTalkNetworkID                     = CFSTR("NetworkID");
-const CFStringRef kSCPropNetAppleTalkNetworkRange                  = CFSTR("NetworkRange");
 const CFStringRef kSCPropNetAppleTalkNodeID                        = CFSTR("NodeID");
-const CFStringRef kSCPropNetAppleTalkSeedNetworkRange              = CFSTR("SeedNetworkRange");
-const CFStringRef kSCPropNetAppleTalkSeedZones                     = CFSTR("SeedZones");
 const CFStringRef kSCValNetAppleTalkConfigMethodNode               = CFSTR("Node");
-const CFStringRef kSCValNetAppleTalkConfigMethodRouter             = CFSTR("Router");
-const CFStringRef kSCValNetAppleTalkConfigMethodSeedRouter         = CFSTR("SeedRouter");
 #endif	// !TARGET_OS_IPHONE
 
 
@@ -255,18 +249,6 @@ const CFStringRef kSCPropNetModemSpeed                             = CFSTR("Spee
 const CFStringRef kSCValNetModemDialModeIgnoreDialTone             = CFSTR("IgnoreDialTone");
 const CFStringRef kSCValNetModemDialModeManual                     = CFSTR("Manual");
 const CFStringRef kSCValNetModemDialModeWaitForDialTone            = CFSTR("WaitForDialTone");
-
-#if	!TARGET_OS_IPHONE
-const CFStringRef kSCPropNetNetInfoBindingMethods                  = CFSTR("BindingMethods");
-const CFStringRef kSCPropNetNetInfoServerAddresses                 = CFSTR("ServerAddresses");
-const CFStringRef kSCPropNetNetInfoServerTags                      = CFSTR("ServerTags");
-const CFStringRef kSCPropNetNetInfoBroadcastServerTag              = CFSTR("BroadcastServerTag");
-const CFStringRef kSCValNetNetInfoBindingMethodsBroadcast          = CFSTR("Broadcast");
-const CFStringRef kSCValNetNetInfoBindingMethodsDHCP               = CFSTR("DHCP");
-const CFStringRef kSCValNetNetInfoBindingMethodsManual             = CFSTR("Manual");
-const CFStringRef kSCValNetNetInfoDefaultServerTag                 = CFSTR("network");
-#endif	// !TARGET_OS_IPHONE
-
 const CFStringRef kSCPropNetPPPACSPEnabled                         = CFSTR("ACSPEnabled");
 const CFStringRef kSCPropNetPPPConnectTime                         = CFSTR("ConnectTime");
 const CFStringRef kSCPropNetPPPDeviceLastCause                     = CFSTR("DeviceLastCause");
@@ -381,7 +363,11 @@ const CFStringRef kSCPropNetProxiesScoped                          = CFSTR("__SC
 const CFStringRef kSCPropNetProxiesServices                        = CFSTR("__SERVICES__");
 const CFStringRef kSCPropNetProxiesSupplemental                    = CFSTR("__SUPPLEMENTAL__");
 const CFStringRef kSCPropNetProxiesSupplementalMatchDomain         = CFSTR("__MATCH_DOMAIN__");
+const CFStringRef kSCPropNetQoSMarkingAppleAudioVideoCalls         = CFSTR("QoSMarkingAppleAudioVideoCalls");
+const CFStringRef kSCPropNetQoSMarkingEnabled                      = CFSTR("QoSMarkingEnabled");
+const CFStringRef kSCPropNetQoSMarkingWhitelistedAppIdentifiers    = CFSTR("QoSMarkingWhitelistedAppIdentifiers");
 const CFStringRef kSCPropNetServicePrimaryRank                     = CFSTR("PrimaryRank");
+const CFStringRef kSCPropNetServiceServiceIndex                    = CFSTR("ServiceIndex");
 const CFStringRef kSCPropNetServiceUserDefinedName                 = CFSTR("UserDefinedName");
 const CFStringRef kSCValNetServicePrimaryRankFirst                 = CFSTR("First");
 const CFStringRef kSCValNetServicePrimaryRankLast                  = CFSTR("Last");
diff --git a/SystemConfiguration.fproj/SCSchemaDefinitions.h b/SystemConfiguration.fproj/SCSchemaDefinitions.h
index cf992c3..9f8bd6d 100644
--- a/SystemConfiguration.fproj/SCSchemaDefinitions.h
+++ b/SystemConfiguration.fproj/SCSchemaDefinitions.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -326,10 +326,6 @@
  *
  *   * RESERVED FOR FUTURE USE *
  *
- * kSCEntNetPPTP Entity Keys
- *
- *   * RESERVED FOR FUTURE USE *
- *
  * kSCEntNetL2TP Entity Keys
  *
  *   kSCPropNetL2TPIPSecSharedSecret                    "IPSecSharedSecret"            CFString
@@ -570,13 +566,6 @@ extern const CFStringRef kSCCompAnyRegex                                    __OS
 extern const CFStringRef kSCEntNetAirPort                                   __OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_2_0/*SPI*/);
 #define kSCEntNetAirPort kSCEntNetAirPort
 
-/*!
-  @const kSCEntNetAppleTalk
-  @discussion Value is a CFDictionary
- */
-extern const CFStringRef kSCEntNetAppleTalk                                 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_6,__IPHONE_NA,__IPHONE_NA);
-#define kSCEntNetAppleTalk kSCEntNetAppleTalk
-
 /*!
   @const kSCEntNetDHCP
   @discussion Value is a CFDictionary
@@ -654,13 +643,6 @@ extern const CFStringRef kSCEntNetLink                                      __OS
 extern const CFStringRef kSCEntNetModem                                     __OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_2_0/*SPI*/);
 #define kSCEntNetModem kSCEntNetModem
 
-/*!
-  @const kSCEntNetNetInfo
-  @discussion Value is a CFDictionary
- */
-extern const CFStringRef kSCEntNetNetInfo                                   __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_5,__IPHONE_NA,__IPHONE_NA);
-#define kSCEntNetNetInfo kSCEntNetNetInfo
-
 /*!
   @const kSCEntNetPPP
   @discussion Value is a CFDictionary
@@ -686,7 +668,7 @@ extern const CFStringRef kSCEntNetPPPSerial                                 __OS
   @const kSCEntNetPPTP
   @discussion Value is a CFDictionary
  */
-extern const CFStringRef kSCEntNetPPTP                                      __OSX_AVAILABLE_STARTING(__MAC_10_3,__IPHONE_2_0/*SPI*/);
+extern const CFStringRef kSCEntNetPPTP                                      __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3,__MAC_10_12,__IPHONE_2_0/*SPI*/,__IPHONE_10_0/*SPI*/);
 #define kSCEntNetPPTP kSCEntNetPPTP
 
 /*!
@@ -846,91 +828,6 @@ extern const CFStringRef kSCValNetAirPortJoinModeStrongest                  __OS
 extern const CFStringRef kSCValNetAirPortAuthPasswordEncryptionKeychain     __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3,__MAC_10_9,__IPHONE_2_0/*SPI*/,__IPHONE_FUTURE/*SPI*/);
 #define kSCValNetAirPortAuthPasswordEncryptionKeychain kSCValNetAirPortAuthPasswordEncryptionKeychain
 
-/*!
-  @group kSCEntNetAppleTalk Entity Keys
- */
-
-/*!
-  @const kSCPropNetAppleTalkComputerName
-  @discussion Value is a CFString
- */
-extern const CFStringRef kSCPropNetAppleTalkComputerName                    __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_6,__IPHONE_NA,__IPHONE_NA);
-#define kSCPropNetAppleTalkComputerName kSCPropNetAppleTalkComputerName
-
-/*!
-  @const kSCPropNetAppleTalkComputerNameEncoding
-  @discussion Value is a CFNumber
- */
-extern const CFStringRef kSCPropNetAppleTalkComputerNameEncoding            __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_6,__IPHONE_NA,__IPHONE_NA);
-#define kSCPropNetAppleTalkComputerNameEncoding kSCPropNetAppleTalkComputerNameEncoding
-
-/*!
-  @const kSCPropNetAppleTalkConfigMethod
-  @discussion Value is a CFString
- */
-extern const CFStringRef kSCPropNetAppleTalkConfigMethod                    __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_6,__IPHONE_NA,__IPHONE_NA);
-#define kSCPropNetAppleTalkConfigMethod kSCPropNetAppleTalkConfigMethod
-
-/*!
-  @const kSCPropNetAppleTalkDefaultZone
-  @discussion Value is a CFString
- */
-extern const CFStringRef kSCPropNetAppleTalkDefaultZone                     __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_6,__IPHONE_NA,__IPHONE_NA);
-#define kSCPropNetAppleTalkDefaultZone kSCPropNetAppleTalkDefaultZone
-
-/*!
-  @const kSCPropNetAppleTalkNetworkID
-  @discussion Value is a CFNumber
- */
-extern const CFStringRef kSCPropNetAppleTalkNetworkID                       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_6,__IPHONE_NA,__IPHONE_NA);
-#define kSCPropNetAppleTalkNetworkID kSCPropNetAppleTalkNetworkID
-
-/*!
-  @const kSCPropNetAppleTalkNetworkRange
-  @discussion Value is a CFArray[CFNumber]
- */
-extern const CFStringRef kSCPropNetAppleTalkNetworkRange                    __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_6,__IPHONE_NA,__IPHONE_NA);
-#define kSCPropNetAppleTalkNetworkRange kSCPropNetAppleTalkNetworkRange
-
-/*!
-  @const kSCPropNetAppleTalkNodeID
-  @discussion Value is a CFNumber
- */
-extern const CFStringRef kSCPropNetAppleTalkNodeID                          __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_6,__IPHONE_NA,__IPHONE_NA);
-#define kSCPropNetAppleTalkNodeID kSCPropNetAppleTalkNodeID
-
-/*!
-  @const kSCPropNetAppleTalkSeedNetworkRange
-  @discussion Value is a CFArray[CFNumber]
- */
-extern const CFStringRef kSCPropNetAppleTalkSeedNetworkRange                __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_6,__IPHONE_NA,__IPHONE_NA);
-#define kSCPropNetAppleTalkSeedNetworkRange kSCPropNetAppleTalkSeedNetworkRange
-
-/*!
-  @const kSCPropNetAppleTalkSeedZones
-  @discussion Value is a CFArray[CFString]
- */
-extern const CFStringRef kSCPropNetAppleTalkSeedZones                       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_6,__IPHONE_NA,__IPHONE_NA);
-#define kSCPropNetAppleTalkSeedZones kSCPropNetAppleTalkSeedZones
-
-/*!
-  @const kSCValNetAppleTalkConfigMethodNode
- */
-extern const CFStringRef kSCValNetAppleTalkConfigMethodNode                 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_6,__IPHONE_NA,__IPHONE_NA);
-#define kSCValNetAppleTalkConfigMethodNode kSCValNetAppleTalkConfigMethodNode
-
-/*!
-  @const kSCValNetAppleTalkConfigMethodRouter
- */
-extern const CFStringRef kSCValNetAppleTalkConfigMethodRouter               __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_6,__IPHONE_NA,__IPHONE_NA);
-#define kSCValNetAppleTalkConfigMethodRouter kSCValNetAppleTalkConfigMethodRouter
-
-/*!
-  @const kSCValNetAppleTalkConfigMethodSeedRouter
- */
-extern const CFStringRef kSCValNetAppleTalkConfigMethodSeedRouter           __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_6,__IPHONE_NA,__IPHONE_NA);
-#define kSCValNetAppleTalkConfigMethodSeedRouter kSCValNetAppleTalkConfigMethodSeedRouter
-
 /*!
   @group kSCEntNetDNS Entity Keys
  */
@@ -1118,7 +1015,7 @@ extern const CFStringRef kSCValNetInterfaceSubTypePPPSerial                 __OS
 /*!
   @const kSCValNetInterfaceSubTypePPTP
  */
-extern const CFStringRef kSCValNetInterfaceSubTypePPTP                      __OSX_AVAILABLE_STARTING(__MAC_10_2,__IPHONE_2_0/*SPI*/);
+extern const CFStringRef kSCValNetInterfaceSubTypePPTP                      __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_12,__IPHONE_2_0/*SPI*/,__IPHONE_10_0/*SPI*/);
 #define kSCValNetInterfaceSubTypePPTP kSCValNetInterfaceSubTypePPTP
 
 /*!
@@ -1619,62 +1516,6 @@ extern const CFStringRef kSCValNetModemDialModeManual                       __OS
 extern const CFStringRef kSCValNetModemDialModeWaitForDialTone              __OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_2_0/*SPI*/);
 #define kSCValNetModemDialModeWaitForDialTone kSCValNetModemDialModeWaitForDialTone
 
-/*!
-  @group kSCEntNetNetInfo Entity Keys
- */
-
-/*!
-  @const kSCPropNetNetInfoBindingMethods
-  @discussion Value is a CFString
- */
-extern const CFStringRef kSCPropNetNetInfoBindingMethods                    __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_5,__IPHONE_NA,__IPHONE_NA);
-#define kSCPropNetNetInfoBindingMethods kSCPropNetNetInfoBindingMethods
-
-/*!
-  @const kSCPropNetNetInfoServerAddresses
-  @discussion Value is a CFArray[CFString]
- */
-extern const CFStringRef kSCPropNetNetInfoServerAddresses                   __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_5,__IPHONE_NA,__IPHONE_NA);
-#define kSCPropNetNetInfoServerAddresses kSCPropNetNetInfoServerAddresses
-
-/*!
-  @const kSCPropNetNetInfoServerTags
-  @discussion Value is a CFArray[CFString]
- */
-extern const CFStringRef kSCPropNetNetInfoServerTags                        __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_5,__IPHONE_NA,__IPHONE_NA);
-#define kSCPropNetNetInfoServerTags kSCPropNetNetInfoServerTags
-
-/*!
-  @const kSCPropNetNetInfoBroadcastServerTag
-  @discussion Value is a CFString
- */
-extern const CFStringRef kSCPropNetNetInfoBroadcastServerTag                __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_5,__IPHONE_NA,__IPHONE_NA);
-#define kSCPropNetNetInfoBroadcastServerTag kSCPropNetNetInfoBroadcastServerTag
-
-/*!
-  @const kSCValNetNetInfoBindingMethodsBroadcast
- */
-extern const CFStringRef kSCValNetNetInfoBindingMethodsBroadcast            __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_5,__IPHONE_NA,__IPHONE_NA);
-#define kSCValNetNetInfoBindingMethodsBroadcast kSCValNetNetInfoBindingMethodsBroadcast
-
-/*!
-  @const kSCValNetNetInfoBindingMethodsDHCP
- */
-extern const CFStringRef kSCValNetNetInfoBindingMethodsDHCP                 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_5,__IPHONE_NA,__IPHONE_NA);
-#define kSCValNetNetInfoBindingMethodsDHCP kSCValNetNetInfoBindingMethodsDHCP
-
-/*!
-  @const kSCValNetNetInfoBindingMethodsManual
- */
-extern const CFStringRef kSCValNetNetInfoBindingMethodsManual               __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_5,__IPHONE_NA,__IPHONE_NA);
-#define kSCValNetNetInfoBindingMethodsManual kSCValNetNetInfoBindingMethodsManual
-
-/*!
-  @const kSCValNetNetInfoDefaultServerTag
- */
-extern const CFStringRef kSCValNetNetInfoDefaultServerTag                   __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_5,__IPHONE_NA,__IPHONE_NA);
-#define kSCValNetNetInfoDefaultServerTag kSCValNetNetInfoDefaultServerTag
-
 /*!
   @group kSCEntNetPPP Entity Keys
  */
@@ -2091,10 +1932,6 @@ extern const CFStringRef kSCPropNetPPPLCPTransmitACCM                       __OS
   @group kSCEntNetPPPSerial Entity Keys
  */
 
-/*!
-  @group kSCEntNetPPTP Entity Keys
- */
-
 /*!
   @group kSCEntNetL2TP Entity Keys
  */
diff --git a/SystemConfiguration.fproj/SCSchemaDefinitionsPrivate.h b/SystemConfiguration.fproj/SCSchemaDefinitionsPrivate.h
index 5e08fdd..2454232 100644
--- a/SystemConfiguration.fproj/SCSchemaDefinitionsPrivate.h
+++ b/SystemConfiguration.fproj/SCSchemaDefinitionsPrivate.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -50,6 +50,7 @@
  *   kSCEntNetLinkQuality                               "LinkQuality"                  CFDictionary
  *   kSCEntNetLoopback                                  "Loopback"                     CFDictionary
  *   kSCEntNetOnDemand                                  "OnDemand"                     CFDictionary
+ *   kSCEntNetQoSMarkingPolicy                          "QoSMarkingPolicy"             CFDictionary
  *   kSCEntNetService                                   "__SERVICE__"                  CFDictionary
  *   kSCEntNetVPN                                       "VPN"                          CFDictionary
  *
@@ -177,9 +178,16 @@
  *   kSCPropNetProxiesSupplemental                      "__SUPPLEMENTAL__"             CFArray[CFDictionary]
  *   kSCPropNetProxiesSupplementalMatchDomain           "__MATCH_DOMAIN__"             CFString
  *
+ * kSCEntNetQoSMarkingPolicy Entity Keys
+ *
+ *   kSCPropNetQoSMarkingAppleAudioVideoCalls           "QoSMarkingAppleAudioVideoCalls" CFBoolean
+ *   kSCPropNetQoSMarkingEnabled                        "QoSMarkingEnabled"            CFBoolean
+ *   kSCPropNetQoSMarkingWhitelistedAppIdentifiers      "QoSMarkingWhitelistedAppIdentifiers" CFArray[CFString]
+ *
  * kSCEntNetService Entity Keys
  *
  *   kSCPropNetServicePrimaryRank                       "PrimaryRank"                  CFString
+ *   kSCPropNetServiceServiceIndex                      "ServiceIndex"                 CFNumber
  *   kSCPropNetServiceUserDefinedName                   "UserDefinedName"              CFString
  *
  *   --- kSCPropNetServicePrimaryRank values ---
@@ -415,6 +423,13 @@ extern const CFStringRef kSCEntNetLoopback                                  __OS
 extern const CFStringRef kSCEntNetOnDemand                                  __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_3_0/*SPI*/);
 #define kSCEntNetOnDemand kSCEntNetOnDemand
 
+/*!
+  @const kSCEntNetQoSMarkingPolicy
+  @discussion Value is a CFDictionary
+ */
+extern const CFStringRef kSCEntNetQoSMarkingPolicy                          __OSX_AVAILABLE_STARTING(__MAC_10_12,__IPHONE_10_0/*SPI*/);
+#define kSCEntNetQoSMarkingPolicy kSCEntNetQoSMarkingPolicy
+
 /*!
   @const kSCEntNetService
   @discussion Value is a CFDictionary
@@ -971,6 +986,31 @@ extern const CFStringRef kSCPropNetProxiesSupplemental                      __OS
 extern const CFStringRef kSCPropNetProxiesSupplementalMatchDomain           __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0/*SPI*/);
 #define kSCPropNetProxiesSupplementalMatchDomain kSCPropNetProxiesSupplementalMatchDomain
 
+/*!
+  @group kSCEntNetQoSMarkingPolicy Entity Keys
+ */
+
+/*!
+  @const kSCPropNetQoSMarkingAppleAudioVideoCalls
+  @discussion Value is a CFBoolean
+ */
+extern const CFStringRef kSCPropNetQoSMarkingAppleAudioVideoCalls           __OSX_AVAILABLE_STARTING(__MAC_10_12,__IPHONE_10_0/*SPI*/);
+#define kSCPropNetQoSMarkingAppleAudioVideoCalls kSCPropNetQoSMarkingAppleAudioVideoCalls
+
+/*!
+  @const kSCPropNetQoSMarkingEnabled
+  @discussion Value is a CFBoolean
+ */
+extern const CFStringRef kSCPropNetQoSMarkingEnabled                        __OSX_AVAILABLE_STARTING(__MAC_10_12,__IPHONE_10_0/*SPI*/);
+#define kSCPropNetQoSMarkingEnabled kSCPropNetQoSMarkingEnabled
+
+/*!
+  @const kSCPropNetQoSMarkingWhitelistedAppIdentifiers
+  @discussion Value is a CFArray[CFString]
+ */
+extern const CFStringRef kSCPropNetQoSMarkingWhitelistedAppIdentifiers      __OSX_AVAILABLE_STARTING(__MAC_10_12,__IPHONE_10_0/*SPI*/);
+#define kSCPropNetQoSMarkingWhitelistedAppIdentifiers kSCPropNetQoSMarkingWhitelistedAppIdentifiers
+
 /*!
   @group kSCEntNetService Entity Keys
  */
@@ -982,6 +1022,13 @@ extern const CFStringRef kSCPropNetProxiesSupplementalMatchDomain           __OS
 extern const CFStringRef kSCPropNetServicePrimaryRank                       __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_2_0/*SPI*/);
 #define kSCPropNetServicePrimaryRank kSCPropNetServicePrimaryRank
 
+/*!
+  @const kSCPropNetServiceServiceIndex
+  @discussion Value is a CFNumber
+ */
+extern const CFStringRef kSCPropNetServiceServiceIndex                      __OSX_AVAILABLE_STARTING(__MAC_10_12,__IPHONE_10_0/*SPI*/);
+#define kSCPropNetServiceServiceIndex kSCPropNetServiceServiceIndex
+
 /*!
   @const kSCPropNetServiceUserDefinedName
   @discussion Value is a CFString
diff --git a/SystemConfiguration.fproj/VLANConfiguration.c b/SystemConfiguration.fproj/VLANConfiguration.c
index 8c37733..8acf6a1 100644
--- a/SystemConfiguration.fproj/VLANConfiguration.c
+++ b/SystemConfiguration.fproj/VLANConfiguration.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003-2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2013, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -35,11 +35,8 @@
 #include 
 #include 
 
-#include 
 #include "SCNetworkConfigurationInternal.h"
 #include "SCPreferencesInternal.h"
-#include 
-#include 
 
 #include 
 #include 
@@ -222,11 +219,9 @@ SCVLANInterfaceCopyAll(SCPreferencesRef prefs)
 	SCPreferencesRef	ni_prefs;
 	CFStringRef		path;
 
-	if ((prefs == NULL) ||
-	    (__SCPreferencesUsingDefaultPrefs(prefs) == TRUE)) {
+	if (__SCPreferencesUsingDefaultPrefs(prefs)) {
 		ni_prefs = NULL;
-	}
-	else {
+	} else {
 		ni_prefs = __SCPreferencesCreateNIPrefsFromPrefs(prefs);
 	}
 	context.vlans = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
@@ -284,7 +279,9 @@ CFArrayRef
 SCVLANInterfaceCopyAvailablePhysicalInterfaces()
 {
 	CFMutableArrayRef	available;
+#if	!TARGET_OS_IPHONE
 	CFArrayRef		bond_interfaces		= NULL;
+#endif	// !TARGET_OS_IPHONE
 	CFArrayRef		bridge_interfaces	= NULL;
 	CFMutableSetRef		excluded		= NULL;
 	CFArrayRef		interfaces;
@@ -320,11 +317,13 @@ SCVLANInterfaceCopyAvailablePhysicalInterfaces()
 		CFRelease(interfaces);
 	}
 
+#if	!TARGET_OS_IPHONE
 	// add bond interfaces
 	if (bond_interfaces != NULL) {
 		addAvailableInterfaces(available, bond_interfaces, NULL);
 		CFRelease(bond_interfaces);
 	}
+#endif	// !TARGET_OS_IPHONE
 
 	// add bridge interfaces
 	if (bridge_interfaces != NULL) {
@@ -451,10 +450,9 @@ SCVLANInterfaceCreate(SCPreferencesRef prefs, SCNetworkInterfaceRef physical, CF
 
 	interfacePrivate = (SCNetworkInterfacePrivateRef)physical;
 	if (!interfacePrivate->supportsVLAN) {
-		if (__SCPreferencesUsingDefaultPrefs(prefs) == FALSE) {
+		if (!__SCPreferencesUsingDefaultPrefs(prefs)) {
 			interfacePrivate->supportsVLAN = TRUE;
-		}
-		else {
+		} else {
 			_SCErrorSet(kSCStatusInvalidArgument);
 			return NULL;
 		}
@@ -631,10 +629,9 @@ SCVLANInterfaceSetPhysicalInterfaceAndTag(SCVLANInterfaceRef vlan, SCNetworkInte
 	prefs = interfacePrivate->prefs;
 
 	if (!interfacePrivate->supportsVLAN) {
-		if (__SCPreferencesUsingDefaultPrefs(prefs) == FALSE) {
+		if (!__SCPreferencesUsingDefaultPrefs(prefs)) {
 			interfacePrivate->supportsVLAN = TRUE;
-		}
-		else {
+		} else {
 			_SCErrorSet(kSCStatusInvalidArgument);
 			return FALSE;
 		}
diff --git a/SystemConfiguration.fproj/VPNAppLayer.c b/SystemConfiguration.fproj/VPNAppLayer.c
index 991a54e..1462f70 100644
--- a/SystemConfiguration.fproj/VPNAppLayer.c
+++ b/SystemConfiguration.fproj/VPNAppLayer.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 Apple Inc.
+ * Copyright (c) 2012-2016 Apple Inc.
  * All rights reserved.
  */
 
diff --git a/SystemConfiguration.fproj/VPNConfiguration.c b/SystemConfiguration.fproj/VPNConfiguration.c
index d1a8d1a..3cbf047 100644
--- a/SystemConfiguration.fproj/VPNConfiguration.c
+++ b/SystemConfiguration.fproj/VPNConfiguration.c
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2009-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2009-2016 Apple Inc. All rights reserved.
  */
 
diff --git a/SystemConfiguration.fproj/VPNConfiguration.h b/SystemConfiguration.fproj/VPNConfiguration.h
index 31255b2..e1b450e 100644
--- a/SystemConfiguration.fproj/VPNConfiguration.h
+++ b/SystemConfiguration.fproj/VPNConfiguration.h
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2009-2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (c) 2009-2011, 2013-2015 Apple Inc. All rights reserved.
  */
 
diff --git a/SystemConfiguration.fproj/VPNPrivate.c b/SystemConfiguration.fproj/VPNPrivate.c
index bb973ec..ca26b2b 100644
--- a/SystemConfiguration.fproj/VPNPrivate.c
+++ b/SystemConfiguration.fproj/VPNPrivate.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2014 Apple Inc. All rights reserved.
+ * Copyright (c) 2009-2016 Apple Inc. All rights reserved.
  */
 
 
diff --git a/SystemConfiguration.fproj/VPNService.c b/SystemConfiguration.fproj/VPNService.c
index d5091c9..29f0f5e 100644
--- a/SystemConfiguration.fproj/VPNService.c
+++ b/SystemConfiguration.fproj/VPNService.c
@@ -1,9 +1,8 @@
 /*
- * Copyright (c) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (c) 2012, 2013, 2016 Apple Inc. All rights reserved.
  */
 
-#include 
-#include 
+#include "SCNetworkConfigurationInternal.h"
 #include "dy_framework.h"
 
 static CFStringRef g_apple_app_prefix = CFSTR("com.apple.");
diff --git a/SystemConfiguration.fproj/com.apple.SystemConfiguration.plist b/SystemConfiguration.fproj/com.apple.SystemConfiguration.plist
new file mode 100644
index 0000000..7ba6945
--- /dev/null
+++ b/SystemConfiguration.fproj/com.apple.SystemConfiguration.plist
@@ -0,0 +1,148 @@
+
+
+
+
+	DEFAULT-OPTIONS
+	
+		Default-Privacy-Setting
+		Public
+		Level
+		
+			Enable
+			Inherit
+			Persist
+			Inherit
+		
+	
+	SCDynamicStore
+	
+		Level
+		
+			Enable
+			Inherit
+			Persist
+			Inherit
+		
+	
+	SCNetworkConfiguration
+	
+		Level
+		
+			Enable
+			Inherit
+			Persist
+			Inherit
+		
+	
+	SCNetworkConnection
+	
+		Level
+		
+			Enable
+			Inherit
+			Persist
+			Inherit
+		
+	
+	SCNetworkReachability
+	
+		Level
+		
+			Enable
+			Inherit
+			Persist
+			Inherit
+		
+	
+	SCPreferences
+	
+		Level
+		
+			Enable
+			Inherit
+			Persist
+			Inherit
+		
+	
+	InterfaceNamer
+	
+		Level
+		
+			Enable
+			Inherit
+			Persist
+			Inherit
+		
+	
+	IPMonitor
+	
+		Level
+		
+			Enable
+			Inherit
+			Persist
+			Inherit
+		
+	
+	KernelEventMonitor
+	
+		Level
+		
+			Enable
+			Inherit
+			Persist
+			Inherit
+		
+	
+	LinkConfiguration
+	
+		Level
+		
+			Enable
+			Inherit
+			Persist
+			Inherit
+		
+	
+	PreferencesMonitor
+	
+		Level
+		
+			Enable
+			Inherit
+			Persist
+			Inherit
+		
+	
+	QoSMarking
+	
+		Level
+		
+			Enable
+			Inherit
+			Persist
+			Inherit
+		
+	
+	SimulatorSupport
+	
+		Level
+		
+			Enable
+			Inherit
+			Persist
+			Inherit
+		
+	
+	SCMonitor
+	
+		Level
+		
+			Enable
+			Inherit
+			Persist
+			Inherit
+		
+	
+
+
diff --git a/SystemConfiguration.fproj/config_types.h b/SystemConfiguration.fproj/config_types.h
index fb93019..2979730 100644
--- a/SystemConfiguration.fproj/config_types.h
+++ b/SystemConfiguration.fproj/config_types.h
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2000, 2001, 2003, 2005, 2007, 2013 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003, 2005, 2007, 2013, 2015 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@
  */
 
@@ -41,12 +41,12 @@
 /*
  * Mach server port name
  */
-#if	!TARGET_IPHONE_SIMULATOR
+#if	!TARGET_OS_SIMULATOR
 #define SCD_SERVER	"com.apple.SystemConfiguration.configd"
-#else	// !TARGET_IPHONE_SIMULATOR
+#else	// !TARGET_OS_SIMULATOR
 #define SCD_SERVER_HOST	"com.apple.SystemConfiguration.configd"
 #define SCD_SERVER	"com.apple.SystemConfiguration.configd_sim"
-#endif	// !TARGET_IPHONE_SIMULATOR
+#endif	// !TARGET_OS_SIMULATOR
 
 /*
  * Input arguments: serialized key's, list delimiters, ...
diff --git a/SystemConfiguration.fproj/dy_framework.c b/SystemConfiguration.fproj/dy_framework.c
index 9ec21fd..47863d6 100644
--- a/SystemConfiguration.fproj/dy_framework.c
+++ b/SystemConfiguration.fproj/dy_framework.c
@@ -33,32 +33,60 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include "dy_framework.h"
 
 
-#pragma mark -
-#pragma mark IOKit.framework APIs
+void *
+_SC_dlopen(const char *framework)
+{
+	void			*image;
+	static dispatch_once_t	once;
+	static const char	*suffix	= NULL;
 
-static void *
-__loadIOKit(void) {
-	static void *image = NULL;
-	if (NULL == image) {
-		const char	*framework		= "/System/Library/Frameworks/IOKit.framework/IOKit";
+	dispatch_once(&once, ^{
+		if (!dyld_process_is_restricted()) {
+			suffix = getenv("DYLD_IMAGE_SUFFIX");
+			if ((suffix != NULL) &&
+			    ((strlen(suffix) < 2) || (suffix[0] != '_'))) {
+				// if too short or no leading "_"
+				suffix = NULL;
+			}
+		}
+	});
+
+	if (suffix != NULL) {
 		struct stat	statbuf;
-		const char	*suffix			= getenv("DYLD_IMAGE_SUFFIX");
 		char		path[MAXPATHLEN];
 
 		strlcpy(path, framework, sizeof(path));
-		if (suffix) strlcat(path, suffix, sizeof(path));
+		strlcat(path, suffix, sizeof(path));
 		if (0 <= stat(path, &statbuf)) {
 			image = dlopen(path, RTLD_LAZY | RTLD_LOCAL);
-		} else {
-			image = dlopen(framework, RTLD_LAZY | RTLD_LOCAL);
+			return image;
 		}
 	}
-	return (void *)image;
+
+	image = dlopen(framework, RTLD_LAZY | RTLD_LOCAL);
+	return image;
+}
+
+
+#pragma mark -
+#pragma mark IOKit.framework APIs
+
+static void *
+__loadIOKit(void) {
+	static void		*image	= NULL;
+	static dispatch_once_t	once;
+
+	dispatch_once(&once, ^{
+		image = _SC_dlopen("/System/Library/Frameworks/IOKit.framework/IOKit");
+	});
+
+	return image;
 }
 
 
@@ -385,22 +413,14 @@ _IOServiceMatching(const char *name)
 
 static void *
 __loadSecurity(void) {
-	static void *image = NULL;
-	if (NULL == image) {
-		const char	*framework		= "/System/Library/Frameworks/Security.framework/Security";
-		struct stat	statbuf;
-		const char	*suffix			= getenv("DYLD_IMAGE_SUFFIX");
-		char		path[MAXPATHLEN];
+	static void		*image	= NULL;
+	static dispatch_once_t	once;
 
-		strlcpy(path, framework, sizeof(path));
-		if (suffix) strlcat(path, suffix, sizeof(path));
-		if (0 <= stat(path, &statbuf)) {
-			image = dlopen(path, RTLD_LAZY | RTLD_LOCAL);
-		} else {
-			image = dlopen(framework, RTLD_LAZY | RTLD_LOCAL);
-		}
-	}
-	return (void *)image;
+	dispatch_once(&once, ^{
+		image = _SC_dlopen("/System/Library/Frameworks/Security.framework/Security");
+	});
+
+	return image;
 }
 
 #define	SECURITY_FRAMEWORK_EXTERN(t, s)				\
diff --git a/SystemConfiguration.fproj/genSCPreferences.c b/SystemConfiguration.fproj/genSCPreferences.c
index bf70d86..dfe409a 100644
--- a/SystemConfiguration.fproj/genSCPreferences.c
+++ b/SystemConfiguration.fproj/genSCPreferences.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -62,7 +62,7 @@
 
 char copyright_string[] =
 "/*\n"
-" * Copyright (c) 2000-2015 Apple Inc. All rights reserved.\n"
+" * Copyright (c) 2000-2016 Apple Inc. All rights reserved.\n"
 " *\n"
 " * @APPLE_LICENSE_HEADER_START@\n"
 " *\n"
@@ -95,11 +95,8 @@ typedef enum {
 	SC_10_3,
 	SC_10_1_10_4,	// deprecated in 10.4
 	SC_10_4,
-	SC_10_1_10_5,	// deprecated in 10.5
 	SC_10_5,
 	SC_10_5_10_7,	// deprecated in 10.7
-	SC_10_1_10_6,	// deprecated in 10.6
-	SC_10_2_10_6,	// deprecated in 10.6
 	SC_10_1_10_9,	// deprecated in 10.9
 	SC_10_2_10_9,	// deprecated in 10.9
 	SC_10_3_10_9,	// deprecated in 10.9
@@ -110,6 +107,8 @@ typedef enum {
 	COMMENT_PRIVATE,
 	GROUP_PRIVATE,
 	SC_10_5_PRIVATE,
+	SC_10_2_10_12_IPHONE_2_0_10_0,  // deprecated in OSX 10.12, iOS 10.0
+	SC_10_3_10_12_IPHONE_2_0_10_0,	// deprecated in OSX 10.12, iOS 10.0
 	SC_10_6_IPHONE_2_0_PRIVATE,
 	SC_10_6_IPHONE_3_0_PRIVATE,
 	SC_10_7_IPHONE_4_0_PRIVATE,
@@ -120,9 +119,13 @@ typedef enum {
 	SC_10_10_IPHONE_7_0_PRIVATE,
 	SC_10_10_IPHONE_8_0_PRIVATE,
 	SC_10_11_IPHONE_9_0_PRIVATE,
+	SC_10_12_IPHONE_10_0_PRIVATE,
 	SC_IPHONE_2_0_PRIVATE,
 	COMMENT_DEPRECATED,
 	GROUP_DEPRECATED,
+	COMMENT_DEPRECATED_NO_HEADER,
+	GROUP_DEPRECATED_NO_HEADER,
+	DEPRECATED_NO_HEADER,
 	END
 } controlType;
 
@@ -160,8 +163,6 @@ typedef enum {
 #define CFNUMBER_BOOL		"CFNumber (0 or 1)"
 #define CFSTRING		"CFString"
 
-#define APP			"App"
-#define ARP			"ARP"
 #define ACCESSPOINTNAME		"AccessPointName"
 #define ACCOUNT			"Account"
 #define ACSP			"ACSP"			// Apple Client Server Protocol
@@ -181,7 +182,11 @@ typedef enum {
 #define ALTERNATE		"Alternate"
 #define ALWAYS			"Always"
 #define ANYREGEX		"AnyRegex"
+#define APP			"App"
+#define APPLE			"Apple"
 #define APPLETALK		"AppleTalk"
+#define ARP			"ARP"
+#define AUDIOVIDEOCALLS		"AudioVideoCalls"
 #define AUTH			"Auth"
 #define AUTHENTICATIONMETHOD	"AuthenticationMethod"
 #define AUTOCONFIG		"AutoConfig"
@@ -190,19 +195,19 @@ typedef enum {
 #define AV			"AV"
 #define BEFORE			"Before"
 #define BINDINGMETHODS		"BindingMethods"
-#define	BOND			"Bond"
+#define BOND			"Bond"
 #define BOOTP			"BOOTP"
-#define	BRIDGE			"Bridge"
+#define BRIDGE			"Bridge"
 #define BROADCAST		"Broadcast"
 #define BYPASS			"Bypass"
 #define CALLWAITINGAUDIBLEALERT	"CallWaitingAudibleAlert"
-#define CAPABILITY		"Capability"
 #define CAPABILITIES		"Capabilities"
+#define CAPABILITY		"Capability"
 #define CAUSE			"Cause"
 #define CCP			"CCP"
-#define CHAP			"CHAP"
 #define CELLULAR		"Cellular"
 #define CERTIFICATE		"Certificate"
+#define CHAP			"CHAP"
 #define COMM			"Comm"
 #define COMPATIBLE		"Compatible"
 #define COMPRESSIONACFIELD	"CompressionACField"
@@ -270,7 +275,7 @@ typedef enum {
 #define EXTERNAL		"External"
 #define FAILOVER		"Failover"
 #define FAILURE			"Failure"
-#define	FALLBACK		"FallBack"
+#define FALLBACK		"FallBack"
 #define FILE			"File"
 #define FIREWIRE		"FireWire"
 #define FIRST			"First"
@@ -289,6 +294,7 @@ typedef enum {
 #define HTTPS			"HTTPS"
 #define HYBRID			"Hybrid"
 #define IDENTIFIER		"Identifier"
+#define IDENTIFIERS		"Identifiers"
 #define IDLEREMINDER		"IdleReminder"
 #define IDLEREMINDERTIMER	"IdleReminderTimer"
 #define IFNEEDED		"IfNeeded"
@@ -297,16 +303,16 @@ typedef enum {
 #define IGNORELINKSTATUS	"IgnoreLinkStatus"
 #define INACTIVE		"Inactive"
 #define INCLUDED		"Included"
-#define	INFO			"Info"
+#define INFO			"Info"
 #define INFORM			"INFORM"
 #define INTERFACE		"Interface"
 #define INTERFACENAME		"InterfaceName"
 #define INTERFACES		"Interfaces"
 #define IP			"IP"
 #define IPCP			"IPCP"
+#define IPSEC			"IPSec"
 #define IPV4			"IPv4"
 #define IPV6			"IPv6"
-#define IPSEC			"IPSec"
 #define JAVASCRIPT		"JavaScript"
 #define JOIN			"Join"
 #define JUMBO_MTU		"JUMBO_MTU"
@@ -332,12 +338,12 @@ typedef enum {
 #define MATCH			"Match"
 #define MEDIA			"Media"
 #define MIXED			"Mixed"
-#define MODEL			"Model"
 #define MODE			"Mode"
+#define MODEL			"Model"
 #define MODEM			"Modem"
 #define MODULEID		"ModuleID"
-#define MPPE40			"MPPE40"
 #define MPPE128			"MPPE128"
+#define MPPE40			"MPPE40"
 #define MRU			"MRU"
 #define MSCHAP1			"MSCHAP1"
 #define MSCHAP2			"MSCHAP2"
@@ -368,8 +374,9 @@ typedef enum {
 #define PERSONALITY		"Personality"
 #define PLUGIN			"Plugin"
 #define PLUGINS			"Plugins"
-#define POWER			"Power"
+#define POLICY			"Policy"
 #define PORT			"Port"
+#define POWER			"Power"
 #define PPP			"PPP"
 #define PPPOE			"PPPoE"
 #define PPPSERIAL		"PPPSerial"
@@ -387,11 +394,12 @@ typedef enum {
 #define PROXIES			"Proxies"
 #define PROXY			"Proxy"
 #define PULSEDIAL		"PulseDial"
+#define QOSMARKING		"QoSMarking"
 #define RANKED			"Ranked"
 #define RECEIVEACCM		"ReceiveACCM"
 #define RECENT			"Recent"
-#define REDIALCOUNT		"RedialCount"
 #define REDIAL			"Redial"
+#define REDIALCOUNT		"RedialCount"
 #define REDIALINTERVAL		"RedialInterval"
 #define REGION			"Region"
 #define RELAY			"Relay"
@@ -406,8 +414,8 @@ typedef enum {
 #define ROOTSEPARATOR		"RootSeparator"
 #define ROUTE			"Route"
 #define ROUTER			"Router"
-#define ROUTES			"Routes"
 #define ROUTERADVERTISEMENT	"RouterAdvertisement"
+#define ROUTES			"Routes"
 #define RTSP			"RTSP"
 #define RULE			"Rule"
 #define RULES			"Rules"
@@ -423,13 +431,14 @@ typedef enum {
 #define SERVER			"Server"
 #define SERVERS			"Servers"
 #define SERVICE			"Service"
-#define SERVICES		"Services"
 #define SERVICEID		"ServiceID"
 #define SERVICEIDS		"ServiceIDs"
+#define SERVICEINDEX		"ServiceIndex"
+#define SERVICES		"Services"
 #define SESSIONTIMER		"SessionTimer"
 #define SETS			"Sets"
 #define SETUP			"Setup"
-#define	SHAREDSECRET		"SharedSecret"
+#define SHAREDSECRET		"SharedSecret"
 #define SIGNING			"Signing"
 #define SMB			"SMB"
 #define SOCKS			"SOCKS"
@@ -466,18 +475,19 @@ typedef enum {
 #define UID			"UID"
 #define UPDATED			"Updated"
 #define URLSTRING		"URLString"
-#define USERDEFINEDNAME		"UserDefinedName"
 #define USE			"Use"
+#define USERDEFINEDNAME		"UserDefinedName"
 #define USERS			"Users"
 #define UUID			"UUID"
 #define VENDOR			"Vendor"
 #define VERBOSELOGGING		"VerboseLogging"
 #define VIRTUALNETWORKINTERFACES	"VirtualNetworkInterfaces"
-#define	VLAN			"VLAN"
+#define VLAN			"VLAN"
 #define VLAN_HWTAGGING		"VLAN_HWTAGGING"
 #define VLAN_MTU		"VLAN_MTU"
-#define	VPN			"VPN"
+#define VPN			"VPN"
 #define WAITFORDIALTONE		"WaitForDialTone"
+#define WHITELISTED		"Whitelisted"
 #define WIFI			"WiFi"
 #define WINS			"WINS"
 #define WORKGROUP		"Workgroup"
@@ -547,7 +557,7 @@ static schemaDefinition names[] = {
 
     { SC_10_1, NETENT, AIRPORT, NULL, CFDICTIONARY },
     { DEFINE, "#if", "!TARGET_OS_IPHONE", NULL, NULL },
-    { SC_10_1_10_6, NETENT, APPLETALK, NULL, CFDICTIONARY },
+    { DEPRECATED_NO_HEADER, NETENT, APPLETALK, NULL, CFDICTIONARY },
     { DEFINE, "#endif", "// !TARGET_OS_IPHONE", NULL, NULL },
     { SC_10_1, NETENT, DHCP, NULL, CFDICTIONARY },
     { SC_10_1, NETENT, DNS, NULL, CFDICTIONARY },
@@ -561,12 +571,12 @@ static schemaDefinition names[] = {
     { SC_10_1, NETENT, LINK, NULL, CFDICTIONARY },
     { SC_10_1, NETENT, MODEM, NULL, CFDICTIONARY },
     { DEFINE, "#if", "!TARGET_OS_IPHONE", NULL, NULL },
-    { SC_10_1_10_5, NETENT, NETINFO, NULL, CFDICTIONARY },
+    { DEPRECATED_NO_HEADER, NETENT, NETINFO, NULL, CFDICTIONARY },
     { DEFINE, "#endif", "// !TARGET_OS_IPHONE", NULL, NULL },
     { SC_10_1, NETENT, PPP, NULL, CFDICTIONARY },
     { SC_10_1, NETENT, PPPOE, NULL, CFDICTIONARY },
     { SC_10_3, NETENT, PPPSERIAL, NULL, CFDICTIONARY },
-    { SC_10_3, NETENT, PPTP, NULL, CFDICTIONARY },
+    { SC_10_3_10_12_IPHONE_2_0_10_0, NETENT, PPTP, NULL, CFDICTIONARY },
     { SC_10_1, NETENT, PROXIES, NULL, CFDICTIONARY },
     { DEFINE, "#if", "!TARGET_OS_IPHONE", NULL, NULL },
     { SC_10_5, NETENT, SMB, NULL, CFDICTIONARY },
@@ -586,6 +596,7 @@ static schemaDefinition names[] = {
     { SC_10_7_IPHONE_5_0_PRIVATE, NETENT, LINKQUALITY, NULL, CFDICTIONARY},
     { SC_10_7_IPHONE_4_0_PRIVATE, NETENT, LOOPBACK, NULL, CFDICTIONARY },
     { SC_10_6_IPHONE_3_0_PRIVATE, NETENT, ONDEMAND, NULL, CFDICTIONARY },
+    { SC_10_12_IPHONE_10_0_PRIVATE, NETENT, QOSMARKING POLICY, NULL, CFDICTIONARY },
     { SC_10_6_IPHONE_2_0_PRIVATE, NETENT, SERVICE, "__SERVICE__", CFDICTIONARY },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETENT, VPN, NULL, CFDICTIONARY },
     { COMMENT_PRIVATE, "", NULL, NULL, NULL },
@@ -628,25 +639,25 @@ static schemaDefinition names[] = {
     { SC_10_3_10_9, NETVAL AIRPORT AUTH PASSWORD ENCRYPTION, KEYCHAIN, NULL, NULL },
     { COMMENT_DEPRECATED, "", NULL, NULL, NULL },
 
-  { GROUP_DEPRECATED, NETPROP APPLETALK, KEY_PREFIX NETENT APPLETALK " Entity Keys", NULL, NULL },
+  { GROUP_DEPRECATED_NO_HEADER, NETPROP APPLETALK, KEY_PREFIX NETENT APPLETALK " Entity Keys", NULL, NULL },
 
     { DEFINE, "#if", "!TARGET_OS_IPHONE", NULL, NULL },
-    { SC_10_1_10_6, NETPROP APPLETALK, COMPUTERNAME, NULL, CFSTRING },
-    { SC_10_1_10_6, NETPROP APPLETALK, COMPUTERNAME ENCODING, NULL, CFNUMBER },
-    { SC_10_1_10_6, NETPROP APPLETALK, CONFIGMETHOD, NULL, CFSTRING },
-    { SC_10_1_10_6, NETPROP APPLETALK, DEFAULTZONE, NULL, CFSTRING },
-    { SC_10_1_10_6, NETPROP APPLETALK, NETWORKID, NULL, CFNUMBER },
-    { SC_10_2_10_6, NETPROP APPLETALK, NETWORKRANGE, NULL, CFARRAY_CFNUMBER },
-    { SC_10_1_10_6, NETPROP APPLETALK, NODEID, NULL, CFNUMBER },
-    { SC_10_1_10_6, NETPROP APPLETALK, SEEDNETWORKRANGE, NULL, CFARRAY_CFNUMBER },
-    { SC_10_1_10_6, NETPROP APPLETALK, SEEDZONES, NULL, CFARRAY_CFSTRING },
-    { COMMENT_DEPRECATED, "", NULL, NULL, NULL },
-    { COMMENT_DEPRECATED, "--- " KEY_PREFIX NETPROP APPLETALK CONFIGMETHOD " values ---", NULL, NULL, NULL },
-    { SC_10_1_10_6, NETVAL APPLETALK CONFIGMETHOD, NODE, NULL, NULL },
-    { SC_10_1_10_6, NETVAL APPLETALK CONFIGMETHOD, ROUTER, NULL, NULL },
-    { SC_10_1_10_6, NETVAL APPLETALK CONFIGMETHOD, SEEDROUTER, NULL, NULL },
+//  { DEPRECATED_NO_HEADER, NETPROP APPLETALK, COMPUTERNAME, NULL, CFSTRING },
+//  { DEPRECATED_NO_HEADER, NETPROP APPLETALK, COMPUTERNAME ENCODING, NULL, CFNUMBER },
+    { DEPRECATED_NO_HEADER, NETPROP APPLETALK, CONFIGMETHOD, NULL, CFSTRING },
+    { DEPRECATED_NO_HEADER, NETPROP APPLETALK, DEFAULTZONE, NULL, CFSTRING },
+    { DEPRECATED_NO_HEADER, NETPROP APPLETALK, NETWORKID, NULL, CFNUMBER },
+//  { DEPRECATED_NO_HEADER, NETPROP APPLETALK, NETWORKRANGE, NULL, CFARRAY_CFNUMBER },
+    { DEPRECATED_NO_HEADER, NETPROP APPLETALK, NODEID, NULL, CFNUMBER },
+//  { DEPRECATED_NO_HEADER, NETPROP APPLETALK, SEEDNETWORKRANGE, NULL, CFARRAY_CFNUMBER },
+//  { DEPRECATED_NO_HEADER, NETPROP APPLETALK, SEEDZONES, NULL, CFARRAY_CFSTRING },
+    { COMMENT_DEPRECATED_NO_HEADER, "", NULL, NULL, NULL },
+    { COMMENT_DEPRECATED_NO_HEADER, "--- " KEY_PREFIX NETPROP APPLETALK CONFIGMETHOD " values ---", NULL, NULL, NULL },
+    { DEPRECATED_NO_HEADER, NETVAL APPLETALK CONFIGMETHOD, NODE, NULL, NULL },
+//  { DEPRECATED_NO_HEADER, NETVAL APPLETALK CONFIGMETHOD, ROUTER, NULL, NULL },
+//  { DEPRECATED_NO_HEADER, NETVAL APPLETALK CONFIGMETHOD, SEEDROUTER, NULL, NULL },
     { DEFINE, "#endif", "// !TARGET_OS_IPHONE", NULL, NULL },
-    { COMMENT_DEPRECATED, "", NULL, NULL, NULL },
+    { COMMENT_DEPRECATED_NO_HEADER, "", NULL, NULL, NULL },
 
 
   { GROUP, NETPROP DNS, KEY_PREFIX NETENT DNS " Entity Keys", NULL, NULL },
@@ -666,8 +677,8 @@ static schemaDefinition names[] = {
   { GROUP_PRIVATE, NETPROP DNS, KEY_PREFIX NETENT DNS " Entity Keys", NULL, NULL },
 
     { SC_10_11_IPHONE_9_0_PRIVATE, NETPROP DNS, CONFIRMED SERVICEID, NULL, CFSTRING },
-	{ SC_10_9_IPHONE_7_0_PRIVATE, NETPROP DNS, SERVICE IDENTIFIER, NULL, CFNUMBER },
-	{ SC_10_9_IPHONE_7_0_PRIVATE, NETPROP DNS, SUPPLEMENTAL MATCH DOMAINS NO SEARCH, NULL, CFNUMBER_BOOL},
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP DNS, SERVICE IDENTIFIER, NULL, CFNUMBER },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP DNS, SUPPLEMENTAL MATCH DOMAINS NO SEARCH, NULL, CFNUMBER_BOOL},
     { COMMENT_PRIVATE, "", NULL, NULL, NULL },
 
   { GROUP, NETPROP ETHERNET, KEY_PREFIX NETENT ETHERNET " (Hardware) Entity Keys", NULL, NULL },
@@ -714,7 +725,7 @@ static schemaDefinition names[] = {
     { COMMENT, "--- " KEY_PREFIX NETPROP SERVICE SUBTYPE " values (for " PPP ") ---", NULL, NULL, NULL },
     { SC_10_1, NETVAL INTERFACE SUBTYPE, PPPOE, NULL, NULL },
     { SC_10_1, NETVAL INTERFACE SUBTYPE, PPPSERIAL, NULL, NULL },
-    { SC_10_2, NETVAL INTERFACE SUBTYPE, PPTP, NULL, NULL },
+    { SC_10_2_10_12_IPHONE_2_0_10_0, NETVAL INTERFACE SUBTYPE, PPTP, NULL, NULL },
     { SC_10_3, NETVAL INTERFACE SUBTYPE, L2TP, NULL, NULL },
     { COMMENT, "", NULL, NULL, NULL },
 
@@ -902,23 +913,23 @@ static schemaDefinition names[] = {
     { SC_10_1, NETVAL MODEM DIALMODE, WAITFORDIALTONE, NULL, NULL },
     { COMMENT, "", NULL, NULL, NULL },
 
-  { GROUP_DEPRECATED, NETPROP NETINFO, KEY_PREFIX NETENT NETINFO " Entity Keys", NULL, NULL },
-
-    { DEFINE, "#if", "!TARGET_OS_IPHONE", NULL, NULL },
-    { SC_10_1_10_5, NETPROP NETINFO, BINDINGMETHODS, NULL, CFSTRING },
-    { SC_10_1_10_5, NETPROP NETINFO, SERVER ADDRESSES, NULL, CFARRAY_CFSTRING },
-    { SC_10_1_10_5, NETPROP NETINFO, SERVER TAGS, NULL, CFARRAY_CFSTRING },
-    { SC_10_1_10_5, NETPROP NETINFO, BROADCAST SERVER TAG, NULL, CFSTRING },
-    { COMMENT_DEPRECATED, "", NULL, NULL, NULL },
-    { COMMENT_DEPRECATED, "--- " KEY_PREFIX NETPROP NETINFO BINDINGMETHODS " values ---", NULL, NULL, NULL },
-    { SC_10_1_10_5, NETVAL NETINFO BINDINGMETHODS, BROADCAST, NULL, NULL },
-    { SC_10_1_10_5, NETVAL NETINFO BINDINGMETHODS, DHCP, NULL, NULL },
-    { SC_10_1_10_5, NETVAL NETINFO BINDINGMETHODS, MANUAL, NULL, NULL },
-    { COMMENT_DEPRECATED, "", NULL, NULL, NULL },
-    { COMMENT_DEPRECATED, "--- " KEY_PREFIX NETPROP NETINFO BROADCAST SERVER TAG " default value ---", NULL, NULL, NULL },
-    { SC_10_1_10_5, NETVAL NETINFO, DEFAULT SERVER TAG, "network", NULL },
-    { DEFINE, "#endif", "// !TARGET_OS_IPHONE", NULL, NULL },
-    { COMMENT_DEPRECATED, "", NULL, NULL, NULL },
+//{ GROUP_DEPRECATED_NO_HEADER, NETPROP NETINFO, KEY_PREFIX NETENT NETINFO " Entity Keys", NULL, NULL },
+//
+//  { DEFINE, "#if", "!TARGET_OS_IPHONE", NULL, NULL },
+//  { DEPRECATED_NO_HEADER, NETPROP NETINFO, BINDINGMETHODS, NULL, CFSTRING },
+//  { DEPRECATED_NO_HEADER, NETPROP NETINFO, SERVER ADDRESSES, NULL, CFARRAY_CFSTRING },
+//  { DEPRECATED_NO_HEADER, NETPROP NETINFO, SERVER TAGS, NULL, CFARRAY_CFSTRING },
+//  { DEPRECATED_NO_HEADER, NETPROP NETINFO, BROADCAST SERVER TAG, NULL, CFSTRING },
+//  { COMMENT_DEPRECATED_NO_HEADER, "", NULL, NULL, NULL },
+//  { COMMENT_DEPRECATED_NO_HEADER, "--- " KEY_PREFIX NETPROP NETINFO BINDINGMETHODS " values ---", NULL, NULL, NULL },
+//  { DEPRECATED_NO_HEADER, NETVAL NETINFO BINDINGMETHODS, BROADCAST, NULL, NULL },
+//  { DEPRECATED_NO_HEADER, NETVAL NETINFO BINDINGMETHODS, DHCP, NULL, NULL },
+//  { DEPRECATED_NO_HEADER, NETVAL NETINFO BINDINGMETHODS, MANUAL, NULL, NULL },
+//  { COMMENT_DEPRECATED_NO_HEADER, "", NULL, NULL, NULL },
+//  { COMMENT_DEPRECATED_NO_HEADER, "--- " KEY_PREFIX NETPROP NETINFO BROADCAST SERVER TAG " default value ---", NULL, NULL, NULL },
+//  { DEPRECATED_NO_HEADER, NETVAL NETINFO, DEFAULT SERVER TAG, "network", NULL },
+//  { DEFINE, "#endif", "// !TARGET_OS_IPHONE", NULL, NULL },
+//  { COMMENT_DEPRECATED_NO_HEADER, "", NULL, NULL, NULL },
 
   { GROUP, NETPROP PPP, KEY_PREFIX NETENT PPP " Entity Keys", NULL, NULL },
 
@@ -1038,11 +1049,6 @@ static schemaDefinition names[] = {
     { COMMENT, "* RESERVED FOR FUTURE USE *", NULL, NULL, NULL },
     { COMMENT, "", NULL, NULL, NULL },
 
-  { GROUP, NETPROP PPTP, KEY_PREFIX NETENT PPTP " Entity Keys", NULL, NULL },
-
-    { COMMENT, "* RESERVED FOR FUTURE USE *", NULL, NULL, NULL },
-    { COMMENT, "", NULL, NULL, NULL },
-
   { GROUP, NETPROP L2TP, KEY_PREFIX NETENT L2TP " Entity Keys", NULL, NULL },
 
     { SC_10_3, NETPROP L2TP, IPSEC SHAREDSECRET, NULL, CFSTRING },
@@ -1100,9 +1106,23 @@ static schemaDefinition names[] = {
     { SC_10_7_IPHONE_5_0_PRIVATE, NETPROP PROXIES, SUPPLEMENTAL MATCH DOMAIN, "__MATCH_DOMAIN__", CFSTRING},
     { COMMENT_PRIVATE, "", NULL, NULL, NULL },
 
+   { GROUP_PRIVATE, NETPROP LINK, KEY_PREFIX NETENT QOSMARKING POLICY " Entity Keys", NULL, NULL },
+
+    { SC_10_12_IPHONE_10_0_PRIVATE, NETPROP QOSMARKING, APPLE AUDIOVIDEOCALLS,
+				    QOSMARKING APPLE AUDIOVIDEOCALLS,
+				    CFBOOLEAN},
+    { SC_10_12_IPHONE_10_0_PRIVATE, NETPROP QOSMARKING, ENABLED,
+				    QOSMARKING ENABLED,
+				    CFBOOLEAN},
+    { SC_10_12_IPHONE_10_0_PRIVATE, NETPROP QOSMARKING, WHITELISTED APP IDENTIFIERS,
+				    QOSMARKING WHITELISTED APP IDENTIFIERS,
+				    CFARRAY_CFSTRING},
+    { COMMENT_PRIVATE, "", NULL, NULL, NULL },
+
   { GROUP_PRIVATE, NETPROP SERVICE, KEY_PREFIX NETENT SERVICE " Entity Keys", NULL, NULL },
 
     { SC_10_6_IPHONE_2_0_PRIVATE, NETPROP SERVICE, PRIMARYRANK, NULL, CFSTRING },
+    { SC_10_12_IPHONE_10_0_PRIVATE, NETPROP SERVICE, SERVICEINDEX, NULL, CFNUMBER },
     { SC_10_6_IPHONE_2_0_PRIVATE, NETPROP SERVICE, USERDEFINEDNAME, NULL, CFSTRING },
     { COMMENT_PRIVATE, "", NULL, NULL, NULL },
     { COMMENT_PRIVATE, "--- " KEY_PREFIX NETPROP SERVICE PRIMARYRANK " values ---", NULL, NULL, NULL },
@@ -1358,9 +1378,6 @@ print_headerdoc(schemaDefinition *def)
 	    case SC_10_4:
 		printf("  __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0/*SPI*/);\n");
 		break;
-	    case SC_10_1_10_5:
-		printf("  __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_5,__IPHONE_NA,__IPHONE_NA);\n");
-		break;
 	    case SC_10_5:
 		printf("  __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0/*SPI*/);\n");
 		break;
@@ -1370,12 +1387,6 @@ print_headerdoc(schemaDefinition *def)
 	    case SC_10_5_PRIVATE:
 		printf("  __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0/*SPI*/);\n");
 		break;
-	    case SC_10_1_10_6:
-		printf("  __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_6,__IPHONE_NA,__IPHONE_NA);\n");
-		break;
-	    case SC_10_2_10_6:
-		printf("  __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_6,__IPHONE_NA,__IPHONE_NA);\n");
-		break;
 	    case SC_10_1_10_9:
 		printf("  __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_9,__IPHONE_2_0/*SPI*/,__IPHONE_FUTURE/*SPI*/);\n");
 		break;
@@ -1388,6 +1399,12 @@ print_headerdoc(schemaDefinition *def)
 	    case SC_10_4_10_9:
 		printf("  __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4,__MAC_10_9,__IPHONE_2_0/*SPI*/,__IPHONE_FUTURE/*SPI*/);\n");
 		break;
+	    case SC_10_2_10_12_IPHONE_2_0_10_0:
+		printf("  __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_12,__IPHONE_2_0/*SPI*/,__IPHONE_10_0/*SPI*/);\n");
+		break;
+	    case SC_10_3_10_12_IPHONE_2_0_10_0:
+		printf("  __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3,__MAC_10_12,__IPHONE_2_0/*SPI*/,__IPHONE_10_0/*SPI*/);\n");
+		break;
 	    case SC_10_6_IPHONE_2_0:
 	    case SC_10_6_IPHONE_2_0_PRIVATE:
 		printf("  __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_2_0/*SPI*/);\n");
@@ -1421,6 +1438,9 @@ print_headerdoc(schemaDefinition *def)
 	    case SC_10_11_IPHONE_9_0_PRIVATE:
 		printf("  __OSX_AVAILABLE_STARTING(__MAC_10_11,__IPHONE_9_0/*SPI*/);\n");
 		break;
+	    case SC_10_12_IPHONE_10_0_PRIVATE:
+		printf("  __OSX_AVAILABLE_STARTING(__MAC_10_12,__IPHONE_10_0/*SPI*/);\n");
+		break;
 	    case SC_IPHONE_2_0_PRIVATE:
 		printf("  __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_2_0/*SPI*/);\n");
 		break;
@@ -1476,7 +1496,8 @@ dump_names(int type)
 		break;
 	    }
 
-	    case COMMENT_DEPRECATED: {
+	    case COMMENT_DEPRECATED:
+	    case COMMENT_DEPRECATED_NO_HEADER: {
 		break;
 	    }
 
@@ -1533,6 +1554,10 @@ dump_names(int type)
 		break;
 	    }
 
+	    case GROUP_DEPRECATED_NO_HEADER: {
+		break;
+	    }
+
 	    case GROUP_PRIVATE: {
 		switch (type) {
 		    case gen_comments_private_e:
@@ -1571,10 +1596,8 @@ dump_names(int type)
 
 		    case gen_comments_e:
 			switch (names[i].control) {
+			    case DEPRECATED_NO_HEADER:
 			    case SC_10_1_10_4:
-			    case SC_10_1_10_5:
-			    case SC_10_1_10_6:
-			    case SC_10_2_10_6:
 			    case SC_10_1_10_9:
 			    case SC_10_2_10_9:
 			    case SC_10_3_10_9:
@@ -1592,6 +1615,7 @@ dump_names(int type)
 			    case SC_10_10_IPHONE_7_0_PRIVATE:
 			    case SC_10_10_IPHONE_8_0_PRIVATE:
 			    case SC_10_11_IPHONE_9_0_PRIVATE:
+			    case SC_10_12_IPHONE_10_0_PRIVATE:
 			    case SC_IPHONE_2_0_PRIVATE:
 				// don't report private definitions
 				break;
@@ -1602,10 +1626,8 @@ dump_names(int type)
 			break;
 		    case gen_comments_private_e:
 			switch (names[i].control) {
+			    case DEPRECATED_NO_HEADER:
 			    case SC_10_1_10_4:
-			    case SC_10_1_10_5:
-			    case SC_10_1_10_6:
-			    case SC_10_2_10_6:
 			    case SC_10_1_10_9:
 			    case SC_10_2_10_9:
 			    case SC_10_3_10_9:
@@ -1623,6 +1645,7 @@ dump_names(int type)
 			    case SC_10_10_IPHONE_7_0_PRIVATE:
 			    case SC_10_10_IPHONE_8_0_PRIVATE:
 			    case SC_10_11_IPHONE_9_0_PRIVATE:
+			    case SC_10_12_IPHONE_10_0_PRIVATE:
 			    case SC_IPHONE_2_0_PRIVATE:
 				print_comment(&names[i]);
 				break;
@@ -1634,6 +1657,7 @@ dump_names(int type)
 
 		    case gen_headerdoc_e:
 			switch (names[i].control) {
+			    case DEPRECATED_NO_HEADER:
 			    case SC_10_5_PRIVATE:
 			    case SC_10_6_IPHONE_2_0_PRIVATE:
 			    case SC_10_6_IPHONE_3_0_PRIVATE:
@@ -1645,6 +1669,7 @@ dump_names(int type)
 			    case SC_10_10_IPHONE_7_0_PRIVATE:
 			    case SC_10_10_IPHONE_8_0_PRIVATE:
 			    case SC_10_11_IPHONE_9_0_PRIVATE:
+			    case SC_10_12_IPHONE_10_0_PRIVATE:
 			    case SC_IPHONE_2_0_PRIVATE:
 				// don't report private definitions
 				break;
@@ -1666,6 +1691,7 @@ dump_names(int type)
 			    case SC_10_10_IPHONE_7_0_PRIVATE:
 			    case SC_10_10_IPHONE_8_0_PRIVATE:
 			    case SC_10_11_IPHONE_9_0_PRIVATE:
+			    case SC_10_12_IPHONE_10_0_PRIVATE:
 			    case SC_IPHONE_2_0_PRIVATE:
 				print_headerdoc(&names[i]);
 				break;
diff --git a/SystemConfiguration.fproj/helper/SCHelper_client.c b/SystemConfiguration.fproj/helper/SCHelper_client.c
index fd7835a..b3cc66d 100644
--- a/SystemConfiguration.fproj/helper/SCHelper_client.c
+++ b/SystemConfiguration.fproj/helper/SCHelper_client.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005-2008, 2010, 2011, 2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2005-2008, 2010, 2011, 2013, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -39,9 +39,7 @@
 #include 
 #include 
 
-#include 
-#include 
-
+#include "SCPreferencesInternal.h"
 #include "SCHelper_client.h"
 #include "helper.h"		// MiG generated file
 
@@ -53,8 +51,24 @@
 #define	SUFFIX_SYM_LEN				(sizeof(SUFFIX_SYM) - 1)
 
 
-static pthread_mutex_t	_helper_lock	= PTHREAD_MUTEX_INITIALIZER;
-static mach_port_t	_helper_server	= MACH_PORT_NULL;
+static pthread_mutex_t	_helper_lock		= PTHREAD_MUTEX_INITIALIZER;
+static mach_port_t	_helper_server		= MACH_PORT_NULL;
+
+
+static os_activity_t
+__SCHelperActivity()
+{
+	static os_activity_t	activity	= NULL;
+	static dispatch_once_t	once;
+
+	dispatch_once(&once, ^{
+		activity = os_activity_create("accessing SCPreferences [helper]",
+					      OS_ACTIVITY_CURRENT,
+					      OS_ACTIVITY_FLAG_DEFAULT);
+	});
+
+	return activity;
+}
 
 
 static mach_port_t
@@ -115,6 +129,8 @@ _SCHelperOpen(CFDataRef authorizationData, mach_port_t *helper_port)
 	server = _helper_server;
 	while (TRUE) {
 		if (server != MACH_PORT_NULL) {
+			os_activity_scope(__SCHelperActivity());
+
 			kr = helperinit(server,
 					helper_port,
 					&status);
@@ -225,7 +241,7 @@ _SCHelperExecCopyBacktrace()
 
 		backtrace = _SC_copyBacktrace();
 		if (backtrace != NULL) {
-			_SCSerializeString(backtrace, &traceData, NULL, NULL);
+			(void)_SCSerializeString(backtrace, &traceData, NULL, NULL);
 			CFRelease(backtrace);
 		}
 	}
@@ -246,6 +262,8 @@ _SCHelperExec(mach_port_t port, uint32_t msgID, CFDataRef data, uint32_t *status
 
 	traceData = _SCHelperExecCopyBacktrace();
 
+	os_activity_scope(__SCHelperActivity());
+
 	kr = helperexec(port,
 			msgID,
 			(data != NULL) ? (void *)CFDataGetBytePtr(data) : NULL,
diff --git a/SystemConfiguration.fproj/helper/SCHelper_server.c b/SystemConfiguration.fproj/helper/SCHelper_server.c
index 28b7ece..63ce43d 100644
--- a/SystemConfiguration.fproj/helper/SCHelper_server.c
+++ b/SystemConfiguration.fproj/helper/SCHelper_server.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2005-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -37,10 +37,8 @@
 #include 
 #include 
 #include 
-#include 
-#include 
-#include 
 
+#define SC_LOG_HANDLE	__log_SCHelper()
 #include "SCPreferencesInternal.h"
 #include "SCHelper_client.h"
 #include "helper_types.h"
@@ -118,6 +116,23 @@ static int		sessions_generation		= 0;
 static pthread_mutex_t	sessions_lock			= PTHREAD_MUTEX_INITIALIZER;
 
 
+#pragma mark -
+#pragma mark Logging
+
+
+static os_log_t
+__log_SCHelper()
+{
+	static os_log_t	log	= NULL;
+
+	if (log == NULL) {
+		log = os_log_create("com.apple.SystemConfiguration", "SCPreferences");
+	}
+
+	return log;
+}
+
+
 #pragma mark -
 #pragma mark Helper session management
 
@@ -230,7 +245,6 @@ __SCHelperSessionSetThreadName(SCHelperSessionRef session)
 	char				*path_s		= NULL;
 	SCHelperSessionPrivateRef	sessionPrivate	= (SCHelperSessionPrivateRef)session;
 
-
 	if (sessionPrivate->mp == NULL) {
 		return;
 	}
@@ -257,7 +271,7 @@ __SCHelperSessionSetThreadName(SCHelperSessionRef session)
 	if (caller != NULL) {
 		snprintf(name, sizeof(name), "SESSION|%p|%s|%s%s",
 			(void *)(uintptr_t)CFMachPortGetPort(sessionPrivate->mp),
-			(caller != NULL) ? caller : "?",
+			caller,
 			(path_s != NULL) ? "*/"   : "",
 			(path   != NULL) ? path   : "?");
 		CFAllocatorDeallocate(NULL, caller);
@@ -499,22 +513,16 @@ __SCHelperSessionCreate(CFAllocatorRef allocator)
 		return NULL;
 	}
 
+	/* initialize non-zero/NULL members */
 	if (pthread_mutex_init(&sessionPrivate->lock, NULL) != 0) {
 		SC_log(LOG_NOTICE, "pthread_mutex_init(): failure to initialize per session lock");
 		CFRelease(sessionPrivate);
 		return NULL;
 	}
-	sessionPrivate->authorization		= NULL;
-	sessionPrivate->use_entitlement		= FALSE;
-	sessionPrivate->port			= MACH_PORT_NULL;
-	sessionPrivate->mp			= NULL;
 	sessionPrivate->callerReadAccess	= UNKNOWN;
 	sessionPrivate->callerWriteAccess	= UNKNOWN;
 	sessionPrivate->isSetChange		= UNKNOWN;
 	sessionPrivate->isVPNChange		= UNKNOWN;
-	sessionPrivate->vpnTypes		= NULL;
-	sessionPrivate->prefs			= NULL;
-	sessionPrivate->backtraces		= NULL;
 
 	// keep track this session
 	pthread_mutex_lock(&sessions_lock);
@@ -682,7 +690,7 @@ do_Auth(SCHelperSessionRef session, void *info, CFDataRef data, uint32_t *status
 #endif
 	Boolean		ok			= FALSE;
 
-	if (_SCUnserialize((CFPropertyListRef*)&authorizationDict, data, NULL, 0) == FALSE) {
+	if (!_SCUnserialize((CFPropertyListRef*)&authorizationDict, data, NULL, 0)) {
 		return FALSE;
 	}
 
@@ -1295,7 +1303,7 @@ do_prefs_Commit(SCHelperSessionRef session, void *info, CFDataRef data, uint32_t
 	savePrefs = prefsPrivate->prefs;
 	saveAccessed = prefsPrivate->accessed;
 	saveChanged = prefsPrivate->changed;
-	
+
 	prefsPrivate->prefs	= CFDictionaryCreateMutableCopy(NULL, 0, prefsData);
 	prefsPrivate->accessed	= TRUE;
 	prefsPrivate->changed	= TRUE;
@@ -1316,7 +1324,7 @@ do_prefs_Commit(SCHelperSessionRef session, void *info, CFDataRef data, uint32_t
 			if (prefsPrivate->prefs != NULL) {
 				CFRelease(prefsPrivate->prefs);
 			}
-			
+
 			prefsPrivate->prefs = savePrefs;
 			prefsPrivate->accessed = saveAccessed;
 			prefsPrivate->changed = saveChanged;
@@ -1925,7 +1933,6 @@ helper_demux(mach_msg_header_t *request, mach_msg_header_t *reply)
 static void
 helperCallback(CFMachPortRef port, void *msg, CFIndex size, void *info)
 {
-	os_activity_t		activity_id;
 	mig_reply_error_t *	bufRequest	= msg;
 	uint32_t		bufReply_q[MACH_MSG_BUFFER_SIZE/sizeof(uint32_t)];
 	mig_reply_error_t *	bufReply	= (mig_reply_error_t *)bufReply_q;
@@ -1933,9 +1940,6 @@ helperCallback(CFMachPortRef port, void *msg, CFIndex size, void *info)
 	mach_msg_return_t	mr;
 	int			options;
 
-	activity_id = os_activity_start("processing SCHelper request",
-					OS_ACTIVITY_FLAG_DEFAULT);
-
 	if (bufSize == 0) {
 		// get max size for MiG reply buffers
 		bufSize = _helper_subsystem.maxsize;
@@ -2013,8 +2017,6 @@ helperCallback(CFMachPortRef port, void *msg, CFIndex size, void *info)
 	if (bufReply != (mig_reply_error_t *)bufReply_q)
 		CFAllocatorDeallocate(NULL, bufReply);
 
-	os_activity_end(activity_id);
-
 	return;
 }
 
@@ -2228,8 +2230,6 @@ _helperexec(mach_port_t			server,
 
 			ok = _SCSerializeData(reply, (void **)replyRef, &len);
 			*replyLen = (mach_msg_type_number_t)len;
-			CFRelease(reply);
-			reply = NULL;
 			if (!ok) {
 				*status = SCError();
 				goto done;
diff --git a/SystemConfiguration.fproj/helper/com.apple.SCHelper-embedded.plist b/SystemConfiguration.fproj/helper/com.apple.SCHelper-embedded.plist
index bafb82f..209e217 100644
--- a/SystemConfiguration.fproj/helper/com.apple.SCHelper-embedded.plist
+++ b/SystemConfiguration.fproj/helper/com.apple.SCHelper-embedded.plist
@@ -2,6 +2,10 @@
 
 
 
+	EnableTransactions
+	
+	EnablePressuredExit
+	
 	Label
 	com.apple.SCHelper
 	Program
diff --git a/SystemConfiguration.fproj/moh.c b/SystemConfiguration.fproj/moh.c
deleted file mode 100644
index 074f90a..0000000
--- a/SystemConfiguration.fproj/moh.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (c) 2002, 2003, 2005, 2013-2015 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * Modification History
- *
- * May 29, 2002		Roger Smith 
- * - initial revision
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-#include 
-
-#include "moh.h"
-#include "moh_msg.h"
-
-// Note: right now we are not currently using the deviceName.  This could be the raw
-//       tty name such as "modem" since this is guaranteed to be unique in the /dev.
-//       We would use this deviceName to differientate between multiple MOH devices
-//       present in the system when we create the socket.
-
-
-static ssize_t
-readn(int ref, void *data, size_t len)
-{
-	size_t	left	= len;
-	ssize_t	n;
-	void	*p	= data;
-
-	while (left > 0) {
-		if ((n = read(ref, p, left)) == -1) {
-			if (errno != EINTR) {
-				return -1;
-			}
-			n = 0;
-		} else if (n == 0) {
-			break; /* EOF */
-		}
-
-		left -= n;
-		p += n;
-	}
-	return (len - left);
-}
-
-
-static ssize_t
-writen(int ref, const void *data, size_t len)
-{
-	size_t		left	= len;
-	ssize_t		n;
-	const void	*p	= data;
-
-	while (left > 0) {
-		if ((n = write(ref, p, left)) == -1) {
-			if (errno != EINTR) {
-				return -1;
-			}
-			n = 0;
-		}
-		left -= n;
-		p += n;
-	}
-	return len;
-}
-
-
-__private_extern__
-int
-MOHInit(int *ref, CFStringRef deviceName)
-{
-	int			sock;
-	int			status;
-	struct sockaddr_un	sun;
-
-	sock = socket(AF_LOCAL, SOCK_STREAM, 0);
-
-	bzero(&sun, sizeof(sun));
-	sun.sun_family = AF_LOCAL;
-	strncpy(sun.sun_path, MOH_PATH, sizeof(sun.sun_path));
-
-	status = connect(sock, (struct sockaddr *)&sun, sizeof(sun));
-	if (status == -1) {
-		return errno;
-	}
-
-	*ref = sock;
-	return 0;
-}
-
-
-__private_extern__
-int
-MOHDispose(int ref)
-{
-	if (close(ref) == -1) {
-		return errno;
-	}
-	return 0;
-}
-
-
-__private_extern__
-int
-MOHExec(int		ref,
-	uint32_t	link,
-	uint32_t	cmd,
-	void		*request,
-	size_t		requestLen,
-	void		**reply,
-	size_t		*replyLen)
-{
-	struct moh_msg_hdr	msg;
-	char			*buf		= NULL;
-	ssize_t			n;
-
-	bzero(&msg, sizeof(msg));
-	msg.m_type = cmd;
-	msg.m_link = link;
-	msg.m_len  = ((request != NULL) && (requestLen > 0)) ? (uint32_t)requestLen : 0;
-
-	//  send the command
-	n = writen(ref, &msg, sizeof(msg));
-	if (n == -1) {
-		SC_log(LOG_INFO, "writen() failed: %s", strerror(errno));
-		return errno;
-	} else if (n != sizeof(msg)) {
-		SC_log(LOG_INFO, "writen() failed: wrote=%ld", n);
-		return -1;
-	}
-
-	if ((request != NULL) && (requestLen > 0)) {
-		n = writen(ref, request, requestLen);
-		if (n == -1) {
-			SC_log(LOG_INFO, "writen() failed: %s", strerror(errno));
-			return errno;
-		} else if (n != (ssize_t)requestLen) {
-			SC_log(LOG_INFO, "writen() failed: wrote=%ld", n);
-			return -1;
-		}
-	}
-
-	// always expect a reply
-	n = readn(ref, &msg, sizeof(msg));
-	if (n == -1) {
-		SC_log(LOG_INFO, "readn() failed: error=%s", strerror(errno));
-		return errno;
-	} else if (n != sizeof(msg)) {
-		SC_log(LOG_INFO, "readn() failed: insufficent data, read=%ld", n);
-		return -1;
-	}
-
-	if (msg.m_len) {
-		buf = CFAllocatorAllocate(NULL, msg.m_len, 0);
-		if (buf) {
-			// read reply
-			n = readn(ref, buf, msg.m_len);
-			if (n == -1) {
-				SC_log(LOG_INFO, "readn() failed: error=%s", strerror(errno));
-				CFAllocatorDeallocate(NULL, buf);
-				return errno;
-			} else if (n != (ssize_t)msg.m_len) {
-				SC_log(LOG_INFO, "readn() failed: insufficent data, read=%ld", n);
-				CFAllocatorDeallocate(NULL, buf);
-				return -1;
-			}
-		}
-	}
-
-	if (reply && replyLen) {
-		*reply    = buf;
-		*replyLen = msg.m_len;
-	} else if (buf) {
-		// if additional returned data is unwanted
-		CFAllocatorDeallocate(NULL, buf);
-	}
-
-	return msg.m_result;
-}
-
diff --git a/SystemConfiguration.fproj/moh_msg.h b/SystemConfiguration.fproj/moh_msg.h
deleted file mode 100644
index 77b120f..0000000
--- a/SystemConfiguration.fproj/moh_msg.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2002, 2003, 2005 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef _MOH_MSG_H
-#define _MOH_MSG_H
-
-#include 
-
-/* local socket path */
-#define MOH_PATH		"/tmp/.modemOnHold"
-#define CURRENT_VERSION		1
-
-/* MOH message paquets */
-struct moh_msg_hdr {
-	uint32_t	m_type;		// type of the message
-	uint32_t	m_result;	// error code of notification message
-	uint32_t	m_cookie;	// user param
-	uint32_t	m_link;		// link for this message
-	uint32_t	m_len;		// len of the following data
-};
-
-struct moh_msg {
-	uint32_t	m_type;		// type of the message
-	uint32_t	m_result;	// error code of notification message
-	uint32_t	m_cookie;	// user param, or error num for event
-	uint32_t	m_link;		// link for this message
-	uint32_t	m_len;		// len of the following data
-	u_char		m_data[1];	// msg data sent or received
-};
-
-/* codes for MOH messages */
-enum {
-	/* API client commands */
-	MOH_VERSION = 1,
-	MOH_DEVICE_SUPPORTS_HOLD,
-	MOH_SESSION_SUPPORTS_HOLD,
-	MOH_PUT_SESSION_ON_HOLD,
-	MOH_RESUME_SESSION_ON_HOLD,
-	MOH_SESSION_IS_ON_HOLD,
-	MOH_SESSION_GET_STATUS
-};
-
-#endif	/* _MOH_MSG_H */
-
diff --git a/SystemConfiguration.fproj/scprefs_observer.c b/SystemConfiguration.fproj/scprefs_observer.c
index e4a9dec..fd56df8 100644
--- a/SystemConfiguration.fproj/scprefs_observer.c
+++ b/SystemConfiguration.fproj/scprefs_observer.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2012, 2013, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -23,10 +23,17 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+
+#ifndef	SC_LOG_HANDLE
+#define SC_LOG_HANDLE	__log_SCPreferences()
+#endif	//SC_LOG_HANDLE
+os_log_t	SC_LOG_HANDLE;
+
 #include 
 #include 
 
@@ -102,7 +109,7 @@ build_digest(const char *top_dir, const char *file)
 	CC_SHA1_Init(&ctx);
 	iterate_dir(top_dir, file, &ctx, &found);
 	CC_SHA1_Final(bytes, &ctx);
-	if (found == TRUE) {
+	if (found) {
 		digest = CFDataCreate(NULL, bytes, sizeof(bytes));
 	}
 	return (digest);
@@ -207,16 +214,22 @@ prefs_observer_handle_notifications()
 static void
 _prefs_observer_init()
 {
-	static int token;
+	uint32_t	status;
+	static int	token;
 
 	prefs_observer_queue = dispatch_queue_create("com.apple.SystemConfiguration.SCPreferencesObserver", NULL);
 
 	SLIST_INIT(&head);
 
-	notify_register_dispatch(PREFS_OBSERVER_KEY,
-			     &token,
-			     prefs_observer_queue,
-			     ^(int token) { prefs_observer_handle_notifications(); });
+	status = notify_register_dispatch(PREFS_OBSERVER_KEY,
+					  &token,
+					  prefs_observer_queue,
+					  ^(int token) {
+						  prefs_observer_handle_notifications();
+					  });
+	if (status != NOTIFY_STATUS_OK) {
+		SC_log(LOG_INFO, "notify_register_dispatch() failed: %d", status);
+	}
 }
 
 static scprefs_observer_t
diff --git a/config-agent-info/config_agent_info.c b/config-agent-info/config_agent_info.c
new file mode 100644
index 0000000..8071d4d
--- /dev/null
+++ b/config-agent-info/config_agent_info.c
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2015, 2016 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * 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@
+ */
+
+
+#include "config_agent_info.h"
+#include "configAgentDefines.h"
+#include "network_config_agent_info_priv.h"
+
+#include 
+
+static void
+get_agent_uuid_if_OOB_data_required(xpc_object_t info, uuid_t uuid)
+{
+	__block xpc_object_t agent_uuid = NULL;
+
+	if (xpc_get_type(info) == XPC_TYPE_ARRAY) {
+		xpc_array_apply(info, ^bool(size_t index, xpc_object_t value) {
+			if (value && xpc_get_type(value) == XPC_TYPE_DICTIONARY) {
+				agent_uuid = xpc_dictionary_get_value(info,
+								      kConfigAgentOutOfBandDataUUID);
+				if (agent_uuid != NULL) {
+					return false;
+				}
+			}
+			return true;
+		});
+	} else if (xpc_get_type(info) == XPC_TYPE_DICTIONARY) {
+		agent_uuid = xpc_dictionary_get_value(info,
+						      kConfigAgentOutOfBandDataUUID);
+	}
+
+	if (agent_uuid != NULL) {
+		const void *bytes = xpc_data_get_bytes_ptr(agent_uuid);
+		uuid_copy(uuid, bytes);
+	} else {
+		uuid_clear(uuid);
+	}
+}
+
+static boolean_t
+is_a_config_agent(const struct netagent *agent)
+{
+	const char *agentDomain;
+
+	if (agent == NULL) {
+		return false;
+	}
+
+	agentDomain = agent->netagent_domain;
+	if (agentDomain == NULL || strcmp(agentDomain, kConfigAgentDomain)) {
+		return false;
+	}
+
+	return true;
+}
+
+boolean_t
+is_config_agent_type_dns(const struct netagent *agent)
+{
+	if (!is_a_config_agent(agent)) {
+		return false;
+	}
+
+	const char *agentDesc = agent->netagent_type;
+	if (agentDesc == NULL || strcmp(agentDesc, kConfigAgentTypeDNS)) {
+		return false;
+	}
+
+	return true;
+}
+
+boolean_t
+is_config_agent_type_proxy(const struct netagent *agent)
+{
+	if (!is_a_config_agent(agent)) {
+		return false;
+	}
+
+	const char *agentDesc = agent->netagent_type;
+	if (agentDesc == NULL || strcmp(agentDesc, kConfigAgentTypeProxy)) {
+		return false;
+	}
+
+	return true;
+}
+
+static boolean_t
+is_config_agent_type_dns_multicast(const struct netagent *agent)
+{
+	if (strncmp(agent->netagent_desc, kConfigAgentTypeDNSMulticast, sizeof(kConfigAgentTypeDNSMulticast)-1) == 0) {
+		return true;
+	}
+
+	return false;
+}
+
+static boolean_t
+is_config_agent_type_dns_private(const struct netagent *agent)
+{
+	if (strncmp(agent->netagent_desc, kConfigAgentTypeDNSPrivate, sizeof(kConfigAgentTypeDNSPrivate)-1) == 0) {
+		return true;
+	}
+
+	return false;
+}
+
+xpc_object_t
+config_agent_copy_dns_information(const struct netagent *agent)
+{
+	xpc_object_t resolver = NULL;
+
+	if (!is_config_agent_type_dns(agent)) {
+		goto done;
+	}
+
+	if (agent->netagent_data_size <= 0 ) {
+		if (!is_config_agent_type_dns_private(agent) && !is_config_agent_type_dns_multicast(agent)) {
+			const char *agent_desc = (*(agent->netagent_desc) != '\0') ? agent->netagent_desc : kConfigAgentTypeDNS;
+			syslog(LOG_ERR, "Cannot parse config agent (%s). No data available", agent_desc);
+		}
+
+		goto done;
+	}
+
+	resolver = xpc_create_from_plist(agent->netagent_data, agent->netagent_data_size);
+
+done:
+	return resolver;
+}
+
+xpc_object_t
+config_agent_get_dns_nameservers(xpc_object_t resolver)
+{
+	if (resolver == NULL) {
+		return NULL;
+	}
+
+	return xpc_dictionary_get_value(resolver, kConfigAgentDNSNameServers);
+}
+
+xpc_object_t
+config_agent_get_dns_searchdomains(xpc_object_t resolver)
+{
+	if (resolver == NULL) {
+		return NULL;
+	}
+
+	return xpc_dictionary_get_value(resolver, kConfigAgentDNSSearchDomains);
+}
+
+void
+config_agent_free_dns_information(xpc_object_t resolver)
+{
+	if (resolver == NULL) {
+		syslog(LOG_ERR, "Attempting to free invalid resolver");
+		return;
+	}
+
+	xpc_release(resolver);
+}
+
+xpc_object_t
+config_agent_copy_proxy_information(const struct netagent *agent)
+{
+	xpc_object_t info = NULL;
+
+	if (!is_config_agent_type_proxy(agent)) {
+		goto done;
+	}
+
+	if (agent->netagent_data_size <= 0 ) {
+		const char *agent_desc = (*(agent->netagent_desc) != '\0') ? agent->netagent_desc : kConfigAgentTypeProxy;
+		syslog(LOG_ERR, "Cannot parse config agent (%s). No data available", agent_desc);
+		goto done;
+	}
+
+	info = xpc_create_from_plist(agent->netagent_data, agent->netagent_data_size);
+
+done:
+	return info;
+}
+ 
+xpc_object_t
+config_agent_update_proxy_information(xpc_object_t proxyConfig)
+{
+	if (proxyConfig == NULL) {
+		return NULL;
+	}
+
+	xpc_object_t newProxyConfig = NULL;
+	struct netagent agent;
+
+	get_agent_uuid_if_OOB_data_required(proxyConfig, agent.netagent_uuid);
+
+	if (uuid_is_null(agent.netagent_uuid) == 0) {
+		strlcpy(agent.netagent_type, kConfigAgentTypeProxy, sizeof(agent.netagent_type));
+		
+		uint64_t length;
+		const void *buffer = _nwi_config_agent_copy_data(&agent, &length);
+		if (buffer != NULL && length > 0) {
+			newProxyConfig = xpc_create_from_plist(buffer, (size_t)length);
+			free((void *)buffer);
+		}
+	}
+
+	return newProxyConfig;
+}
+
+void
+config_agent_free_proxy_information(xpc_object_t proxyConfig)
+{
+	if (proxyConfig == NULL) {
+		syslog(LOG_ERR, "Attempting to free proxy configuration");
+		return;
+	}
+
+	xpc_release(proxyConfig);
+}
diff --git a/config-agent-info/config_agent_info.h b/config-agent-info/config_agent_info.h
new file mode 100644
index 0000000..7671c6c
--- /dev/null
+++ b/config-agent-info/config_agent_info.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2015, 2016 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * 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@
+ */
+
+#ifndef CONFIG_AGENT_INFO_H
+#define CONFIG_AGENT_INFO_H
+
+#include 
+#include 
+#include 
+
+__BEGIN_DECLS
+
+/*	
+	Returns true for agent with type DNSAgent and domain SystemConfig
+ */
+boolean_t
+is_config_agent_type_dns		(const struct netagent *agent)		__OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_10_0);
+
+/*
+	Returns true for agent with type ProxyAgent and domain SystemConfig
+ */
+boolean_t
+is_config_agent_type_proxy		(const struct netagent *agent)		__OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_10_0);
+
+/*
+	Returns xpc_object_t corresponding to the raw DNSAgent data
+		NULL if the agent is NOT a DNSAgent
+ */
+xpc_object_t
+config_agent_copy_dns_information	(const struct netagent	*agentStruct)	__OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_10_0);
+
+/*
+	Returns xpc_object_t (XPC_TYPE_ARRAY) corresponding to the DNS nameservers
+		NULL if the agent is NOT a DNSAgent
+ */
+xpc_object_t
+config_agent_get_dns_nameservers	(xpc_object_t resolver)			__OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_10_0);
+
+/*
+	Returns xpc_object_t (XPC_TYPE_ARRAY) corresponding to the DNS search domains
+		NULL if the agent is NOT a DNSAgent
+ */
+xpc_object_t
+config_agent_get_dns_searchdomains	(xpc_object_t resolver)			__OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_10_0);
+
+/*
+	Frees the xpc_object_t returned by config_agent_copy_dns_information()
+ */
+void
+config_agent_free_dns_information	(xpc_object_t resolver)			__OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_10_0);
+
+/*
+	Returns xpc_object_t corresponding to the raw ProxyAgent data
+		NULL if the agent is NOT a ProxyAgent
+ */
+xpc_object_t
+config_agent_copy_proxy_information	(const struct netagent	*agentStruct)	__OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_10_0);
+
+/*
+	Updates the proxy config with PAC, if applicable. The proxyConfig MUST be 
+	of type XPC_TYPE_ARRAY containing a XPC_TYPE_DICTIONARY. This format is
+	returned by config_agent_copy_proxy_information()
+ 
+	Returns xpc_object_t to be freed by the caller.
+		NULL if the the provided configuration does not need any update.
+ */
+xpc_object_t
+config_agent_update_proxy_information	(xpc_object_t proxyConfig)		__OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_10_0);
+
+/*
+	Frees the xpc_object_t returned by config_agent_copy_proxy_information()
+ */
+void
+config_agent_free_proxy_information	(xpc_object_t proxyConfig)		__OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_10_0);
+
+__END_DECLS
+
+#endif /* CONFIG_AGENT_INFO_H */
diff --git a/configd.tproj/_SCD.c b/configd.tproj/_SCD.c
index 1bcc18b..a9e1c50 100644
--- a/configd.tproj/_SCD.c
+++ b/configd.tproj/_SCD.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2001, 2003-2005, 2009, 2011, 2012, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003-2005, 2009, 2011, 2012, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -72,7 +72,7 @@ _addWatcher(CFNumberRef sessionNum, CFStringRef watchedKey)
 	 * Get the dictionary associated with this key out of the store
 	 */
 	dict = CFDictionaryGetValue(storeData, watchedKey);
-	if (dict) {
+	if (dict != NULL) {
 		newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
 	} else {
 		newDict = CFDictionaryCreateMutable(NULL,
@@ -157,7 +157,7 @@ _removeWatcher(CFNumberRef sessionNum, CFStringRef watchedKey)
 	 * Get the dictionary associated with this key out of the store
 	 */
 	dict = CFDictionaryGetValue(storeData, watchedKey);
-	if ((dict == NULL) || (CFDictionaryContainsKey(dict, kSCDWatchers) == FALSE)) {
+	if ((dict == NULL) || !CFDictionaryContainsKey(dict, kSCDWatchers)) {
 		/* key doesn't exist (isn't this really fatal?) */
 #ifdef	DEBUG
 		SC_log(LOG_DEBUG, "  _removeWatcher: %@, %@, key not watched", sessionNum, watchedKey);
@@ -237,7 +237,7 @@ _removeWatcher(CFNumberRef sessionNum, CFStringRef watchedKey)
 
 __private_extern__
 void
-pushNotifications(FILE *_configd_trace)
+pushNotifications()
 {
 	CFIndex				notifyCnt;
 	int				server;
@@ -258,6 +258,8 @@ pushNotifications(FILE *_configd_trace)
 					kCFNumberIntType,
 					&server);
 		theSession = getSession(server);
+		assert(theSession != NULL);
+
 		storePrivate = (SCDynamicStorePrivateRef)theSession->store;
 
 		/*
@@ -265,11 +267,15 @@ pushNotifications(FILE *_configd_trace)
 		 */
 		if ((storePrivate->notifyStatus == Using_NotifierInformViaMachPort) &&
 		    (storePrivate->notifyPort != MACH_PORT_NULL)) {
+			/*
+			 * Associate notification activity with the client
+			 */
+			os_activity_scope(theSession->activity);
+
 			/*
 			 * Post notification as mach message
 			 */
-			SC_trace(_configd_trace, "%s : %5d : port = %d\n",
-				 "-->port",
+			SC_trace("-->port : %5d : port = %d",
 				 storePrivate->server,
 				 storePrivate->notifyPort);
 
@@ -285,8 +291,12 @@ pushNotifications(FILE *_configd_trace)
 		    (storePrivate->notifyFile >= 0)) {
 			ssize_t		written;
 
-			SC_trace(_configd_trace, "%s : %5d : fd = %d, msgid = %d\n",
-				 "-->fd  ",
+			/*
+			 * Associate notification activity with the client
+			 */
+			os_activity_scope(theSession->activity);
+
+			SC_trace("-->fd   : %5d : fd = %d, msgid = %d",
 				 storePrivate->server,
 				 storePrivate->notifyFile,
 				 storePrivate->notifyFileIdentifier);
@@ -318,13 +328,18 @@ pushNotifications(FILE *_configd_trace)
 		    (storePrivate->notifySignal > 0)) {
 			kern_return_t	status;
 			pid_t		pid;
+
+			/*
+			 * Associate notification activity with the client
+			 */
+			os_activity_scope(theSession->activity);
+
 			/*
 			 * Post notification as signal
 			 */
 			status = pid_for_task(storePrivate->notifySignalTask, &pid);
 			if (status == KERN_SUCCESS) {
-				SC_trace(_configd_trace, "%s : %5d : pid = %d, signal = sig%s (%d)\n",
-					 "-->sig ",
+				SC_trace("-->sig  : %5d : pid = %d, signal = sig%s (%d)",
 					 storePrivate->server,
 					 pid,
 					 sys_signame[storePrivate->notifySignal],
diff --git a/configd.tproj/_SCD.h b/configd.tproj/_SCD.h
index 535ed9e..b3f01b7 100644
--- a/configd.tproj/_SCD.h
+++ b/configd.tproj/_SCD.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2001, 2003, 2004, 2006, 2009, 2011, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003, 2004, 2006, 2009, 2011, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -191,7 +191,7 @@ _removeWatcher				(CFNumberRef		sessionNum,
 					 CFStringRef		watchedKey);
 
 void
-pushNotifications			(FILE			*_configd_trace);
+pushNotifications			();
 
 __END_DECLS
 
diff --git a/configd.tproj/_configadd.c b/configd.tproj/_configadd.c
index 0f84e88..bdc5d4f 100644
--- a/configd.tproj/_configadd.c
+++ b/configd.tproj/_configadd.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2001, 2003, 2004, 2006, 2008, 2011, 2012, 2014, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003, 2004, 2006, 2008, 2011, 2012, 2014-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -42,8 +42,7 @@ __SCDynamicStoreAddValue(SCDynamicStoreRef store, CFStringRef key, CFDataRef val
 	SCDynamicStorePrivateRef	storePrivate	= (SCDynamicStorePrivateRef)store;
 	CFDataRef			tempValue;
 
-	SC_trace(_configd_trace, "%s%s : %5d : %@\n",
-		 "add  ",
+	SC_trace("add  %s : %5d : %@",
 		 storePrivate->useSessionKeys ? "t " : "  ",
 		 storePrivate->server,
 		 key);
diff --git a/configd.tproj/_configclose.c b/configd.tproj/_configclose.c
index 2b0fd7b..425e364 100644
--- a/configd.tproj/_configclose.c
+++ b/configd.tproj/_configclose.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2001, 2003, 2004, 2006-2012, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003, 2004, 2006-2012, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -101,7 +101,7 @@ __SCDynamicStoreClose(SCDynamicStoreRef *store)
 	CFStringRef			sessionKey;
 	SCDynamicStorePrivateRef	storePrivate = (SCDynamicStorePrivateRef)*store;
 
-	SC_trace(_configd_trace, "close   : %5d\n",
+	SC_trace("close   : %5d",
 		 storePrivate->server);
 
 	/* Remove all notification keys and patterns */
@@ -140,6 +140,8 @@ __SCDynamicStoreClose(SCDynamicStoreRef *store)
 	 * port (for this client).  Then, release the port.
 	 */
 	mySession = getSession(storePrivate->server);
+	assert(mySession != NULL);
+
 	if (mySession->serverRunLoopSource) {
 		CFRunLoopSourceInvalidate(mySession->serverRunLoopSource);
 		CFRelease(mySession->serverRunLoopSource);
diff --git a/configd.tproj/_configget.c b/configd.tproj/_configget.c
index 7b0335f..6a08c54 100644
--- a/configd.tproj/_configget.c
+++ b/configd.tproj/_configget.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2006, 2008, 2011, 2013-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2006, 2008, 2011, 2013-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -41,13 +41,13 @@ __SCDynamicStoreCopyValue(SCDynamicStoreRef store, CFStringRef key, CFDataRef *v
 	SCDynamicStorePrivateRef	storePrivate = (SCDynamicStorePrivateRef)store;
 	CFDictionaryRef			dict;
 
-	SC_trace(_configd_trace, "%s : %5d : %@\n",
+	SC_trace("%s : %5d : %@",
 		 internal ? "*copy  " : "copy   ",
 		 storePrivate->server,
 		 key);
 
 	dict = CFDictionaryGetValue(storeData, key);
-	if ((dict == NULL) || (CFDictionaryContainsKey(dict, kSCDData) == FALSE)) {
+	if ((dict == NULL) || !CFDictionaryContainsKey(dict, kSCDData)) {
 		/* key doesn't exist (or data never defined) */
 		return kSCStatusNoKey;
 	}
@@ -184,7 +184,7 @@ __SCDynamicStoreCopyMultiple(SCDynamicStoreRef store, CFArrayRef keys, CFArrayRe
 	SCDynamicStorePrivateRef	storePrivate = (SCDynamicStorePrivateRef)store;
 	addSpecific			myContext;
 
-	SC_trace(_configd_trace, "copy m  : %5d : %ld keys, %ld patterns\n",
+	SC_trace("copy m  : %5d : %ld keys, %ld patterns",
 		 storePrivate->server,
 		 keys     ? CFArrayGetCount(keys)     : 0,
 		 patterns ? CFArrayGetCount(patterns) : 0);
diff --git a/configd.tproj/_configlist.c b/configd.tproj/_configlist.c
index 355a4af..6ec426e 100644
--- a/configd.tproj/_configlist.c
+++ b/configd.tproj/_configlist.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2008, 2011, 2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2008, 2011, 2013, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -47,8 +47,7 @@ __SCDynamicStoreCopyKeyList(SCDynamicStoreRef store, CFStringRef key, Boolean is
 	CFStringRef			storeStr;
 	CFDictionaryRef			storeValue;
 
-	SC_trace(_configd_trace, "%s : %5d : %s : %@\n",
-		 "list   ",
+	SC_trace("list    : %5d : %s : %@",
 		 storePrivate->server,
 		 isRegex  ? "pattern" : "key",
 		 key);
diff --git a/configd.tproj/_confignotify.c b/configd.tproj/_confignotify.c
index 76cc73d..26725d2 100644
--- a/configd.tproj/_confignotify.c
+++ b/configd.tproj/_confignotify.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2004, 2006, 2008, 2011, 2012, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2004, 2006, 2008, 2011, 2012, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -41,7 +41,7 @@ __SCDynamicStoreNotifyValue(SCDynamicStoreRef store, CFStringRef key, Boolean in
 	int				sc_status	= kSCStatusOK;
 	CFDataRef			value;
 
-	SC_trace(_configd_trace, "%s : %5d : %@\n",
+	SC_trace("%s : %5d : %@",
 		 internal ? "*notify" : "notify ",
 		 storePrivate->server,
 		 key);
diff --git a/configd.tproj/_configopen.c b/configd.tproj/_configopen.c
index 4d68d9b..da5d8a6 100644
--- a/configd.tproj/_configopen.c
+++ b/configd.tproj/_configopen.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2009, 2011, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2009, 2011, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -171,7 +171,7 @@ _configopen(mach_port_t			server,
 			   mySession->serverRunLoopSource,
 			   kCFRunLoopDefaultMode);
 
-	SC_trace(_configd_trace, "open    : %5d : %@\n",
+	SC_trace("open    : %5d : %@",
 		 *newServer,
 		 name);
 
diff --git a/configd.tproj/_configremove.c b/configd.tproj/_configremove.c
index 2cffdeb..04c532e 100644
--- a/configd.tproj/_configremove.c
+++ b/configd.tproj/_configremove.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2004, 2006, 2008, 2011, 2012, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2004, 2006, 2008, 2011, 2012, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -44,7 +44,7 @@ __SCDynamicStoreRemoveValue(SCDynamicStoreRef store, CFStringRef key, Boolean in
 	int				sc_status	= kSCStatusOK;
 	CFStringRef			sessionKey;
 
-	SC_trace(_configd_trace, "%s : %5d : %@\n",
+	SC_trace("%s : %5d : %@",
 		 internal ? "*remove" : "remove ",
 		 storePrivate->server,
 		 key);
@@ -53,7 +53,7 @@ __SCDynamicStoreRemoveValue(SCDynamicStoreRef store, CFStringRef key, Boolean in
 	 * Ensure that this key exists.
 	 */
 	dict = CFDictionaryGetValue(storeData, key);
-	if ((dict == NULL) || (CFDictionaryContainsKey(dict, kSCDData) == FALSE)) {
+	if ((dict == NULL) || !CFDictionaryContainsKey(dict, kSCDData)) {
 		/* key doesn't exist (or data never defined) */
 		sc_status = kSCStatusNoKey;
 		goto done;
diff --git a/configd.tproj/_configset.c b/configd.tproj/_configset.c
index 16044ad..432ad4f 100644
--- a/configd.tproj/_configset.c
+++ b/configd.tproj/_configset.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2004, 2006, 2008, 2011, 2012, 2014, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2004, 2006, 2008, 2011, 2012, 2014-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -49,7 +49,7 @@ __SCDynamicStoreSetValue(SCDynamicStoreRef store, CFStringRef key, CFDataRef val
 	SCDynamicStorePrivateRef	storePrivate	= (SCDynamicStorePrivateRef)store;
 	CFStringRef			storeSessionKey;
 
-	SC_trace(_configd_trace, "%s%s : %5d : %@\n",
+	SC_trace("%s%s : %5d : %@",
 		 internal ? "*set " : "set  ",
 		 storePrivate->useSessionKeys ? "t " : "  ",
 		 storePrivate->server,
@@ -324,7 +324,7 @@ __SCDynamicStoreSetMultiple(SCDynamicStoreRef store, CFDictionaryRef keysToSet,
 	int				sc_status	= kSCStatusOK;
 	SCDynamicStorePrivateRef	storePrivate	= (SCDynamicStorePrivateRef)store;
 
-	SC_trace(_configd_trace, "set m   : %5d : %ld set, %ld remove, %ld notify\n",
+	SC_trace("set m   : %5d : %ld set, %ld remove, %ld notify",
 		 storePrivate->server,
 		 keysToSet    ? CFDictionaryGetCount(keysToSet)    : 0,
 		 keysToRemove ? CFArrayGetCount     (keysToRemove) : 0,
diff --git a/configd.tproj/_configunlock.c b/configd.tproj/_configunlock.c
index c5df463..2e14b25 100644
--- a/configd.tproj/_configunlock.c
+++ b/configd.tproj/_configunlock.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2004, 2006, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2004, 2006, 2011, 2015 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -69,7 +69,7 @@ _notifyWatchers()
 		const void **		watchers	= watchers_q;
 
 		dict = CFDictionaryGetValue(storeData, (CFStringRef)keys[keyCnt]);
-		if ((dict == NULL) || (CFDictionaryContainsKey(dict, kSCDWatchers) == FALSE)) {
+		if ((dict == NULL) || !CFDictionaryContainsKey(dict, kSCDWatchers)) {
 			/* key doesn't exist or nobody cares if it changed */
 			continue;
 		}
@@ -95,7 +95,7 @@ _notifyWatchers()
 
 			sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@"), watchers[watcherCnt]);
 			info = CFDictionaryGetValue(sessionData, sessionKey);
-			if (info) {
+			if (info != NULL) {
 				newInfo = CFDictionaryCreateMutableCopy(NULL, 0, info);
 			} else {
 				newInfo = CFDictionaryCreateMutable(NULL,
@@ -111,9 +111,9 @@ _notifyWatchers()
 				newChanges = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
 			}
 
-			if (CFArrayContainsValue(newChanges,
-						 CFRangeMake(0, CFArrayGetCount(newChanges)),
-						 (CFStringRef)keys[keyCnt]) == FALSE) {
+			if (!CFArrayContainsValue(newChanges,
+						  CFRangeMake(0, CFArrayGetCount(newChanges)),
+						  (CFStringRef)keys[keyCnt])) {
 				CFArrayAppendValue(newChanges, (CFStringRef)keys[keyCnt]);
 			}
 			CFDictionarySetValue(newInfo, kSCDChangedKeys, newChanges);
diff --git a/configd.tproj/_notifyadd.c b/configd.tproj/_notifyadd.c
index 17506fb..76f3564 100644
--- a/configd.tproj/_notifyadd.c
+++ b/configd.tproj/_notifyadd.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2004, 2006, 2008, 2010, 2011, 2014, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2004, 2006, 2008, 2010, 2011, 2014-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -89,7 +89,7 @@ __SCDynamicStoreAddWatchedKey(SCDynamicStoreRef store, CFStringRef key, Boolean
 	CFNumberRef			sessionNum	= NULL;
 	SCDynamicStorePrivateRef	storePrivate	= (SCDynamicStorePrivateRef)store;
 
-	SC_trace(_configd_trace, "%s : %5d : %s : %@\n",
+	SC_trace("%s : %5d : %s : %@",
 		 internal ? "*watch+" : "watch+ ",
 		 storePrivate->server,
 		 isRegex  ? "pattern" : "key",
@@ -243,7 +243,7 @@ __SCDynamicStoreSetNotificationKeys(SCDynamicStoreRef store, CFArrayRef keys, CF
 	updateKeysContext		myContext;
 	SCDynamicStorePrivateRef	storePrivate = (SCDynamicStorePrivateRef)store;
 
-	SC_trace(_configd_trace, "watch   : %5d : %ld keys, %ld patterns\n",
+	SC_trace("watch   : %5d : %ld keys, %ld patterns",
 		 storePrivate->server,
 		 keys     ? CFArrayGetCount(keys)     : 0,
 		 patterns ? CFArrayGetCount(patterns) : 0);
diff --git a/configd.tproj/_notifychanges.c b/configd.tproj/_notifychanges.c
index b8aad1b..5bc4268 100644
--- a/configd.tproj/_notifychanges.c
+++ b/configd.tproj/_notifychanges.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2004, 2006, 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2004, 2006, 2011, 2013, 2015 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -46,7 +46,7 @@ __SCDynamicStoreCopyNotifiedKeys(SCDynamicStoreRef store, CFArrayRef *notifierKe
 	sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), storePrivate->server);
 	info = CFDictionaryGetValue(sessionData, sessionKey);
 	if ((info == NULL) ||
-	    (CFDictionaryContainsKey(info, kSCDChangedKeys) == FALSE)) {
+	    !CFDictionaryContainsKey(info, kSCDChangedKeys)) {
 		CFRelease(sessionKey);
 		*notifierKeys = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks);
 		return kSCStatusOK;
diff --git a/configd.tproj/_notifyremove.c b/configd.tproj/_notifyremove.c
index f3269b8..811290b 100644
--- a/configd.tproj/_notifyremove.c
+++ b/configd.tproj/_notifyremove.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2004, 2006, 2008, 2010-2012, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2004, 2006, 2008, 2010-2012, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -69,7 +69,7 @@ __SCDynamicStoreRemoveWatchedKey(SCDynamicStoreRef store, CFStringRef key, Boole
 	CFNumberRef			sessionNum;
 	SCDynamicStorePrivateRef	storePrivate	= (SCDynamicStorePrivateRef)store;
 
-	SC_trace(_configd_trace, "%s : %5d : %s : %@\n",
+	SC_trace("%s : %5d : %s : %@",
 		 internal ? "*watch-" : "watch- ",
 		 storePrivate->server,
 		 isRegex  ? "pattern" : "key",
diff --git a/configd.tproj/_snapshot.c b/configd.tproj/_snapshot.c
index b606be1..76c9370 100644
--- a/configd.tproj/_snapshot.c
+++ b/configd.tproj/_snapshot.c
@@ -82,7 +82,11 @@ _expandStore(CFDictionaryRef storeData)
 
 				nValues[i] = CFDictionaryCreateMutableCopy(NULL, 0, oValues[i]);
 
-				_SCUnserialize(&plist, data, NULL, 0);
+				if (!_SCUnserialize(&plist, data, NULL, 0)) {
+					SC_log(LOG_NOTICE, "_SCUnserialize() failed, key=%@", keys[i]);
+					continue;
+				}
+
 				CFDictionarySetValue((CFMutableDictionaryRef)nValues[i],
 						     kSCDData,
 						     plist);
diff --git a/configd.tproj/configd.h b/configd.tproj/configd.h
index 15e251c..58228b7 100644
--- a/configd.tproj/configd.h
+++ b/configd.tproj/configd.h
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2000, 2001, 2003, 2006, 2007, 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003, 2006, 2007, 2011, 2013, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -36,28 +36,31 @@
 
 #include 
 #include 
-#include 
-#include 
-#include 
 
 /* configd doesn't need the preference keys */
 #define _SCSCHEMADEFINITIONS_H
 #define _SCSCHEMADEFINITIONSPRIVATE_H
 
-#include 
-#include 
+#define	SC_LOG_HANDLE	__configd_SCDynamicStore()
 #include "SCDynamicStoreInternal.h"
-#include 
 #include "config_types.h"
 #include "_SCD.h"
 
-extern Boolean		_configd_verbose;	/* TRUE if verbose logging enabled */
-extern FILE		*_configd_trace;	/* non-NULL if tracing enabled */
-extern CFMutableSetRef	_plugins_allowed;	/* bundle identifiers to allow when loading */
-extern CFMutableSetRef	_plugins_exclude;	/* bundle identifiers to exclude from loading */
-extern CFMutableSetRef	_plugins_verbose;	/* bundle identifiers to enable verbose logging */
+extern Boolean		_configd_verbose;		/* TRUE if verbose logging enabled */
+extern CFMutableSetRef	_plugins_allowed;		/* bundle identifiers to allow when loading */
+extern CFMutableSetRef	_plugins_exclude;		/* bundle identifiers to exclude from loading */
+extern CFMutableSetRef	_plugins_verbose;		/* bundle identifiers to enable verbose logging */
+
+
+#define SC_trace(__string, ...)	\
+	os_log_debug(SC_LOG_HANDLE, __string, ## __VA_ARGS__)
+
 
 __BEGIN_DECLS
+
+os_log_t
+__configd_SCDynamicStore	();
+
 __END_DECLS
 
 #endif /* !_S_CONFIGD_H */
diff --git a/configd.tproj/configd.m b/configd.tproj/configd.m
index d4dda37..623d632 100644
--- a/configd.tproj/configd.m
+++ b/configd.tproj/configd.m
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2011, 2013-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2011, 2013-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -62,9 +62,6 @@
 __private_extern__
 Boolean	_configd_verbose		= FALSE;	/* TRUE if verbose logging enabled */
 
-__private_extern__
-FILE	*_configd_trace			= NULL;		/* non-NULL if tracing enabled */
-
 __private_extern__
 CFMutableSetRef	_plugins_allowed	= NULL;		/* bundle identifiers to allow when loading */
 
@@ -108,6 +105,19 @@ usage(const char *prog)
 }
 
 
+__private_extern__ os_log_t
+__configd_SCDynamicStore()
+{
+	static os_log_t	log	= NULL;
+
+	if (log == NULL) {
+		log = os_log_create("com.apple.SystemConfiguration", "SCDynamicStore");
+	}
+
+	return log;
+}
+
+
 static void
 catcher(int signum)
 {
@@ -201,22 +211,6 @@ init_fds()
 }
 
 
-static void
-set_trace()
-{
-	int	fd;
-
-	/* set _configd_trace */
-	fd = open("/var/log/configd.trace", O_WRONLY|O_APPEND, 0);
-	if (fd != -1) {
-		_configd_trace = fdopen(fd, "a");
-		SC_trace(_configd_trace, "start\n");
-	}
-
-	return;
-}
-
-
 static int
 fork_child()
 {
@@ -338,12 +332,12 @@ main(int argc, char * const argv[])
 //	argv += optind;
 
 	/* check credentials */
-#if	!TARGET_IPHONE_SIMULATOR
+#if	!TARGET_OS_SIMULATOR
 	if (getuid() != 0) {
 		fprintf(stderr, "%s: permission denied.\n", prog);
 		exit (EX_NOPERM);
 	}
-#endif	// !TARGET_IPHONE_SIMULATOR
+#endif	// !TARGET_OS_SIMULATOR
 
 	/* check if we have been started by launchd */
 	vproc_swap_integer(NULL, VPROC_GSK_IS_MANAGED, NULL, &is_launchd_job);
@@ -376,7 +370,7 @@ main(int argc, char * const argv[])
 #endif	// TARGET_OS_EMBEDDED && !defined(DO_NOT_INFORM)
 
 	/* ensure that forked plugins behave */
-	if ((testBundle != NULL) && (getenv("__FORKED_PLUGIN__") != NULL)) {
+	if (testBundle != NULL) {
 		forcePlugin = TRUE;
 	}
 
@@ -424,9 +418,6 @@ main(int argc, char * const argv[])
 		_sc_log = FALSE;	/* redirect SCLog() to stdout/stderr */
 	}
 
-	/* check/enable trace logging */
-	set_trace();
-
 	/* add signal handler to catch a SIGHUP */
 	nact.sa_handler = catcher;
 	sigemptyset(&nact.sa_mask);
diff --git a/configd.tproj/configd_server.c b/configd.tproj/configd_server.c
index 182d629..d586863 100644
--- a/configd.tproj/configd_server.c
+++ b/configd.tproj/configd_server.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2011, 2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2011, 2013, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -52,6 +52,7 @@ extern boolean_t		config_server(mach_msg_header_t *, mach_msg_header_t *);
 /* configd server port (for new session requests) */
 static CFMachPortRef		configd_port		= NULL;
 
+
 __private_extern__
 boolean_t
 config_demux(mach_msg_header_t *request, mach_msg_header_t *reply)
@@ -97,7 +98,6 @@ __private_extern__
 void
 configdCallback(CFMachPortRef port, void *msg, CFIndex size, void *info)
 {
-	os_activity_t		activity_id;
 	mig_reply_error_t *	bufRequest	= msg;
 	uint32_t		bufReply_q[MACH_MSG_BUFFER_SIZE/sizeof(uint32_t)];
 	mig_reply_error_t *	bufReply	= (mig_reply_error_t *)bufReply_q;
@@ -105,9 +105,6 @@ configdCallback(CFMachPortRef port, void *msg, CFIndex size, void *info)
 	mach_msg_return_t	mr;
 	int			options;
 
-	activity_id = os_activity_start("processing SCDynamicStore request",
-					OS_ACTIVITY_FLAG_DEFAULT);
-
 	if (bufSize == 0) {
 		// get max size for MiG reply buffers
 		bufSize = _config_subsystem.maxsize;
@@ -185,8 +182,6 @@ configdCallback(CFMachPortRef port, void *msg, CFIndex size, void *info)
 	if (bufReply != (mig_reply_error_t *)bufReply_q)
 		CFAllocatorDeallocate(NULL, bufReply);
 
-	os_activity_end(activity_id);
-
 	return;
 }
 
@@ -210,7 +205,7 @@ server_init()
 	kern_return_t 		status;
 
 	service_name = getenv("SCD_SERVER");
-	if (!service_name) {
+	if (service_name == NULL) {
 		service_name = SCD_SERVER;
 	}
 
@@ -296,6 +291,6 @@ server_loop()
 		 * check for, and if necessary, push out change notifications
 		 * to other processes.
 		 */
-		pushNotifications(_configd_trace);
+		pushNotifications();
 	}
 }
diff --git a/configd.tproj/entitlements-ios.plist b/configd.tproj/entitlements-ios.plist
index f04bc3a..af4aaa1 100644
--- a/configd.tproj/entitlements-ios.plist
+++ b/configd.tproj/entitlements-ios.plist
@@ -24,6 +24,8 @@
 	
 	com.apple.private.necp.match
 	
+	com.apple.private.nehelper.privileged
+	
 	com.apple.private.snhelper
 	
 	com.apple.security.network.client
@@ -36,5 +38,11 @@
 	
 	com.apple.wlan.authentication
 	
+	com.apple.captiveagent.privileged
+	
+	com.apple.networkd_privileged
+	
+	com.apple.networkd.modify_settings
+	
 
 
diff --git a/configd.tproj/plugin_support.c b/configd.tproj/plugin_support.c
index 75b3c52..54e5d7f 100644
--- a/configd.tproj/plugin_support.c
+++ b/configd.tproj/plugin_support.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -42,9 +42,9 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
-#include 
 
 #include "configd.h"
 #include "configd_server.h"
@@ -82,7 +82,7 @@ static const CFStringRef	pluginWhitelist[]	= {
 	PLUGIN_ALL   ("com.apple.SystemConfiguration.Logger"),
 	PLUGIN_ALL   ("com.apple.SystemConfiguration.PPPController"),
 	PLUGIN_ALL   ("com.apple.SystemConfiguration.PreferencesMonitor"),
-	PLUGIN_ALL   ("com.apple.SystemConfiguration.SCNetworkReachability"),
+	PLUGIN_IOS   ("com.apple.SystemConfiguration.QoSMarking"),
 	PLUGIN_MACOSX("com.apple.print.notification"),
 };
 #define	N_PLUGIN_WHITELIST	(sizeof(pluginWhitelist) / sizeof(pluginWhitelist[0]))
@@ -115,14 +115,17 @@ CFRunLoopRef			plugin_runLoop		= NULL;
 
 extern SCDynamicStoreBundleLoadFunction		load_IPMonitor;
 extern SCDynamicStoreBundlePrimeFunction	prime_IPMonitor;
-#if	!TARGET_IPHONE_SIMULATOR
+#if	!TARGET_OS_SIMULATOR
 extern SCDynamicStoreBundleLoadFunction		load_InterfaceNamer;
 extern SCDynamicStoreBundleLoadFunction		load_KernelEventMonitor;
 extern SCDynamicStoreBundlePrimeFunction	prime_KernelEventMonitor;
 extern SCDynamicStoreBundleLoadFunction		load_LinkConfiguration;
 extern SCDynamicStoreBundleLoadFunction		load_PreferencesMonitor;
 extern SCDynamicStoreBundlePrimeFunction	prime_PreferencesMonitor;
-#endif	// !TARGET_IPHONE_SIMULATOR
+#if	TARGET_OS_IPHONE
+extern SCDynamicStoreBundleLoadFunction		load_QoSMarking;
+#endif	// TARGET_OS_IPHONE
+#endif	// !TARGET_OS_SIMULATOR
 
 
 typedef struct {
@@ -142,7 +145,7 @@ static const builtin builtin_plugins[] = {
 		&prime_IPMonitor,
 		NULL
 	},
-#if	!TARGET_IPHONE_SIMULATOR
+#if	!TARGET_OS_SIMULATOR
 	{
 		CFSTR("com.apple.SystemConfiguration.InterfaceNamer"),
 		&load_InterfaceNamer,
@@ -171,68 +174,19 @@ static const builtin builtin_plugins[] = {
 		&prime_PreferencesMonitor,
 		NULL
 	},
-#endif	// !TARGET_IPHONE_SIMULATOR
+#if	TARGET_OS_IPHONE
+	{
+		CFSTR("com.apple.SystemConfiguration.QoSMarking"),
+		&load_QoSMarking,
+		NULL,
+		NULL,
+		NULL
+	},
+#endif	// TARGET_OS_IPHONE
+#endif	// !TARGET_OS_SIMULATOR
 };
 
 
-#ifdef	DEBUG
-static void
-traceBundle(const char *op, CFBundleRef bundle)
-{
-	if (bundle != NULL) {
-		CFStringRef	bundleID	= CFBundleGetIdentifier(bundle);
-
-		SC_trace(_configd_trace, "bundle  : %s %@\n",
-			 op,
-			 bundleID);
-	} else {
-		SC_trace(_configd_trace, "bundle  : %s\n",
-			 op);
-	}
-
-	const char *path = getenv("LOG_CONFIGD_BUNDLE_USAGE");
-	if (path != NULL) {
-		FILE	*file;
-		int	status;
-		char	*top_command;
-
-		file = fopen(path, "a");
-		if (file == NULL) {
-			return;
-		}
-
-		// let everything settle down before grabbing a snapshot
-		(void)sleep(2);
-
-		SCPrint(TRUE, file, CFSTR("\n--------------------\n\n"), op);
-		if (bundle != NULL) {
-			CFStringRef	bundleID	= CFBundleGetIdentifier(bundle);
-
-			SC_trace(file, "%s bundle \"%@\"\n\n", op, bundleID);
-		} else {
-			SC_trace(file, "%s\n\n", op);
-		}
-		SCPrint(TRUE, file, CFSTR("%@\n\n"), CFRunLoopGetCurrent());
-		fclose(file);
-
-		if (asprintf(&top_command, "/usr/bin/top -o+pid -l 1 >> %s", path) == -1) {
-			return;
-		}
-
-		status = system(top_command);
-		if ((status == -1) ||
-		    !WIFEXITED(status) ||
-		    (WEXITSTATUS(status) != 0)) {
-			SC_log(LOG_NOTICE, "system(\"%s\") failed", top_command);
-		}
-		free(top_command);
-	}
-
-	return;
-}
-#endif	/* DEBUG */
-
-
 static void
 addBundle(CFBundleRef bundle, Boolean forceEnabled)
 {
@@ -453,10 +407,6 @@ loadBundle(const void *value, void *context) {
 
 		SC_log(LOG_INFO, "loading %@", bundleID);
 
-#ifdef	DEBUG
-		traceBundle("loading", bundleInfo->bundle);
-#endif	/* DEBUG */
-
 		if (!CFBundleLoadExecutableAndReturnError(bundleInfo->bundle, &error)) {
 			CFDictionaryRef	user_info;
 
@@ -509,9 +459,8 @@ callLoadFunction(const void *value, void *context) {
 		return;
 	}
 
-#ifdef	DEBUG
-	traceBundle("calling load() for", bundleInfo->bundle);
-#endif	/* DEBUG */
+	SC_log(LOG_DEBUG, "calling load() for %@",
+	       CFBundleGetIdentifier(bundleInfo->bundle));
 
 	(*bundleInfo->load)(bundleInfo->bundle, bundleInfo->verbose);
 
@@ -555,9 +504,8 @@ callStartFunction(const void *value, void *context) {
 	len = strlen(bundleName) - (sizeof(BUNDLE_DIR_EXTENSION) - 1);
 	bundleName[len] = '\0';
 
-#ifdef	DEBUG
-	traceBundle("calling start() for", bundleInfo->bundle);
-#endif	/* DEBUG */
+	SC_log(LOG_DEBUG, "calling start() for %@",
+	       CFBundleGetIdentifier(bundleInfo->bundle));
 
 	(*bundleInfo->start)(bundleName, bundlePath);
 
@@ -582,9 +530,8 @@ callPrimeFunction(const void *value, void *context) {
 		return;
 	}
 
-#ifdef	DEBUG
-	traceBundle("calling prime() for", bundleInfo->bundle);
-#endif	/* DEBUG */
+	SC_log(LOG_DEBUG, "calling prime() for %@",
+	       CFBundleGetIdentifier(bundleInfo->bundle));
 
 	(*bundleInfo->prime)();
 
@@ -813,23 +760,6 @@ plugin_term(int *status)
 #pragma mark initialization
 
 
-#ifdef	DEBUG
-static void
-timerCallback(CFRunLoopTimerRef timer, void *info)
-{
-	static int	pass	= 0;
-
-	pass++;
-	if ((pass > 120) && ((pass % 60) != 0)) {
-		return;
-	}
-
-	traceBundle("the [plugin] CFRunLoop is waiting...", NULL);
-	return;
-}
-#endif	/* DEBUG */
-
-
 static void
 sortBundles(CFMutableArrayRef orig)
 {
@@ -905,7 +835,7 @@ sortBundles(CFMutableArrayRef orig)
 			}
 		}
 
-		if (inserted == FALSE) {
+		if (!inserted) {
 			SC_log(LOG_NOTICE, "Bundles have circular dependency!!!");
 			break;
 		}
@@ -962,19 +892,19 @@ plugin_exec(void *arg)
 	_SCDPluginExecInit();
 
 	if (arg == NULL) {
-		char				path[MAXPATHLEN];
-		NSSearchPathEnumerationState	state;
+		char					path[MAXPATHLEN];
+		sysdir_search_path_enumeration_state	state;
 
 		/*
 		 * identify and load all bundles
 		 */
-		state = NSStartSearchPathEnumeration(NSLibraryDirectory,
-						     NSSystemDomainMask);
-		while ((state = NSGetNextSearchPathEnumeration(state, path))) {
+		state = sysdir_start_search_path_enumeration(SYSDIR_DIRECTORY_LIBRARY,
+							     SYSDIR_DOMAIN_MASK_SYSTEM);
+		while ((state = sysdir_get_next_search_path_enumeration(state, path))) {
 			CFArrayRef	bundles;
 			CFURLRef	url;
 
-#if	TARGET_IPHONE_SIMULATOR
+#if	TARGET_OS_SIMULATOR
 			const char	*path_sim_prefix;
 
 			path_sim_prefix = getenv("IPHONE_SIMULATOR_ROOT");
@@ -987,7 +917,7 @@ plugin_exec(void *arg)
 			} else {
 				path[0] = '\0';
 			}
-#endif	// TARGET_IPHONE_SIMULATOR
+#endif	// TARGET_OS_SIMULATOR
 
 			/* load any available bundle */
 			strlcat(path, BUNDLE_DIRECTORY, sizeof(path));
@@ -1078,10 +1008,6 @@ plugin_exec(void *arg)
 		}
 	}
 
-#ifdef	DEBUG
-	traceBundle("before loading any plugins", NULL);
-#endif	/* DEBUG */
-
 	/*
 	 * load each bundle.
 	 */
@@ -1143,27 +1069,6 @@ plugin_exec(void *arg)
 			     callPrimeFunction,
 			     NULL);
 
-#ifdef	DEBUG
-	if (arg == NULL && (nLoaded > 0)) {
-		CFRunLoopTimerRef	timer;
-
-		/* allocate a periodic event (to help show we're not blocking) */
-		timer = CFRunLoopTimerCreate(NULL,				/* allocator */
-					     CFAbsoluteTimeGetCurrent() + 1.0,	/* fireDate */
-					     1.0,				/* interval */
-					     0,					/* flags */
-					     0,					/* order */
-					     timerCallback,			/* callout */
-					     NULL);				/* context */
-		CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopDefaultMode);
-		CFRelease(timer);
-	}
-#endif	/* DEBUG */
-
-#ifdef	DEBUG
-	traceBundle("about to start plugin CFRunLoop", NULL);
-#endif	/* DEBUG */
-
 	/*
 	 * The assumption is that each loaded plugin will establish CFMachPortRef,
 	 * CFSocketRef, and CFRunLoopTimerRef input sources to handle any events
diff --git a/configd.tproj/session.c b/configd.tproj/session.c
index bd29b7b..5ac44c9 100644
--- a/configd.tproj/session.c
+++ b/configd.tproj/session.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2001, 2003-2005, 2007-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003-2005, 2007-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -41,7 +41,7 @@
 #include 
 #include 
 
-#if !TARGET_IPHONE_SIMULATOR || (defined(IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED) && (IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED >= 1090))
+#if !TARGET_OS_SIMULATOR || (defined(IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED) && (IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED >= 1090))
 #define HAVE_MACHPORT_GUARDS
 #endif
 
@@ -54,9 +54,6 @@ static int		lastSession	= -1;	/* # of last used session */
 /* CFMachPortInvalidation runloop */
 static CFRunLoopRef	sessionRunLoop	= NULL;
 
-/* temp session */
-static serverSessionRef	temp_session	= NULL;
-
 
 __private_extern__
 serverSessionRef
@@ -100,34 +97,36 @@ serverSessionRef
 tempSession(mach_port_t server, CFStringRef name, audit_token_t auditToken)
 {
 	static dispatch_once_t		once;
-	SCDynamicStorePrivateRef	storePrivate;
+	SCDynamicStorePrivateRef	storePrivate;	/* temp session */
+	static serverSession		temp_session;
+
+	dispatch_once(&once, ^{
+		temp_session = *sessions[0];	/* use "server" session */
+		temp_session.activity = NULL;
+		(void) __SCDynamicStoreOpen(&temp_session.store, NULL);
+	});
 
-	if (sessions[0]->key != server) {
+	if (temp_session.key != server) {
 		// if not SCDynamicStore "server" port
 		return NULL;
 	}
 
-	dispatch_once(&once, ^{
-		temp_session = sessions[0];	/* use "server" session */
-		(void) __SCDynamicStoreOpen(&temp_session->store, NULL);
-	});
-
 	/* save audit token, caller entitlements */
-	temp_session->auditToken		= auditToken;
-	temp_session->callerEUID		= 1;		/* not "root" */
-	temp_session->callerRootAccess		= UNKNOWN;
-	if ((temp_session->callerWriteEntitlement != NULL) &&
-	    (temp_session->callerWriteEntitlement != kCFNull)) {
-		CFRelease(temp_session->callerWriteEntitlement);
+	temp_session.auditToken			= auditToken;
+	temp_session.callerEUID			= 1;		/* not "root" */
+	temp_session.callerRootAccess		= UNKNOWN;
+	if ((temp_session.callerWriteEntitlement != NULL) &&
+	    (temp_session.callerWriteEntitlement != kCFNull)) {
+		CFRelease(temp_session.callerWriteEntitlement);
 	}
-	temp_session->callerWriteEntitlement	= kCFNull;	/* UNKNOWN */
+	temp_session.callerWriteEntitlement	= kCFNull;	/* UNKNOWN */
 
 	/* save name */
-	storePrivate = (SCDynamicStorePrivateRef)temp_session->store;
+	storePrivate = (SCDynamicStorePrivateRef)temp_session.store;
 	if (storePrivate->name != NULL) CFRelease(storePrivate->name);
 	storePrivate->name = CFRetain(name);
 
-	return temp_session;
+	return &temp_session;
 }
 
 
@@ -270,13 +269,17 @@ addSession(mach_port_t server, CFStringRef (*copyDescription)(const void *info))
 		}
 	}
 
+	newSession->activity			= os_activity_create("processing SCDynamicStore notification",
+								     OS_ACTIVITY_CURRENT,
+								     OS_ACTIVITY_FLAG_DEFAULT);
+	newSession->callerEUID			= 1;		/* not "root" */
+	newSession->callerRootAccess		= UNKNOWN;
+	newSession->callerWriteEntitlement	= kCFNull;	/* UNKNOWN */
+	newSession->key				= mp;
+//	newSession->serverRunLoopSource		= NULL;
+//	newSession->store			= NULL;
+
 	sessions[n] = newSession;
-	sessions[n]->key			= mp;
-//	sessions[n]->serverRunLoopSource	= NULL;
-//	sessions[n]->store			= NULL;
-	sessions[n]->callerEUID			= 1;		/* not "root" */
-	sessions[n]->callerRootAccess		= UNKNOWN;
-	sessions[n]->callerWriteEntitlement	= kCFNull;	/* UNKNOWN */
 
 	return newSession;
 }
@@ -302,7 +305,7 @@ cleanupSession(mach_port_t server)
 			 * session entry still exists.
 			 */
 
-			SC_trace(_configd_trace, "cleanup : %5d\n", server);
+			SC_trace("cleanup : %5d", server);
 
 			/*
 			 * Close any open connections including cancelling any outstanding
@@ -329,6 +332,13 @@ cleanupSession(mach_port_t server)
 				CFRelease(thisSession->callerWriteEntitlement);
 			}
 
+			/*
+			 * release our per-session activity
+			 */
+			if (thisSession->activity != NULL) {
+				os_release(thisSession->activity);
+			}
+
 			/*
 			 * We don't need any remaining information in the
 			 * sessionData dictionary, remove it.
@@ -505,7 +515,7 @@ __private_extern__
 Boolean
 hasRootAccess(serverSessionRef session)
 {
-#if	!TARGET_IPHONE_SIMULATOR
+#if	!TARGET_OS_SIMULATOR
 
 	if (session->callerRootAccess == UNKNOWN) {
 #if     (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) && !TARGET_OS_IPHONE
@@ -526,7 +536,7 @@ hasRootAccess(serverSessionRef session)
 
 	return (session->callerRootAccess == YES) ? TRUE : FALSE;
 
-#else	// !TARGET_IPHONE_SIMULATOR
+#else	// !TARGET_OS_SIMULATOR
 
 	/*
 	 * assume that all processes interacting with
@@ -534,7 +544,7 @@ hasRootAccess(serverSessionRef session)
 	 */
 	return TRUE;
 
-#endif	// !TARGET_IPHONE_SIMULATOR
+#endif	// !TARGET_OS_SIMULATOR
 }
 
 
diff --git a/configd.tproj/session.h b/configd.tproj/session.h
index 273f8f3..9142546 100644
--- a/configd.tproj/session.h
+++ b/configd.tproj/session.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2001, 2005-2007, 2009-2012, 2014 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2005-2007, 2009-2012, 2014, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -74,6 +74,9 @@ typedef struct {
 	/* data associated with this "open" session */
 	SCDynamicStoreRef	store;
 
+	/* caller's activity */
+	os_activity_t		activity;
+
 	/* credentials associated with this "open" session */
 	uid_t			callerEUID;
 
diff --git a/configd.tproj/update-mach-services b/configd.tproj/update-mach-services
index 94f15e4..22775b8 100755
--- a/configd.tproj/update-mach-services
+++ b/configd.tproj/update-mach-services
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-CONFIGD_LAUNCHD_PLIST=${INSTALL_ROOT}/System/Library/LaunchDaemons/${1}
+CONFIGD_LAUNCHD_PLIST=${DSTROOT}/System/Library/LaunchDaemons/${1}
 CONFIGD_PLUGINS=/tmp/plugins.$$
 EMBEDDED_PROJECTS=/tmp/projects.$$
 PLUGIN_MACHSERVICES=/tmp/plugin.$$
@@ -9,8 +9,8 @@ HAVE_CONFIGD_PLUGINS="MISSING"
 HAVE_IPCONFIGURATION="MISSING"
 
 cp /dev/null ${CONFIGD_PLUGINS}
-if [ -d ${INSTALL_ROOT}/System/Library/SystemConfiguration ]; then
-	(cd ${INSTALL_ROOT}/System/Library/SystemConfiguration ; ls -1d *.bundle >> ${CONFIGD_PLUGINS} 2>/dev/null )
+if [ -d ${DSTROOT}/System/Library/SystemConfiguration ]; then
+	(cd ${DSTROOT}/System/Library/SystemConfiguration ; ls -1d *.bundle >> ${CONFIGD_PLUGINS} 2>/dev/null )
 fi
 
 cp /dev/null ${EMBEDDED_PROJECTS}
@@ -41,14 +41,14 @@ do
 	PLUGIN_PLIST=""
 
 #	if [ -z "${PLUGIN_PLIST}" ]; then
-		PLUGIN_INF=${INSTALL_ROOT}/System/Library/SystemConfiguration/${PLUGIN}/Contents/Info.plist
+		PLUGIN_INF=${DSTROOT}/System/Library/SystemConfiguration/${PLUGIN}/Contents/Info.plist
 		if [ -f ${PLUGIN_INF} ]; then
 			PLUGIN_PLIST=${PLUGIN_INF}
 		fi
 #	fi
 
 	if [ -z "${PLUGIN_PLIST}" ]; then
-		PLUGIN_INF=${INSTALL_ROOT}/System/Library/SystemConfiguration/${PLUGIN}/Info.plist
+		PLUGIN_INF=${DSTROOT}/System/Library/SystemConfiguration/${PLUGIN}/Info.plist
 		if [ -f ${PLUGIN_INF} ]; then
 			PLUGIN_PLIST=${PLUGIN_INF}
 		fi
diff --git a/configd.xcodeproj/project.pbxproj b/configd.xcodeproj/project.pbxproj
index 853f071..6151974 100644
--- a/configd.xcodeproj/project.pbxproj
+++ b/configd.xcodeproj/project.pbxproj
@@ -44,9 +44,9 @@
 			buildPhases = (
 			);
 			dependencies = (
+				72C4A4801BE44D19009D570E /* PBXTargetDependency */,
 				1558480607550D470046C2E9 /* PBXTargetDependency */,
 				1558480807550D470046C2E9 /* PBXTargetDependency */,
-				1558480A07550D470046C2E9 /* PBXTargetDependency */,
 				D6DDAC3D147A24BC00A2E902 /* PBXTargetDependency */,
 				150ECB300D0042DA0065E94D /* PBXTargetDependency */,
 			);
@@ -103,6 +103,8 @@
 				158317B50CFB8660006F62B9 /* PBXTargetDependency */,
 				157A85520D56CA9E00B6F1A0 /* PBXTargetDependency */,
 				157A85540D56CACA00B6F1A0 /* PBXTargetDependency */,
+				155F49AD1C86511300E47D08 /* PBXTargetDependency */,
+				155F49AF1C86511300E47D08 /* PBXTargetDependency */,
 			);
 			name = "configd_plugins-Embedded";
 			productName = Plugins;
@@ -144,6 +146,7 @@
 			isa = PBXAggregateTarget;
 			buildConfigurationList = 15C64A270F684C6B00D78394 /* Build configuration list for PBXAggregateTarget "configd_libSystem" */;
 			buildPhases = (
+				1502C5611BDD4936005CF7EA /* Move libsystem_configuration_asan.dylib */,
 			);
 			dependencies = (
 				15C64A220F684C4900D78394 /* PBXTargetDependency */,
@@ -155,6 +158,7 @@
 			isa = PBXAggregateTarget;
 			buildConfigurationList = 15C64A2B0F684C6B00D78394 /* Build configuration list for PBXAggregateTarget "configd_libSystem-Embedded" */;
 			buildPhases = (
+				15AC9A4C1BE3ED87003071BD /* Move libsystem_configuration_asan.dylib */,
 			);
 			dependencies = (
 				15C64A310F684C8F00D78394 /* PBXTargetDependency */,
@@ -236,7 +240,7 @@
 		153ACCA914E322D5005029A5 /* network_information_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 153ACCA614E322D5005029A5 /* network_information_server.c */; };
 		153ACCAB14E322D5005029A5 /* network_information_server.h in Headers */ = {isa = PBXBuildFile; fileRef = 153ACCA714E322D5005029A5 /* network_information_server.h */; };
 		153ACCAC14E322D5005029A5 /* network_information_server.h in Headers */ = {isa = PBXBuildFile; fileRef = 153ACCA714E322D5005029A5 /* network_information_server.h */; };
-		1540E3610987DA9500157C07 /* com.apple.configd.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1540E3600987DA9500157C07 /* com.apple.configd.plist */; };
+		1540E3610987DA9500157C07 /* com.apple.configd.plist in Copy Files */ = {isa = PBXBuildFile; fileRef = 1540E3600987DA9500157C07 /* com.apple.configd.plist */; };
 		154361E00752C81800A8EC6C /* set-hostname.c in Sources */ = {isa = PBXBuildFile; fileRef = 159D53AB07528B36004F8947 /* set-hostname.c */; };
 		1543636B0752D03C00A8EC6C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1543636A0752D03C00A8EC6C /* IOKit.framework */; };
 		154707300D1F70C80075C28D /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1547072E0D1F70C80075C28D /* SystemConfiguration.framework */; };
@@ -286,6 +290,8 @@
 		155D223B0AF13A7300D52ED0 /* dns-configuration.h in Headers */ = {isa = PBXBuildFile; fileRef = 155D22380AF13A7300D52ED0 /* dns-configuration.h */; };
 		155D223C0AF13A7300D52ED0 /* set-hostname.h in Headers */ = {isa = PBXBuildFile; fileRef = 155D22390AF13A7300D52ED0 /* set-hostname.h */; };
 		155D223D0AF13A7300D52ED0 /* smb-configuration.h in Headers */ = {isa = PBXBuildFile; fileRef = 155D223A0AF13A7300D52ED0 /* smb-configuration.h */; };
+		155F49A61C864FFC00E47D08 /* qos-marking.m in Sources */ = {isa = PBXBuildFile; fileRef = 155F49A51C864FE500E47D08 /* qos-marking.m */; };
+		155F49A71C86500100E47D08 /* qos-marking.m in Sources */ = {isa = PBXBuildFile; fileRef = 155F49A51C864FE500E47D08 /* qos-marking.m */; };
 		1565D85018B847590097062B /* SCNetworkMigration.c in Sources */ = {isa = PBXBuildFile; fileRef = 55A3DB9D183C2A8200ED3DB7 /* SCNetworkMigration.c */; };
 		1565D85118B847F20097062B /* SCNetworkMigration.c in Sources */ = {isa = PBXBuildFile; fileRef = 55A3DB9D183C2A8200ED3DB7 /* SCNetworkMigration.c */; };
 		156BD6BC07E0DFA9008698FF /* SCPreferencesSetSpecificPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 156BD6BB07E0DFA9008698FF /* SCPreferencesSetSpecificPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -313,9 +319,6 @@
 		1572C4BE0CFB55B400E2776E /* SCValidation.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693905C0722B0099E85F /* SCValidation.h */; settings = {ATTRIBUTES = (Private, Project, ); }; };
 		1572C4BF0CFB55B400E2776E /* DHCPClientPreferences.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693D05C0722B0099E85F /* DHCPClientPreferences.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		1572C4C00CFB55B400E2776E /* SCDynamicStoreCopyDHCPInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693F05C0722B0099E85F /* SCDynamicStoreCopyDHCPInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
-		1572C4C10CFB55B400E2776E /* moh_msg.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB694105C0722B0099E85F /* moh_msg.h */; };
-		1572C4C20CFB55B400E2776E /* moh.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB694305C0722B0099E85F /* moh.h */; };
-		1572C4C30CFB55B400E2776E /* DeviceOnHold.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB694505C0722B0099E85F /* DeviceOnHold.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		1572C4C50CFB55B400E2776E /* dy_framework.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB694905C0722B0099E85F /* dy_framework.h */; };
 		1572C4C70CFB55B400E2776E /* SCPreferencesPathKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 151BDA2B05D9E28B00657BC7 /* SCPreferencesPathKey.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		1572C4CA0CFB55B400E2776E /* pppcontroller_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 23C1E2B4062DD2C700835B54 /* pppcontroller_types.h */; };
@@ -376,8 +379,6 @@
 		1572C50C0CFB55B400E2776E /* SCNetworkReachability.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69A605C0722B0099E85F /* SCNetworkReachability.c */; settings = {ATTRIBUTES = (); }; };
 		1572C50D0CFB55B400E2776E /* SCProxies.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69A805C0722B0099E85F /* SCProxies.c */; settings = {ATTRIBUTES = (); }; };
 		1572C50E0CFB55B400E2776E /* DHCP.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69AC05C0722B0099E85F /* DHCP.c */; settings = {ATTRIBUTES = (); }; };
-		1572C50F0CFB55B400E2776E /* moh.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69AE05C0722B0099E85F /* moh.c */; settings = {ATTRIBUTES = (); }; };
-		1572C5100CFB55B400E2776E /* DeviceOnHold.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69B005C0722B0099E85F /* DeviceOnHold.c */; settings = {ATTRIBUTES = (); }; };
 		1572C5110CFB55B400E2776E /* LinkConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69B205C0722B0099E85F /* LinkConfiguration.c */; settings = {ATTRIBUTES = (); }; };
 		1572C5120CFB55B400E2776E /* dy_framework.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69B405C0722B0099E85F /* dy_framework.c */; settings = {ATTRIBUTES = (); }; };
 		1572C5140CFB55B400E2776E /* config.defs in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69BE05C0722B0099E85F /* config.defs */; settings = {ATTRIBUTES = (Client, ); }; };
@@ -427,7 +428,6 @@
 		15732A9616EA503200F3AC4C /* _notifycancel.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A1405C0722B0099E85F /* _notifycancel.c */; settings = {ATTRIBUTES = (); }; };
 		15732A9716EA503200F3AC4C /* _snapshot.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A1605C0722B0099E85F /* _snapshot.c */; settings = {ATTRIBUTES = (); }; };
 		15732A9816EA503200F3AC4C /* config.defs in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69BE05C0722B0099E85F /* config.defs */; settings = {ATTRIBUTES = (Server, ); }; };
-		15732A9916EA503200F3AC4C /* dnsinfo_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15B73F0D05FD1B670096477F /* dnsinfo_server.c */; };
 		15732A9C16EA503200F3AC4C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */; };
 		15732A9D16EA503200F3AC4C /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1547072E0D1F70C80075C28D /* SystemConfiguration.framework */; };
 		15732A9E16EA503200F3AC4C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1543636A0752D03C00A8EC6C /* IOKit.framework */; };
@@ -562,21 +562,18 @@
 		158317450CFB80A1006F62B9 /* _notifycancel.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A1405C0722B0099E85F /* _notifycancel.c */; settings = {ATTRIBUTES = (); }; };
 		158317460CFB80A1006F62B9 /* _snapshot.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A1605C0722B0099E85F /* _snapshot.c */; settings = {ATTRIBUTES = (); }; };
 		158317470CFB80A1006F62B9 /* config.defs in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69BE05C0722B0099E85F /* config.defs */; settings = {ATTRIBUTES = (Server, ); }; };
-		158317490CFB80A1006F62B9 /* dnsinfo_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15B73F0D05FD1B670096477F /* dnsinfo_server.c */; };
 		1583174C0CFB80A1006F62B9 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */; };
 		1583174E0CFB80A1006F62B9 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1543636A0752D03C00A8EC6C /* IOKit.framework */; };
 		158317500CFB80A1006F62B9 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 15BAA32207F0699A00D9EC95 /* libbsm.dylib */; };
-		158317520CFB80A1006F62B9 /* libKernelEventMonitor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 159D53D407528BDA004F8947 /* libKernelEventMonitor.a */; };
-		158317530CFB80A1006F62B9 /* libInterfaceNamer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 159D53E507528C4A004F8947 /* libInterfaceNamer.a */; };
-		158317540CFB80A1006F62B9 /* libIPMonitor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 159D53EC07528C61004F8947 /* libIPMonitor.a */; };
-		158317550CFB80A1006F62B9 /* libLinkConfiguration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 159D53F307528C79004F8947 /* libLinkConfiguration.a */; };
-		158317570CFB80A1006F62B9 /* libPreferencesMonitor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 159D53FA07528C95004F8947 /* libPreferencesMonitor.a */; };
 		1583175C0CFB80A1006F62B9 /* com.apple.configd.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1540E3600987DA9500157C07 /* com.apple.configd.plist */; };
 		1583379C0CFB6B9E0033AB93 /* SCHelper_client.h in Headers */ = {isa = PBXBuildFile; fileRef = 155B7BF60847776D00F0E262 /* SCHelper_client.h */; };
 		1583379E0CFB6B9E0033AB93 /* SCHelper_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15DAF2D908466D4900D1B2BD /* SCHelper_server.c */; };
 		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 */; };
+		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 */; };
 		158E595E1107CAE40062081E /* helper.defs in Sources */ = {isa = PBXBuildFile; fileRef = 152E0E7E10FE820E00E402F2 /* helper.defs */; };
 		158E595F1107CAE80062081E /* helper.defs in Sources */ = {isa = PBXBuildFile; fileRef = 152E0E7E10FE820E00E402F2 /* helper.defs */; };
 		158E59611107CAF40062081E /* helper.defs in Sources */ = {isa = PBXBuildFile; fileRef = 152E0E7E10FE820E00E402F2 /* helper.defs */; };
@@ -644,13 +641,7 @@
 		159D54C407529FFF004F8947 /* _notifycancel.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A1405C0722B0099E85F /* _notifycancel.c */; settings = {ATTRIBUTES = (); }; };
 		159D54C507529FFF004F8947 /* _snapshot.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A1605C0722B0099E85F /* _snapshot.c */; settings = {ATTRIBUTES = (); }; };
 		159D54C607529FFF004F8947 /* config.defs in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69BE05C0722B0099E85F /* config.defs */; settings = {ATTRIBUTES = (Server, ); }; };
-		159D54C807529FFF004F8947 /* dnsinfo_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15B73F0D05FD1B670096477F /* dnsinfo_server.c */; };
 		159D54CC07529FFF004F8947 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */; };
-		159D54CE07529FFF004F8947 /* libKernelEventMonitor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 159D53D407528BDA004F8947 /* libKernelEventMonitor.a */; };
-		159D54D007529FFF004F8947 /* libInterfaceNamer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 159D53E507528C4A004F8947 /* libInterfaceNamer.a */; };
-		159D54D107529FFF004F8947 /* libIPMonitor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 159D53EC07528C61004F8947 /* libIPMonitor.a */; };
-		159D54D207529FFF004F8947 /* libLinkConfiguration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 159D53F307528C79004F8947 /* libLinkConfiguration.a */; };
-		159D54D307529FFF004F8947 /* libPreferencesMonitor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 159D53FA07528C95004F8947 /* libPreferencesMonitor.a */; };
 		159D54D607529FFF004F8947 /* configd.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 15CB6A2005C0722B0099E85F /* configd.8 */; };
 		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 */; };
@@ -682,9 +673,6 @@
 		15A5A1FC0D5B94190087BDA0 /* SCValidation.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693905C0722B0099E85F /* SCValidation.h */; settings = {ATTRIBUTES = (Private, Project, ); }; };
 		15A5A1FD0D5B94190087BDA0 /* DHCPClientPreferences.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693D05C0722B0099E85F /* DHCPClientPreferences.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		15A5A1FE0D5B94190087BDA0 /* SCDynamicStoreCopyDHCPInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693F05C0722B0099E85F /* SCDynamicStoreCopyDHCPInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
-		15A5A1FF0D5B94190087BDA0 /* moh_msg.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB694105C0722B0099E85F /* moh_msg.h */; };
-		15A5A2000D5B94190087BDA0 /* moh.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB694305C0722B0099E85F /* moh.h */; };
-		15A5A2010D5B94190087BDA0 /* DeviceOnHold.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB694505C0722B0099E85F /* DeviceOnHold.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		15A5A2030D5B94190087BDA0 /* dy_framework.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB694905C0722B0099E85F /* dy_framework.h */; };
 		15A5A2050D5B94190087BDA0 /* SCPreferencesPathKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 151BDA2B05D9E28B00657BC7 /* SCPreferencesPathKey.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		15A5A2060D5B94190087BDA0 /* dnsinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B73F0905FD1B670096477F /* dnsinfo.h */; };
@@ -746,8 +734,6 @@
 		15A5A24B0D5B94190087BDA0 /* SCNetworkReachability.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69A605C0722B0099E85F /* SCNetworkReachability.c */; settings = {ATTRIBUTES = (); }; };
 		15A5A24C0D5B94190087BDA0 /* SCProxies.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69A805C0722B0099E85F /* SCProxies.c */; settings = {ATTRIBUTES = (); }; };
 		15A5A24D0D5B94190087BDA0 /* DHCP.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69AC05C0722B0099E85F /* DHCP.c */; settings = {ATTRIBUTES = (); }; };
-		15A5A24E0D5B94190087BDA0 /* moh.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69AE05C0722B0099E85F /* moh.c */; settings = {ATTRIBUTES = (); }; };
-		15A5A24F0D5B94190087BDA0 /* DeviceOnHold.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69B005C0722B0099E85F /* DeviceOnHold.c */; settings = {ATTRIBUTES = (); }; };
 		15A5A2500D5B94190087BDA0 /* LinkConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69B205C0722B0099E85F /* LinkConfiguration.c */; settings = {ATTRIBUTES = (); }; };
 		15A5A2510D5B94190087BDA0 /* dy_framework.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69B405C0722B0099E85F /* dy_framework.c */; settings = {ATTRIBUTES = (); }; };
 		15A5A2530D5B94190087BDA0 /* config.defs in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69BE05C0722B0099E85F /* config.defs */; settings = {ATTRIBUTES = (Client, ); }; };
@@ -768,7 +754,6 @@
 		15AAA7F7108E310700C2A607 /* VPNTunnelPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AAA7F1108E310700C2A607 /* VPNTunnelPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		15AAA7F8108E310700C2A607 /* VPNTunnel.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AAA7F2108E310700C2A607 /* VPNTunnel.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		15AAA7F9108E310700C2A607 /* VPNTunnel.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AAA7F3108E310700C2A607 /* VPNTunnel.c */; };
-		15AB752D16EC2AE900FAA8CE /* libIPMonitor_sim.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 15E1B05916EBAE3C00E5F06F /* libIPMonitor_sim.a */; };
 		15BAA32307F0699A00D9EC95 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 15BAA32207F0699A00D9EC95 /* libbsm.dylib */; };
 		15C330D1134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */; };
 		15C330D2134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */; };
@@ -776,15 +761,12 @@
 		15C8C6BF170AAB4E005375CE /* cache.c in Sources */ = {isa = PBXBuildFile; fileRef = 159D53CA07528B36004F8947 /* cache.c */; };
 		15C8C6C0170AAB4E005375CE /* cache.h in Headers */ = {isa = PBXBuildFile; fileRef = 159D53CB07528B36004F8947 /* cache.h */; };
 		15D2E437167643460078F547 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1520A3DE0846B2DC0010B584 /* Security.framework */; };
-		15D3083316F3EB0700014F82 /* libSimulatorSupport_sim.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 15D3082716F3E4DA00014F82 /* libSimulatorSupport_sim.a */; };
 		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 */; };
 		15D48EBF0F67061600B4711E /* dnsinfo_create.c in Sources */ = {isa = PBXBuildFile; fileRef = 1521FC5C060F296A003B28F5 /* dnsinfo_create.c */; };
 		15D48EC00F67061700B4711E /* dnsinfo_create.h in Headers */ = {isa = PBXBuildFile; fileRef = 1532629006281C9D00B1C10C /* dnsinfo_create.h */; };
 		15D48EC10F67061F00B4711E /* dnsinfo_create.c in Sources */ = {isa = PBXBuildFile; fileRef = 1521FC5C060F296A003B28F5 /* dnsinfo_create.c */; };
 		15D48EC20F67061F00B4711E /* dnsinfo_create.h in Headers */ = {isa = PBXBuildFile; fileRef = 1532629006281C9D00B1C10C /* dnsinfo_create.h */; };
-		15D54E2715B4FA4600F5229A /* com.apple.networking.IPMonitor in com.apple.networking.IPMonitor */ = {isa = PBXBuildFile; fileRef = D68AD25F159BCD5900D4F1BE /* com.apple.networking.IPMonitor */; };
-		15D54E2B15B4FB0300F5229A /* com.apple.networking.IPMonitor in com.apple.networking.IPMonitor */ = {isa = PBXBuildFile; fileRef = D68AD25F159BCD5900D4F1BE /* com.apple.networking.IPMonitor */; };
 		15D8B22A1450D8450090CECF /* SCD.h in Headers */ = {isa = PBXBuildFile; fileRef = 15D8B2291450D8450090CECF /* SCD.h */; };
 		15D8B22B1450D8450090CECF /* SCD.h in Headers */ = {isa = PBXBuildFile; fileRef = 15D8B2291450D8450090CECF /* SCD.h */; };
 		15D8B22C1450D8450090CECF /* SCD.h in Headers */ = {isa = PBXBuildFile; fileRef = 15D8B2291450D8450090CECF /* SCD.h */; };
@@ -815,9 +797,6 @@
 		15DAD65707591A1A0084A6ED /* SCValidation.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693905C0722B0099E85F /* SCValidation.h */; settings = {ATTRIBUTES = (Private, Project, ); }; };
 		15DAD65807591A1A0084A6ED /* DHCPClientPreferences.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693D05C0722B0099E85F /* DHCPClientPreferences.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		15DAD65907591A1A0084A6ED /* SCDynamicStoreCopyDHCPInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693F05C0722B0099E85F /* SCDynamicStoreCopyDHCPInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
-		15DAD65A07591A1A0084A6ED /* moh_msg.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB694105C0722B0099E85F /* moh_msg.h */; };
-		15DAD65B07591A1A0084A6ED /* moh.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB694305C0722B0099E85F /* moh.h */; };
-		15DAD65C07591A1A0084A6ED /* DeviceOnHold.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB694505C0722B0099E85F /* DeviceOnHold.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		15DAD65E07591A1A0084A6ED /* dy_framework.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB694905C0722B0099E85F /* dy_framework.h */; };
 		15DAD66107591A1A0084A6ED /* SCPreferencesPathKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 151BDA2B05D9E28B00657BC7 /* SCPreferencesPathKey.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		15DAD66407591A1A0084A6ED /* pppcontroller_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 23C1E2B4062DD2C700835B54 /* pppcontroller_types.h */; };
@@ -867,8 +846,6 @@
 		15DAD69807591A1A0084A6ED /* SCNetworkReachability.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69A605C0722B0099E85F /* SCNetworkReachability.c */; settings = {ATTRIBUTES = (); }; };
 		15DAD69907591A1A0084A6ED /* SCProxies.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69A805C0722B0099E85F /* SCProxies.c */; settings = {ATTRIBUTES = (); }; };
 		15DAD69A07591A1A0084A6ED /* DHCP.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69AC05C0722B0099E85F /* DHCP.c */; settings = {ATTRIBUTES = (); }; };
-		15DAD69B07591A1A0084A6ED /* moh.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69AE05C0722B0099E85F /* moh.c */; settings = {ATTRIBUTES = (); }; };
-		15DAD69C07591A1A0084A6ED /* DeviceOnHold.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69B005C0722B0099E85F /* DeviceOnHold.c */; settings = {ATTRIBUTES = (); }; };
 		15DAD69D07591A1A0084A6ED /* LinkConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69B205C0722B0099E85F /* LinkConfiguration.c */; settings = {ATTRIBUTES = (); }; };
 		15DAD69E07591A1A0084A6ED /* dy_framework.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69B405C0722B0099E85F /* dy_framework.c */; settings = {ATTRIBUTES = (); }; };
 		15DAD69F07591A1A0084A6ED /* VLANConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69B605C0722B0099E85F /* VLANConfiguration.c */; settings = {ATTRIBUTES = (); COMPILER_FLAGS = "-Wno-deprecated-declarations"; }; };
@@ -885,7 +862,7 @@
 		15DAF2E108466D4900D1B2BD /* SCHelper_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15DAF2D908466D4900D1B2BD /* SCHelper_server.c */; };
 		15E1B04316EBAE3C00E5F06F /* dns-configuration.h in Headers */ = {isa = PBXBuildFile; fileRef = 155D22380AF13A7300D52ED0 /* dns-configuration.h */; };
 		15E1B04416EBAE3C00E5F06F /* dnsinfo_create.h in Headers */ = {isa = PBXBuildFile; fileRef = 1532629006281C9D00B1C10C /* dnsinfo_create.h */; };
-		15E1B04516EBAE3C00E5F06F /* network_information_priv.h in Headers */ = {isa = PBXBuildFile; fileRef = D6986A761368911E0091C931 /* network_information_priv.h */; };
+		15E1B04516EBAE3C00E5F06F /* network_state_information_priv.h in Headers */ = {isa = PBXBuildFile; fileRef = D6986A761368911E0091C931 /* network_state_information_priv.h */; };
 		15E1B04616EBAE3C00E5F06F /* proxy-configuration.h in Headers */ = {isa = PBXBuildFile; fileRef = 1575FD2612CD15C60003D86E /* proxy-configuration.h */; };
 		15E1B04816EBAE3C00E5F06F /* network_information_server.h in Headers */ = {isa = PBXBuildFile; fileRef = 153ACCA714E322D5005029A5 /* network_information_server.h */; };
 		15E1B04916EBAE3C00E5F06F /* libSystemConfiguration_server.h in Headers */ = {isa = PBXBuildFile; fileRef = 1596A7B014EDB73D00798C39 /* libSystemConfiguration_server.h */; };
@@ -893,7 +870,7 @@
 		15E1B04C16EBAE3C00E5F06F /* dnsinfo_create.c in Sources */ = {isa = PBXBuildFile; fileRef = 1521FC5C060F296A003B28F5 /* dnsinfo_create.c */; };
 		15E1B04D16EBAE3C00E5F06F /* dnsinfo_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15B73F0D05FD1B670096477F /* dnsinfo_server.c */; };
 		15E1B04E16EBAE3C00E5F06F /* ip_plugin.c in Sources */ = {isa = PBXBuildFile; fileRef = 159D53A707528B36004F8947 /* ip_plugin.c */; };
-		15E1B04F16EBAE3C00E5F06F /* network_information_priv.c in Sources */ = {isa = PBXBuildFile; fileRef = D6986A75136891120091C931 /* network_information_priv.c */; };
+		15E1B04F16EBAE3C00E5F06F /* network_state_information_priv.c in Sources */ = {isa = PBXBuildFile; fileRef = D6986A75136891120091C931 /* network_state_information_priv.c */; };
 		15E1B05016EBAE3C00E5F06F /* network_information_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 153ACCA614E322D5005029A5 /* network_information_server.c */; };
 		15E1B05116EBAE3C00E5F06F /* proxy-configuration.c in Sources */ = {isa = PBXBuildFile; fileRef = 1575FD2512CD15C60003D86E /* proxy-configuration.c */; };
 		15E1B05316EBAE3C00E5F06F /* libSystemConfiguration_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 1596A7AF14EDB73D00798C39 /* libSystemConfiguration_server.c */; };
@@ -908,22 +885,58 @@
 		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 */; };
+		720985441C580D9F00966D30 /* network_config_agent_info_priv.h in Headers */ = {isa = PBXBuildFile; fileRef = 720985431C580D9F00966D30 /* network_config_agent_info_priv.h */; };
+		720985451C580D9F00966D30 /* network_config_agent_info_priv.h in Headers */ = {isa = PBXBuildFile; fileRef = 720985431C580D9F00966D30 /* network_config_agent_info_priv.h */; };
+		720985471C5835DB00966D30 /* agent-monitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 728015931BE1697E009F4F60 /* agent-monitor.h */; };
+		720A4C0A1C585C7D007436B8 /* configAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 728015781BE16833009F4F60 /* configAgent.h */; };
+		720A4C0B1C585C93007436B8 /* controller.h in Headers */ = {isa = PBXBuildFile; fileRef = 7280157A1BE16833009F4F60 /* controller.h */; };
+		720A4C0C1C585C97007436B8 /* dnsAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 7280157C1BE16833009F4F60 /* dnsAgent.h */; };
+		720A4C0D1C585C9F007436B8 /* proxyAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 7280157F1BE16833009F4F60 /* proxyAgent.h */; };
+		7214BCE31BEB392000A8F056 /* Network.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 728015951BE16B6C009F4F60 /* Network.framework */; };
+		7214BCE41BEB392300A8F056 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 728015961BE16B6C009F4F60 /* NetworkExtension.framework */; };
 		72499BA41AC9B7AB0090C49F /* get-network-info in Resources */ = {isa = PBXBuildFile; fileRef = 72499BA31AC9B7AB0090C49F /* get-network-info */; };
 		72499BA51AC9B7AB0090C49F /* get-network-info in Resources */ = {isa = PBXBuildFile; fileRef = 72499BA31AC9B7AB0090C49F /* get-network-info */; };
-		725E53D71A92D2C3009997E1 /* com.apple.networking.IPMonitor in com.apple.networking.IPMonitor */ = {isa = PBXBuildFile; fileRef = 725E53D51A92D2A5009997E1 /* com.apple.networking.IPMonitor */; };
+		725CB7551BF439C6000C05A8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 725CB7541BF439C6000C05A8 /* Foundation.framework */; };
+		725CB7561BF439D2000C05A8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 725CB7541BF439C6000C05A8 /* Foundation.framework */; };
+		725CB7581BF514F2000C05A8 /* configAgentDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 725CB7571BF51476000C05A8 /* configAgentDefines.h */; };
+		725CB7591BF514F5000C05A8 /* configAgentDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 725CB7571BF51476000C05A8 /* configAgentDefines.h */; };
 		7264C144147319E7004FD76D /* CaptiveNetwork.c in Sources */ = {isa = PBXBuildFile; fileRef = 15A1FF3110597F17004C9CC9 /* CaptiveNetwork.c */; };
 		7264C14614731A1F004FD76D /* CaptiveNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = 15A1FF3010597F17004C9CC9 /* CaptiveNetwork.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		726DB2F41BEA80E5001B2C6C /* config_agent_info.c in Sources */ = {isa = PBXBuildFile; fileRef = 726DB2F11BEA80E5001B2C6C /* config_agent_info.c */; };
+		726DB2F61BEA80E5001B2C6C /* config_agent_info.h in Headers */ = {isa = PBXBuildFile; fileRef = 726DB2F21BEA80E5001B2C6C /* config_agent_info.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		727AF25419138699009AB153 /* VPNAppLayerPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = B0A88CA616397A1200A60B3A /* VPNAppLayerPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		727AF255191386A0009AB153 /* VPNFlow.h in Headers */ = {isa = PBXBuildFile; fileRef = C4CDB8111631933400819B44 /* VPNFlow.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		727AF257191386DA009AB153 /* VPNTunnel.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AAA7F2108E310700C2A607 /* VPNTunnel.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		727AF258191386E3009AB153 /* VPNTunnelPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AAA7F1108E310700C2A607 /* VPNTunnelPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		727AF25919138E24009AB153 /* VPNTunnel.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AAA7F3108E310700C2A607 /* VPNTunnel.c */; };
+		728015811BE1683B009F4F60 /* agent-monitor.m in Sources */ = {isa = PBXBuildFile; fileRef = 728015751BE16833009F4F60 /* agent-monitor.m */; };
+		728015821BE16840009F4F60 /* agent-monitor.m in Sources */ = {isa = PBXBuildFile; fileRef = 728015751BE16833009F4F60 /* agent-monitor.m */; };
+		728015871BE1684E009F4F60 /* configAgent.m in Sources */ = {isa = PBXBuildFile; fileRef = 728015791BE16833009F4F60 /* configAgent.m */; };
+		728015881BE16851009F4F60 /* configAgent.m in Sources */ = {isa = PBXBuildFile; fileRef = 728015791BE16833009F4F60 /* configAgent.m */; };
+		7280158B1BE1685B009F4F60 /* controller.m in Sources */ = {isa = PBXBuildFile; fileRef = 7280157B1BE16833009F4F60 /* controller.m */; };
+		7280158C1BE1685D009F4F60 /* controller.m in Sources */ = {isa = PBXBuildFile; fileRef = 7280157B1BE16833009F4F60 /* controller.m */; };
+		7280158D1BE16861009F4F60 /* dnsAgent.m in Sources */ = {isa = PBXBuildFile; fileRef = 7280157D1BE16833009F4F60 /* dnsAgent.m */; };
+		7280158E1BE16863009F4F60 /* dnsAgent.m in Sources */ = {isa = PBXBuildFile; fileRef = 7280157D1BE16833009F4F60 /* dnsAgent.m */; };
+		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 */; };
+		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 */; };
+		7280159D1BE1812B009F4F60 /* dnsAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 7280157C1BE16833009F4F60 /* dnsAgent.h */; };
+		7280159E1BE1812B009F4F60 /* proxyAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 7280157F1BE16833009F4F60 /* proxyAgent.h */; };
+		728CEAFF1BEA951A00F13F92 /* config_agent_info.c in Sources */ = {isa = PBXBuildFile; fileRef = 726DB2F11BEA80E5001B2C6C /* config_agent_info.c */; };
+		728CEB001BEA993100F13F92 /* config_agent_info.h in Headers */ = {isa = PBXBuildFile; fileRef = 726DB2F21BEA80E5001B2C6C /* config_agent_info.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		72B43728113C7BFC00EBF1B6 /* nc.h in Headers */ = {isa = PBXBuildFile; fileRef = 72B43726113C7BFC00EBF1B6 /* nc.h */; };
 		72B43729113C7BFC00EBF1B6 /* nc.c in Sources */ = {isa = PBXBuildFile; fileRef = 72B43727113C7BFC00EBF1B6 /* nc.c */; };
 		72B4372A113C7BFC00EBF1B6 /* nc.h in Headers */ = {isa = PBXBuildFile; fileRef = 72B43726113C7BFC00EBF1B6 /* nc.h */; };
 		72B4372B113C7BFC00EBF1B6 /* nc.c in Sources */ = {isa = PBXBuildFile; fileRef = 72B43727113C7BFC00EBF1B6 /* nc.c */; };
 		72D3E6611AE6EA3A00DB4C69 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72D3E6601AE6EA3A00DB4C69 /* main.swift */; };
 		72D3E66C1AE6EAF600DB4C69 /* test-objC.m in Sources */ = {isa = PBXBuildFile; fileRef = 72D3E66B1AE6EAF600DB4C69 /* test-objC.m */; };
+		90507AB01CE2F55B0067D16B /* libnetwork.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 90507AAF1CE2F55B0067D16B /* libnetwork.dylib */; };
+		90507AB21CE2F5720067D16B /* libnetwork.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 90507AB11CE2F5720067D16B /* libnetwork.dylib */; };
+		90507AB31CE2F58A0067D16B /* libnetwork.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 90507AB11CE2F5720067D16B /* libnetwork.dylib */; };
 		B03FEFB616376D2800A1B88F /* VPNAppLayer.c in Sources */ = {isa = PBXBuildFile; fileRef = B03FEFB516376D2800A1B88F /* VPNAppLayer.c */; };
 		B03FEFB716376D2800A1B88F /* VPNAppLayer.c in Sources */ = {isa = PBXBuildFile; fileRef = B03FEFB516376D2800A1B88F /* VPNAppLayer.c */; };
 		B03FEFBA16382C0700A1B88F /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 15BAA32207F0699A00D9EC95 /* libbsm.dylib */; };
@@ -959,10 +972,10 @@
 		D661C2F21368BB720030B977 /* network_information.h in Headers */ = {isa = PBXBuildFile; fileRef = D6986A781368913C0091C931 /* network_information.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		D6623873120B2AA7007F8E95 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1520A3DE0846B2DC0010B584 /* Security.framework */; };
 		D6986A79136891650091C931 /* network_information.c in Sources */ = {isa = PBXBuildFile; fileRef = D6986A77136891300091C931 /* network_information.c */; };
-		E49173E1137C4E4F0000089F /* network_information_priv.c in Sources */ = {isa = PBXBuildFile; fileRef = D6986A75136891120091C931 /* network_information_priv.c */; };
-		E4F211D3137B0AB900BBB915 /* network_information_priv.c in Sources */ = {isa = PBXBuildFile; fileRef = D6986A75136891120091C931 /* network_information_priv.c */; };
-		E4F211D4137B0ABD00BBB915 /* network_information_priv.h in Headers */ = {isa = PBXBuildFile; fileRef = D6986A761368911E0091C931 /* network_information_priv.h */; };
-		E4F211D7137B0AF200BBB915 /* network_information_priv.h in Headers */ = {isa = PBXBuildFile; fileRef = D6986A761368911E0091C931 /* network_information_priv.h */; };
+		E49173E1137C4E4F0000089F /* network_state_information_priv.c in Sources */ = {isa = PBXBuildFile; fileRef = D6986A75136891120091C931 /* network_state_information_priv.c */; };
+		E4F211D3137B0AB900BBB915 /* network_state_information_priv.c in Sources */ = {isa = PBXBuildFile; fileRef = D6986A75136891120091C931 /* network_state_information_priv.c */; };
+		E4F211D4137B0ABD00BBB915 /* network_state_information_priv.h in Headers */ = {isa = PBXBuildFile; fileRef = D6986A761368911E0091C931 /* network_state_information_priv.h */; };
+		E4F211D7137B0AF200BBB915 /* network_state_information_priv.h in Headers */ = {isa = PBXBuildFile; fileRef = D6986A761368911E0091C931 /* network_state_information_priv.h */; };
 		F9347FF7187C796E003D4178 /* IPMonitorControl.c in Sources */ = {isa = PBXBuildFile; fileRef = F9B7AE5C1862116500C78D18 /* IPMonitorControl.c */; };
 		F9347FF8187C7993003D4178 /* IPMonitorControl.h in Headers */ = {isa = PBXBuildFile; fileRef = F9B7AE5D1862116500C78D18 /* IPMonitorControl.h */; };
 		F9347FF9187C7993003D4178 /* IPMonitorControlPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = F9B7AE5E1862116500C78D18 /* IPMonitorControlPrivate.h */; };
@@ -1017,19 +1030,26 @@
 			remoteGlobalIDString = 1558481207550EC10046C2E9;
 			remoteInfo = scselect;
 		};
-		1558480907550D470046C2E9 /* PBXContainerItemProxy */ = {
+		1558480E07550DD00046C2E9 /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
 			containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
 			proxyType = 1;
-			remoteGlobalIDString = 155847430754FDCD0046C2E9;
-			remoteInfo = scutil;
+			remoteGlobalIDString = 155847FA07550D210046C2E9;
+			remoteInfo = configd_executables;
 		};
-		1558480E07550DD00046C2E9 /* PBXContainerItemProxy */ = {
+		155F49AC1C86511300E47D08 /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
 			containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
 			proxyType = 1;
-			remoteGlobalIDString = 155847FA07550D210046C2E9;
-			remoteInfo = configd_executables;
+			remoteGlobalIDString = 155F49951C864F4E00E47D08;
+			remoteInfo = "QoSMarking-Embedded";
+		};
+		155F49AE1C86511300E47D08 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 155F499D1C864F5400E47D08;
+			remoteInfo = "QoSMarking.bundle-Embedded";
 		};
 		15732AE516EA6BCE00F3AC4C /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
@@ -1388,6 +1408,13 @@
 			remoteGlobalIDString = 15DAD63F07591A1A0084A6ED;
 			remoteInfo = SystemConfiguration.framework;
 		};
+		72C4A47F1BE44D19009D570E /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 155847430754FDCD0046C2E9;
+			remoteInfo = scutil;
+		};
 		D6DDAC3C147A24BC00A2E902 /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
 			containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
@@ -1448,78 +1475,79 @@
 			);
 			runOnlyForDeploymentPostprocessing = 1;
 		};
-		159D54D507529FFF004F8947 /* CopyFiles */ = {
+		158D6D881C974E7E00A08E78 /* Logging Preferences */ = {
 			isa = PBXCopyFilesBuildPhase;
 			buildActionMask = 8;
-			dstPath = /usr/share/man/man8;
+			dstPath = /System/Library/Preferences/Logging/Subsystems;
 			dstSubfolderSpec = 0;
 			files = (
-				159D54D607529FFF004F8947 /* configd.8 in CopyFiles */,
+				158D6D891C974E9E00A08E78 /* com.apple.SystemConfiguration.plist in Logging Preferences */,
 			);
+			name = "Logging Preferences";
 			runOnlyForDeploymentPostprocessing = 1;
 		};
-		159D54D707529FFF004F8947 /* CopyFiles */ = {
+		158D6D8A1C974EF700A08E78 /* Logging Preferences */ = {
 			isa = PBXCopyFilesBuildPhase;
 			buildActionMask = 8;
-			dstPath = /System/Library/LaunchDaemons;
+			dstPath = /System/Library/Preferences/Logging/Subsystems;
 			dstSubfolderSpec = 0;
 			files = (
-				1540E3610987DA9500157C07 /* com.apple.configd.plist in CopyFiles */,
+				158D6D8B1C974F1800A08E78 /* com.apple.SystemConfiguration.plist in Logging Preferences */,
 			);
+			name = "Logging Preferences";
 			runOnlyForDeploymentPostprocessing = 1;
 		};
-		15D54E2515B4FA1900F5229A /* com.apple.networking.IPMonitor */ = {
+		158D6D8C1C974F4800A08E78 /* Logging Preferences */ = {
 			isa = PBXCopyFilesBuildPhase;
 			buildActionMask = 8;
-			dstPath = /private/etc/asl;
+			dstPath = /System/Library/Preferences/Logging/Subsystems;
 			dstSubfolderSpec = 0;
 			files = (
-				15D54E2715B4FA4600F5229A /* com.apple.networking.IPMonitor in com.apple.networking.IPMonitor */,
+				158D6D8D1C974F5800A08E78 /* com.apple.SystemConfiguration.plist in Logging Preferences */,
 			);
-			name = com.apple.networking.IPMonitor;
+			name = "Logging Preferences";
 			runOnlyForDeploymentPostprocessing = 1;
 		};
-		15D54E2A15B4FAF100F5229A /* com.apple.networking.IPMonitor */ = {
+		159D54D507529FFF004F8947 /* CopyFiles */ = {
 			isa = PBXCopyFilesBuildPhase;
 			buildActionMask = 8;
-			dstPath = /private/etc/asl;
+			dstPath = /usr/share/man/man8;
 			dstSubfolderSpec = 0;
 			files = (
-				15D54E2B15B4FB0300F5229A /* com.apple.networking.IPMonitor in com.apple.networking.IPMonitor */,
+				159D54D607529FFF004F8947 /* configd.8 in CopyFiles */,
 			);
-			name = com.apple.networking.IPMonitor;
 			runOnlyForDeploymentPostprocessing = 1;
 		};
-		15D9DCF910DD909F004E545D /* AppWorkaround.plist */ = {
+		159D54D707529FFF004F8947 /* Copy Files */ = {
 			isa = PBXCopyFilesBuildPhase;
 			buildActionMask = 8;
-			dstPath = /usr/local/AppSpecificWorkaround/SystemConfiguration;
+			dstPath = /System/Library/LaunchDaemons;
 			dstSubfolderSpec = 0;
 			files = (
-				15D9DCFB10DD90A1004E545D /* AppWorkaround.plist in AppWorkaround.plist */,
+				1540E3610987DA9500157C07 /* com.apple.configd.plist in Copy Files */,
 			);
-			name = AppWorkaround.plist;
+			name = "Copy Files";
 			runOnlyForDeploymentPostprocessing = 1;
 		};
-		15FF5C380CDF778F00EEC8AA /* CopyFiles */ = {
+		15D9DCF910DD909F004E545D /* AppWorkaround.plist */ = {
 			isa = PBXCopyFilesBuildPhase;
 			buildActionMask = 8;
-			dstPath = /System/Library/LaunchDaemons;
+			dstPath = /usr/local/AppSpecificWorkaround/SystemConfiguration;
 			dstSubfolderSpec = 0;
 			files = (
-				15FF5C370CDF776200EEC8AA /* com.apple.SCHelper.plist in CopyFiles */,
+				15D9DCFB10DD90A1004E545D /* AppWorkaround.plist in AppWorkaround.plist */,
 			);
+			name = AppWorkaround.plist;
 			runOnlyForDeploymentPostprocessing = 1;
 		};
-		72AD314B1A843C1000D2226E /* com.apple.networking.IPMonitor */ = {
+		15FF5C380CDF778F00EEC8AA /* CopyFiles */ = {
 			isa = PBXCopyFilesBuildPhase;
 			buildActionMask = 8;
-			dstPath = /private/etc/asl;
+			dstPath = /System/Library/LaunchDaemons;
 			dstSubfolderSpec = 0;
 			files = (
-				725E53D71A92D2C3009997E1 /* com.apple.networking.IPMonitor in com.apple.networking.IPMonitor */,
+				15FF5C370CDF776200EEC8AA /* com.apple.SCHelper.plist in CopyFiles */,
 			);
-			name = com.apple.networking.IPMonitor;
 			runOnlyForDeploymentPostprocessing = 1;
 		};
 		72D3E65C1AE6EA3900DB4C69 /* CopyFiles */ = {
@@ -1589,6 +1617,12 @@
 		155D22380AF13A7300D52ED0 /* dns-configuration.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "dns-configuration.h"; sourceTree = ""; };
 		155D22390AF13A7300D52ED0 /* set-hostname.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "set-hostname.h"; sourceTree = ""; };
 		155D223A0AF13A7300D52ED0 /* smb-configuration.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "smb-configuration.h"; sourceTree = ""; };
+		155F498D1C864F1400E47D08 /* libQoSMarking.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libQoSMarking.a; sourceTree = BUILT_PRODUCTS_DIR; };
+		155F49931C864F3700E47D08 /* QoSMarking.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = QoSMarking.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
+		155F499C1C864F4E00E47D08 /* libQoSMarking.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libQoSMarking.a; sourceTree = BUILT_PRODUCTS_DIR; };
+		155F49A21C864F5400E47D08 /* QoSMarking.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = QoSMarking.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
+		155F49A41C864FE500E47D08 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Plugins/QoSMarking/Info.plist; sourceTree = ""; };
+		155F49A51C864FE500E47D08 /* qos-marking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "qos-marking.m"; path = "Plugins/QoSMarking/qos-marking.m"; sourceTree = ""; };
 		1567333E0DD1FD6500145179 /* entitlements-ios.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "entitlements-ios.plist"; sourceTree = ""; };
 		156BD6BB07E0DFA9008698FF /* SCPreferencesSetSpecificPrivate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCPreferencesSetSpecificPrivate.h; sourceTree = ""; };
 		1572C57E171CCF9500870549 /* pppcontroller_mach_defines.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; name = pppcontroller_mach_defines.h; path = usr/local/include/ppp/pppcontroller_mach_defines.h; sourceTree = SDKROOT; };
@@ -1612,6 +1646,7 @@
 		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 = ""; };
+		158D6D871C974DBA00A08E78 /* com.apple.SystemConfiguration.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.SystemConfiguration.plist; sourceTree = ""; };
 		1596A7AF14EDB73D00798C39 /* libSystemConfiguration_server.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; name = libSystemConfiguration_server.c; path = libSystemConfiguration/libSystemConfiguration_server.c; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.c; };
 		1596A7B014EDB73D00798C39 /* libSystemConfiguration_server.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = libSystemConfiguration_server.h; path = libSystemConfiguration/libSystemConfiguration_server.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
 		159A7513107FEAA400A57EAB /* VPNPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VPNPrivate.h; sourceTree = ""; };
@@ -1652,7 +1687,6 @@
 		15AAA7F1108E310700C2A607 /* VPNTunnelPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VPNTunnelPrivate.h; sourceTree = ""; };
 		15AAA7F2108E310700C2A607 /* VPNTunnel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VPNTunnel.h; sourceTree = ""; };
 		15AAA7F3108E310700C2A607 /* VPNTunnel.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = VPNTunnel.c; sourceTree = ""; };
-		15AC2D8816C574FE00340E28 /* libcupolicy.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcupolicy.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.Internal.sdk/usr/lib/libcupolicy.dylib; sourceTree = DEVELOPER_DIR; };
 		15AD7A380670A85900BFE03C /* SCNetworkConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCNetworkConfiguration.h; sourceTree = ""; };
 		15AD7A390670A85900BFE03C /* SCNetworkConfigurationInternal.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = SCNetworkConfigurationInternal.c; sourceTree = ""; };
 		15AD7A3A0670A85900BFE03C /* SCNetworkConfigurationInternal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCNetworkConfigurationInternal.h; sourceTree = ""; };
@@ -1668,7 +1702,6 @@
 		15B73F0E05FD1B670096477F /* dnsinfo_server.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dnsinfo_server.h; path = dnsinfo/dnsinfo_server.h; sourceTree = ""; };
 		15BAA32207F0699A00D9EC95 /* libbsm.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbsm.dylib; path = /usr/lib/libbsm.dylib; sourceTree = ""; };
 		15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCNetworkReachabilityInternal.h; sourceTree = ""; };
-		15CAEF381712690500367CE1 /* libcupolicy.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcupolicy.dylib; path = Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.0.sdk/usr/local/lib/libcupolicy.dylib; sourceTree = DEVELOPER_DIR; };
 		15CB691305C0722B0099E85F /* SystemConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SystemConfiguration.h; sourceTree = ""; };
 		15CB691505C0722B0099E85F /* SCPrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SCPrivate.h; sourceTree = ""; };
 		15CB691705C0722B0099E85F /* SCDPlugin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SCDPlugin.h; sourceTree = ""; };
@@ -1690,9 +1723,6 @@
 		15CB693905C0722B0099E85F /* SCValidation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SCValidation.h; sourceTree = ""; };
 		15CB693D05C0722B0099E85F /* DHCPClientPreferences.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DHCPClientPreferences.h; sourceTree = ""; };
 		15CB693F05C0722B0099E85F /* SCDynamicStoreCopyDHCPInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SCDynamicStoreCopyDHCPInfo.h; sourceTree = ""; };
-		15CB694105C0722B0099E85F /* moh_msg.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = moh_msg.h; sourceTree = ""; };
-		15CB694305C0722B0099E85F /* moh.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = moh.h; sourceTree = ""; };
-		15CB694505C0722B0099E85F /* DeviceOnHold.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeviceOnHold.h; sourceTree = ""; };
 		15CB694905C0722B0099E85F /* dy_framework.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = dy_framework.h; sourceTree = ""; };
 		15CB695005C0722B0099E85F /* SCD.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SCD.c; sourceTree = ""; };
 		15CB695205C0722B0099E85F /* SCDKeys.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SCDKeys.c; sourceTree = ""; };
@@ -1735,8 +1765,6 @@
 		15CB69A605C0722B0099E85F /* SCNetworkReachability.c */ = {isa = PBXFileReference; indentWidth = 8; lastKnownFileType = sourcecode.c.c; path = SCNetworkReachability.c; sourceTree = ""; };
 		15CB69A805C0722B0099E85F /* SCProxies.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SCProxies.c; sourceTree = ""; };
 		15CB69AC05C0722B0099E85F /* DHCP.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = DHCP.c; sourceTree = ""; };
-		15CB69AE05C0722B0099E85F /* moh.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = moh.c; sourceTree = ""; };
-		15CB69B005C0722B0099E85F /* DeviceOnHold.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = DeviceOnHold.c; sourceTree = ""; };
 		15CB69B205C0722B0099E85F /* LinkConfiguration.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = LinkConfiguration.c; sourceTree = ""; };
 		15CB69B405C0722B0099E85F /* dy_framework.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = dy_framework.c; sourceTree = ""; };
 		15CB69B605C0722B0099E85F /* VLANConfiguration.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = VLANConfiguration.c; sourceTree = ""; };
@@ -1834,8 +1862,25 @@
 		23C1E2B8062DD45900835B54 /* pppcontroller.defs */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.mig; name = pppcontroller.defs; path = SystemConfiguration.fproj/pppcontroller.defs; sourceTree = ""; };
 		23C1E2BE062DD5DB00835B54 /* pppcontroller.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = pppcontroller.h; path = configd.build/SystemConfiguration.framework.build/DerivedSources/pppcontroller.h; sourceTree = BUILT_PRODUCTS_DIR; };
 		55A3DB9D183C2A8200ED3DB7 /* SCNetworkMigration.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SCNetworkMigration.c; sourceTree = ""; };
+		720985431C580D9F00966D30 /* network_config_agent_info_priv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = network_config_agent_info_priv.h; path = nwi/network_config_agent_info_priv.h; sourceTree = ""; };
 		72499BA31AC9B7AB0090C49F /* get-network-info */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "get-network-info"; sourceTree = SOURCE_ROOT; };
+		725CB7541BF439C6000C05A8 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+		725CB7571BF51476000C05A8 /* configAgentDefines.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = configAgentDefines.h; sourceTree = ""; };
 		725E53D51A92D2A5009997E1 /* com.apple.networking.IPMonitor */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = com.apple.networking.IPMonitor; sourceTree = ""; };
+		726DB2F11BEA80E5001B2C6C /* config_agent_info.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = config_agent_info.c; path = "config-agent-info/config_agent_info.c"; sourceTree = ""; };
+		726DB2F21BEA80E5001B2C6C /* config_agent_info.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = config_agent_info.h; path = "config-agent-info/config_agent_info.h"; sourceTree = ""; };
+		728015751BE16833009F4F60 /* agent-monitor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = "agent-monitor.m"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
+		728015781BE16833009F4F60 /* configAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = configAgent.h; sourceTree = ""; };
+		728015791BE16833009F4F60 /* configAgent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = configAgent.m; sourceTree = ""; };
+		7280157A1BE16833009F4F60 /* controller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = controller.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+		7280157B1BE16833009F4F60 /* controller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = controller.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
+		7280157C1BE16833009F4F60 /* dnsAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dnsAgent.h; sourceTree = ""; };
+		7280157D1BE16833009F4F60 /* dnsAgent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = dnsAgent.m; sourceTree = ""; };
+		7280157F1BE16833009F4F60 /* proxyAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = proxyAgent.h; sourceTree = ""; };
+		728015801BE16833009F4F60 /* proxyAgent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = proxyAgent.m; sourceTree = ""; };
+		728015931BE1697E009F4F60 /* agent-monitor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "agent-monitor.h"; sourceTree = ""; };
+		728015951BE16B6C009F4F60 /* Network.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Network.framework; path = System/Library/PrivateFrameworks/Network.framework; sourceTree = SDKROOT; };
+		728015961BE16B6C009F4F60 /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; };
 		72B43726113C7BFC00EBF1B6 /* nc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nc.h; sourceTree = ""; };
 		72B43727113C7BFC00EBF1B6 /* nc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nc.c; sourceTree = ""; };
 		72D3E6591AE6E8A900DB4C69 /* Modules */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Modules; path = SystemConfiguration.fproj/Modules; sourceTree = SOURCE_ROOT; };
@@ -1843,6 +1888,8 @@
 		72D3E6601AE6EA3A00DB4C69 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; };
 		72D3E6691AE6EAF600DB4C69 /* SCTest-ObjC */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "SCTest-ObjC"; sourceTree = BUILT_PRODUCTS_DIR; };
 		72D3E66B1AE6EAF600DB4C69 /* test-objC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "test-objC.m"; sourceTree = ""; };
+		90507AAF1CE2F55B0067D16B /* libnetwork.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libnetwork.dylib; path = usr/lib/libnetwork.dylib; sourceTree = SDKROOT; };
+		90507AB11CE2F5720067D16B /* libnetwork.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libnetwork.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.0.Internal.sdk/usr/lib/libnetwork.dylib; sourceTree = DEVELOPER_DIR; };
 		9EE943F306AF409B00772EB5 /* BondConfiguration.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = BondConfiguration.c; sourceTree = ""; };
 		B03FEFB516376D2800A1B88F /* VPNAppLayer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = VPNAppLayer.c; sourceTree = ""; };
 		B084710E16385121006C92A3 /* SCNetworkConnectionInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCNetworkConnectionInternal.h; sourceTree = ""; };
@@ -1854,9 +1901,8 @@
 		C4F1847F16237AFC00D97043 /* VPNService.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = VPNService.c; sourceTree = ""; };
 		D61AAEAD1522C99C0066B003 /* scprefs_observer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = scprefs_observer.c; sourceTree = ""; };
 		D61AAEB41522C9BD0066B003 /* scprefs_observer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = scprefs_observer.h; sourceTree = ""; };
-		D68AD25F159BCD5900D4F1BE /* com.apple.networking.IPMonitor */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = com.apple.networking.IPMonitor; sourceTree = ""; };
-		D6986A75136891120091C931 /* network_information_priv.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = network_information_priv.c; path = nwi/network_information_priv.c; sourceTree = ""; };
-		D6986A761368911E0091C931 /* network_information_priv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = network_information_priv.h; path = nwi/network_information_priv.h; sourceTree = ""; };
+		D6986A75136891120091C931 /* network_state_information_priv.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = network_state_information_priv.c; path = nwi/network_state_information_priv.c; sourceTree = ""; };
+		D6986A761368911E0091C931 /* network_state_information_priv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = network_state_information_priv.h; path = nwi/network_state_information_priv.h; sourceTree = ""; };
 		D6986A77136891300091C931 /* network_information.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = network_information.c; path = nwi/network_information.c; sourceTree = ""; };
 		D6986A781368913C0091C931 /* network_information.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = network_information.h; path = nwi/network_information.h; sourceTree = ""; };
 		D6AEB89815AE4446009F2FAF /* ip_plugin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ip_plugin.h; sourceTree = ""; };
@@ -1922,6 +1968,7 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				90507AB21CE2F5720067D16B /* libnetwork.dylib in Frameworks */,
 				1572C5240CFB55B400E2776E /* CoreFoundation.framework in Frameworks */,
 				B03FEFBB16382C1300A1B88F /* libbsm.dylib in Frameworks */,
 			);
@@ -1936,8 +1983,6 @@
 				15732A9E16EA503200F3AC4C /* IOKit.framework in Frameworks */,
 				15732A9F16EA503200F3AC4C /* Security.framework in Frameworks */,
 				15732AA016EA503200F3AC4C /* libbsm.dylib in Frameworks */,
-				15AB752D16EC2AE900FAA8CE /* libIPMonitor_sim.a in Frameworks */,
-				15D3083316F3EB0700014F82 /* libSimulatorSupport_sim.a in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -1988,17 +2033,15 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				725CB7561BF439D2000C05A8 /* Foundation.framework in Frameworks */,
+				7214BCE31BEB392000A8F056 /* Network.framework in Frameworks */,
+				7214BCE41BEB392300A8F056 /* NetworkExtension.framework in Frameworks */,
 				1583174C0CFB80A1006F62B9 /* CoreFoundation.framework in Frameworks */,
 				154707350D1F70C80075C28D /* SystemConfiguration.framework in Frameworks */,
 				1583174E0CFB80A1006F62B9 /* IOKit.framework in Frameworks */,
 				152439EC180716ED00D91708 /* MobileWiFi.framework in Frameworks */,
 				159C32B60F583724008A72EE /* Security.framework in Frameworks */,
 				158317500CFB80A1006F62B9 /* libbsm.dylib in Frameworks */,
-				158317520CFB80A1006F62B9 /* libKernelEventMonitor.a in Frameworks */,
-				158317530CFB80A1006F62B9 /* libInterfaceNamer.a in Frameworks */,
-				158317540CFB80A1006F62B9 /* libIPMonitor.a in Frameworks */,
-				158317550CFB80A1006F62B9 /* libLinkConfiguration.a in Frameworks */,
-				158317570CFB80A1006F62B9 /* libPreferencesMonitor.a in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2017,17 +2060,15 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				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 */,
 				152439E8180399D800D91708 /* CoreWLAN.framework in Frameworks */,
 				1543636B0752D03C00A8EC6C /* IOKit.framework in Frameworks */,
 				D6623873120B2AA7007F8E95 /* Security.framework in Frameworks */,
 				15BAA32307F0699A00D9EC95 /* libbsm.dylib in Frameworks */,
-				159D54CE07529FFF004F8947 /* libKernelEventMonitor.a in Frameworks */,
-				159D54D007529FFF004F8947 /* libInterfaceNamer.a in Frameworks */,
-				159D54D107529FFF004F8947 /* libIPMonitor.a in Frameworks */,
-				159D54D207529FFF004F8947 /* libLinkConfiguration.a in Frameworks */,
-				159D54D307529FFF004F8947 /* libPreferencesMonitor.a in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2035,6 +2076,7 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				90507AB31CE2F58A0067D16B /* libnetwork.dylib in Frameworks */,
 				15A5A2630D5B94190087BDA0 /* CoreFoundation.framework in Frameworks */,
 				B0FEF41A164406F400174B99 /* libbsm.dylib in Frameworks */,
 			);
@@ -2051,6 +2093,7 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				90507AB01CE2F55B0067D16B /* libnetwork.dylib in Frameworks */,
 				15DAD6AE07591A1A0084A6ED /* CoreFoundation.framework in Frameworks */,
 				B03FEFBA16382C0700A1B88F /* libbsm.dylib in Frameworks */,
 				15FBB54C17D6834C0035D752 /* libCrashReporterClient.a in Frameworks */,
@@ -2187,6 +2230,15 @@
 			name = Sources;
 			sourceTree = "";
 		};
+		155F49851C864ED400E47D08 /* QoSMarking */ = {
+			isa = PBXGroup;
+			children = (
+				155F49A51C864FE500E47D08 /* qos-marking.m */,
+				155F49A41C864FE500E47D08 /* Info.plist */,
+			);
+			name = QoSMarking;
+			sourceTree = "";
+		};
 		1582B36B05FD1A4D009C2750 /* DNSConfiguration */ = {
 			isa = PBXGroup;
 			children = (
@@ -2255,6 +2307,7 @@
 				159D53AF07528B36004F8947 /* KernelEventMonitor */,
 				159D53C007528B36004F8947 /* LinkConfiguration */,
 				159D53C207528B36004F8947 /* PreferencesMonitor */,
+				155F49851C864ED400E47D08 /* QoSMarking */,
 				15D3080E16F3E49F00014F82 /* SimulatorSupport */,
 			);
 			name = Plugins;
@@ -2263,6 +2316,7 @@
 		159D53A607528B36004F8947 /* IPMonitor */ = {
 			isa = PBXGroup;
 			children = (
+				728015741BE1681B009F4F60 /* AgentMonitor */,
 				725E53D41A92D289009997E1 /* Simulator */,
 				D6AEB89815AE4446009F2FAF /* ip_plugin.h */,
 				159D53A707528B36004F8947 /* ip_plugin.c */,
@@ -2276,7 +2330,6 @@
 				1572EB7A0A506D3B00D02459 /* smb-configuration.c */,
 				15FD743E0754DE7A001CC321 /* Info.plist */,
 				15FBB54E17D7899C0035D752 /* Info-EmbeddedSimulator.plist */,
-				D68AD25F159BCD5900D4F1BE /* com.apple.networking.IPMonitor */,
 			);
 			name = IPMonitor;
 			path = Plugins/IPMonitor;
@@ -2352,6 +2405,7 @@
 				1596A7AF14EDB73D00798C39 /* libSystemConfiguration_server.c */,
 				1582B36B05FD1A4D009C2750 /* DNSConfiguration */,
 				D6986A70136890B60091C931 /* NetworkInformation */,
+				726DB2F01BEA8075001B2C6C /* ConfigAgentInformation */,
 			);
 			name = libsystem_configuration;
 			sourceTree = "";
@@ -2363,9 +2417,10 @@
 				15A6F7C20A4B266D00B907EA /* Localizable.strings */,
 				15B686220678B65C00FF4023 /* NetworkConfiguration.plist */,
 				1577253606EFBF3100D7B52B /* NetworkInterface.strings */,
+				158D6D871C974DBA00A08E78 /* com.apple.SystemConfiguration.plist */,
 				15CFC229068B222F00123568 /* get-mobility-info */,
-				153393E20D34994100FE74E7 /* update-headers */,
 				72499BA31AC9B7AB0090C49F /* get-network-info */,
+				153393E20D34994100FE74E7 /* update-headers */,
 			);
 			name = "Supporting Files";
 			sourceTree = "";
@@ -2611,6 +2666,7 @@
 				72D3E65F1AE6EA3A00DB4C69 /* SCTest-Swift */,
 				72D3E66A1AE6EAF600DB4C69 /* SCTest-ObjC */,
 				15CB690F05C0722B0099E85F /* Products */,
+				90507AAE1CE2F55B0067D16B /* Frameworks */,
 			);
 			indentWidth = 8;
 			name = configd;
@@ -2653,6 +2709,10 @@
 				15D3082D16F3E4E100014F82 /* SimulatorSupport.bundle */,
 				72D3E65E1AE6EA3A00DB4C69 /* SCTest-Swift */,
 				72D3E6691AE6EAF600DB4C69 /* SCTest-ObjC */,
+				155F498D1C864F1400E47D08 /* libQoSMarking.a */,
+				155F49931C864F3700E47D08 /* QoSMarking.bundle */,
+				155F499C1C864F4E00E47D08 /* libQoSMarking.a */,
+				155F49A21C864F5400E47D08 /* QoSMarking.bundle */,
 			);
 			name = Products;
 			sourceTree = "";
@@ -2671,12 +2731,9 @@
 				F95B8A450B03E09300993BA3 /* SCNetworkSignaturePrivate.h */,
 				15CB693905C0722B0099E85F /* SCValidation.h */,
 				15A1FF3010597F17004C9CC9 /* CaptiveNetwork.h */,
-				15CB694505C0722B0099E85F /* DeviceOnHold.h */,
 				15CB693D05C0722B0099E85F /* DHCPClientPreferences.h */,
 				15CB694905C0722B0099E85F /* dy_framework.h */,
 				D61AAEB41522C9BD0066B003 /* scprefs_observer.h */,
-				15CB694305C0722B0099E85F /* moh.h */,
-				15CB694105C0722B0099E85F /* moh_msg.h */,
 			);
 			name = "Other Headers";
 			sourceTree = "";
@@ -2696,8 +2753,6 @@
 				15CB69A805C0722B0099E85F /* SCProxies.c */,
 				15A1FF3110597F17004C9CC9 /* CaptiveNetwork.c */,
 				15CB69AC05C0722B0099E85F /* DHCP.c */,
-				15CB69AE05C0722B0099E85F /* moh.c */,
-				15CB69B005C0722B0099E85F /* DeviceOnHold.c */,
 				15CB69B405C0722B0099E85F /* dy_framework.c */,
 			);
 			name = "Other Sources";
@@ -2861,6 +2916,9 @@
 		15CB6A6E05C0722B0099E85F /* External Frameworks and Libraries */ = {
 			isa = PBXGroup;
 			children = (
+				725CB7541BF439C6000C05A8 /* Foundation.framework */,
+				728015961BE16B6C009F4F60 /* NetworkExtension.framework */,
+				728015951BE16B6C009F4F60 /* Network.framework */,
 				15FEE80D0CCFD341001312F9 /* ApplicationServices.framework */,
 				15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */,
 				152439E7180399D800D91708 /* CoreWLAN.framework */,
@@ -2868,10 +2926,8 @@
 				152439EB180716ED00D91708 /* MobileWiFi.framework */,
 				1520A3DE0846B2DC0010B584 /* Security.framework */,
 				15BAA32207F0699A00D9EC95 /* libbsm.dylib */,
-				15AC2D8816C574FE00340E28 /* libcupolicy.dylib */,
 				152CEED0070CF6640050F23C /* libedit.dylib */,
 				15FBB54B17D6834C0035D752 /* libCrashReporterClient.a */,
-				15CAEF381712690500367CE1 /* libcupolicy.dylib */,
 			);
 			name = "External Frameworks and Libraries";
 			sourceTree = "";
@@ -2924,6 +2980,33 @@
 			path = Simulator;
 			sourceTree = "";
 		};
+		726DB2F01BEA8075001B2C6C /* ConfigAgentInformation */ = {
+			isa = PBXGroup;
+			children = (
+				726DB2F11BEA80E5001B2C6C /* config_agent_info.c */,
+				726DB2F21BEA80E5001B2C6C /* config_agent_info.h */,
+			);
+			name = ConfigAgentInformation;
+			sourceTree = "";
+		};
+		728015741BE1681B009F4F60 /* AgentMonitor */ = {
+			isa = PBXGroup;
+			children = (
+				728015751BE16833009F4F60 /* agent-monitor.m */,
+				728015931BE1697E009F4F60 /* agent-monitor.h */,
+				728015781BE16833009F4F60 /* configAgent.h */,
+				725CB7571BF51476000C05A8 /* configAgentDefines.h */,
+				728015791BE16833009F4F60 /* configAgent.m */,
+				7280157A1BE16833009F4F60 /* controller.h */,
+				7280157B1BE16833009F4F60 /* controller.m */,
+				7280157C1BE16833009F4F60 /* dnsAgent.h */,
+				7280157D1BE16833009F4F60 /* dnsAgent.m */,
+				7280157F1BE16833009F4F60 /* proxyAgent.h */,
+				728015801BE16833009F4F60 /* proxyAgent.m */,
+			);
+			name = AgentMonitor;
+			sourceTree = "";
+		};
 		72D3E65F1AE6EA3A00DB4C69 /* SCTest-Swift */ = {
 			isa = PBXGroup;
 			children = (
@@ -2940,6 +3023,15 @@
 			path = "SCTest-ObjC";
 			sourceTree = "";
 		};
+		90507AAE1CE2F55B0067D16B /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				90507AB11CE2F5720067D16B /* libnetwork.dylib */,
+				90507AAF1CE2F55B0067D16B /* libnetwork.dylib */,
+			);
+			name = Frameworks;
+			sourceTree = "";
+		};
 		D6986A70136890B60091C931 /* NetworkInformation */ = {
 			isa = PBXGroup;
 			children = (
@@ -2953,7 +3045,8 @@
 			isa = PBXGroup;
 			children = (
 				D6986A781368913C0091C931 /* network_information.h */,
-				D6986A761368911E0091C931 /* network_information_priv.h */,
+				D6986A761368911E0091C931 /* network_state_information_priv.h */,
+				720985431C580D9F00966D30 /* network_config_agent_info_priv.h */,
 				153ACCA714E322D5005029A5 /* network_information_server.h */,
 			);
 			name = Headers;
@@ -2963,7 +3056,7 @@
 			isa = PBXGroup;
 			children = (
 				D6986A77136891300091C931 /* network_information.c */,
-				D6986A75136891120091C931 /* network_information_priv.c */,
+				D6986A75136891120091C931 /* network_state_information_priv.c */,
 				153ACCA614E322D5005029A5 /* network_information_server.c */,
 			);
 			name = Sources;
@@ -3024,6 +3117,20 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
+		155F49871C864F1400E47D08 /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		155F49961C864F4E00E47D08 /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		1572C4A80CFB55B400E2776E /* Headers */ = {
 			isa = PBXHeadersBuildPhase;
 			buildActionMask = 2147483647;
@@ -3056,9 +3163,6 @@
 				1572C4BE0CFB55B400E2776E /* SCValidation.h in Headers */,
 				1572C4BF0CFB55B400E2776E /* DHCPClientPreferences.h in Headers */,
 				1572C4C00CFB55B400E2776E /* SCDynamicStoreCopyDHCPInfo.h in Headers */,
-				1572C4C10CFB55B400E2776E /* moh_msg.h in Headers */,
-				1572C4C20CFB55B400E2776E /* moh.h in Headers */,
-				1572C4C30CFB55B400E2776E /* DeviceOnHold.h in Headers */,
 				1572C4C50CFB55B400E2776E /* dy_framework.h in Headers */,
 				1572C4C70CFB55B400E2776E /* SCPreferencesPathKey.h in Headers */,
 				1572C4CE0CFB55B400E2776E /* SCPreferencesSetSpecificPrivate.h in Headers */,
@@ -3169,6 +3273,7 @@
 				D661C2F21368BB720030B977 /* network_information.h in Headers */,
 				157A84DB0D56C63900B6F1A0 /* dnsinfo_private.h in Headers */,
 				153338C014BE7978004FCE22 /* libSystemConfiguration_client.h in Headers */,
+				726DB2F61BEA80E5001B2C6C /* config_agent_info.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -3178,13 +3283,20 @@
 			files = (
 				F9B7AE6C186211DE00C78D18 /* IPMonitorControlServer.h in Headers */,
 				157A84F60D56C7E800B6F1A0 /* dns-configuration.h in Headers */,
+				720A4C0B1C585C93007436B8 /* controller.h in Headers */,
 				15D48EC20F67061F00B4711E /* dnsinfo_create.h in Headers */,
-				E4F211D4137B0ABD00BBB915 /* network_information_priv.h in Headers */,
+				720A4C0C1C585C97007436B8 /* dnsAgent.h in Headers */,
+				720985451C580D9F00966D30 /* network_config_agent_info_priv.h in Headers */,
+				E4F211D4137B0ABD00BBB915 /* network_state_information_priv.h in Headers */,
+				720A4C0D1C585C9F007436B8 /* proxyAgent.h in Headers */,
 				1575FD2812CD15C60003D86E /* proxy-configuration.h in Headers */,
 				F9B7AE6F186211F600C78D18 /* symbol_scope.h in Headers */,
 				F9B7AE68186211C900C78D18 /* IPMonitorControlPrivate.h in Headers */,
+				725CB7591BF514F5000C05A8 /* configAgentDefines.h in Headers */,
+				720985471C5835DB00966D30 /* agent-monitor.h in Headers */,
 				157A84F70D56C7E800B6F1A0 /* set-hostname.h in Headers */,
 				153ACCAC14E322D5005029A5 /* network_information_server.h in Headers */,
+				720A4C0A1C585C7D007436B8 /* configAgent.h in Headers */,
 				1596A7B514EDB73D00798C39 /* libSystemConfiguration_server.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -3270,9 +3382,16 @@
 			isa = PBXHeadersBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				728015991BE1812B009F4F60 /* agent-monitor.h in Headers */,
+				7280159B1BE1812B009F4F60 /* configAgent.h in Headers */,
+				7280159C1BE1812B009F4F60 /* controller.h in Headers */,
+				7280159D1BE1812B009F4F60 /* dnsAgent.h in Headers */,
+				7280159E1BE1812B009F4F60 /* proxyAgent.h in Headers */,
 				155D223B0AF13A7300D52ED0 /* dns-configuration.h in Headers */,
 				15D48EC00F67061700B4711E /* dnsinfo_create.h in Headers */,
-				E4F211D7137B0AF200BBB915 /* network_information_priv.h in Headers */,
+				725CB7581BF514F2000C05A8 /* configAgentDefines.h in Headers */,
+				E4F211D7137B0AF200BBB915 /* network_state_information_priv.h in Headers */,
+				720985441C580D9F00966D30 /* network_config_agent_info_priv.h in Headers */,
 				1575FD2A12CD15C60003D86E /* proxy-configuration.h in Headers */,
 				155D223C0AF13A7300D52ED0 /* set-hostname.h in Headers */,
 				F9B7AE67186211C200C78D18 /* IPMonitorControlPrivate.h in Headers */,
@@ -3346,9 +3465,6 @@
 				D61AAEB71522C9EF0066B003 /* scprefs_observer.h in Headers */,
 				15A5A1FE0D5B94190087BDA0 /* SCDynamicStoreCopyDHCPInfo.h in Headers */,
 				727AF258191386E3009AB153 /* VPNTunnelPrivate.h in Headers */,
-				15A5A1FF0D5B94190087BDA0 /* moh_msg.h in Headers */,
-				15A5A2000D5B94190087BDA0 /* moh.h in Headers */,
-				15A5A2010D5B94190087BDA0 /* DeviceOnHold.h in Headers */,
 				15A5A2030D5B94190087BDA0 /* dy_framework.h in Headers */,
 				15A5A2050D5B94190087BDA0 /* SCPreferencesPathKey.h in Headers */,
 				15A5A2060D5B94190087BDA0 /* dnsinfo.h in Headers */,
@@ -3388,6 +3504,7 @@
 				D661C2EF1368BB280030B977 /* network_information.h in Headers */,
 				15DAD5E2075913CE0084A6ED /* dnsinfo_private.h in Headers */,
 				153338BF14BE7978004FCE22 /* libSystemConfiguration_client.h in Headers */,
+				728CEB001BEA993100F13F92 /* config_agent_info.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -3427,9 +3544,6 @@
 				15DAD65707591A1A0084A6ED /* SCValidation.h in Headers */,
 				15DAD65807591A1A0084A6ED /* DHCPClientPreferences.h in Headers */,
 				15DAD65907591A1A0084A6ED /* SCDynamicStoreCopyDHCPInfo.h in Headers */,
-				15DAD65A07591A1A0084A6ED /* moh_msg.h in Headers */,
-				15DAD65B07591A1A0084A6ED /* moh.h in Headers */,
-				15DAD65C07591A1A0084A6ED /* DeviceOnHold.h in Headers */,
 				15DAD65E07591A1A0084A6ED /* dy_framework.h in Headers */,
 				15DAD66107591A1A0084A6ED /* SCPreferencesPathKey.h in Headers */,
 				B0A88CA716397A1200A60B3A /* VPNAppLayerPrivate.h in Headers */,
@@ -3460,7 +3574,7 @@
 			files = (
 				15E1B04316EBAE3C00E5F06F /* dns-configuration.h in Headers */,
 				15E1B04416EBAE3C00E5F06F /* dnsinfo_create.h in Headers */,
-				15E1B04516EBAE3C00E5F06F /* network_information_priv.h in Headers */,
+				15E1B04516EBAE3C00E5F06F /* network_state_information_priv.h in Headers */,
 				15E1B04616EBAE3C00E5F06F /* proxy-configuration.h in Headers */,
 				15E1B04816EBAE3C00E5F06F /* network_information_server.h in Headers */,
 				15E1B04916EBAE3C00E5F06F /* libSystemConfiguration_server.h in Headers */,
@@ -3560,17 +3674,82 @@
 			productReference = 1558481D07550EC10046C2E9 /* scselect */;
 			productType = "com.apple.product-type.tool";
 		};
+		155F49861C864F1400E47D08 /* QoSMarking */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 155F498A1C864F1400E47D08 /* Build configuration list for PBXNativeTarget "QoSMarking" */;
+			buildPhases = (
+				155F49871C864F1400E47D08 /* Headers */,
+				155F49881C864F1400E47D08 /* Sources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = QoSMarking;
+			productName = QoSMarking;
+			productReference = 155F498D1C864F1400E47D08 /* libQoSMarking.a */;
+			productType = "com.apple.product-type.library.static";
+		};
+		155F498E1C864F3700E47D08 /* QoSMarking.bundle */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 155F49901C864F3700E47D08 /* Build configuration list for PBXNativeTarget "QoSMarking.bundle" */;
+			buildPhases = (
+				155F498F1C864F3700E47D08 /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = QoSMarking.bundle;
+			productInstallPath = "$(USER_LIBRARY_DIR)/Bundles";
+			productName = QoSMarking.bundle;
+			productReference = 155F49931C864F3700E47D08 /* QoSMarking.bundle */;
+			productType = "com.apple.product-type.bundle";
+		};
+		155F49951C864F4E00E47D08 /* QoSMarking-Embedded */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 155F49991C864F4E00E47D08 /* Build configuration list for PBXNativeTarget "QoSMarking-Embedded" */;
+			buildPhases = (
+				155F49961C864F4E00E47D08 /* Headers */,
+				155F49971C864F4E00E47D08 /* Sources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = "QoSMarking-Embedded";
+			productName = QoSMarking;
+			productReference = 155F499C1C864F4E00E47D08 /* libQoSMarking.a */;
+			productType = "com.apple.product-type.library.static";
+		};
+		155F499D1C864F5400E47D08 /* QoSMarking.bundle-Embedded */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 155F499F1C864F5400E47D08 /* Build configuration list for PBXNativeTarget "QoSMarking.bundle-Embedded" */;
+			buildPhases = (
+				155F499E1C864F5400E47D08 /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = "QoSMarking.bundle-Embedded";
+			productInstallPath = "$(USER_LIBRARY_DIR)/Bundles";
+			productName = QoSMarking.bundle;
+			productReference = 155F49A21C864F5400E47D08 /* QoSMarking.bundle */;
+			productType = "com.apple.product-type.bundle";
+		};
 		1572C4A60CFB55B400E2776E /* SystemConfiguration.framework-Embedded */ = {
 			isa = PBXNativeTarget;
 			buildConfigurationList = 1572C5290CFB55B400E2776E /* Build configuration list for PBXNativeTarget "SystemConfiguration.framework-Embedded" */;
 			buildPhases = (
 				1572C4A80CFB55B400E2776E /* Headers */,
 				153393E40D34999D00FE74E7 /* Update Headers */,
-				1572C4D90CFB55B400E2776E /* Resources */,
 				1572C4DE0CFB55B400E2776E /* Sources */,
 				1572C5230CFB55B400E2776E /* Frameworks */,
-				1572C5270CFB55B400E2776E /* get-mobility-info */,
+				1572C4D90CFB55B400E2776E /* Resources */,
 				1510A7301B17E1AF00125A85 /* Add framework symlink (TEMPORARY) */,
+				1572C5270CFB55B400E2776E /* get-mobility-info */,
+				158D6D8A1C974EF700A08E78 /* Logging Preferences */,
 			);
 			buildRules = (
 			);
@@ -3683,6 +3862,7 @@
 				157A84D90D56C63900B6F1A0 /* Headers */,
 				157A84DD0D56C63900B6F1A0 /* Sources */,
 				157A84E20D56C63900B6F1A0 /* Frameworks */,
+				154070A11B98E8D3003195EF /* Update "install_path" for address sanitizer */,
 			);
 			buildRules = (
 			);
@@ -3814,7 +3994,6 @@
 			buildConfigurationList = 158317800CFB85C8006F62B9 /* Build configuration list for PBXNativeTarget "IPMonitor.bundle-Embedded" */;
 			buildPhases = (
 				1583177E0CFB85C8006F62B9 /* Resources */,
-				15D54E2515B4FA1900F5229A /* com.apple.networking.IPMonitor */,
 			);
 			buildRules = (
 			);
@@ -3997,7 +4176,7 @@
 				159D54AB07529FFF004F8947 /* Sources */,
 				159D54CA07529FFF004F8947 /* Frameworks */,
 				159D54D507529FFF004F8947 /* CopyFiles */,
-				159D54D707529FFF004F8947 /* CopyFiles */,
+				159D54D707529FFF004F8947 /* Copy Files */,
 				15FBB54D17D75DE70035D752 /* Update MachServices */,
 			);
 			buildRules = (
@@ -4016,10 +4195,11 @@
 			buildPhases = (
 				15A5A1E60D5B94190087BDA0 /* Headers */,
 				15A5A2170D5B94190087BDA0 /* Update Headers */,
-				15A5A2180D5B94190087BDA0 /* Resources */,
 				15A5A21D0D5B94190087BDA0 /* Sources */,
 				15A5A2620D5B94190087BDA0 /* Frameworks */,
+				15A5A2180D5B94190087BDA0 /* Resources */,
 				1535FEDC1B0FDDCD00B2A3AD /* Add framework symlink (TEMPORARY) */,
+				158D6D8C1C974F4800A08E78 /* Logging Preferences */,
 			);
 			buildRules = (
 			);
@@ -4070,6 +4250,7 @@
 				15DAD5E0075913CE0084A6ED /* Headers */,
 				15DAD5E4075913CE0084A6ED /* Sources */,
 				15DAD5E9075913CE0084A6ED /* Frameworks */,
+				154070A01B968548003195EF /* Update "install_path" for address sanitizer */,
 			);
 			buildRules = (
 			);
@@ -4088,11 +4269,12 @@
 				15DAD6AC07591A1A0084A6ED /* SystemConfiguration.order */,
 				15DAD64107591A1A0084A6ED /* Headers */,
 				15AC82480D376E2400A579D0 /* Update Headers */,
-				15DAD66807591A1A0084A6ED /* Resources */,
 				15DAD66C07591A1A0084A6ED /* Sources */,
 				15DAD6AD07591A1A0084A6ED /* Frameworks */,
+				15DAD66807591A1A0084A6ED /* Resources */,
 				15DAD6B007591A1A0084A6ED /* get-mobility-info */,
 				15D9DCF910DD909F004E545D /* AppWorkaround.plist */,
+				158D6D881C974E7E00A08E78 /* Logging Preferences */,
 			);
 			buildRules = (
 			);
@@ -4125,7 +4307,6 @@
 			buildConfigurationList = 15E1B05E16EBAE7800E5F06F /* Build configuration list for PBXNativeTarget "IPMonitor.bundle-EmbeddedSimulator" */;
 			buildPhases = (
 				15E1B05B16EBAE7800E5F06F /* Resources */,
-				72AD314B1A843C1000D2226E /* com.apple.networking.IPMonitor */,
 			);
 			buildRules = (
 			);
@@ -4158,7 +4339,6 @@
 			buildConfigurationList = 156EB5F20905594A00EEF749 /* Build configuration list for PBXNativeTarget "IPMonitor.bundle" */;
 			buildPhases = (
 				15FD72A20754DA4C001CC321 /* Resources */,
-				15D54E2A15B4FAF100F5229A /* com.apple.networking.IPMonitor */,
 			);
 			buildRules = (
 			);
@@ -4244,7 +4424,7 @@
 		15CB6A7705C0722B0099E85F /* Project object */ = {
 			isa = PBXProject;
 			attributes = {
-				LastUpgradeCheck = 0700;
+				LastUpgradeCheck = 0800;
 				TargetAttributes = {
 					72D3E65D1AE6EA3900DB4C69 = {
 						CreatedOnToolsVersion = 7.0;
@@ -4286,6 +4466,8 @@
 				15FD72B10754DA69001CC321 /* LinkConfiguration.bundle */,
 				159D53F907528C95004F8947 /* PreferencesMonitor */,
 				15FD72C50754DA7E001CC321 /* PreferencesMonitor.bundle */,
+				155F49861C864F1400E47D08 /* QoSMarking */,
+				155F498E1C864F3700E47D08 /* QoSMarking.bundle */,
 				155847FA07550D210046C2E9 /* configd_executables */,
 				159D549F07529FFF004F8947 /* configd */,
 				1558481207550EC10046C2E9 /* scselect */,
@@ -4308,6 +4490,8 @@
 				158317980CFB860C006F62B9 /* LinkConfiguration.bundle-Embedded */,
 				157A853C0D56C96F00B6F1A0 /* PreferencesMonitor-Embedded */,
 				158317A80CFB8639006F62B9 /* PreferencesMonitor.bundle-Embedded */,
+				155F49951C864F4E00E47D08 /* QoSMarking-Embedded */,
+				155F499D1C864F5400E47D08 /* QoSMarking.bundle-Embedded */,
 				158317040CFB7782006F62B9 /* configd_executables-Embedded */,
 				158317230CFB80A1006F62B9 /* configd-Embedded */,
 				157433DD0D4A8122002ACA73 /* scselect-Embedded */,
@@ -4340,6 +4524,20 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
+		155F498F1C864F3700E47D08 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		155F499E1C864F5400E47D08 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		1572C4D90CFB55B400E2776E /* Resources */ = {
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
@@ -4416,10 +4614,10 @@
 			buildActionMask = 2147483647;
 			files = (
 				15A6F7C40A4B266D00B907EA /* Localizable.strings in Resources */,
-				15DAD66B07591A1A0084A6ED /* NetworkInterface.strings in Resources */,
-				72499BA41AC9B7AB0090C49F /* get-network-info in Resources */,
 				15DAD66907591A1A0084A6ED /* NetworkConfiguration.plist in Resources */,
+				15DAD66B07591A1A0084A6ED /* NetworkInterface.strings in Resources */,
 				15DAD66A07591A1A0084A6ED /* get-mobility-info in Resources */,
+				72499BA41AC9B7AB0090C49F /* get-network-info in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -4461,6 +4659,21 @@
 /* End PBXResourcesBuildPhase section */
 
 /* Begin PBXShellScriptBuildPhase section */
+		1502C5611BDD4936005CF7EA /* Move libsystem_configuration_asan.dylib */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 8;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "Move libsystem_configuration_asan.dylib";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 1;
+			shellPath = /bin/sh;
+			shellScript = "#\n# move libsystem_configuration_asan.dylib out of /usr/lib/system\n#\n# Note: to use the asan .dylib, set DYLD_INSERT_LIBRARIES=...\n#\nfor VARIANT in ${BUILD_VARIANTS}\ndo\n    if [ \"${VARIANT}\" = \"asan\" ]; then\n        DIR_O=\"/usr/lib/system\"\n        DIR_N=\"/usr/local/lib\"\n        DYLIB=\"libsystem_configuration_${VARIANT}.dylib\"\n\n\t\tmkdir -p \"${DSTROOT}/${DIR_N}\"\n\t\tmv \"${DSTROOT}/${DIR_O}/${DYLIB}\" \"${DSTROOT}/${DIR_N}/${DYLIB}\"\n\t\tif [ -d \"${DSTROOT}/${DIR_O}/${DYLIB}.dSYM\" ]; then\n\t\t\tmv \"${DSTROOT}/${DIR_O}/${DYLIB}.dSYM\" \"${DSTROOT}/${DIR_N}/${DYLIB}.dSYM\"\n\t\tfi\n    fi\ndone";
+			showEnvVarsInLog = 0;
+		};
 		1510A7301B17E1AF00125A85 /* Add framework symlink (TEMPORARY) */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
@@ -4473,7 +4686,7 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "if [ \"${USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK}\" = \"YES\" ]; then\n    mkdir -p ${INSTALL_ROOT}/System/Library/Frameworks\n    cd ${INSTALL_ROOT}/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";
 			showEnvVarsInLog = 0;
 		};
 		151F63DB09328A3C0096DCC9 /* ShellScript */ = {
@@ -4521,7 +4734,37 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "if [ \"${USING_PRIVATE_SYSTEMCONFIGURATION_FRAMEWORK}\" = \"YES\" ]; then\n    mkdir -p ${INSTALL_ROOT}/System/Library/Frameworks\n    cd ${INSTALL_ROOT}/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";
+			showEnvVarsInLog = 0;
+		};
+		154070A01B968548003195EF /* Update "install_path" for address sanitizer */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 8;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "Update \"install_path\" for address sanitizer";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 1;
+			shellPath = /bin/sh;
+			shellScript = "#\n# fix address-sanitizer library @rpath references\n#\n\nfor VARIANT in ${BUILD_VARIANTS}\ndo\n    if [ \"${VARIANT}\" = \"asan\" ]; then\n        ASAN_SDK_DIR=\"${TOOLCHAIN_DIR}/usr/lib/clang/${CLANG_VERS}/lib/darwin\"\n        ASAN_DST_DIR=\"/usr/local/lib\"\n        case \"${PLATFORM_NAME}\" in\n            macosx )\n\t\t\t\tASAN_LIB=\"clang_rt.asan_osx_dynamic.dylib\"\n                ;;\n            iphoneos )\n\t\t\t\tASAN_LIB=\"clang_rt.asan_ios_dynamic.dylib\"\n                ;;\n            iphonesimulator )\n\t\t\t\tASAN_LIB=\"clang_rt.asan_iossim_dynamic.dylib\"\n                ;;\n            tvos )\n\t\t\t\tASAN_LIB=\"clang_rt.asan_tvos_dynamic.dylib\"\n                ;;\n            tvsosimulator )\n\t\t\t\tASAN_LIB=\"clang_rt.asan_tvossim_dynamic.dylib\"\n                ;;\n            watchos )\n\t\t\t\tASAN_LIB=\"clang_rt.asan_watchos_dynamic.dylib\"\n                ;;\n            watchsimulator )\n\t\t\t\tASAN_LIB=\"clang_rt.asan_watchossim_dynamic.dylib\"\n                ;;\n        esac\n\n        if [ ! -f \"${ASAN_SDK_DIR}/lib${ASAN_LIB}\" ]; then exit 0; fi\n\n\t\t# ensure that the ASAN dylib will be in the DSTROOT\n        ditto \"${ASAN_SDK_DIR}/lib${ASAN_LIB}\" \"${DSTROOT}${ASAN_DST_DIR}/lib${ASAN_LIB}\"\n\n\t\t# change @rpath reference\n        install_name_tool                                           \\\n            -change                                                 \\\n            \"@rpath/lib${ASAN_LIB}\"                                 \\\n            \"${ASAN_DST_DIR}/lib${ASAN_LIB}\"                        \\\n            \"${DSTROOT}${INSTALL_PATH}/${PRODUCT_NAME}_asan.dylib\"\n    fi\ndone";
+			showEnvVarsInLog = 0;
+		};
+		154070A11B98E8D3003195EF /* Update "install_path" for address sanitizer */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 8;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "Update \"install_path\" for address sanitizer";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 1;
+			shellPath = /bin/sh;
+			shellScript = "#\n# fix address-sanitizer library @rpath references\n#\n\nfor VARIANT in ${BUILD_VARIANTS}\ndo\n    if [ \"${VARIANT}\" = \"asan\" ]; then\n        ASAN_SDK_DIR=\"${TOOLCHAIN_DIR}/usr/lib/clang/${CLANG_VERS}/lib/darwin\"\n        ASAN_DST_DIR=\"/usr/local/lib\"\n        case \"${PLATFORM_NAME}\" in\n            macosx )\n\t\t\t\tASAN_LIB=\"clang_rt.asan_osx_dynamic.dylib\"\n                ;;\n            iphoneos )\n\t\t\t\tASAN_LIB=\"clang_rt.asan_ios_dynamic.dylib\"\n                ;;\n            iphonesimulator )\n\t\t\t\tASAN_LIB=\"clang_rt.asan_iossim_dynamic.dylib\"\n                ;;\n            tvos )\n\t\t\t\tASAN_LIB=\"clang_rt.asan_tvos_dynamic.dylib\"\n                ;;\n            tvsosimulator )\n\t\t\t\tASAN_LIB=\"clang_rt.asan_tvossim_dynamic.dylib\"\n                ;;\n            watchos )\n\t\t\t\tASAN_LIB=\"clang_rt.asan_watchos_dynamic.dylib\"\n                ;;\n            watchsimulator )\n\t\t\t\tASAN_LIB=\"clang_rt.asan_watchossim_dynamic.dylib\"\n                ;;\n        esac\n\n        if [ ! -f \"${ASAN_SDK_DIR}/lib${ASAN_LIB}\" ]; then exit 0; fi\n\n\t\t# ensure that the ASAN dylib will be in the DSTROOT\n        ditto \"${ASAN_SDK_DIR}/lib${ASAN_LIB}\" \"${DSTROOT}${ASAN_DST_DIR}/lib${ASAN_LIB}\"\n\n\t\t# change @rpath reference\n        install_name_tool                                           \\\n            -change                                                 \\\n            \"@rpath/lib${ASAN_LIB}\"                                 \\\n            \"${ASAN_DST_DIR}/lib${ASAN_LIB}\"                        \\\n            \"${DSTROOT}${INSTALL_PATH}/${PRODUCT_NAME}_asan.dylib\"\n    fi\ndone";
 			showEnvVarsInLog = 0;
 		};
 		1572C5270CFB55B400E2776E /* get-mobility-info */ = {
@@ -4551,7 +4794,7 @@
 			);
 			runOnlyForDeploymentPostprocessing = 1;
 			shellPath = /bin/sh;
-			shellScript = "SCHELPER_LAUNCHD_PLIST=\"${INSTALL_ROOT}/System/Library/LaunchDaemons/com.apple.SCHelper-embedded.plist\"\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";
+			shellScript = "SCHELPER_LAUNCHD_PLIST=\"${DSTROOT}/System/Library/LaunchDaemons/com.apple.SCHelper-embedded.plist\"\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;
 		};
 		15A5A2170D5B94190087BDA0 /* Update Headers */ = {
@@ -4586,6 +4829,21 @@
 			shellScript = "if [ -x ${SCRIPT_INPUT_FILE_0} ]; then\n\t${SCRIPT_INPUT_FILE_0} clean\nfi\n";
 			showEnvVarsInLog = 0;
 		};
+		15AC9A4C1BE3ED87003071BD /* Move libsystem_configuration_asan.dylib */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 8;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "Move libsystem_configuration_asan.dylib";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 1;
+			shellPath = /bin/sh;
+			shellScript = "#\n# move libsystem_configuration_asan.dylib out of /usr/lib/system\n#\n# Note: to use the asan .dylib, set DYLD_INSERT_LIBRARIES=...\n#\nfor VARIANT in ${BUILD_VARIANTS}\ndo\n    if [ \"${VARIANT}\" = \"asan\" ]; then\n        DIR_O=\"/usr/lib/system\"\n        DIR_N=\"/usr/local/lib\"\n        DYLIB=\"libsystem_configuration_${VARIANT}.dylib\"\n\n\t\tmkdir -p \"${DSTROOT}/${DIR_N}\"\n\t\tmv \"${DSTROOT}/${DIR_O}/${DYLIB}\" \"${DSTROOT}/${DIR_N}/${DYLIB}\"\n\t\tif [ -d \"${DSTROOT}/${DIR_O}/${DYLIB}.dSYM\" ]; then\n\t\t\tmv \"${DSTROOT}/${DIR_O}/${DYLIB}.dSYM\" \"${DSTROOT}/${DIR_N}/${DYLIB}.dSYM\"\n\t\tfi\n    fi\ndone";
+			showEnvVarsInLog = 0;
+		};
 		15DAD6AC07591A1A0084A6ED /* SystemConfiguration.order */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
@@ -4715,6 +4973,22 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
+		155F49881C864F1400E47D08 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				155F49A61C864FFC00E47D08 /* qos-marking.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		155F49971C864F4E00E47D08 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				155F49A71C86500100E47D08 /* qos-marking.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		1572C4DE0CFB55B400E2776E /* Sources */ = {
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
@@ -4765,8 +5039,6 @@
 				1572C50C0CFB55B400E2776E /* SCNetworkReachability.c in Sources */,
 				1572C50D0CFB55B400E2776E /* SCProxies.c in Sources */,
 				1572C50E0CFB55B400E2776E /* DHCP.c in Sources */,
-				1572C50F0CFB55B400E2776E /* moh.c in Sources */,
-				1572C5100CFB55B400E2776E /* DeviceOnHold.c in Sources */,
 				1572C5110CFB55B400E2776E /* LinkConfiguration.c in Sources */,
 				1572C5120CFB55B400E2776E /* dy_framework.c in Sources */,
 				1572C5150CFB55B400E2776E /* SCPreferencesPathKey.c in Sources */,
@@ -4822,7 +5094,6 @@
 				15732A9516EA503200F3AC4C /* _notifyviasignal.c in Sources */,
 				15732A9616EA503200F3AC4C /* _notifycancel.c in Sources */,
 				15732A9716EA503200F3AC4C /* _snapshot.c in Sources */,
-				15732A9916EA503200F3AC4C /* dnsinfo_server.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -4895,6 +5166,7 @@
 				157A84DF0D56C63900B6F1A0 /* dnsinfo_copy.c in Sources */,
 				D661C2F11368BB600030B977 /* network_information.c in Sources */,
 				153338BD14BE7978004FCE22 /* libSystemConfiguration_client.c in Sources */,
+				726DB2F41BEA80E5001B2C6C /* config_agent_info.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -4904,13 +5176,18 @@
 			files = (
 				157A84FB0D56C7E800B6F1A0 /* dns-configuration.c in Sources */,
 				15D48EC10F67061F00B4711E /* dnsinfo_create.c in Sources */,
+				7280158E1BE16863009F4F60 /* dnsAgent.m in Sources */,
 				F9B7AE69186211CE00C78D18 /* IPMonitorControlServer.c in Sources */,
+				728015881BE16851009F4F60 /* configAgent.m in Sources */,
+				728015911BE1686C009F4F60 /* proxyAgent.m in Sources */,
 				150BEC1A14CA252200237116 /* dnsinfo_server.c in Sources */,
 				155281020E3E4A0F00C54315 /* ip_plugin.c in Sources */,
-				E4F211D3137B0AB900BBB915 /* network_information_priv.c in Sources */,
+				E4F211D3137B0AB900BBB915 /* network_state_information_priv.c in Sources */,
 				153ACCA914E322D5005029A5 /* network_information_server.c in Sources */,
 				1575FD2712CD15C60003D86E /* proxy-configuration.c in Sources */,
 				157A84FC0D56C7E800B6F1A0 /* set-hostname.c in Sources */,
+				7280158B1BE1685B009F4F60 /* controller.m in Sources */,
+				728015821BE16840009F4F60 /* agent-monitor.m in Sources */,
 				1596A7B214EDB73D00798C39 /* libSystemConfiguration_server.c in Sources */,
 				D61AAEB11522C99C0066B003 /* scprefs_observer.c in Sources */,
 				F9A3781116A4849100C57CDC /* IPMonitorControlPrefs.c in Sources */,
@@ -4983,7 +5260,6 @@
 				158317440CFB80A1006F62B9 /* _notifyviasignal.c in Sources */,
 				158317450CFB80A1006F62B9 /* _notifycancel.c in Sources */,
 				158317460CFB80A1006F62B9 /* _snapshot.c in Sources */,
-				158317490CFB80A1006F62B9 /* dnsinfo_server.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -5022,17 +5298,22 @@
 			buildActionMask = 2147483647;
 			files = (
 				159D541807528E09004F8947 /* dns-configuration.c in Sources */,
+				728015871BE1684E009F4F60 /* configAgent.m in Sources */,
 				15D48EBF0F67061600B4711E /* dnsinfo_create.c in Sources */,
 				1522FCFB0FA7FE4B00B24128 /* dnsinfo_flatfile.c in Sources */,
 				150BEC1814CA24F900237116 /* dnsinfo_server.c in Sources */,
 				F9B7AE6A186211D300C78D18 /* IPMonitorControlServer.c in Sources */,
 				159D541707528E05004F8947 /* ip_plugin.c in Sources */,
-				E49173E1137C4E4F0000089F /* network_information_priv.c in Sources */,
+				7280158D1BE16861009F4F60 /* dnsAgent.m in Sources */,
+				E49173E1137C4E4F0000089F /* network_state_information_priv.c in Sources */,
 				153ACCA814E322D5005029A5 /* network_information_server.c in Sources */,
 				1575FD2912CD15C60003D86E /* proxy-configuration.c in Sources */,
 				154361E00752C81800A8EC6C /* set-hostname.c in Sources */,
+				728015921BE1686F009F4F60 /* proxyAgent.m in Sources */,
 				1572EB7B0A506D3B00D02459 /* smb-configuration.c in Sources */,
 				1596A7B114EDB73D00798C39 /* libSystemConfiguration_server.c in Sources */,
+				728015811BE1683B009F4F60 /* agent-monitor.m in Sources */,
+				7280158C1BE1685D009F4F60 /* controller.m in Sources */,
 				D61AAEAF1522C99C0066B003 /* scprefs_observer.c in Sources */,
 				F9A3781016A4847700C57CDC /* IPMonitorControlPrefs.c in Sources */,
 			);
@@ -5083,7 +5364,6 @@
 				159D54C307529FFF004F8947 /* _notifyviasignal.c in Sources */,
 				159D54C407529FFF004F8947 /* _notifycancel.c in Sources */,
 				159D54C507529FFF004F8947 /* _snapshot.c in Sources */,
-				159D54C807529FFF004F8947 /* dnsinfo_server.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -5136,8 +5416,6 @@
 				15A5A24B0D5B94190087BDA0 /* SCNetworkReachability.c in Sources */,
 				15A5A24C0D5B94190087BDA0 /* SCProxies.c in Sources */,
 				15A5A24D0D5B94190087BDA0 /* DHCP.c in Sources */,
-				15A5A24E0D5B94190087BDA0 /* moh.c in Sources */,
-				15A5A24F0D5B94190087BDA0 /* DeviceOnHold.c in Sources */,
 				15A5A2500D5B94190087BDA0 /* LinkConfiguration.c in Sources */,
 				15A5A2510D5B94190087BDA0 /* dy_framework.c in Sources */,
 				15A5A2540D5B94190087BDA0 /* SCPreferencesPathKey.c in Sources */,
@@ -5179,6 +5457,7 @@
 				15DAD5E6075913CE0084A6ED /* dnsinfo_copy.c in Sources */,
 				D6986A79136891650091C931 /* network_information.c in Sources */,
 				153338BC14BE7978004FCE22 /* libSystemConfiguration_client.c in Sources */,
+				728CEAFF1BEA951A00F13F92 /* config_agent_info.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -5235,8 +5514,6 @@
 				15DAD69807591A1A0084A6ED /* SCNetworkReachability.c in Sources */,
 				15DAD69907591A1A0084A6ED /* SCProxies.c in Sources */,
 				15DAD69A07591A1A0084A6ED /* DHCP.c in Sources */,
-				15DAD69B07591A1A0084A6ED /* moh.c in Sources */,
-				15DAD69C07591A1A0084A6ED /* DeviceOnHold.c in Sources */,
 				15DAD69D07591A1A0084A6ED /* LinkConfiguration.c in Sources */,
 				15DAD69E07591A1A0084A6ED /* dy_framework.c in Sources */,
 				15DAD69F07591A1A0084A6ED /* VLANConfiguration.c in Sources */,
@@ -5270,7 +5547,7 @@
 				15E1B04C16EBAE3C00E5F06F /* dnsinfo_create.c in Sources */,
 				15E1B04D16EBAE3C00E5F06F /* dnsinfo_server.c in Sources */,
 				15E1B04E16EBAE3C00E5F06F /* ip_plugin.c in Sources */,
-				15E1B04F16EBAE3C00E5F06F /* network_information_priv.c in Sources */,
+				15E1B04F16EBAE3C00E5F06F /* network_state_information_priv.c in Sources */,
 				15E1B05016EBAE3C00E5F06F /* network_information_server.c in Sources */,
 				15E1B05116EBAE3C00E5F06F /* proxy-configuration.c in Sources */,
 				15E1B05316EBAE3C00E5F06F /* libSystemConfiguration_server.c in Sources */,
@@ -5318,16 +5595,21 @@
 			target = 1558481207550EC10046C2E9 /* scselect */;
 			targetProxy = 1558480707550D470046C2E9 /* PBXContainerItemProxy */;
 		};
-		1558480A07550D470046C2E9 /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			target = 155847430754FDCD0046C2E9 /* scutil */;
-			targetProxy = 1558480907550D470046C2E9 /* PBXContainerItemProxy */;
-		};
 		1558480F07550DD00046C2E9 /* PBXTargetDependency */ = {
 			isa = PBXTargetDependency;
 			target = 155847FA07550D210046C2E9 /* configd_executables */;
 			targetProxy = 1558480E07550DD00046C2E9 /* PBXContainerItemProxy */;
 		};
+		155F49AD1C86511300E47D08 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 155F49951C864F4E00E47D08 /* QoSMarking-Embedded */;
+			targetProxy = 155F49AC1C86511300E47D08 /* PBXContainerItemProxy */;
+		};
+		155F49AF1C86511300E47D08 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 155F499D1C864F5400E47D08 /* QoSMarking.bundle-Embedded */;
+			targetProxy = 155F49AE1C86511300E47D08 /* PBXContainerItemProxy */;
+		};
 		15732AE616EA6BCE00F3AC4C /* PBXTargetDependency */ = {
 			isa = PBXTargetDependency;
 			target = 15732AD616EA6B6700F3AC4C /* libsystem_configuration-EmbeddedSimulator */;
@@ -5583,6 +5865,11 @@
 			target = 15DAD63F07591A1A0084A6ED /* SystemConfiguration.framework */;
 			targetProxy = 723050331AE6F29D004AC149 /* PBXContainerItemProxy */;
 		};
+		72C4A4801BE44D19009D570E /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 155847430754FDCD0046C2E9 /* scutil */;
+			targetProxy = 72C4A47F1BE44D19009D570E /* PBXContainerItemProxy */;
+		};
 		D6DDAC3D147A24BC00A2E902 /* PBXTargetDependency */ = {
 			isa = PBXTargetDependency;
 			target = 1547001808455B98006787CE /* SCHelper */;
@@ -5643,6 +5930,7 @@
 				FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
 				INFOPLIST_FILE = SCMonitor/Info.plist;
 				INSTALL_PATH = /System/Library/UserEventPlugins;
+				PRODUCT_BUNDLE_IDENTIFIER = "com.apple.SystemConfiguration.${EXECUTABLE_NAME}";
 				PRODUCT_NAME = SCMonitor;
 				PROVISIONING_PROFILE = "";
 				WRAPPER_EXTENSION = plugin;
@@ -5658,6 +5946,7 @@
 				FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
 				INFOPLIST_FILE = SCMonitor/Info.plist;
 				INSTALL_PATH = /System/Library/UserEventPlugins;
+				PRODUCT_BUNDLE_IDENTIFIER = "com.apple.SystemConfiguration.${EXECUTABLE_NAME}";
 				PRODUCT_NAME = SCMonitor;
 				PROVISIONING_PROFILE = "";
 				WRAPPER_EXTENSION = plugin;
@@ -5708,6 +5997,111 @@
 			};
 			name = Release;
 		};
+		155F498B1C864F1400E47D08 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				"ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD)";
+				CLANG_ENABLE_OBJC_ARC = YES;
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				FRAMEWORK_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+				HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
+				INSTALL_PATH = /usr/local/lib/SystemConfiguration;
+				LIBRARY_STYLE = STATIC;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				STRIP_INSTALLED_PRODUCT = NO;
+			};
+			name = Debug;
+		};
+		155F498C1C864F1400E47D08 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CLANG_ENABLE_OBJC_ARC = YES;
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				FRAMEWORK_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+				HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
+				INSTALL_PATH = /usr/local/lib/SystemConfiguration;
+				LIBRARY_STYLE = STATIC;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				STRIP_INSTALLED_PRODUCT = NO;
+			};
+			name = Release;
+		};
+		155F49911C864F3700E47D08 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				INFOPLIST_FILE = Plugins/QoSMarking/Info.plist;
+				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.QoSMarking;
+				PRODUCT_NAME = QoSMarking;
+			};
+			name = Debug;
+		};
+		155F49921C864F3700E47D08 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				INFOPLIST_FILE = Plugins/QoSMarking/Info.plist;
+				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.QoSMarking;
+				PRODUCT_NAME = QoSMarking;
+			};
+			name = Release;
+		};
+		155F499A1C864F4E00E47D08 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CLANG_ENABLE_OBJC_ARC = YES;
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				FRAMEWORK_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+				HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
+				INSTALL_PATH = /usr/local/lib/SystemConfiguration;
+				LIBRARY_STYLE = STATIC;
+				PRODUCT_NAME = QoSMarking;
+				SDKROOT = iphoneos.internal;
+				STRIP_INSTALLED_PRODUCT = NO;
+				SUPPORTED_PLATFORMS = iphoneos;
+			};
+			name = Debug;
+		};
+		155F499B1C864F4E00E47D08 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CLANG_ENABLE_OBJC_ARC = YES;
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				FRAMEWORK_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+				HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
+				INSTALL_PATH = /usr/local/lib/SystemConfiguration;
+				LIBRARY_STYLE = STATIC;
+				PRODUCT_NAME = QoSMarking;
+				SDKROOT = iphoneos.internal;
+				STRIP_INSTALLED_PRODUCT = NO;
+				SUPPORTED_PLATFORMS = iphoneos;
+			};
+			name = Release;
+		};
+		155F49A01C864F5400E47D08 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				INFOPLIST_FILE = Plugins/QoSMarking/Info.plist;
+				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.QoSMarking;
+				PRODUCT_NAME = QoSMarking;
+				SDKROOT = iphoneos.internal;
+				SUPPORTED_PLATFORMS = iphoneos;
+			};
+			name = Debug;
+		};
+		155F49A11C864F5400E47D08 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				INFOPLIST_FILE = Plugins/QoSMarking/Info.plist;
+				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.QoSMarking;
+				PRODUCT_NAME = QoSMarking;
+				SDKROOT = iphoneos.internal;
+				SUPPORTED_PLATFORMS = iphoneos;
+			};
+			name = Release;
+		};
 		156EB5DB0905594A00EEF749 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
@@ -5715,8 +6109,10 @@
 					normal,
 					debug,
 					profile,
+					"${EXTRA_BUILD_VARIANT}",
 				);
 				GENERATE_PROFILING_CODE_profile = YES;
+				HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
 				INSTALLHDRS_COPY_PHASE = YES;
 				INSTALL_PATH = /usr/lib/system;
 				LINK_WITH_STANDARD_LIBRARIES = NO;
@@ -5735,9 +6131,12 @@
 					"-lsystem_notify",
 					"-lsystem$(INTERPOSITION_SIM_SUFFIX)_platform",
 					"-lsystem$(INTERPOSITION_SIM_SUFFIX)_pthread",
+					"-lsystem_trace",
 					"-lxpc",
 				);
+				OTHER_LDFLAGS_asan = "-headerpad_max_install_names -L${TOOLCHAIN_DIR}/usr/lib/clang/${CLANG_VERS}/lib/darwin -lclang_rt.asan_osx_dynamic";
 				PRODUCT_NAME = libsystem_configuration;
+				STRIP_INSTALLED_PRODUCT_asan = NO;
 				STRIP_INSTALLED_PRODUCT_debug = NO;
 				STRIP_INSTALLED_PRODUCT_normal = YES;
 				STRIP_INSTALLED_PRODUCT_profile = NO;
@@ -5751,14 +6150,14 @@
 					normal,
 					debug,
 					profile,
+					"${EXTRA_BUILD_VARIANT}",
 				);
 				GENERATE_PROFILING_CODE_profile = YES;
+				HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
 				INSTALLHDRS_COPY_PHASE = YES;
 				INSTALL_PATH = /usr/lib/system;
 				LINK_WITH_STANDARD_LIBRARIES = NO;
 				OTHER_CFLAGS_debug = "-O0";
-				OTHER_CFLAGS_normal = "";
-				OTHER_CFLAGS_profile = "";
 				OTHER_LDFLAGS = (
 					"-Wl,-umbrella,System",
 					"-L/usr/lib/system",
@@ -5773,9 +6172,12 @@
 					"-lsystem_notify",
 					"-lsystem$(INTERPOSITION_SIM_SUFFIX)_platform",
 					"-lsystem$(INTERPOSITION_SIM_SUFFIX)_pthread",
+					"-lsystem_trace",
 					"-lxpc",
 				);
+				OTHER_LDFLAGS_asan = "-headerpad_max_install_names -L${TOOLCHAIN_DIR}/usr/lib/clang/${CLANG_VERS}/lib/darwin -lclang_rt.asan_osx_dynamic";
 				PRODUCT_NAME = libsystem_configuration;
+				STRIP_INSTALLED_PRODUCT_asan = NO;
 				STRIP_INSTALLED_PRODUCT_debug = NO;
 				STRIP_INSTALLED_PRODUCT_normal = YES;
 				STRIP_INSTALLED_PRODUCT_profile = NO;
@@ -5799,6 +6201,12 @@
 				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
 				LIBRARY_SEARCH_PATHS = "$(SYMROOT)";
 				MODULEMAP_FILE = SystemConfiguration.fproj/Modules/sc_modules.modulemap;
+				OTHER_CFLAGS = (
+					"$(inherited)",
+					"-DSC_LOG_OR_PRINT",
+				);
+				OTHER_CFLAGS_debug = "-O0";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration;
 				PRODUCT_NAME = SystemConfiguration;
 				WRAPPER_EXTENSION = framework;
 			};
@@ -5821,6 +6229,12 @@
 				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
 				LIBRARY_SEARCH_PATHS = "$(SYMROOT)";
 				MODULEMAP_FILE = SystemConfiguration.fproj/Modules/sc_modules.modulemap;
+				OTHER_CFLAGS = (
+					"$(inherited)",
+					"-DSC_LOG_OR_PRINT",
+				);
+				OTHER_CFLAGS_debug = "-O0";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration;
 				PRODUCT_NAME = SystemConfiguration;
 				SECTORDER_FLAGS = (
 					"-sectorder",
@@ -5869,10 +6283,17 @@
 		156EB5EF0905594A00EEF749 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
+				"ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD)";
+				CLANG_ENABLE_OBJC_ARC = YES;
 				DEBUG_INFORMATION_FORMAT = dwarf;
+				FRAMEWORK_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
 				HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
 				INSTALL_PATH = /usr/local/lib/SystemConfiguration;
 				LIBRARY_STYLE = STATIC;
+				OTHER_CFLAGS = (
+					"$(inherited)",
+					"-DSC_LOG_HANDLE=\"__log_IPMonitor()\"",
+				);
 				PRODUCT_NAME = IPMonitor;
 				STRIP_INSTALLED_PRODUCT = NO;
 			};
@@ -5881,10 +6302,16 @@
 		156EB5F00905594A00EEF749 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
+				CLANG_ENABLE_OBJC_ARC = YES;
 				DEBUG_INFORMATION_FORMAT = dwarf;
+				FRAMEWORK_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
 				HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
 				INSTALL_PATH = /usr/local/lib/SystemConfiguration;
 				LIBRARY_STYLE = STATIC;
+				OTHER_CFLAGS = (
+					"$(inherited)",
+					"-DSC_LOG_HANDLE=\"__log_IPMonitor()\"",
+				);
 				PRODUCT_NAME = IPMonitor;
 				STRIP_INSTALLED_PRODUCT = NO;
 			};
@@ -5895,6 +6322,7 @@
 			buildSettings = {
 				INFOPLIST_FILE = Plugins/IPMonitor/Info.plist;
 				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.IPMonitor;
 				PRODUCT_NAME = IPMonitor;
 			};
 			name = Debug;
@@ -5904,6 +6332,7 @@
 			buildSettings = {
 				INFOPLIST_FILE = Plugins/IPMonitor/Info.plist;
 				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.IPMonitor;
 				PRODUCT_NAME = IPMonitor;
 			};
 			name = Release;
@@ -5935,6 +6364,7 @@
 			buildSettings = {
 				INFOPLIST_FILE = Plugins/InterfaceNamer/Info.plist;
 				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.InterfaceNamer;
 				PRODUCT_NAME = InterfaceNamer;
 			};
 			name = Debug;
@@ -5944,6 +6374,7 @@
 			buildSettings = {
 				INFOPLIST_FILE = Plugins/InterfaceNamer/Info.plist;
 				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.InterfaceNamer;
 				PRODUCT_NAME = InterfaceNamer;
 			};
 			name = Release;
@@ -5953,6 +6384,7 @@
 			buildSettings = {
 				INFOPLIST_FILE = Plugins/KernelEventMonitor/Info.plist;
 				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.KernelEventMonitor;
 				PRODUCT_NAME = KernelEventMonitor;
 			};
 			name = Debug;
@@ -5962,6 +6394,7 @@
 			buildSettings = {
 				INFOPLIST_FILE = Plugins/KernelEventMonitor/Info.plist;
 				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.KernelEventMonitor;
 				PRODUCT_NAME = KernelEventMonitor;
 			};
 			name = Release;
@@ -5974,6 +6407,10 @@
 				HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
 				INSTALL_PATH = /usr/local/lib/SystemConfiguration;
 				LIBRARY_STYLE = STATIC;
+				OTHER_CFLAGS = (
+					"$(inherited)",
+					"-DSC_LOG_HANDLE=\"__log_KernelEventMonitor()\"",
+				);
 				PRODUCT_NAME = KernelEventMonitor;
 				STRIP_INSTALLED_PRODUCT = NO;
 			};
@@ -5987,6 +6424,10 @@
 				HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
 				INSTALL_PATH = /usr/local/lib/SystemConfiguration;
 				LIBRARY_STYLE = STATIC;
+				OTHER_CFLAGS = (
+					"$(inherited)",
+					"-DSC_LOG_HANDLE=\"__log_KernelEventMonitor()\"",
+				);
 				PRODUCT_NAME = KernelEventMonitor;
 				STRIP_INSTALLED_PRODUCT = NO;
 			};
@@ -6019,6 +6460,7 @@
 			buildSettings = {
 				INFOPLIST_FILE = Plugins/LinkConfiguration/Info.plist;
 				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.LinkConfiguration;
 				PRODUCT_NAME = LinkConfiguration;
 			};
 			name = Debug;
@@ -6028,6 +6470,7 @@
 			buildSettings = {
 				INFOPLIST_FILE = Plugins/LinkConfiguration/Info.plist;
 				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.LinkConfiguration;
 				PRODUCT_NAME = LinkConfiguration;
 			};
 			name = Release;
@@ -6059,6 +6502,7 @@
 			buildSettings = {
 				INFOPLIST_FILE = Plugins/PreferencesMonitor/Info.plist;
 				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.PreferencesMonitor;
 				PRODUCT_NAME = PreferencesMonitor;
 			};
 			name = Debug;
@@ -6068,6 +6512,7 @@
 			buildSettings = {
 				INFOPLIST_FILE = Plugins/PreferencesMonitor/Info.plist;
 				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.PreferencesMonitor;
 				PRODUCT_NAME = PreferencesMonitor;
 			};
 			name = Release;
@@ -6089,13 +6534,24 @@
 		156EB6230905594A00EEF749 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
+				"ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD)";
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(SYMROOT)",
+					"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+				);
 				GCC_DYNAMIC_NO_PIC = NO;
 				HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
 				INSTALL_PATH = /usr/libexec;
 				LIBRARY_SEARCH_PATHS = (
 					"$(SYMROOT)",
-					/usr/local/lib/SystemConfiguration,
+					"$(SDKROOT)/usr/local/lib/SystemConfiguration",
+				);
+				OTHER_LDFLAGS = (
+					"-lKernelEventMonitor$(EXECUTABLE_VARIANT_SUFFIX)",
+					"-lInterfaceNamer$(EXECUTABLE_VARIANT_SUFFIX)",
+					"-lIPMonitor$(EXECUTABLE_VARIANT_SUFFIX)",
+					"-lLinkConfiguration$(EXECUTABLE_VARIANT_SUFFIX)",
+					"-lPreferencesMonitor$(EXECUTABLE_VARIANT_SUFFIX)",
 				);
 				PRODUCT_NAME = configd;
 			};
@@ -6104,13 +6560,23 @@
 		156EB6240905594A00EEF749 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(SYMROOT)",
+					"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+				);
 				GCC_DYNAMIC_NO_PIC = NO;
 				HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
 				INSTALL_PATH = /usr/libexec;
 				LIBRARY_SEARCH_PATHS = (
 					"$(SYMROOT)",
-					/usr/local/lib/SystemConfiguration,
+					"$(SDKROOT)/usr/local/lib/SystemConfiguration",
+				);
+				OTHER_LDFLAGS = (
+					"-lKernelEventMonitor$(EXECUTABLE_VARIANT_SUFFIX)",
+					"-lInterfaceNamer$(EXECUTABLE_VARIANT_SUFFIX)",
+					"-lIPMonitor$(EXECUTABLE_VARIANT_SUFFIX)",
+					"-lLinkConfiguration$(EXECUTABLE_VARIANT_SUFFIX)",
+					"-lPreferencesMonitor$(EXECUTABLE_VARIANT_SUFFIX)",
 				);
 				PRODUCT_NAME = configd;
 			};
@@ -6142,10 +6608,7 @@
 				FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
 				GCC_DYNAMIC_NO_PIC = NO;
 				INSTALL_PATH = /usr/sbin;
-				LIBRARY_SEARCH_PATHS = (
-					"$(SYMROOT)",
-					/usr/local/lib/SystemConfiguration,
-				);
+				LIBRARY_SEARCH_PATHS = "$(SYMROOT)";
 				PRODUCT_NAME = scutil;
 			};
 			name = Debug;
@@ -6156,10 +6619,7 @@
 				FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
 				GCC_DYNAMIC_NO_PIC = NO;
 				INSTALL_PATH = /usr/sbin;
-				LIBRARY_SEARCH_PATHS = (
-					"$(SYMROOT)",
-					/usr/local/lib/SystemConfiguration,
-				);
+				LIBRARY_SEARCH_PATHS = "$(SYMROOT)";
 				PRODUCT_NAME = scutil;
 			};
 			name = Release;
@@ -6195,8 +6655,11 @@
 		156EB63F0905594A00EEF749 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				"ARCHS[sdk=iphoneos*]" = "$(NATIVE_ARCH)";
-				"ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD_32_64_BIT)";
+				APPLY_RULES_IN_COPY_FILES = YES;
+				BUILD_VARIANTS = (
+					normal,
+					"${EXTRA_BUILD_VARIANT}",
+				);
 				COMBINE_HIDPI_IMAGES = YES;
 				COPY_PHASE_STRIP = NO;
 				CURRENT_PROJECT_VERSION = "$(RC_ProjectSourceVersion)";
@@ -6204,15 +6667,25 @@
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				DYLIB_COMPATIBILITY_VERSION = 1;
 				DYLIB_CURRENT_VERSION = "$(RC_ProjectSourceVersion)";
+				ENABLE_TESTABILITY = YES;
+				GCC_NO_COMMON_BLOCKS = YES;
 				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"$(inherited)",
+					"DEBUG=1",
+				);
 				INSTALL_PATH = /usr/sbin;
 				INTERPOSITION_SIM_SUFFIX = "";
 				"INTERPOSITION_SIM_SUFFIX[sdk=iphonesimulator*]" = _sim;
 				OTHER_CFLAGS = (
+					"$(inherited)",
 					"-fconstant-cfstrings",
 					"-fstack-protector-all",
-					"-D_FORTIFY_SOURCE=2",
+					"-DOS_ACTIVITY_OBJECT_API=1",
 				);
+				OTHER_CFLAGS_asan = "-fsanitize=address";
+				OTHER_LDFLAGS_asan = "-fsanitize=address";
+				PLIST_FILE_OUTPUT_FORMAT = binary;
 				RUN_CLANG_STATIC_ANALYZER = YES;
 				SDKROOT = macosx.internal;
 				SUPPORTED_PLATFORMS = macosx;
@@ -6231,20 +6704,30 @@
 		156EB6400905594A00EEF749 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
+				APPLY_RULES_IN_COPY_FILES = YES;
+				BUILD_VARIANTS = (
+					normal,
+					"${EXTRA_BUILD_VARIANT}",
+				);
 				COMBINE_HIDPI_IMAGES = YES;
 				CURRENT_PROJECT_VERSION = "$(RC_ProjectSourceVersion)";
 				DEAD_CODE_STRIPPING = YES;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				DYLIB_COMPATIBILITY_VERSION = 1;
 				DYLIB_CURRENT_VERSION = "$(RC_ProjectSourceVersion)";
+				GCC_NO_COMMON_BLOCKS = YES;
 				INSTALL_PATH = /usr/sbin;
 				INTERPOSITION_SIM_SUFFIX = "";
 				"INTERPOSITION_SIM_SUFFIX[sdk=iphonesimulator*]" = _sim;
 				OTHER_CFLAGS = (
+					"$(inherited)",
 					"-fconstant-cfstrings",
 					"-fstack-protector-all",
-					"-D_FORTIFY_SOURCE=2",
+					"-DOS_ACTIVITY_OBJECT_API=1",
 				);
+				OTHER_CFLAGS_asan = "-fsanitize=address";
+				OTHER_LDFLAGS_asan = "-fsanitize=address";
+				PLIST_FILE_OUTPUT_FORMAT = binary;
 				SDKROOT = macosx.internal;
 				SUPPORTED_PLATFORMS = macosx;
 				VERSIONING_SYSTEM = "apple-generic";
@@ -6274,6 +6757,11 @@
 				"INSTALL_PATH[sdk=watch*]" = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
 				LIBRARY_SEARCH_PATHS = "$(SYMROOT)";
 				MODULEMAP_FILE = SystemConfiguration.fproj/Modules/sc_modules.modulemap;
+				OTHER_CFLAGS = (
+					"$(inherited)",
+					"-DSC_LOG_OR_PRINT",
+				);
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration;
 				PRODUCT_NAME = SystemConfiguration;
 				SDKROOT = iphoneos.internal;
 				SUPPORTED_PLATFORMS = iphoneos;
@@ -6299,6 +6787,11 @@
 				"INSTALL_PATH[sdk=watch*]" = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
 				LIBRARY_SEARCH_PATHS = "$(SYMROOT)";
 				MODULEMAP_FILE = SystemConfiguration.fproj/Modules/sc_modules.modulemap;
+				OTHER_CFLAGS = (
+					"$(inherited)",
+					"-DSC_LOG_OR_PRINT",
+				);
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration;
 				PRODUCT_NAME = SystemConfiguration;
 				SDKROOT = iphoneos.internal;
 				SUPPORTED_PLATFORMS = iphoneos;
@@ -6312,7 +6805,7 @@
 		15732AAA16EA503200F3AC4C /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				APPLY_RULES_IN_COPY_FILES = YES;
+				BUILD_VARIANTS = normal;
 				FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
 				HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
 				INSTALL_PATH = /usr/libexec;
@@ -6320,6 +6813,10 @@
 					"$(SYMROOT)",
 					"$(SDKROOT)/usr/local/lib/SystemConfiguration",
 				);
+				OTHER_LDFLAGS = (
+					"-lIPMonitor_sim$(EXECUTABLE_VARIANT_SUFFIX)",
+					"-lSimulatorSupport_sim$(EXECUTABLE_VARIANT_SUFFIX)",
+				);
 				PRODUCT_NAME = configd_sim;
 				SDKROOT = iphoneos.internal;
 				SUPPORTED_PLATFORMS = iphonesimulator;
@@ -6329,7 +6826,7 @@
 		15732AAB16EA503200F3AC4C /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				APPLY_RULES_IN_COPY_FILES = YES;
+				BUILD_VARIANTS = normal;
 				FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
 				HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
 				INSTALL_PATH = /usr/libexec;
@@ -6337,6 +6834,10 @@
 					"$(SYMROOT)",
 					"$(SDKROOT)/usr/local/lib/SystemConfiguration",
 				);
+				OTHER_LDFLAGS = (
+					"-lIPMonitor_sim$(EXECUTABLE_VARIANT_SUFFIX)",
+					"-lSimulatorSupport_sim$(EXECUTABLE_VARIANT_SUFFIX)",
+				);
 				PRODUCT_NAME = configd_sim;
 				SDKROOT = iphoneos.internal;
 				SUPPORTED_PLATFORMS = iphonesimulator;
@@ -6346,6 +6847,7 @@
 		15732AD316EA511900F3AC4C /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
+				BUILD_VARIANTS = normal;
 				FRAMEWORK_SEARCH_PATHS = (
 					"$(SYMROOT)",
 					"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
@@ -6364,6 +6866,7 @@
 		15732AD416EA511900F3AC4C /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
+				BUILD_VARIANTS = normal;
 				FRAMEWORK_SEARCH_PATHS = (
 					"$(SYMROOT)",
 					"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
@@ -6382,20 +6885,12 @@
 		15732AE216EA6B6700F3AC4C /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				BUILD_VARIANTS = (
-					normal,
-					debug,
-					profile,
-				);
+				BUILD_VARIANTS = normal;
 				FRAMEWORK_SEARCH_PATHS = "$(inherited)";
 				GENERATE_PROFILING_CODE_profile = YES;
 				INSTALLHDRS_COPY_PHASE = YES;
 				INSTALL_PATH = /usr/lib/system;
-				LIBRARY_SEARCH_PATHS = "$(SDKDIR)/usr/lib";
 				LINK_WITH_STANDARD_LIBRARIES = NO;
-				OTHER_CFLAGS_debug = "-O0";
-				OTHER_CFLAGS_normal = "";
-				OTHER_CFLAGS_profile = "";
 				OTHER_LDFLAGS = (
 					"-Wl,-umbrella,System",
 					"-L/usr/lib/system",
@@ -6410,15 +6905,14 @@
 					"-lsystem_notify",
 					"-lsystem$(INTERPOSITION_SIM_SUFFIX)_platform",
 					"-lsystem$(INTERPOSITION_SIM_SUFFIX)_pthread",
+					"-lsystem_trace",
 					"-lxpc",
 				);
 				PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include;
 				PRODUCT_NAME = libsystem_configuration;
 				PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include;
 				SDKROOT = iphoneos.internal;
-				STRIP_INSTALLED_PRODUCT_debug = NO;
 				STRIP_INSTALLED_PRODUCT_normal = YES;
-				STRIP_INSTALLED_PRODUCT_profile = NO;
 				SUPPORTED_PLATFORMS = iphonesimulator;
 			};
 			name = Debug;
@@ -6426,20 +6920,12 @@
 		15732AE316EA6B6700F3AC4C /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				BUILD_VARIANTS = (
-					normal,
-					debug,
-					profile,
-				);
+				BUILD_VARIANTS = normal;
 				FRAMEWORK_SEARCH_PATHS = "$(inherited)";
 				GENERATE_PROFILING_CODE_profile = YES;
 				INSTALLHDRS_COPY_PHASE = YES;
 				INSTALL_PATH = /usr/lib/system;
-				LIBRARY_SEARCH_PATHS = "$(SDKDIR)/usr/lib";
 				LINK_WITH_STANDARD_LIBRARIES = NO;
-				OTHER_CFLAGS_debug = "-O0";
-				OTHER_CFLAGS_normal = "";
-				OTHER_CFLAGS_profile = "";
 				OTHER_LDFLAGS = (
 					"-Wl,-umbrella,System",
 					"-L/usr/lib/system",
@@ -6454,15 +6940,14 @@
 					"-lsystem_notify",
 					"-lsystem$(INTERPOSITION_SIM_SUFFIX)_platform",
 					"-lsystem$(INTERPOSITION_SIM_SUFFIX)_pthread",
+					"-lsystem_trace",
 					"-lxpc",
 				);
 				PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include;
 				PRODUCT_NAME = libsystem_configuration;
 				PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include;
 				SDKROOT = iphoneos.internal;
-				STRIP_INSTALLED_PRODUCT_debug = NO;
 				STRIP_INSTALLED_PRODUCT_normal = YES;
-				STRIP_INSTALLED_PRODUCT_profile = NO;
 				SUPPORTED_PLATFORMS = iphonesimulator;
 			};
 			name = Release;
@@ -6528,18 +7013,12 @@
 		157A84E50D56C63900B6F1A0 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				BUILD_VARIANTS = (
-					normal,
-					debug,
-					profile,
-				);
 				GENERATE_PROFILING_CODE_profile = YES;
+				HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
 				INSTALLHDRS_COPY_PHASE = YES;
 				INSTALL_PATH = /usr/lib/system;
+				INSTALL_PATH_asan = /usr/local/lib;
 				LINK_WITH_STANDARD_LIBRARIES = NO;
-				OTHER_CFLAGS_debug = "-O0";
-				OTHER_CFLAGS_normal = "";
-				OTHER_CFLAGS_profile = "";
 				OTHER_LDFLAGS = (
 					"-Wl,-umbrella,System",
 					"-L/usr/lib/system",
@@ -6554,14 +7033,20 @@
 					"-lsystem_notify",
 					"-lsystem_platform",
 					"-lsystem_pthread",
+					"-lsystem_trace",
 					"-lxpc",
 					"-Wl,-upward-lSystem",
 				);
+				"OTHER_LDFLAGS_asan[sdk=iphoneos*]" = "-headerpad_max_install_names -L${TOOLCHAIN_DIR}/usr/lib/clang/${CLANG_VERS}/lib/darwin -lclang_rt.asan_ios_dynamic";
+				"OTHER_LDFLAGS_asan[sdk=iphonesimulator*]" = "-headerpad_max_install_names -L${TOOLCHAIN_DIR}/usr/lib/clang/${CLANG_VERS}/lib/darwin -lclang_rt.asan_iossim_dynamic";
+				"OTHER_LDFLAGS_asan[sdk=tvos*]" = "-headerpad_max_install_names -L${TOOLCHAIN_DIR}/usr/lib/clang/${CLANG_VERS}/lib/darwin -lclang_rt.asan_tvos_dynamic";
+				"OTHER_LDFLAGS_asan[sdk=tvossimulator*]" = "-headerpad_max_install_names -L${TOOLCHAIN_DIR}/usr/lib/clang/${CLANG_VERS}/lib/darwin -lclang_rt.asan_tvosossim_dynamic";
+				"OTHER_LDFLAGS_asan[sdk=watchos*]" = "-headerpad_max_install_names -L${TOOLCHAIN_DIR}/usr/lib/clang/${CLANG_VERS}/lib/darwin -lclang_rt.asan_watchos_dynamic";
+				"OTHER_LDFLAGS_asan[sdk=watchsimulator*]" = "-headerpad_max_install_names -L${TOOLCHAIN_DIR}/usr/lib/clang/${CLANG_VERS}/lib/darwin -lclang_rt.asan_watchossim_dynamic";
 				PRODUCT_NAME = libsystem_configuration;
 				SDKROOT = iphoneos.internal;
-				STRIP_INSTALLED_PRODUCT_debug = NO;
+				STRIP_INSTALLED_PRODUCT_asan = NO;
 				STRIP_INSTALLED_PRODUCT_normal = YES;
-				STRIP_INSTALLED_PRODUCT_profile = NO;
 				SUPPORTED_PLATFORMS = "iphoneos tvos watchos";
 			};
 			name = Debug;
@@ -6569,18 +7054,12 @@
 		157A84E60D56C63900B6F1A0 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				BUILD_VARIANTS = (
-					normal,
-					debug,
-					profile,
-				);
 				GENERATE_PROFILING_CODE_profile = YES;
+				HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
 				INSTALLHDRS_COPY_PHASE = YES;
 				INSTALL_PATH = /usr/lib/system;
+				INSTALL_PATH_asan = /usr/local/lib;
 				LINK_WITH_STANDARD_LIBRARIES = NO;
-				OTHER_CFLAGS_debug = "-O0";
-				OTHER_CFLAGS_normal = "";
-				OTHER_CFLAGS_profile = "";
 				OTHER_LDFLAGS = (
 					"-Wl,-umbrella,System",
 					"-L/usr/lib/system",
@@ -6595,14 +7074,20 @@
 					"-lsystem_notify",
 					"-lsystem_platform",
 					"-lsystem_pthread",
+					"-lsystem_trace",
 					"-lxpc",
 					"-Wl,-upward-lSystem",
 				);
+				"OTHER_LDFLAGS_asan[sdk=iphoneos*]" = "-headerpad_max_install_names -L${TOOLCHAIN_DIR}/usr/lib/clang/${CLANG_VERS}/lib/darwin -lclang_rt.asan_ios_dynamic";
+				"OTHER_LDFLAGS_asan[sdk=iphonesimulator*]" = "-headerpad_max_install_names -L${TOOLCHAIN_DIR}/usr/lib/clang/${CLANG_VERS}/lib/darwin -lclang_rt.asan_iossim_dynamic";
+				"OTHER_LDFLAGS_asan[sdk=tvos*]" = "-headerpad_max_install_names -L${TOOLCHAIN_DIR}/usr/lib/clang/${CLANG_VERS}/lib/darwin -lclang_rt.asan_tvos_dynamic";
+				"OTHER_LDFLAGS_asan[sdk=tvossimulator*]" = "-headerpad_max_install_names -L${TOOLCHAIN_DIR}/usr/lib/clang/${CLANG_VERS}/lib/darwin -lclang_rt.asan_tvosossim_dynamic";
+				"OTHER_LDFLAGS_asan[sdk=watchos*]" = "-headerpad_max_install_names -L${TOOLCHAIN_DIR}/usr/lib/clang/${CLANG_VERS}/lib/darwin -lclang_rt.asan_watchos_dynamic";
+				"OTHER_LDFLAGS_asan[sdk=watchsimulator*]" = "-headerpad_max_install_names -L${TOOLCHAIN_DIR}/usr/lib/clang/${CLANG_VERS}/lib/darwin -lclang_rt.asan_watchossim_dynamic";
 				PRODUCT_NAME = libsystem_configuration;
 				SDKROOT = iphoneos.internal;
-				STRIP_INSTALLED_PRODUCT_debug = NO;
+				STRIP_INSTALLED_PRODUCT_asan = NO;
 				STRIP_INSTALLED_PRODUCT_normal = YES;
-				STRIP_INSTALLED_PRODUCT_profile = NO;
 				SUPPORTED_PLATFORMS = "iphoneos tvos watchos";
 			};
 			name = Release;
@@ -6610,10 +7095,16 @@
 		157A84FF0D56C7E800B6F1A0 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
+				CLANG_ENABLE_OBJC_ARC = YES;
 				DEBUG_INFORMATION_FORMAT = dwarf;
+				FRAMEWORK_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
 				HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
 				INSTALL_PATH = /usr/local/lib/SystemConfiguration;
 				LIBRARY_STYLE = STATIC;
+				OTHER_CFLAGS = (
+					"$(inherited)",
+					"-DSC_LOG_HANDLE=\"__log_IPMonitor()\"",
+				);
 				PRODUCT_NAME = IPMonitor;
 				SDKROOT = iphoneos.internal;
 				STRIP_INSTALLED_PRODUCT = NO;
@@ -6624,10 +7115,16 @@
 		157A85000D56C7E800B6F1A0 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
+				CLANG_ENABLE_OBJC_ARC = YES;
 				DEBUG_INFORMATION_FORMAT = dwarf;
+				FRAMEWORK_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
 				HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
 				INSTALL_PATH = /usr/local/lib/SystemConfiguration;
 				LIBRARY_STYLE = STATIC;
+				OTHER_CFLAGS = (
+					"$(inherited)",
+					"-DSC_LOG_HANDLE=\"__log_IPMonitor()\"",
+				);
 				PRODUCT_NAME = IPMonitor;
 				SDKROOT = iphoneos.internal;
 				STRIP_INSTALLED_PRODUCT = NO;
@@ -6668,6 +7165,10 @@
 				HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
 				INSTALL_PATH = /usr/local/lib/SystemConfiguration;
 				LIBRARY_STYLE = STATIC;
+				OTHER_CFLAGS = (
+					"$(inherited)",
+					"-DSC_LOG_HANDLE=\"__log_KernelEventMonitor()\"",
+				);
 				PRODUCT_NAME = KernelEventMonitor;
 				SDKROOT = iphoneos.internal;
 				STRIP_INSTALLED_PRODUCT = NO;
@@ -6682,6 +7183,10 @@
 				HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
 				INSTALL_PATH = /usr/local/lib/SystemConfiguration;
 				LIBRARY_STYLE = STATIC;
+				OTHER_CFLAGS = (
+					"$(inherited)",
+					"-DSC_LOG_HANDLE=\"__log_KernelEventMonitor()\"",
+				);
 				PRODUCT_NAME = KernelEventMonitor;
 				SDKROOT = iphoneos.internal;
 				STRIP_INSTALLED_PRODUCT = NO;
@@ -6744,7 +7249,6 @@
 		157FDE3F164A075F0040D6A8 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				INSTALLHDRS_COPY_PHASE = YES;
 				PRODUCT_NAME = "configd_libSystem (EmbeddedSimulator)";
 				SUPPORTED_PLATFORMS = iphonesimulator;
 			};
@@ -6753,7 +7257,6 @@
 		157FDE40164A075F0040D6A8 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				INSTALLHDRS_COPY_PHASE = YES;
 				PRODUCT_NAME = "configd_libSystem (EmbeddedSimulator)";
 				SUPPORTED_PLATFORMS = iphonesimulator;
 			};
@@ -6810,7 +7313,6 @@
 		1583175E0CFB80A1006F62B9 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				APPLY_RULES_IN_COPY_FILES = YES;
 				CODE_SIGN_ENTITLEMENTS = "configd.tproj/entitlements-ios.plist";
 				CODE_SIGN_IDENTITY = "-";
 				FRAMEWORK_SEARCH_PATHS = (
@@ -6823,6 +7325,14 @@
 					"$(SYMROOT)",
 					"$(SDKROOT)/usr/local/lib/SystemConfiguration",
 				);
+				OTHER_LDFLAGS = (
+					"-lKernelEventMonitor$(EXECUTABLE_VARIANT_SUFFIX)",
+					"-lInterfaceNamer$(EXECUTABLE_VARIANT_SUFFIX)",
+					"-lIPMonitor$(EXECUTABLE_VARIANT_SUFFIX)",
+					"-lLinkConfiguration$(EXECUTABLE_VARIANT_SUFFIX)",
+					"-lPreferencesMonitor$(EXECUTABLE_VARIANT_SUFFIX)",
+					"-lQoSMarking$(EXECUTABLE_VARIANT_SUFFIX)",
+				);
 				PRODUCT_NAME = configd;
 				SDKROOT = iphoneos.internal;
 				SUPPORTED_PLATFORMS = iphoneos;
@@ -6832,7 +7342,6 @@
 		1583175F0CFB80A1006F62B9 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				APPLY_RULES_IN_COPY_FILES = YES;
 				CODE_SIGN_ENTITLEMENTS = "configd.tproj/entitlements-ios.plist";
 				CODE_SIGN_IDENTITY = "-";
 				FRAMEWORK_SEARCH_PATHS = (
@@ -6845,6 +7354,14 @@
 					"$(SYMROOT)",
 					"$(SDKROOT)/usr/local/lib/SystemConfiguration",
 				);
+				OTHER_LDFLAGS = (
+					"-lKernelEventMonitor$(EXECUTABLE_VARIANT_SUFFIX)",
+					"-lInterfaceNamer$(EXECUTABLE_VARIANT_SUFFIX)",
+					"-lIPMonitor$(EXECUTABLE_VARIANT_SUFFIX)",
+					"-lLinkConfiguration$(EXECUTABLE_VARIANT_SUFFIX)",
+					"-lPreferencesMonitor$(EXECUTABLE_VARIANT_SUFFIX)",
+					"-lQoSMarking$(EXECUTABLE_VARIANT_SUFFIX)",
+				);
 				PRODUCT_NAME = configd;
 				SDKROOT = iphoneos.internal;
 				SUPPORTED_PLATFORMS = iphoneos;
@@ -6856,6 +7373,7 @@
 			buildSettings = {
 				INFOPLIST_FILE = Plugins/IPMonitor/Info.plist;
 				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.IPMonitor;
 				PRODUCT_NAME = IPMonitor;
 				SDKROOT = iphoneos.internal;
 				SUPPORTED_PLATFORMS = iphoneos;
@@ -6867,6 +7385,7 @@
 			buildSettings = {
 				INFOPLIST_FILE = Plugins/IPMonitor/Info.plist;
 				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.IPMonitor;
 				PRODUCT_NAME = IPMonitor;
 				SDKROOT = iphoneos.internal;
 				SUPPORTED_PLATFORMS = iphoneos;
@@ -6878,6 +7397,7 @@
 			buildSettings = {
 				INFOPLIST_FILE = Plugins/InterfaceNamer/Info.plist;
 				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.InterfaceNamer;
 				PRODUCT_NAME = InterfaceNamer;
 				SDKROOT = iphoneos.internal;
 				SUPPORTED_PLATFORMS = iphoneos;
@@ -6889,6 +7409,7 @@
 			buildSettings = {
 				INFOPLIST_FILE = Plugins/InterfaceNamer/Info.plist;
 				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.InterfaceNamer;
 				PRODUCT_NAME = InterfaceNamer;
 				SDKROOT = iphoneos.internal;
 				SUPPORTED_PLATFORMS = iphoneos;
@@ -6900,6 +7421,7 @@
 			buildSettings = {
 				INFOPLIST_FILE = Plugins/KernelEventMonitor/Info.plist;
 				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.KernelEventMonitor;
 				PRODUCT_NAME = KernelEventMonitor;
 				SDKROOT = iphoneos.internal;
 				SUPPORTED_PLATFORMS = iphoneos;
@@ -6911,6 +7433,7 @@
 			buildSettings = {
 				INFOPLIST_FILE = Plugins/KernelEventMonitor/Info.plist;
 				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.KernelEventMonitor;
 				PRODUCT_NAME = KernelEventMonitor;
 				SDKROOT = iphoneos.internal;
 				SUPPORTED_PLATFORMS = iphoneos;
@@ -6922,6 +7445,7 @@
 			buildSettings = {
 				INFOPLIST_FILE = Plugins/LinkConfiguration/Info.plist;
 				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.LinkConfiguration;
 				PRODUCT_NAME = LinkConfiguration;
 				SDKROOT = iphoneos.internal;
 				SUPPORTED_PLATFORMS = iphoneos;
@@ -6933,6 +7457,7 @@
 			buildSettings = {
 				INFOPLIST_FILE = Plugins/LinkConfiguration/Info.plist;
 				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.LinkConfiguration;
 				PRODUCT_NAME = LinkConfiguration;
 				SDKROOT = iphoneos.internal;
 				SUPPORTED_PLATFORMS = iphoneos;
@@ -6944,6 +7469,7 @@
 			buildSettings = {
 				INFOPLIST_FILE = Plugins/PreferencesMonitor/Info.plist;
 				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.PreferencesMonitor;
 				PRODUCT_NAME = PreferencesMonitor;
 				SDKROOT = iphoneos.internal;
 				SUPPORTED_PLATFORMS = iphoneos;
@@ -6955,6 +7481,7 @@
 			buildSettings = {
 				INFOPLIST_FILE = Plugins/PreferencesMonitor/Info.plist;
 				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.PreferencesMonitor;
 				PRODUCT_NAME = PreferencesMonitor;
 				SDKROOT = iphoneos.internal;
 				SUPPORTED_PLATFORMS = iphoneos;
@@ -6964,7 +7491,6 @@
 		158337A70CFB6B9E0033AB93 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				APPLY_RULES_IN_COPY_FILES = YES;
 				FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
 				"INSTALL_PATH[sdk=appletv*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks/SystemConfiguration.framework";
 				"INSTALL_PATH[sdk=iphone*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks/SystemConfiguration.framework";
@@ -6978,7 +7504,6 @@
 		158337A80CFB6B9E0033AB93 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				APPLY_RULES_IN_COPY_FILES = YES;
 				FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
 				"INSTALL_PATH[sdk=appletv*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks/SystemConfiguration.framework";
 				"INSTALL_PATH[sdk=iphone*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks/SystemConfiguration.framework";
@@ -6992,6 +7517,7 @@
 		15A5A2670D5B94190087BDA0 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
+				BUILD_VARIANTS = normal;
 				DEFINES_MODULE = YES;
 				HEADER_SEARCH_PATHS = (
 					"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders",
@@ -7005,9 +7531,12 @@
 				LIBRARY_SEARCH_PATHS = "$(SYMROOT)";
 				MODULEMAP_FILE = SystemConfiguration.fproj/Modules/sc_modules.modulemap;
 				OTHER_CFLAGS = (
+					"$(inherited)",
 					"-idirafter",
 					"$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders",
+					"-DSC_LOG_OR_PRINT",
 				);
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration;
 				PRODUCT_NAME = SystemConfiguration;
 				SDKROOT = iphoneos.internal;
 				SUPPORTED_PLATFORMS = iphonesimulator;
@@ -7021,6 +7550,7 @@
 		15A5A2680D5B94190087BDA0 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
+				BUILD_VARIANTS = normal;
 				DEFINES_MODULE = YES;
 				HEADER_SEARCH_PATHS = (
 					"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders",
@@ -7034,9 +7564,12 @@
 				LIBRARY_SEARCH_PATHS = "$(SYMROOT)";
 				MODULEMAP_FILE = SystemConfiguration.fproj/Modules/sc_modules.modulemap;
 				OTHER_CFLAGS = (
+					"$(inherited)",
 					"-idirafter",
 					"$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders",
+					"-DSC_LOG_OR_PRINT",
 				);
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration;
 				PRODUCT_NAME = SystemConfiguration;
 				SDKROOT = iphoneos.internal;
 				SUPPORTED_PLATFORMS = iphonesimulator;
@@ -7050,7 +7583,6 @@
 		15C64A1F0F684C3300D78394 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				INSTALL_PATH = /usr/local/lib/system;
 				PRODUCT_NAME = configd_libSystem;
 			};
 			name = Debug;
@@ -7058,7 +7590,6 @@
 		15C64A200F684C3300D78394 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				INSTALL_PATH = /usr/local/lib/system;
 				PRODUCT_NAME = configd_libSystem;
 			};
 			name = Release;
@@ -7066,7 +7597,6 @@
 		15C64A2C0F684C6B00D78394 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				INSTALL_PATH = /usr/local/lib/system;
 				PRODUCT_NAME = "configd_libSystem (Embedded)";
 				SUPPORTED_PLATFORMS = iphoneos;
 			};
@@ -7075,7 +7605,6 @@
 		15C64A2D0F684C6B00D78394 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				INSTALL_PATH = /usr/local/lib/system;
 				PRODUCT_NAME = "configd_libSystem (Embedded)";
 				SUPPORTED_PLATFORMS = iphoneos;
 			};
@@ -7084,10 +7613,15 @@
 		15D3082516F3E4DA00014F82 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
+				BUILD_VARIANTS = normal;
 				DEBUG_INFORMATION_FORMAT = dwarf;
 				HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
 				INSTALL_PATH = /usr/local/lib/SystemConfiguration;
 				LIBRARY_STYLE = STATIC;
+				OTHER_CFLAGS = (
+					"$(inherited)",
+					"-DSC_LOG_HANDLE=\"__log_SimulatorSupport()\"",
+				);
 				PRODUCT_NAME = SimulatorSupport_sim;
 				SDKROOT = iphoneos.internal;
 				STRIP_INSTALLED_PRODUCT = NO;
@@ -7098,10 +7632,15 @@
 		15D3082616F3E4DA00014F82 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
+				BUILD_VARIANTS = normal;
 				DEBUG_INFORMATION_FORMAT = dwarf;
 				HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
 				INSTALL_PATH = /usr/local/lib/SystemConfiguration;
 				LIBRARY_STYLE = STATIC;
+				OTHER_CFLAGS = (
+					"$(inherited)",
+					"-DSC_LOG_HANDLE=\"__log_SimulatorSupport()\"",
+				);
 				PRODUCT_NAME = SimulatorSupport_sim;
 				SDKROOT = iphoneos.internal;
 				STRIP_INSTALLED_PRODUCT = NO;
@@ -7114,6 +7653,7 @@
 			buildSettings = {
 				INFOPLIST_FILE = Plugins/SimulatorSupport/Info.plist;
 				INSTALL_PATH = /System/Library/SystemConfiguration;
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.SimulatorSupport;
 				PRODUCT_NAME = SimulatorSupport;
 				SDKROOT = iphoneos.internal;
 				SUPPORTED_PLATFORMS = iphonesimulator;
@@ -7125,6 +7665,7 @@
 			buildSettings = {
 				INFOPLIST_FILE = Plugins/SimulatorSupport/Info.plist;
 				INSTALL_PATH = /System/Library/SystemConfiguration;
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.SimulatorSupport;
 				PRODUCT_NAME = SimulatorSupport;
 				SDKROOT = iphoneos.internal;
 				SUPPORTED_PLATFORMS = iphonesimulator;
@@ -7134,11 +7675,17 @@
 		15E1B05716EBAE3C00E5F06F /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
+				BUILD_VARIANTS = normal;
 				DEBUG_INFORMATION_FORMAT = dwarf;
 				HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
 				INFOPLIST_FILE = "Plugins/IPMonitor/Info-EmbeddedSimulator.plist";
 				INSTALL_PATH = /usr/local/lib/SystemConfiguration;
 				LIBRARY_STYLE = STATIC;
+				OTHER_CFLAGS = (
+					"$(inherited)",
+					"-DSC_LOG_HANDLE=\"__log_IPMonitor()\"",
+				);
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.IPMonitor;
 				PRODUCT_NAME = IPMonitor_sim;
 				SDKROOT = iphoneos.internal;
 				STRIP_INSTALLED_PRODUCT = NO;
@@ -7149,11 +7696,17 @@
 		15E1B05816EBAE3C00E5F06F /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
+				BUILD_VARIANTS = normal;
 				DEBUG_INFORMATION_FORMAT = dwarf;
 				HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
 				INFOPLIST_FILE = "Plugins/IPMonitor/Info-EmbeddedSimulator.plist";
 				INSTALL_PATH = /usr/local/lib/SystemConfiguration;
 				LIBRARY_STYLE = STATIC;
+				OTHER_CFLAGS = (
+					"$(inherited)",
+					"-DSC_LOG_HANDLE=\"__log_IPMonitor()\"",
+				);
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.IPMonitor;
 				PRODUCT_NAME = IPMonitor_sim;
 				SDKROOT = iphoneos.internal;
 				STRIP_INSTALLED_PRODUCT = NO;
@@ -7166,6 +7719,7 @@
 			buildSettings = {
 				INFOPLIST_FILE = "Plugins/IPMonitor/Info-EmbeddedSimulator.plist";
 				INSTALL_PATH = /System/Library/SystemConfiguration;
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.IPMonitor;
 				PRODUCT_NAME = IPMonitor;
 				SDKROOT = iphoneos.internal;
 				SUPPORTED_PLATFORMS = iphonesimulator;
@@ -7177,6 +7731,7 @@
 			buildSettings = {
 				INFOPLIST_FILE = "Plugins/IPMonitor/Info-EmbeddedSimulator.plist";
 				INSTALL_PATH = /System/Library/SystemConfiguration;
+				PRODUCT_BUNDLE_IDENTIFIER = com.apple.SystemConfiguration.IPMonitor;
 				PRODUCT_NAME = IPMonitor;
 				SDKROOT = iphoneos.internal;
 				SUPPORTED_PLATFORMS = iphonesimulator;
@@ -7235,10 +7790,6 @@
 				GCC_C_LANGUAGE_STANDARD = gnu99;
 				GCC_DYNAMIC_NO_PIC = NO;
 				GCC_NO_COMMON_BLOCKS = YES;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"DEBUG=1",
-					"$(inherited)",
-				);
 				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
@@ -7312,10 +7863,6 @@
 				GCC_C_LANGUAGE_STANDARD = gnu99;
 				GCC_DYNAMIC_NO_PIC = NO;
 				GCC_NO_COMMON_BLOCKS = YES;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"DEBUG=1",
-					"$(inherited)",
-				);
 				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
@@ -7405,6 +7952,42 @@
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Release;
 		};
+		155F498A1C864F1400E47D08 /* Build configuration list for PBXNativeTarget "QoSMarking" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				155F498B1C864F1400E47D08 /* Debug */,
+				155F498C1C864F1400E47D08 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		155F49901C864F3700E47D08 /* Build configuration list for PBXNativeTarget "QoSMarking.bundle" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				155F49911C864F3700E47D08 /* Debug */,
+				155F49921C864F3700E47D08 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		155F49991C864F4E00E47D08 /* Build configuration list for PBXNativeTarget "QoSMarking-Embedded" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				155F499A1C864F4E00E47D08 /* Debug */,
+				155F499B1C864F4E00E47D08 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		155F499F1C864F5400E47D08 /* Build configuration list for PBXNativeTarget "QoSMarking.bundle-Embedded" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				155F49A01C864F5400E47D08 /* Debug */,
+				155F49A11C864F5400E47D08 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
 		156EB5DA0905594A00EEF749 /* Build configuration list for PBXNativeTarget "libsystem_configuration" */ = {
 			isa = XCConfigurationList;
 			buildConfigurations = (
diff --git a/dnsinfo/dnsinfo_copy.c b/dnsinfo/dnsinfo_copy.c
index 004be20..d506920 100644
--- a/dnsinfo/dnsinfo_copy.c
+++ b/dnsinfo/dnsinfo_copy.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2006, 2008-2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2004, 2006, 2008-2013, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -31,9 +31,9 @@
 #include 
 #include 
 #include 
-#include 
-#include 
 #include 
+#include 
+#include 
 #include 
 
 #include "libSystemConfiguration_client.h"
@@ -57,8 +57,24 @@ dns_configuration_notify_key()
 
 
 // Note: protected by __dns_configuration_queue()
-static int			dnsinfo_active	= 0;
-static libSC_info_client_t	*dnsinfo_client	= NULL;
+static int			dnsinfo_active		= 0;
+static libSC_info_client_t	*dnsinfo_client		= NULL;
+
+
+static os_activity_t
+__dns_configuration_activity()
+{
+	static os_activity_t	activity;
+	static dispatch_once_t  once;
+
+	dispatch_once(&once, ^{
+		activity = os_activity_create("accessing DNS configuration",
+					      OS_ACTIVITY_CURRENT,
+					      OS_ACTIVITY_FLAG_DEFAULT);
+	});
+
+	return activity;
+}
 
 
 static dispatch_queue_t
@@ -85,6 +101,11 @@ dns_configuration_copy()
 	xpc_object_t		reqdict;
 	xpc_object_t		reply;
 
+	if (!libSC_info_available()) {
+		os_log(OS_LOG_DEFAULT, "*** DNS configuration requested between fork() and exec()");
+		return NULL;
+	}
+
 	dispatch_sync(__dns_configuration_queue(), ^{
 		if ((dnsinfo_active++ == 0) || (dnsinfo_client == NULL)) {
 			static dispatch_once_t	once;
@@ -120,6 +141,9 @@ dns_configuration_copy()
 		return NULL;
 	}
 
+	// scope DNS configuration activity
+	os_activity_scope(__dns_configuration_activity());
+
 	// create message
 	reqdict = xpc_dictionary_create(NULL, NULL, 0);
 
diff --git a/dnsinfo/dnsinfo_create.c b/dnsinfo/dnsinfo_create.c
index d528c07..5e0b575 100644
--- a/dnsinfo/dnsinfo_create.c
+++ b/dnsinfo/dnsinfo_create.c
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2004-2006, 2009, 2011-2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2006, 2009, 2011-2013, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -17,23 +17,23 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_LICENSE_HEADER_END@
  */
 
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include "SCNetworkReachabilityInternal.h"
 
 #include "dnsinfo_create.h"
 #include "dnsinfo_private.h"
-#include "network_information_priv.h"
+#include "network_state_information_priv.h"
 
 #include "ip_plugin.h"
 
@@ -421,23 +421,6 @@ _dns_resolver_set_port(dns_create_resolver_t *_resolver, uint16_t port)
 }
 
 
-/*
- * rankReachability()
- *   Not reachable       == 0
- *   Connection Required == 1
- *   Reachable           == 2
- */
-static int
-rankReachability(SCNetworkReachabilityFlags flags)
-{
-	int	rank = 0;
-
-	if (flags & kSCNetworkReachabilityFlagsReachable)		rank = 2;
-	if (flags & kSCNetworkReachabilityFlagsConnectionRequired)	rank = 1;
-	return rank;
-}
-
-
 static void
 _dns_resolver_set_reach_flags(dns_create_resolver_t _resolver)
 {
@@ -519,9 +502,13 @@ _dns_resolver_set_reach_flags(dns_create_resolver_t _resolver)
 				}
 
 				if ((n_nameserver++ == 0) ||
-				    (rankReachability(ns_flags) < rankReachability(flags))) {
-					/* return the first (and later, worst case) result */
+				    (__SCNetworkReachabilityRank(ns_flags) > __SCNetworkReachabilityRank(flags))) {
+					/* return the first (and later, best case) result */
 					flags = ns_flags;
+					if (__SCNetworkReachabilityRank(flags) == ReachabilityRankReachable) {
+						// Can't get any better than REACHABLE
+						break;
+					}
 				}
 			}
 
diff --git a/dnsinfo/dnsinfo_flatfile.c b/dnsinfo/dnsinfo_flatfile.c
index bd4e449..28b0861 100644
--- a/dnsinfo/dnsinfo_flatfile.c
+++ b/dnsinfo/dnsinfo_flatfile.c
@@ -305,8 +305,7 @@ _dnsinfo_flatfile_create_resolver(const char *dir, const char *path)
 		line = reallocf(line, len+1);
 		if (line == NULL) continue;
 
-		strncpy(line, buf, len);
-		line[len] = '\0';
+		strlcpy(line, buf, len+1);
 
 		// parse the first word of the line (the config token)
 		lineptr = line;
diff --git a/dnsinfo/dnsinfo_internal.h b/dnsinfo/dnsinfo_internal.h
index 1359cde..9ab6af7 100644
--- a/dnsinfo/dnsinfo_internal.h
+++ b/dnsinfo/dnsinfo_internal.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2013, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -41,7 +41,7 @@ __BEGIN_DECLS
 
 #ifndef	my_log
 #define	MY_LOG_DEFINED_LOCALLY
-#define	my_log(__level, fmt, ...)	SC_log(__level, fmt, ## __VA_ARGS__)
+#define	my_log(__level, __format, ...)	SC_log(__level, __format, ## __VA_ARGS__)
 #endif	// !my_log
 
 
@@ -354,7 +354,8 @@ _dns_resolver_log(dns_resolver_t *resolver, int index, Boolean debug)
 	uint32_t		flags;
 	CFMutableStringRef	str;
 
-	my_log(LOG_INFO, "\nresolver #%d", index);
+	my_log(LOG_INFO, " ");
+	my_log(LOG_INFO, "resolver #%d", index);
 
 	if (resolver->domain != NULL) {
 		my_log(LOG_INFO, "  domain   : %s", resolver->domain);
@@ -470,7 +471,8 @@ _dns_configuration_log(dns_config_t *dns_config, Boolean debug)
 	}
 
 	if ((dns_config->n_scoped_resolver > 0) && (dns_config->scoped_resolver != NULL)) {
-		my_log(LOG_INFO, "\nDNS configuration (for scoped queries)");
+		my_log(LOG_INFO, " ");
+		my_log(LOG_INFO, "DNS configuration (for scoped queries)");
 
 		for (i = 0; i < dns_config->n_scoped_resolver; i++) {
 			dns_resolver_t	*resolver	= dns_config->scoped_resolver[i];
@@ -480,7 +482,8 @@ _dns_configuration_log(dns_config_t *dns_config, Boolean debug)
 	}
 
 	if ((dns_config->n_service_specific_resolver > 0) && (dns_config->service_specific_resolver != NULL)) {
-		my_log(LOG_INFO, "\nDNS configuration (for service-specific queries)");
+		my_log(LOG_INFO, " ");
+		my_log(LOG_INFO, "DNS configuration (for service-specific queries)");
 
 		for (i = 0; i < dns_config->n_service_specific_resolver; i++) {
 			dns_resolver_t	*resolver	= dns_config->service_specific_resolver[i];
diff --git a/dnsinfo/dnsinfo_server.c b/dnsinfo/dnsinfo_server.c
index 3e3b77d..291db1e 100644
--- a/dnsinfo/dnsinfo_server.c
+++ b/dnsinfo/dnsinfo_server.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2008, 2011-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2008, 2011-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -35,11 +35,9 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
-
 #include 
 #include 
 
@@ -50,6 +48,12 @@
 #include "dnsinfo_server.h"
 #include "dnsinfo_private.h"
 
+#ifdef	SC_LOG_HANDLE
+#include 
+os_log_t	SC_LOG_HANDLE;
+#endif	//SC_LOG_HANDLE
+
+
 #pragma mark -
 #pragma mark Globals
 
@@ -62,13 +66,6 @@
 static libSC_info_server_t	S_dns_info;
 
 
-/*
- * S_logger
- *   Logging handle.
- */
-static SCLoggerRef	S_logger = NULL;
-
-
 /*
  * S_sync_handler
  *	ACK (in-sync or not-in-sync) updates should be posted using
@@ -121,9 +118,8 @@ _dnsinfo_copy(xpc_connection_t connection, xpc_object_t request)
 	remote = xpc_dictionary_get_remote_connection(request);
 	reply = xpc_dictionary_create_reply(request);
 	if (reply == NULL) {
-		SCLoggerLog(S_logger, LOG_ERR,
-			    CFSTR("<%p> _dnsinfo_copy: xpc_dictionary_create_reply: failed"),
-			    connection);
+		SC_log(LOG_ERR, "<%p> _dnsinfo_copy: xpc_dictionary_create_reply: failed",
+		       connection);
 		return;
 	}
 
@@ -138,11 +134,11 @@ _dnsinfo_copy(xpc_connection_t connection, xpc_object_t request)
 		proc_name = "???";
 	}
 
-	SCLoggerLog(S_logger, LOG_DEBUG, CFSTR("<%p:%s[%d]> DNS configuration copy: %llu"),
-		    connection,
-		    proc_name,
-		    xpc_connection_get_pid(connection),
-		    generation);
+	SC_log(LOG_DEBUG, "<%p:%s[%d]> DNS configuration copy: %llu",
+	       connection,
+	       proc_name,
+	       xpc_connection_get_pid(connection),
+	       generation);
 
 	// return the DNS configuration (if available)
 	if (data != NULL) {
@@ -176,10 +172,10 @@ _dnsinfo_acknowledge(xpc_connection_t connection, xpc_object_t request)
 
 	generation = xpc_dictionary_get_uint64(request, DNSINFO_GENERATION);
 
-	SCLoggerLog(S_logger, LOG_DEBUG, CFSTR("<%p:%d> DNS configuration ack: %llu"),
-		    connection,
-		    xpc_connection_get_pid(connection),
-		    generation);
+	SC_log(LOG_DEBUG, "<%p:%d> DNS configuration ack: %llu",
+	       connection,
+	       xpc_connection_get_pid(connection),
+	       generation);
 
 	(void) _libSC_info_server_acknowledged(&S_dns_info, connection, generation);
 
@@ -187,7 +183,7 @@ _dnsinfo_acknowledge(xpc_connection_t connection, xpc_object_t request)
 	//       in a [new] network change being posted
 
 	inSync = _libSC_info_server_in_sync(&S_dns_info);
-	if (S_sync_handler) {
+	if (S_sync_handler != NULL) {
 	    S_sync_handler(inSync);
 	}
 	return;
@@ -216,10 +212,9 @@ process_request(xpc_connection_t connection, xpc_object_t request)
 
 			break;
 		default :
-			SCLoggerLog(S_logger, LOG_ERR,
-				    CFSTR("<%p> unknown request : %lld"),
-				    connection,
-				    op);
+			SC_log(LOG_ERR, "<%p> unknown request : %lld",
+			       connection,
+			       op);
 
 			break;
 	}
@@ -231,21 +226,17 @@ process_request(xpc_connection_t connection, xpc_object_t request)
 static void
 process_new_connection(xpc_connection_t c)
 {
-	SCLoggerLog(S_logger, LOG_DEBUG, CFSTR("<%p:%d> DNS configuration session: open"),
-		    c,
-		    xpc_connection_get_pid(c));
+	SC_log(LOG_DEBUG, "<%p:%d> DNS configuration session: open",
+	       c,
+	       xpc_connection_get_pid(c));
 
 	_libSC_info_server_open(&S_dns_info, c);
 
 	xpc_connection_set_target_queue(c, _dnsinfo_server_queue());
 
 	xpc_connection_set_event_handler(c, ^(xpc_object_t xobj) {
-		os_activity_t	activity_id;
 		xpc_type_t	type;
 
-		activity_id = os_activity_start("processing dnsinfo request",
-						OS_ACTIVITY_FLAG_DEFAULT);
-
 		type = xpc_get_type(xobj);
 		if (type == XPC_TYPE_DICTIONARY) {
 			// process the request
@@ -258,9 +249,9 @@ process_new_connection(xpc_connection_t c)
 			if (xobj == XPC_ERROR_CONNECTION_INVALID) {
 				Boolean		changed;
 
-				SCLoggerLog(S_logger, LOG_DEBUG, CFSTR("<%p:%d> DNS configuration session: close"),
-					    c,
-					    xpc_connection_get_pid(c));
+				SC_log(LOG_DEBUG, "<%p:%d> DNS configuration session: close",
+				       c,
+				       xpc_connection_get_pid(c));
 
 				changed = _libSC_info_server_close(&S_dns_info, c);
 				if (changed) {
@@ -268,34 +259,31 @@ process_new_connection(xpc_connection_t c)
 
 					// report change
 					inSync = _libSC_info_server_in_sync(&S_dns_info);
-					S_sync_handler(inSync);
+					if (S_sync_handler != NULL) {
+						S_sync_handler(inSync);
+					}
 				}
 
 			} else if (xobj == XPC_ERROR_CONNECTION_INTERRUPTED) {
-				SCLoggerLog(S_logger, LOG_ERR,
-					    CFSTR("<%p:%d> %s"),
-					    c,
-					    xpc_connection_get_pid(c),
-					    desc);
+				SC_log(LOG_ERR, "<%p:%d> %s",
+				       c,
+				       xpc_connection_get_pid(c),
+				       desc);
 
 			} else {
-				SCLoggerLog(S_logger, LOG_ERR,
-					    CFSTR("<%p:%d> Connection error: %p : %s"),
-					    c,
-					    xpc_connection_get_pid(c),
-					    xobj,
-					    desc);
+				SC_log(LOG_ERR, "<%p:%d> Connection error: %p : %s",
+				       c,
+				       xpc_connection_get_pid(c),
+				       xobj,
+				       desc);
 			}
 
 		}  else {
-			SCLoggerLog(S_logger, LOG_ERR,
-				    CFSTR("<%p:%d> unknown event type : %p"),
-				    c,
-				    xpc_connection_get_pid(c),
-				    type);
+			SC_log(LOG_ERR, "<%p:%d> unknown event type : %p",
+			       c,
+			       xpc_connection_get_pid(c),
+			       type);
 		}
-
-		os_activity_end(activity_id);
 	});
 
 	xpc_connection_resume(c);
@@ -311,14 +299,11 @@ process_new_connection(xpc_connection_t c)
 __private_extern__
 void
 load_DNSConfiguration(CFBundleRef		bundle,
-		      SCLoggerRef		logger,
 		      _dns_sync_handler_t	syncHandler)
 {
 	xpc_connection_t	c;
 	const char		*name;
 
-	S_logger = logger;
-
 	/*
 	 * keep track of DNS configuration acknowledgements
 	 */
@@ -340,12 +325,8 @@ load_DNSConfiguration(CFBundleRef		bundle,
 					       XPC_CONNECTION_MACH_SERVICE_LISTENER);
 
 	xpc_connection_set_event_handler(c, ^(xpc_object_t event) {
-		os_activity_t	activity_id;
 		xpc_type_t	type;
 
-		activity_id = os_activity_start("processing dnsinfo connection",
-						OS_ACTIVITY_FLAG_DEFAULT);
-
 		type = xpc_get_type(event);
 		if (type == XPC_TYPE_CONNECTION) {
 			process_new_connection(event);
@@ -355,30 +336,25 @@ load_DNSConfiguration(CFBundleRef		bundle,
 
 			desc = xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION);
 			if (event == XPC_ERROR_CONNECTION_INVALID) {
-				SCLoggerLog(S_logger, LOG_ERR, CFSTR("DNS configuration server: %s"), desc);
+				SC_log(LOG_ERR, "DNS configuration server: %s", desc);
 				xpc_release(c);
 			} else if (event == XPC_ERROR_CONNECTION_INTERRUPTED) {
-				SCLoggerLog(S_logger, LOG_ERR, CFSTR("DNS configuration server: %s"), desc);
+				SC_log(LOG_ERR, "DNS configuration server: %s", desc);
 			} else {
-				SCLoggerLog(S_logger, LOG_ERR,
-				      CFSTR("DNS configuration server: Connection error: %p : %s"),
-				      event,
-				      desc);
+				SC_log(LOG_ERR, "DNS configuration server: Connection error: %p : %s",
+				       event,
+				       desc);
 			}
 
 		} else {
-			SCLoggerLog(S_logger, LOG_ERR,
-				    CFSTR("DNS configuration server: unknown event type : %p"),
-				    type);
+			SC_log(LOG_ERR, "DNS configuration server: unknown event type : %p", type);
 
 		}
-
-		os_activity_end(activity_id);
 	});
 
 	xpc_connection_resume(c);
 
-SCLoggerLog(S_logger, LOG_DEBUG, CFSTR("XPC server \"%s\" started"), name);
+SC_log(LOG_DEBUG, "XPC server \"%s\" started", name);
 
 	return;
 }
@@ -400,9 +376,8 @@ _dns_configuration_store(dns_create_config_t *_config)
 
 		new_generation = config->config.generation;
 
-		SCLoggerLog(S_logger, LOG_INFO,
-			    CFSTR("DNS configuration updated: %llu"),
-			    new_generation);
+		SC_log(LOG_INFO, "DNS configuration updated: %llu",
+		       new_generation);
 
 		bytes = (const UInt8 *)config;
 		len = sizeof(_dns_config_buf_t) + ntohl(config->n_attribute);
@@ -420,7 +395,7 @@ _dns_configuration_store(dns_create_config_t *_config)
 
 	// if anyone is keeping us in sync, they now need to catch up
 	in_sync = _libSC_info_server_in_sync(&S_dns_info);
-	if (S_sync_handler) {
+	if (S_sync_handler != NULL) {
 	    S_sync_handler(in_sync);
 	}
 
@@ -431,7 +406,7 @@ _dns_configuration_store(dns_create_config_t *_config)
 
 		status = notify_post(notify_key);
 		if (status != NOTIFY_STATUS_OK) {
-			SCLoggerLog(S_logger, LOG_ERR, CFSTR("notify_post() failed: %d"), status);
+			SC_log(LOG_ERR, "notify_post() failed: %d", status);
 			// notification posting failures are non-fatal
 		}
 	}
@@ -455,11 +430,10 @@ main(int argc, char **argv)
 	_sc_debug   = TRUE;
 
 	load_DNSConfiguration(CFBundleGetMainBundle(),		// bundle
-			      NULL,				// SCLogger
 			      ^(Boolean inSync) {		// sync handler
-				      SCLoggerLog(NULL, LOG_INFO,
-					    CFSTR("in sync: %s"),
-					    inSync ? "Yes" : "No")
+				      SC_log(LOG_INFO,
+					     "in sync: %s",
+					     inSync ? "Yes" : "No")
 			      });
 	CFRunLoopRun();
 	/* not reached */
diff --git a/dnsinfo/dnsinfo_server.h b/dnsinfo/dnsinfo_server.h
index 3ec6f42..82a6146 100644
--- a/dnsinfo/dnsinfo_server.h
+++ b/dnsinfo/dnsinfo_server.h
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2004, 2005, 2009, 2011, 2012, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2004, 2005, 2009, 2011, 2012, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -38,7 +38,6 @@ __BEGIN_DECLS
 
 void
 load_DNSConfiguration			(CFBundleRef		bundle,
-					 SCLoggerRef		logger,
 					 _dns_sync_handler_t	syncHandler);
 
 _Bool
diff --git a/get-mobility-info b/get-mobility-info
index f802b93..6df85fd 100755
--- a/get-mobility-info
+++ b/get-mobility-info
@@ -536,53 +536,22 @@ if [ -x /usr/bin/what -a -x /usr/bin/sum -a -x /bin/ls ]; then
 fi
 
 #
-# to give a chance for "networkd" and the DNS service to finish dumping their
-# state, the last thing we do is collect the logs
-#
-
-#
-# system log, kernel.log, early boot log messages
-#
-if [ -x /usr/bin/syslog ]; then
-	#
-	# save the recent activity
-	#
-	${PRIV} /usr/bin/syslog -T local.3					\
-		| ${TAIL_25000}							> syslog
-
-	#
-	# save just the "kernel" activity (in case some of the
-	# interesting/relevant message are before the messages
-	# captured above.
-	#
-	${PRIV} /usr/bin/syslog -T local.3 -k Facility kern			\
-		| ${TAIL_25000}							> kernel
-
-	if [ -d /var/log/DiagnosticMessages ]; then
-		# save any MessageTracer activity
-		${PRIV} /usr/bin/syslog	-d /var/log/DiagnosticMessages		\
-					-F raw					\
-					-T local.3				\
-			| ${TAIL_25000}						> DiagnosticMessages
-	fi
-else
-	if [ -f /var/log/system.log ]; then
-		${PRIV} ${TAIL_25000} /var/log/system.log			> system.log
-	fi
-	if [ -f /var/log/kernel.log ]; then
-		${PRIV} ${TAIL_25000} /var/log/kernel.log			> kernel.log
+# collect the logarchive
+#
+if [ -x /usr/bin/log ]; then
+	LOGARCHIVE_START_TIME=`date -v -1d +"%Y-%m-%d %H:%M:%S"`
+	LOGARCHIVE_OUTPUT="system_logs.logarchive"
+	${PRIV} /usr/bin/log collect --livedata --output "${LOGARCHIVE_OUTPUT}" --start "${LOGARCHIVE_START_TIME}"	2>/dev/null
+	if [ -d ${LOGARCHIVE_OUTPUT} ]; then
+		${PRIV} chown -R ${UID} "${LOGARCHIVE_OUTPUT}"
 	fi
 fi
-if [ -x /sbin/dmesg ]; then
-	${PRIV} /sbin/dmesg							> dmesg
-fi
 
 #
-# IPConfiguration log
+# dmesg
 #
-if [ -f /var/log/com.apple.IPConfiguration.bootp ]; then
-	${PRIV} ${TAIL_2000} /var/log/com.apple.IPConfiguration.bootp	\
-							> com.apple.IPConfiguration.bootp
+if [ -x /sbin/dmesg ]; then
+	${PRIV} /sbin/dmesg							> dmesg
 fi
 
 #
@@ -612,13 +581,6 @@ do
 	fi
 done
 
-#
-# application firewall log
-#
-if [ -f /var/log/appfirewall.log ]; then
-	${PRIV} ${TAIL_2000} /var/log/appfirewall.log	> appfirewall.log
-fi
-
 if [ -x /bin/ls ]; then
 	#
 	# collect crash reports
@@ -654,19 +616,6 @@ if [ -x /bin/ls ]; then
 			fi
 		done
 	done
-
-	#
-	# collect any verbose logging output
-	#
-	/bin/ls -1	/Library/Logs/CrashReporter/com.apple.networking.*.log*		\
-			2>/dev/null							\
-	| while read log
-	do
-		if [ -f "${log}" ]; then
-			b="`basename ${log}`"
-			${PRIV} cat "${log}"			> "${b}"		2>&1
-		fi
-	done
 fi
 
 #
diff --git a/get-network-info b/get-network-info
index 4e23eb0..81a8229 100755
--- a/get-network-info
+++ b/get-network-info
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-#  Copyright © 2015 Apple Inc.
+#  Copyright © 2015, 2016 Apple Inc.
 #
 #  get-network-info
 #
@@ -15,22 +15,29 @@ PATH=/bin:/usr/bin:/sbin:/usr/sbin
 process_opts () {
 
 	for i in $ARGS
-           do
-		case "$i"
-                   in
-                           -s)
-				   COLLECT_SENSITIVE_INFO="Y"
-                                   shift;;
-                           -c)
-				   COLLECT_CONFIGURATION_FILES="Y"
-                                   shift;;
-			   --)
-				   shift;;
-			   *)
-				   REQUESTED_OUTDIR="${i}"
-                                   shift;;
-                   esac
-           done
+	   do
+		case "$i" in
+		    -c)
+			   COLLECT_CONFIGURATION_FILES="Y"
+			   shift
+			   ;;
+		    -n)
+			   COLLECT_NDF_INFO="Y"
+			   shift
+			   ;;
+		    -s)
+			   COLLECT_SENSITIVE_INFO="Y"
+			   shift
+			   ;;
+		    --)
+			   shift
+			   ;;
+		    *)
+			   REQUESTED_OUTDIR="${i}"
+			   shift
+			   ;;
+		esac
+	   done
 
 }
 
@@ -61,13 +68,6 @@ setup () {
 
 # note: the daemons dump to syslog so you need to wait a bit before
 # capturing the logs.
-collect_state_dump () {
-
-	${PRIV} /usr/bin/killall -INFO networkd							2>/dev/null
-
-	sleep 1											&
-}
-
 collect_state_dump_sensitive () {
 
 	${PRIV} /usr/bin/killall -INFO mDNSResponder						2>/dev/null
@@ -116,6 +116,11 @@ run_netstat () {
 	echo "#"							>> netstat.txt
 	/usr/sbin/netstat -s						>> netstat.txt		2>&1
 
+	echo "#"							>> netstat.txt
+	echo "# netstat -rs"						>> netstat.txt
+	echo "#"							>> netstat.txt
+	/usr/sbin/netstat -rs						>> netstat.txt		2>&1
+
 	echo "#"							>> netstat.txt
 	echo "# netstat -mmm"						>> netstat.txt
 	echo "#"							>> netstat.txt
@@ -169,6 +174,9 @@ run_netstat () {
 
 }
 
+#
+# ndp
+#
 run_ndp () {
 
 	if [ ! -x /usr/sbin/ndp ]; then
@@ -202,6 +210,9 @@ run_ndp () {
 
 }
 
+#
+# arp
+#
 run_arp () {
 
 	if   [ ! -x /usr/sbin/arp ]; then
@@ -227,8 +238,9 @@ run_ipconfig () {
 	for if in ${IF_LIST}
 	do
 		case ${if} in
-		lo* )	;;
-		*)
+		    lo* )
+			;;
+		    *)
 			echo "#"					>> ipconfig-info.txt
 			echo "# INTERFACE ${if}"			>> ipconfig-info.txt
 			echo "#"					>> ipconfig-info.txt
@@ -343,6 +355,9 @@ collect_configuration_files () {
 	fi
 }
 
+#
+# VPN
+#
 collect_vpn_logs () {
 
 	for f in										\
@@ -357,6 +372,40 @@ collect_vpn_logs () {
 	done
 }
 
+#
+# Policy
+#
+run_neutil () {
+
+	if [ ! -x /usr/local/bin/neutil ]; then
+		return
+	fi
+
+	echo "#"								>  necp.txt
+	echo "# neutil policy dump"						>> necp.txt
+	echo "#"								>> necp.txt
+	/usr/local/bin/neutil policy dump					>> necp.txt		2>&1
+
+	echo "#"								>  network-agents.txt
+	echo "# neutil agent dump"						>> network-agents.txt
+	echo "#"								>> network-agents.txt
+	/usr/local/bin/neutil agent dump					>> network-agents.txt	2>&1
+
+}
+
+#
+# Path
+#
+run_network_test () {
+
+	if [ ! -x /usr/local/bin/network_test ]; then
+		return
+	fi
+
+	/usr/local/bin/network_test path_watcher				> nw_path.txt	2>&1
+
+}
+
 #
 # Network, DNS, Proxy, Reachability, Cache information
 #
@@ -399,6 +448,16 @@ run_scutil () {
 	echo "#"								>> reachability-info.txt
 	/usr/sbin/scutil -d -v -r 0.0.0.0					>> reachability-info.txt	2>&1
 
+	echo "#"								>> reachability-info.txt
+	echo '# scutil -d -v -r 169.254.0.0'					>> reachability-info.txt
+	echo "#"								>> reachability-info.txt
+	/usr/sbin/scutil -d -v -r 169.254.0.0					>> reachability-info.txt	2>&1
+
+	echo "#"								>  nc-info.txt
+	echo '# scutil --nc list'						>> nc-info.txt
+	echo "#"								>> nc-info.txt
+	/usr/sbin/scutil --nc list						>> nc-info.txt			2>&1
+
 	${PRIV} /usr/sbin/scutil -p --snapshot
 	if [ -f /var/tmp/configd-store.plist ]; then
 		cat /var/tmp/configd-store.plist				> configd-store.plist		2>&1
@@ -415,6 +474,9 @@ run_scutil () {
 
 }
 
+#
+# route
+#
 run_route () {
 
 	if [ ! -x /sbin/route ]; then
@@ -433,6 +495,9 @@ run_route () {
 
 }
 
+#
+# dig
+#
 run_dig () {
 
 	if [ ! -x /usr/bin/dig -o ! -f /etc/resolv.conf ]; then
@@ -447,7 +512,7 @@ run_dig () {
 }
 
 #
-# Host name
+# hostname
 #
 run_hostname () {
 
@@ -459,14 +524,59 @@ run_hostname () {
 
 }
 
+#
+# lsof
+#
+run_lsof () {
+
+	if [ ! -x /usr/sbin/lsof ]; then
+		return
+	fi
+
+	${PRIV} /usr/sbin/lsof -i -n -O -P -T q					> lsof.txt		2>&1	&
+	LSOF_PID=$!
+	# start a watchdog for lsof
+	(
+		WAIT_TIME=5
+		while [ $WAIT_TIME -gt 0 ]
+		do
+			${PRIV} kill -0 ${LSOF_PID}							2>/dev/null
+			if [ $? -eq 0 ]; then
+				# lsof is [still] gathering data...
+				sleep 1
+				WAIT_TIME=$((WAIT_TIME - 1))
+				continue
+			fi
+
+			# lsof completed gathering data
+			break
+		done
+
+		if [ $WAIT_TIME -eq 0 ]; then
+			# lsof timed out
+			${PRIV} kill ${LSOF_PID}							2>/dev/null
+		fi
+	) &
+
+}
+
+collect_ndf_info () {
+	run_lsof
+}
+
 collect_sensitive_info () {
 	collect_state_dump_sensitive
 	run_ndp
 	run_arp
+	run_neutil
+	run_network_test
 }
 
 collect_info () {
-	collect_state_dump
+
+	if [ "${COLLECT_NDF_INFO}" == "Y" ]; then
+		collect_ndf_info
+	fi
 
 	if [ "${COLLECT_SENSITIVE_INFO}" == "Y" ]; then
 		collect_sensitive_info
@@ -493,9 +603,10 @@ collect_info () {
 
 usage () {
 
-	echo "Usage: get-network-info [-s] [-c] "
-	echo "		-s		    collects sensitive information (ARP/NDP/mDNS cache)"
+	echo "Usage: get-network-info [-c] [-n] [-s] "
 	echo "		-c		    collects system configuration files"
+	echo "		-n		    collects NDF information (lsof)"
+	echo "		-s		    collects sensitive information (ARP/NDP/mDNS cache)"
 	echo "		    path to directory where all the information will be collected"
 
 }
@@ -538,7 +649,7 @@ init_globals () {
 #
 # __MAIN__
 #
-ARGS=`getopt sc $*`
+ARGS=`getopt cns $*`
 if [ $? != 0 ]; then
 	usage
 	exit 1
@@ -552,6 +663,4 @@ optimize
 collect_info
 wait
 
-#TO-DO: Add packet trace
-
 exit 0
diff --git a/libSystemConfiguration/libSystemConfiguration_client.c b/libSystemConfiguration/libSystemConfiguration_client.c
index 531a3fd..d315486 100644
--- a/libSystemConfiguration/libSystemConfiguration_client.c
+++ b/libSystemConfiguration/libSystemConfiguration_client.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2012, 2013, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -23,8 +23,9 @@
 
 #include 
 #include 
-#include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -36,9 +37,7 @@
 #pragma mark libSC fork handlers
 
 
-__attribute__((weak_import)) bool _dispatch_is_multithreaded(void);
-
-static boolean_t _has_forked = FALSE;
+static boolean_t _available	= TRUE;
 
 // These functions are registered with libSystem to
 // handle pthread_atfork callbacks.
@@ -58,9 +57,8 @@ _libSC_info_fork_parent()
 void
 _libSC_info_fork_child()
 {
-	if (_dispatch_is_multithreaded()) {
-		// if dispatch was active before fork
-		_has_forked = TRUE;
+	if (_dispatch_is_fork_of_multithreaded_parent()) {
+		_available = FALSE;
 	}
 
 	return;
@@ -77,11 +75,29 @@ log_xpc_object(const char *msg, xpc_object_t obj)
 	char	*desc;
 
 	desc = xpc_copy_description(obj);
-	asl_log(NULL, NULL, ASL_LEVEL_ERR, "%s = %s", msg, desc);
+	os_log(OS_LOG_DEFAULT, "%s = %s", msg, desc);
 	free(desc);
 }
 
 
+__private_extern__
+_Bool
+libSC_info_available()
+{
+	return _available;
+}
+
+
+static void
+libSC_info_client_dealloc(libSC_info_client_t *client)
+{
+	free(client->service_description);
+	free(client->service_name);
+	free(client);
+	return;
+}
+
+
 __private_extern__
 libSC_info_client_t *
 libSC_info_client_create(dispatch_queue_t	q,
@@ -90,13 +106,13 @@ libSC_info_client_create(dispatch_queue_t	q,
 {
 	xpc_connection_t	c;
 	libSC_info_client_t	*client;
-#if	!TARGET_IPHONE_SIMULATOR
+#if	!TARGET_OS_SIMULATOR
 	const uint64_t		flags	=	XPC_CONNECTION_MACH_SERVICE_PRIVILEGED;
-#else	// !TARGET_IPHONE_SIMULATOR
+#else	// !TARGET_OS_SIMULATOR
 	const uint64_t		flags	=	0;
-#endif	// !TARGET_IPHONE_SIMULATOR
+#endif	// !TARGET_OS_SIMULATOR
 
-	if (_has_forked) {
+	if (!_available) {
 		return NULL;
 	}
 
@@ -112,34 +128,37 @@ libSC_info_client_create(dispatch_queue_t	q,
 
 		type = xpc_get_type(xobj);
 		if (type == XPC_TYPE_DICTIONARY) {
-			asl_log(NULL, NULL, ASL_LEVEL_ERR, "%s: unexpected message", client->service_name);
+			os_log(OS_LOG_DEFAULT, "%s: unexpected message", client->service_name);
 			log_xpc_object("  dict = ", xobj);
 		} else if (type == XPC_TYPE_ERROR) {
 			if (xobj == XPC_ERROR_CONNECTION_INVALID) {
-				asl_log(NULL, NULL, ASL_LEVEL_ERR, "%s: server not available", client->service_name);
+				os_log(OS_LOG_DEFAULT, "%s: server not available", client->service_name);
 				client->active = FALSE;
 			} else if (xobj == XPC_ERROR_CONNECTION_INTERRUPTED) {
-				asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "%s: server failed", client->service_name);
+				os_log_debug(OS_LOG_DEFAULT, "%s: server failed", client->service_name);
 			} else {
 				const char	*desc;
 
 				desc = xpc_dictionary_get_string(xobj, XPC_ERROR_KEY_DESCRIPTION);
-				asl_log(NULL, NULL, ASL_LEVEL_DEBUG,
-					"%s: connection error: %d : %s",
-					client->service_name,
-					xpc_connection_get_pid(c),
-					desc);
+				os_log_debug(OS_LOG_DEFAULT,
+					     "%s: connection error: %d : %s",
+					     client->service_name,
+					     xpc_connection_get_pid(c),
+					     desc);
 			}
 		} else {
-			asl_log(NULL, NULL, ASL_LEVEL_ERR,
-				"%s: unknown event type : %p",
-				client->service_name,
-				type);
+			os_log(OS_LOG_DEFAULT,
+			       "%s: unknown event type : %p",
+			       client->service_name,
+			       type);
 		}
 	});
 
 	client->connection = c;
 
+	xpc_connection_set_context(c, client);
+	xpc_connection_set_finalizer_f(c, (xpc_finalizer_t)libSC_info_client_dealloc);
+
 	xpc_connection_resume(c);
 
 	return client;
@@ -151,9 +170,7 @@ void
 libSC_info_client_release(libSC_info_client_t *client)
 {
 	xpc_release(client->connection);
-	free(client->service_description);
-	free(client->service_name);
-	free(client);
+	return;
 }
 
 
@@ -177,23 +194,23 @@ libSC_send_message_with_reply_sync(libSC_info_client_t	*client,
 			}
 
 			if ((type == XPC_TYPE_ERROR) && (reply == XPC_ERROR_CONNECTION_INTERRUPTED)) {
-				asl_log(NULL, NULL, ASL_LEVEL_DEBUG,
-					"%s server failure, retrying",
-					client->service_description);
+				os_log_debug(OS_LOG_DEFAULT,
+					     "%s server failure, retrying",
+					     client->service_description);
 				// retry request
 				xpc_release(reply);
 				continue;
 			}
 
 			if ((type == XPC_TYPE_ERROR) && (reply == XPC_ERROR_CONNECTION_INVALID)) {
-				asl_log(NULL, NULL, ASL_LEVEL_ERR,
-					"%s server not available",
-					client->service_description);
+				os_log(OS_LOG_DEFAULT,
+				       "%s server not available",
+				       client->service_description);
 				client->active = FALSE;
 			} else {
-				asl_log(NULL, NULL, ASL_LEVEL_ERR,
-					"%s xpc_connection_send_message_with_reply_sync() with unexpected reply",
-					client->service_description);
+				os_log(OS_LOG_DEFAULT,
+				       "%s xpc_connection_send_message_with_reply_sync() with unexpected reply",
+				       client->service_description);
 				log_xpc_object("  reply", reply);
 			}
 
diff --git a/libSystemConfiguration/libSystemConfiguration_client.h b/libSystemConfiguration/libSystemConfiguration_client.h
index c93d477..785c9d5 100644
--- a/libSystemConfiguration/libSystemConfiguration_client.h
+++ b/libSystemConfiguration/libSystemConfiguration_client.h
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (c) 2012, 2013, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -37,11 +37,11 @@
 
 #define	DNSINFO_SERVER_VERSION		20130408
 
-#if	!TARGET_IPHONE_SIMULATOR
+#if	!TARGET_OS_SIMULATOR
 #define	DNSINFO_SERVICE_NAME		"com.apple.SystemConfiguration.DNSConfiguration"
-#else	// !TARGET_IPHONE_SIMULATOR
+#else	// !TARGET_OS_SIMULATOR
 #define	DNSINFO_SERVICE_NAME		"com.apple.SystemConfiguration.DNSConfiguration_sim"
-#endif	// !TARGET_IPHONE_SIMULATOR
+#endif	// !TARGET_OS_SIMULATOR
 
 #define	DNSINFO_PROC_NAME		"proc_name"	// string
 
@@ -62,19 +62,25 @@ enum {
 
 #define	NWI_SERVER_VERSION		20130408
 
-#if	!TARGET_IPHONE_SIMULATOR
+#if	!TARGET_OS_SIMULATOR
 #define	NWI_SERVICE_NAME		"com.apple.SystemConfiguration.NetworkInformation"
-#else	// !TARGET_IPHONE_SIMULATOR
+#else	// !TARGET_OS_SIMULATOR
 #define	NWI_SERVICE_NAME		"com.apple.SystemConfiguration.NetworkInformation_sim"
-#endif	// !TARGET_IPHONE_SIMULATOR
+#endif	// !TARGET_OS_SIMULATOR
 
 #define	NWI_PROC_NAME			"proc_name"	// string
 
 #define	NWI_REQUEST			"request_op"	// int64
 
 enum {
-	NWI_REQUEST_COPY		= 0x20001,
-	NWI_REQUEST_ACKNOWLEDGE,
+	/* NWI state requests */
+	NWI_STATE_REQUEST_COPY		= 0x20001,
+	NWI_STATE_REQUEST_ACKNOWLEDGE,
+
+#if !TARGET_OS_SIMULATOR
+	/* NWI config agent requests  */
+	NWI_CONFIG_AGENT_REQUEST_COPY
+#endif // !TARGET_OS_SIMULATOR
 };
 
 #define	NWI_CONFIGURATION		"configuration"	// data
@@ -93,6 +99,9 @@ typedef struct {
 
 __BEGIN_DECLS
 
+_Bool
+libSC_info_available			();
+
 libSC_info_client_t *
 libSC_info_client_create		(
 					 dispatch_queue_t	q,
diff --git a/libSystemConfiguration/libSystemConfiguration_server.c b/libSystemConfiguration/libSystemConfiguration_server.c
index 38cc44f..13feb4f 100644
--- a/libSystemConfiguration/libSystemConfiguration_server.c
+++ b/libSystemConfiguration/libSystemConfiguration_server.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2012-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -23,7 +23,6 @@
 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -32,13 +31,14 @@
 
 #include 
 #include 
-
 #include "libSystemConfiguration_server.h"
 
 #define kTrailingEdgeAgentEntitlement "com.apple.SystemConfiguration.trailing-edge-agent"
 
-#pragma mark -
-#pragma mark Support functions
+#ifdef	SC_LOG_HANDLE
+#include 
+os_log_t	SC_LOG_HANDLE;
+#endif	//SC_LOG_HANDLE
 
 
 #pragma mark -
diff --git a/nwi/network_config_agent_info_priv.h b/nwi/network_config_agent_info_priv.h
new file mode 100644
index 0000000..453d4db
--- /dev/null
+++ b/nwi/network_config_agent_info_priv.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * 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@
+ */
+
+#ifndef _CONFIG_AGENT_INFORMATION_PRIV_H_
+#define _CONFIG_AGENT_INFORMATION_PRIV_H_
+
+#include 
+#include 
+
+__BEGIN_DECLS
+
+const void *
+_nwi_config_agent_copy_data(const struct netagent * agent, uint64_t * length);
+
+__END_DECLS
+
+#endif // _CONFIG_AGENT_INFORMATION_PRIV_H_ 
diff --git a/nwi/network_information.c b/nwi/network_information.c
index 51c584d..9bf12dc 100644
--- a/nwi/network_information.c
+++ b/nwi/network_information.c
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2011-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2011-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -28,11 +28,18 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 
 #include "libSystemConfiguration_client.h"
 #include "network_information.h"
-#include "network_information_priv.h"
+#include "network_state_information_priv.h"
+
+#if !TARGET_OS_SIMULATOR
+#include "network_config_agent_info_priv.h"
+#include "configAgentDefines.h"
+#endif // !TARGET_OS_SIMULATOR
 
 static nwi_state_t	G_nwi_state		= NULL;
 static pthread_mutex_t	nwi_store_lock		= PTHREAD_MUTEX_INITIALIZER;
@@ -42,18 +49,35 @@ static pthread_once_t	initialized		= PTHREAD_ONCE_INIT;
 static int		nwi_store_token;
 
 static boolean_t	nwi_store_force_refresh	= FALSE;
+static const char *	client_proc_name = NULL;
 
 #pragma mark -
 #pragma mark Network information [nwi] client support
 
 
-// Note: protected by __nwi_configuration_queue()
+// Note: protected by __nwi_client_queue()
 static int			nwi_active	= 0;
 static libSC_info_client_t	*nwi_client	= NULL;
 
 
+static os_activity_t
+__nwi_client_activity()
+{
+	static os_activity_t	activity;
+	static dispatch_once_t  once;
+
+	dispatch_once(&once, ^{
+		activity = os_activity_create("accessing network information",
+					      OS_ACTIVITY_CURRENT,
+					      OS_ACTIVITY_FLAG_DEFAULT);
+	});
+
+	return activity;
+}
+
+
 static dispatch_queue_t
-__nwi_configuration_queue()
+__nwi_client_queue()
 {
 	static dispatch_once_t  once;
 	static dispatch_queue_t q;
@@ -118,85 +142,106 @@ nwi_state_retain(nwi_state_t state)
 	return;
 }
 
-/*
- * Function: nwi_state_release
- * Purpose:
- *   Release the memory associated with the network state.
- */
-void
-nwi_state_release(nwi_state_t state)
+static void
+_nwi_client_release()
 {
-	if (ATOMIC_DEC(&state->ref) > 0) {
-		// if not last reference
-		return;
-	}
-
 	// release connection reference on 1-->0 transition
-	dispatch_sync(__nwi_configuration_queue(), ^{
+	dispatch_sync(__nwi_client_queue(), ^{
 		if (--nwi_active == 0) {
-		    // if last reference, drop connection
-		    libSC_info_client_release(nwi_client);
-		    nwi_client = NULL;
+			// if last reference, drop connection
+			libSC_info_client_release(nwi_client);
+			nwi_client = NULL;
 		}
-	    });
-
-	// release nwi_state
-	nwi_state_free(state);
-
-	return;
+	});
 }
 
-static nwi_state *
-_nwi_state_copy_data()
+static void
+_nwi_client_init()
 {
-	nwi_state_t		nwi_state	= NULL;
-	static const char	*proc_name	= NULL;
-	xpc_object_t		reqdict;
-	xpc_object_t		reply;
-
-	dispatch_sync(__nwi_configuration_queue(), ^{
+	dispatch_sync(__nwi_client_queue(), ^{
 		if ((nwi_active++ == 0) || (nwi_client == NULL)) {
 			static dispatch_once_t	once;
 			static const char	*service_name	= NWI_SERVICE_NAME;
 
 			dispatch_once(&once, ^{
+#if	DEBUG
 				const char	*name;
 
 				// get [XPC] service name
 				name = getenv(service_name);
-				if ((name != NULL) && (issetugid() == 0)) {
+				if (name != NULL) {
 					service_name = strdup(name);
 				}
+#endif	// DEBUG
 
 				// get process name
-				proc_name = getprogname();
+				client_proc_name = getprogname();
 			});
 
 			nwi_client =
-				libSC_info_client_create(__nwi_configuration_queue(),	// dispatch queue
-							 service_name,			// XPC service name
-							 "Network information");	// service description
+			libSC_info_client_create(__nwi_client_queue(),	// dispatch queue
+						 service_name,			// XPC service name
+						 "Network information");	// service description
 			if (nwi_client == NULL) {
 				--nwi_active;
 			}
 		}
 	});
+}
+
+/*
+ * Function: nwi_state_release
+ * Purpose:
+ *   Release the memory associated with the network state.
+ */
+void
+nwi_state_release(nwi_state_t state)
+{
+	if (ATOMIC_DEC(&state->ref) > 0) {
+		// if not last reference
+		return;
+	}
+
+	_nwi_client_release();
+
+	// release nwi_state
+	nwi_state_free(state);
+
+	return;
+}
+
+static nwi_state *
+_nwi_state_copy_data()
+{
+	nwi_state_t		nwi_state	= NULL;
+	xpc_object_t		reqdict;
+	xpc_object_t		reply;
+
+	if (!libSC_info_available()) {
+		os_log(OS_LOG_DEFAULT, "*** network information requested between fork() and exec()");
+		return NULL;
+	}
+
+	_nwi_client_init();
 
 	if ((nwi_client == NULL) || !nwi_client->active) {
 		// if network information server not available
 		return NULL;
 	}
 
+	// scope NWI activity
+	os_activity_scope(__nwi_client_activity());
+
 	// create message
 	reqdict = xpc_dictionary_create(NULL, NULL, 0);
 
 	// set process name
-	if (proc_name != NULL) {
-		xpc_dictionary_set_string(reqdict, NWI_PROC_NAME, proc_name);
+	if (client_proc_name != NULL) {
+		xpc_dictionary_set_string(reqdict, NWI_PROC_NAME, client_proc_name);
 	}
 
 	// set request
-	xpc_dictionary_set_int64(reqdict, NWI_REQUEST, NWI_REQUEST_COPY);
+	xpc_dictionary_set_int64(reqdict, NWI_REQUEST, NWI_STATE_REQUEST_COPY);
 
 	// send request to the DNS configuration server
 	reply = libSC_send_message_with_reply_sync(nwi_client, reqdict);
@@ -226,6 +271,62 @@ _nwi_state_copy_data()
 	return nwi_state;
 }
 
+#if !TARGET_OS_SIMULATOR
+/*
+ * Function: _nwi_config_agent_copy_data
+ * Purpose:
+ *   Copy the config agent data and the data length.
+ *   Caller must free the buffer.
+ */
+const void *
+_nwi_config_agent_copy_data(const struct netagent *agent, uint64_t *length)
+{
+	const void	*buffer	= NULL;
+	xpc_object_t	reqdict;
+	xpc_object_t	reply;
+
+	if ((agent == NULL) || (length == NULL)) {
+		return NULL;
+	}
+
+	_nwi_client_init();
+
+	// scope NWI activity
+	os_activity_scope(__nwi_client_activity());
+
+	reqdict = xpc_dictionary_create(NULL, NULL, 0);
+
+	xpc_dictionary_set_int64(reqdict, NWI_REQUEST, NWI_CONFIG_AGENT_REQUEST_COPY);
+	if (client_proc_name != NULL) {
+		xpc_dictionary_set_string(reqdict, NWI_PROC_NAME, client_proc_name);
+	}
+
+	xpc_dictionary_set_uuid(reqdict, kConfigAgentAgentUUID, agent->netagent_uuid);
+	xpc_dictionary_set_string(reqdict, kConfigAgentType, agent->netagent_type);
+
+	// send request to the NWI configuration server
+	reply = libSC_send_message_with_reply_sync(nwi_client, reqdict);
+	xpc_release(reqdict);
+
+	if (reply != NULL) {
+		const void	*xpc_buffer	= NULL;
+		unsigned long	len		= 0;
+
+		xpc_buffer = xpc_dictionary_get_data(reply, kConfigAgentAgentData, &len);
+		if ((xpc_buffer != NULL) && (len > 0)) {
+			buffer = malloc(len);
+			*length = len;
+			bcopy((void *)xpc_buffer, (void *)buffer, len);
+		}
+		xpc_release(reply);
+	}
+
+	_nwi_client_release();
+
+	return buffer;
+}
+#endif // !TARGET_OS_SIMULATOR
+
 /*
  * Function: nwi_state_copy
  * Purpose:
@@ -248,7 +349,7 @@ nwi_state_copy(void)
 		int		check = 0;
 		uint32_t	status;
 
-		if (nwi_store_token_valid == FALSE) {
+		if (!nwi_store_token_valid) {
 			/* have to throw cached copy away every time */
 			check = 1;
 		}
@@ -309,7 +410,7 @@ _nwi_state_ack(nwi_state_t state, const char *bundle_id)
 		return;
 	}
 
-	dispatch_sync(__nwi_configuration_queue(), ^{
+	dispatch_sync(__nwi_client_queue(), ^{
 		nwi_active++;	// keep connection active (for the life of the process)
 	});
 
@@ -317,7 +418,7 @@ _nwi_state_ack(nwi_state_t state, const char *bundle_id)
 	reqdict = xpc_dictionary_create(NULL, NULL, 0);
 
 	// set request
-	xpc_dictionary_set_int64(reqdict, NWI_REQUEST, NWI_REQUEST_ACKNOWLEDGE);
+	xpc_dictionary_set_int64(reqdict, NWI_REQUEST, NWI_STATE_REQUEST_ACKNOWLEDGE);
 
 	// set generation
 	xpc_dictionary_set_uint64(reqdict, NWI_GENERATION, state->generation_count);
@@ -699,7 +800,7 @@ nwi_ifstate_get_dns_signature(nwi_ifstate_t ifstate, int * length)
 		return NULL;
 	}
 
-	if (_nwi_ifstate_is_in_list(ifstate, AF_INET) == TRUE) {
+	if (_nwi_ifstate_is_in_list(ifstate, AF_INET)) {
 		signature = v4_signature;
 		*length = v4_signature_len;
 	} else {
@@ -719,7 +820,7 @@ nwi_ifstate_get_dns_signature(nwi_ifstate_t ifstate, int * length)
 
 unsigned int
 nwi_state_get_interface_names(nwi_state_t state,
-			      const char * names[], 
+			      const char * names[],
 			      unsigned int names_count)
 {
 	int		i;
@@ -783,7 +884,7 @@ nwi_ifstate_print(nwi_ifstate_t ifstate)
 	char 			vpn_ntopbuf[INET6_ADDRSTRLEN];
 	const struct sockaddr *	vpn_addr;
 	const char *		vpn_addr_str = NULL;
-	
+
 	address = nwi_ifstate_get_address(ifstate);
 	addr_str = inet_ntop(ifstate->af, address,
 			     addr_ntopbuf, sizeof(addr_ntopbuf));
@@ -847,7 +948,7 @@ nwi_state_print_common(nwi_state_t state, bool diff)
 	unsigned int	count = 0;
 	int		i;
 	nwi_ifstate_t 	scan;
-	
+
 	if (state == NULL) {
 		return;
 	}
@@ -880,7 +981,7 @@ nwi_state_print_common(nwi_state_t state, bool diff)
 		count = nwi_state_get_interface_names(state, NULL, 0);
 		if (count > 0) {
 			const char *	names[count];
-		
+
 			count = nwi_state_get_interface_names(state, names,
 							      count);
 			printf("%d interfaces%s", count,
@@ -938,7 +1039,7 @@ doit(void)
 	old_state = nwi_state_new(NULL, 5);
 	for (int i = 0; i < 5; i++) {
 		char		ifname[IFNAMSIZ];
-		
+
 		snprintf(ifname, sizeof(ifname), "en%d", i);
 		addr.s_addr = htonl((i % 2) ? i : (i + 1));
 		ifstate = nwi_state_add_ifstate(old_state, ifname, AF_INET, 0,
@@ -988,7 +1089,7 @@ doit(void)
 		addr.s_addr = htonl(i);
 		if (i != 3) {
 			ifstate = nwi_state_add_ifstate(new_state,
-							ifname, AF_INET, 
+							ifname, AF_INET,
 							0,
 							i,
 							&addr,
@@ -1002,7 +1103,7 @@ doit(void)
 	diff_state = nwi_state_diff(old_state_copy, new_state);
 	nwi_state_print_diff(diff_state);
 	nwi_state_free(diff_state);
-	
+
 	diff_state = nwi_state_diff(new_state, old_state_copy);
 	nwi_state_print_diff(diff_state);
 	nwi_state_free(diff_state);
diff --git a/nwi/network_information.h b/nwi/network_information.h
index acc2cf9..6c8e550 100644
--- a/nwi/network_information.h
+++ b/nwi/network_information.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2011-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -27,6 +27,7 @@
 
 #include 
 #include 
+#include 
 
 typedef struct _nwi_state * nwi_state_t;
 typedef struct _nwi_ifstate * nwi_ifstate_t;
diff --git a/nwi/network_information_server.c b/nwi/network_information_server.c
index fd64af3..0c7b179 100644
--- a/nwi/network_information_server.c
+++ b/nwi/network_information_server.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2012-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -39,9 +39,20 @@
 #include "libSystemConfiguration_server.h"
 
 #include 
-#include "network_information_priv.h"
+#include "network_state_information_priv.h"
 #include "network_information_server.h"
 
+#if !TARGET_OS_SIMULATOR
+#include "agent-monitor.h"
+#include "configAgentDefines.h"
+#include "network_config_agent_info_priv.h"
+#endif // !TARGET_OS_SIMULATOR
+
+#ifdef	SC_LOG_HANDLE
+#include 
+os_log_t	SC_LOG_HANDLE;
+#endif	//SC_LOG_HANDLE
+
 
 #pragma mark -
 #pragma mark Globals
@@ -55,13 +66,6 @@
 static libSC_info_server_t	S_nwi_info;
 
 
-/*
- * S_logger
- *   Logging handle.
- */
-static SCLoggerRef	S_logger	= NULL;
-
-
 /*
  * S_sync_handler
  *	ACK (in-sync or not-in-sync) updates should be posted using
@@ -114,9 +118,8 @@ _nwi_state_copy(xpc_connection_t connection, xpc_object_t request)
 	remote = xpc_dictionary_get_remote_connection(request);
 	reply = xpc_dictionary_create_reply(request);
 	if (reply == NULL) {
-		SCLoggerLog(S_logger, LOG_ERR,
-			    CFSTR("<%p> _nwi_state_copy: xpc_dictionary_create_reply: failed"),
-			    connection);
+		SC_log(LOG_ERR, "<%p> _nwi_state_copy: xpc_dictionary_create_reply: failed",
+		       connection);
 		return;
 	}
 
@@ -129,11 +132,11 @@ _nwi_state_copy(xpc_connection_t connection, xpc_object_t request)
 		proc_name = "???";
 	}
 
-	SCLoggerLog(S_logger, LOG_DEBUG, CFSTR("<%p:%s[%d]> Network information copy: %llu"),
-		    connection,
-		    proc_name,
-		    xpc_connection_get_pid(connection),
-		    generation);
+	SC_log(LOG_DEBUG, "<%p:%s[%d]> Network information copy: %llu",
+	       connection,
+	       proc_name,
+	       xpc_connection_get_pid(connection),
+	       generation);
 
 	// return the Network information (if available)
 	if (data != NULL) {
@@ -167,24 +170,96 @@ _nwi_state_acknowledge(xpc_connection_t connection, xpc_object_t request)
 
 	generation = xpc_dictionary_get_uint64(request, NWI_GENERATION);
 
-	SCLoggerLog(S_logger, LOG_DEBUG, CFSTR("<%p:%d> Network information ack: %llu"),
-		    connection,
-		    xpc_connection_get_pid(connection),
-		    generation);
+	SC_log(LOG_DEBUG, "<%p:%d> Network information ack: %llu",
+	       connection,
+	       xpc_connection_get_pid(connection),
+	       generation);
 
-	_libSC_info_server_acknowledged(&S_nwi_info, connection, generation);
 	changed = _libSC_info_server_acknowledged(&S_nwi_info, connection, generation);
 	if (changed) {
 		Boolean		inSync;
 
 		// report change
 		inSync = _libSC_info_server_in_sync(&S_nwi_info);
-		S_sync_handler(inSync);
+		if (S_sync_handler != NULL) {
+			S_sync_handler(inSync);
+		}
 	}
 
 	return;
 }
 
+#if !TARGET_OS_SIMULATOR
+/*
+ * _nwi_config_agent_copy
+ *
+ * Called when a client wants a copy of the agent data
+ *
+ * - caller must be running on the _nwi_server_queue()
+ */
+static void
+_nwi_config_agent_copy(xpc_connection_t connection, xpc_object_t request)
+{
+	const void *buffer = NULL;
+	const char *proc_name = NULL;
+	uint64_t length = 0;
+	xpc_connection_t	remote;
+	xpc_object_t		reply = NULL;
+
+	remote = xpc_dictionary_get_remote_connection(request);
+	reply = xpc_dictionary_create_reply(request);
+
+	uuid_t agent_uuid;
+	const uint8_t *agent_uuid_value = xpc_dictionary_get_uuid(request, kConfigAgentAgentUUID);
+	if (agent_uuid_value != NULL) {
+		uuid_copy(agent_uuid, agent_uuid_value);
+	} else {
+		goto done;
+	}
+
+	const char *agent_type = xpc_dictionary_get_string(request, kConfigAgentType);
+	if (agent_type == NULL) {
+		goto done;
+	}
+
+	proc_name = xpc_dictionary_get_string(request, NWI_PROC_NAME);
+	if (proc_name == NULL) {
+		proc_name = "???";
+	}
+
+	SC_log(LOG_DEBUG, "<%p:%s[%d]> Config agent information copy",
+	       connection,
+	       proc_name,
+	       xpc_connection_get_pid(connection));
+
+	if (strcmp(agent_type, kConfigAgentTypeDNS) == 0) {
+		buffer = copy_dns_information_for_agent_uuid(agent_uuid, &length);
+	} else if (strcmp(agent_type, kConfigAgentTypeProxy) == 0) {
+		buffer = copy_proxy_information_for_agent_uuid(agent_uuid, &length);
+	}
+
+	if (buffer != NULL && length > 0) {
+		xpc_dictionary_set_data(reply,
+					kConfigAgentAgentData,
+					buffer,
+					(size_t)length);
+	}
+
+	xpc_connection_send_message(remote, reply);
+
+done:
+	if (reply != NULL) {
+		xpc_release(reply);
+	}
+
+	if (buffer != NULL) {
+		free((void *)buffer);
+	}
+
+	return;
+}
+#endif // !TARGET_OS_SIMULATOR
+
 
 static void
 process_request(xpc_connection_t connection, xpc_object_t request)
@@ -193,25 +268,33 @@ process_request(xpc_connection_t connection, xpc_object_t request)
 
 	op = xpc_dictionary_get_int64(request, NWI_REQUEST);
 	switch (op) {
-		case NWI_REQUEST_COPY :
+		case NWI_STATE_REQUEST_COPY :
 			/*
 			 * Return the Network information
 			 */
 			_nwi_state_copy(connection, request);
 			break;
 
-		case NWI_REQUEST_ACKNOWLEDGE :
+		case NWI_STATE_REQUEST_ACKNOWLEDGE :
 			/*
 			 * Acknowlege a [processed] Network information
 			 */
 			_nwi_state_acknowledge(connection, request);
 
 			break;
+#if !TARGET_OS_SIMULATOR
+		case NWI_CONFIG_AGENT_REQUEST_COPY :
+			/*
+			 * Return the agent information
+			 */
+			_nwi_config_agent_copy(connection, request);
+
+			break;
+#endif // !TARGET_OS_SIMULATOR
 		default :
-			SCLoggerLog(S_logger, LOG_ERR,
-				    CFSTR("<%p> unknown request : %lld"),
-				    connection,
-				    op);
+			SC_log(LOG_ERR, "<%p> unknown request : %lld",
+			       connection,
+			       op);
 
 			break;
 	}
@@ -223,21 +306,17 @@ process_request(xpc_connection_t connection, xpc_object_t request)
 static void
 process_new_connection(xpc_connection_t c)
 {
-	SCLoggerLog(S_logger, LOG_DEBUG, CFSTR("<%p:%d> Network information session: open"),
-		    c,
-		    xpc_connection_get_pid(c));
+	SC_log(LOG_DEBUG, "<%p:%d> Network information session: open",
+	       c,
+	       xpc_connection_get_pid(c));
 
 	_libSC_info_server_open(&S_nwi_info, c);
 
 	xpc_connection_set_target_queue(c, _nwi_state_server_queue());
 
 	xpc_connection_set_event_handler(c, ^(xpc_object_t xobj) {
-		os_activity_t	activity_id;
 		xpc_type_t	type;
 
-		activity_id = os_activity_start("processing nwi request",
-						OS_ACTIVITY_FLAG_DEFAULT);
-
 		type = xpc_get_type(xobj);
 		if (type == XPC_TYPE_DICTIONARY) {
 			// process the request
@@ -250,9 +329,9 @@ process_new_connection(xpc_connection_t c)
 			if (xobj == XPC_ERROR_CONNECTION_INVALID) {
 				Boolean		changed;
 
-				SCLoggerLog(S_logger, LOG_DEBUG, CFSTR("<%p:%d> Network information session: close"),
-					    c,
-					    xpc_connection_get_pid(c));
+				SC_log(LOG_DEBUG, "<%p:%d> Network information session: close",
+				       c,
+				       xpc_connection_get_pid(c));
 
 				changed = _libSC_info_server_close(&S_nwi_info, c);
 				if (changed) {
@@ -260,34 +339,31 @@ process_new_connection(xpc_connection_t c)
 
 					// report change
 					inSync = _libSC_info_server_in_sync(&S_nwi_info);
-					S_sync_handler(inSync);
+					if (S_sync_handler != NULL) {
+						S_sync_handler(inSync);
+					}
 				}
 
 			} else if (xobj == XPC_ERROR_CONNECTION_INTERRUPTED) {
-				SCLoggerLog(S_logger, LOG_ERR,
-					    CFSTR("<%p:%d> %s"),
-					    c,
-					    xpc_connection_get_pid(c),
-					    desc);
+				SC_log(LOG_ERR, "<%p:%d> %s",
+				       c,
+				       xpc_connection_get_pid(c),
+				       desc);
 
 			} else {
-				SCLoggerLog(S_logger, LOG_ERR,
-					    CFSTR("<%p:%d> Connection error: %p : %s"),
-					    c,
-					    xpc_connection_get_pid(c),
-					    xobj,
-					    desc);
+				SC_log(LOG_ERR, "<%p:%d> Connection error: %p : %s",
+				       c,
+				       xpc_connection_get_pid(c),
+				       xobj,
+				       desc);
 			}
 
 		}  else {
-			SCLoggerLog(S_logger, LOG_ERR,
-				    CFSTR("<%p:%d> unknown event type : %p"),
-				    c,
-				    xpc_connection_get_pid(c),
-				    type);
+			SC_log(LOG_ERR, "<%p:%d> unknown event type : %p",
+			       c,
+			       xpc_connection_get_pid(c),
+			       type);
 		}
-
-		os_activity_end(activity_id);
 	});
 
 	xpc_connection_resume(c);
@@ -303,14 +379,11 @@ process_new_connection(xpc_connection_t c)
 __private_extern__
 void
 load_NetworkInformation(CFBundleRef		bundle,
-			SCLoggerRef		logger,
 			_nwi_sync_handler_t	syncHandler)
 {
 	xpc_connection_t	c;
 	const char		*name;
 
-	S_logger = logger;
-
 	/*
 	 * keep track of Network information acknowledgements
 	 */
@@ -332,12 +405,8 @@ load_NetworkInformation(CFBundleRef		bundle,
 					       XPC_CONNECTION_MACH_SERVICE_LISTENER);
 
 	xpc_connection_set_event_handler(c, ^(xpc_object_t event) {
-		os_activity_t	activity_id;
 		xpc_type_t	type;
 
-		activity_id = os_activity_start("processing nwi connection",
-						OS_ACTIVITY_FLAG_DEFAULT);
-
 		type = xpc_get_type(event);
 		if (type == XPC_TYPE_CONNECTION) {
 			process_new_connection(event);
@@ -347,30 +416,25 @@ load_NetworkInformation(CFBundleRef		bundle,
 
 			desc = xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION);
 			if (event == XPC_ERROR_CONNECTION_INVALID) {
-				SCLoggerLog(S_logger, LOG_ERR, CFSTR("Network information server: %s"), desc);
+				SC_log(LOG_ERR, "Network information server: %s", desc);
 				xpc_release(c);
 			} else if (event == XPC_ERROR_CONNECTION_INTERRUPTED) {
-				SCLoggerLog(S_logger, LOG_ERR, CFSTR("Network information server: %s"), desc);
+				SC_log(LOG_ERR, "Network information server: %s", desc);
 			} else {
-				SCLoggerLog(S_logger, LOG_ERR,
-					    CFSTR("Network information server: Connection error: %p : %s"),
-					    event,
-					    desc);
+				SC_log(LOG_ERR, "Network information server: Connection error: %p : %s",
+				       event,
+				       desc);
 			}
 
 		} else {
-			SCLoggerLog(S_logger, LOG_ERR,
-				    CFSTR("Network information server: unknown event type : %p"),
-				    type);
+			SC_log(LOG_ERR, "Network information server: unknown event type : %p", type);
 
 		}
-
-		os_activity_end(activity_id);
 	});
 
 	xpc_connection_resume(c);
 
-SCLoggerLog(S_logger, LOG_DEBUG, CFSTR("XPC server \"%s\" started"), name);
+SC_log(LOG_DEBUG, "XPC server \"%s\" started", name);
 
 	return;
 }
@@ -391,8 +455,8 @@ _nwi_state_store(nwi_state *state)
 
 		new_generation = state->generation_count;
 
-		SCLoggerLog(S_logger, LOG_DEBUG, CFSTR("Network information updated: %llu"),
-			    new_generation);
+		SC_log(LOG_DEBUG, "Network information updated: %llu",
+		       new_generation);
 
 		bytes = (const UInt8 *)state;
 		len = nwi_state_size(state);
@@ -410,7 +474,9 @@ _nwi_state_store(nwi_state *state)
 
 	// if anyone is keeping us in sync, they now need to catchup
 	in_sync = _libSC_info_server_in_sync(&S_nwi_info);
-	S_sync_handler(in_sync);
+	if (S_sync_handler != NULL) {
+		S_sync_handler(in_sync);
+	}
 
 	// and let everyone else know that the configuration has been updated
 	notify_key = nwi_state_get_notify_key();
@@ -420,7 +486,7 @@ _nwi_state_store(nwi_state *state)
 		_nwi_state_force_refresh();
 		status = notify_post(notify_key);
 		if (status != NOTIFY_STATUS_OK) {
-			SCLoggerLog(S_logger, LOG_ERR, CFSTR("notify_post() failed: %d"), status);
+			SC_log(LOG_ERR, "notify_post() failed: %d", status);
 			// notification posting failures are non-fatal
 		}
 	}
@@ -439,16 +505,15 @@ int
 main(int argc, char **argv)
 {
 	static Boolean verbose = (argc > 1) ? TRUE : FALSE;
-	//	_sc_log     = FALSE;
+//	_sc_log     = FALSE;
 	_sc_verbose = (argc > 1) ? TRUE : FALSE;
 	_sc_debug   = TRUE;
 
 	load_NetworkInformation(CFBundleGetMainBundle(),	// bundle
-				NULL,				// SCLogger
 				^(Boolean inSync) {		// sync handler
-				      SCLoggerLog(NULL, LOG_INFO,
-						  CFSTR("in sync: %s"),
-						  inSync ? "Yes" : "No");
+					SC_log(LOG_INFO,
+					       "in sync: %s",
+					       inSync ? "Yes" : "No")
 				});
 	CFRunLoopRun();
 	/* not reached */
diff --git a/nwi/network_information_server.h b/nwi/network_information_server.h
index 8f147a2..2e1f55a 100644
--- a/nwi/network_information_server.h
+++ b/nwi/network_information_server.h
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2012, 2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2012, 2013, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -36,7 +36,6 @@ __BEGIN_DECLS
 
 void
 load_NetworkInformation		(CFBundleRef		bundle,
-				 SCLoggerRef		logger,
 				 _nwi_sync_handler_t	syncHandler);
 
 void
diff --git a/nwi/network_information_priv.c b/nwi/network_state_information_priv.c
similarity index 98%
rename from nwi/network_information_priv.c
rename to nwi/network_state_information_priv.c
index 361d8aa..77e03cf 100644
--- a/nwi/network_information_priv.c
+++ b/nwi/network_state_information_priv.c
@@ -28,7 +28,7 @@
 #include 
 #include 
 #include 
-#include "network_information_priv.h"
+#include "network_state_information_priv.h"
 #include 
 #include 
 #include 
@@ -657,7 +657,7 @@ _nwi_state_update_interface_generations(nwi_state_t old_state, nwi_state_t state
 
 	for (i = 0, scan = nwi_state_ifstate_list(state, AF_INET);
 	     i < state->ipv4_count; i++, scan++) {
-		if (_nwi_ifstate_has_changed(changes, scan->ifname) == TRUE) {
+		if (_nwi_ifstate_has_changed(changes, scan->ifname)) {
 			/* Update the interface generation count */
 			_nwi_ifstate_set_generation(scan, generation_count);
 		} else {
@@ -666,6 +666,7 @@ _nwi_state_update_interface_generations(nwi_state_t old_state, nwi_state_t state
 			old_ifstate = nwi_state_get_ifstate_with_name(old_state,
 								      AF_INET,
 								      scan->ifname);
+			assert(old_ifstate != NULL);
 			
 			/* Set the current generation count */
 			_nwi_ifstate_set_generation(scan,
@@ -680,7 +681,7 @@ _nwi_state_update_interface_generations(nwi_state_t old_state, nwi_state_t state
 		    generation_count) {
 			continue;
 		}
-		if (_nwi_ifstate_has_changed(changes, scan->ifname) == TRUE) {
+		if (_nwi_ifstate_has_changed(changes, scan->ifname)) {
 			/* update the interface generation count */
 			_nwi_ifstate_set_generation(scan, generation_count);
 		} else {
diff --git a/nwi/network_information_priv.h b/nwi/network_state_information_priv.h
similarity index 97%
rename from nwi/network_information_priv.h
rename to nwi/network_state_information_priv.h
index 9bddc96..8ccffc0 100644
--- a/nwi/network_information_priv.h
+++ b/nwi/network_state_information_priv.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2013 Apple Inc. All rights reserved.
+ * Copyright (c) 2011-2013, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -21,8 +21,8 @@
  * @APPLE_LICENSE_HEADER_END@
  */
 
-#ifndef _NETWORK_INFORMATION_PRIV_H_
-#define _NETWORK_INFORMATION_PRIV_H_
+#ifndef _NETWORK_STATE_INFORMATION_PRIV_H_
+#define _NETWORK_STATE_INFORMATION_PRIV_H_
 
 #include 
 #include 
@@ -330,5 +330,4 @@ void
 _nwi_state_compute_sha1_hash(nwi_state_t state,
 			     unsigned char hash[CC_SHA1_DIGEST_LENGTH]);
 
-
-#endif
+#endif // _NETWORK_STATE_INFORMATION_PRIV_H_
diff --git a/scutil.tproj/dictionary.c b/scutil.tproj/dictionary.c
index 8361c26..49a1fdd 100644
--- a/scutil.tproj/dictionary.c
+++ b/scutil.tproj/dictionary.c
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2000-2005, 2009-2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2005, 2009-2011, 2013, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -35,10 +35,6 @@
 #include "dictionary.h"
 
 
-//#include 
-//#include 
-
-
 __private_extern__
 void
 do_dictInit(int argc, char **argv)
diff --git a/scutil.tproj/nc.c b/scutil.tproj/nc.c
index be0952f..31769e1 100644
--- a/scutil.tproj/nc.c
+++ b/scutil.tproj/nc.c
@@ -608,7 +608,7 @@ nc_ondemand(int argc, char **argv)
 	}
 
 	if (argc == 1) {
-#if	!TARGET_IPHONE_SIMULATOR
+#if	!TARGET_OS_SIMULATOR
 		if (strcmp("--refresh", argv[0]) == 0) {
 			SCNetworkConnectionRef	connection	= NULL;
 
@@ -624,7 +624,7 @@ nc_ondemand(int argc, char **argv)
 			my_CFRelease(&connection);
 			goto done;
 		}
-#endif	// !TARGET_IPHONE_SIMULATOR
+#endif	// !TARGET_OS_SIMULATOR
 
 		ondemand_nodename = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
 	} else if (argc != 0) {
diff --git a/scutil.tproj/net.c b/scutil.tproj/net.c
index db88330..6327c58 100644
--- a/scutil.tproj/net.c
+++ b/scutil.tproj/net.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2007, 2009-2011, 2014 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2007, 2009-2011, 2014, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -238,6 +238,34 @@ _process_options(optionsRef options, int nOptions, int argc, char **argv, CFMuta
 					CFDictionaryRemoveValue(newConfiguration, *(options[optionIndex].key));
 				}
 
+				argv++;
+				argc--;
+				break;
+			case isBool :
+				if (argc < 1) {
+					SCPrint(TRUE, stdout,
+						CFSTR("%s not specified\n"),
+						options[optionIndex].description != NULL ? options[optionIndex].description : "enable/disable");
+					return FALSE;
+				}
+
+				if        ((strcasecmp(argv[0], "disable") == 0) ||
+					   (strcasecmp(argv[0], "no"     ) == 0) ||
+					   (strcasecmp(argv[0], "off"    ) == 0) ||
+					   (strcasecmp(argv[0], "0"      ) == 0)) {
+					CFDictionarySetValue(newConfiguration, *(options[optionIndex].key), kCFBooleanFalse);
+				} else if ((strcasecmp(argv[0], "enable") == 0) ||
+					   (strcasecmp(argv[0], "yes"   ) == 0) ||
+					   (strcasecmp(argv[0], "on"   ) == 0) ||
+					   (strcasecmp(argv[0], "1"     ) == 0)) {
+					CFDictionarySetValue(newConfiguration, *(options[optionIndex].key), kCFBooleanTrue);
+				} else if (strcmp(argv[0], "") == 0) {
+					CFDictionaryRemoveValue(newConfiguration, *(options[optionIndex].key));
+				} else {
+					SCPrint(TRUE, stdout, CFSTR("invalid value\n"));
+					return FALSE;
+				}
+
 				argv++;
 				argc--;
 				break;
@@ -259,6 +287,8 @@ _process_options(optionsRef options, int nOptions, int argc, char **argv, CFMuta
 					   (strcasecmp(argv[0], "on"   ) == 0) ||
 					   (strcasecmp(argv[0], "1"     ) == 0)) {
 					CFDictionarySetValue(newConfiguration, *(options[optionIndex].key), CFNumberRef_1);
+				} else if (strcmp(argv[0], "") == 0) {
+					CFDictionaryRemoveValue(newConfiguration, *(options[optionIndex].key));
 				} else {
 					SCPrint(TRUE, stdout, CFSTR("invalid value\n"));
 					return FALSE;
@@ -825,17 +855,17 @@ do_net_migrate_validate(int argc, char **argv)
 	CFURLRef expectedConfigurationURL = NULL;
 	Boolean isValid = FALSE;
 	CFStringRef str = NULL;
-	
+
 	configuration = argv[0];
 	str = CFStringCreateWithCString(NULL, configuration, kCFStringEncodingUTF8);
 	configurationURL = CFURLCreateWithFileSystemPath(NULL, str, kCFURLPOSIXPathStyle, TRUE);
 	CFRelease(str);
-	
+
 	expectedConfiguration = argv[1];
 	str = CFStringCreateWithCString(NULL, expectedConfiguration, kCFStringEncodingUTF8);
 	expectedConfigurationURL = CFURLCreateWithFileSystemPath(NULL, str, kCFURLPOSIXPathStyle, TRUE);
 	CFRelease(str);
-	
+
 	isValid = _SCNetworkMigrationAreConfigurationsIdentical(configurationURL, expectedConfigurationURL);
 
 	SCPrint(TRUE, stdout, CFSTR("Configuration at location %s %s\n"), configuration, isValid ? "is valid" : "is NOT valid");
@@ -990,67 +1020,25 @@ do_net_update(int argc, char **argv)
 	} else {
 		set = SCNetworkSetCopyCurrent(prefs);
 		if (set == NULL) {
-			CFBundleRef	bundle;
-			Boolean		ok;
-			CFArrayRef	sets;
-			CFStringRef	setName	= NULL;
-
-			sets = SCNetworkSetCopyAll(prefs);
-			if (sets != NULL) {
-				CFIndex	n;
-
-				n = CFArrayGetCount(sets);
-				CFRelease(sets);
-				sets = NULL;
-				if (n > 0) {
-					SCPrint(TRUE, stdout, CFSTR("no current set\n"));
-					return;
-				}
-			}
-
-			bundle = _SC_CFBundleGet();
-			if (bundle != NULL) {
-				setName = CFBundleCopyLocalizedString(bundle,
-								      CFSTR("DEFAULT_SET_NAME"),
-								      CFSTR("Automatic"),
-								      NULL);
-			}
-			if (setName == NULL) {
-				setName = CFSTR("Automatic");
-				CFRetain(setName);
-			}
-
-			set = SCNetworkSetCreate(prefs);
+			// if no "current" set, create a new/default ("Automatic") set
+			set = _SCNetworkSetCreateDefault(prefs);
 			if (set == NULL) {
 				SCPrint(TRUE, stdout,
-					CFSTR("could not initialize \"%@\": %s\n"),
-					setName,
+					CFSTR("could not initialize \"Automatic\" set: %s\n"),
 					SCErrorString(SCError()));
-				CFRelease(setName);
-				return;
-			}
-
-			(void) SCNetworkSetSetName(set, setName);
-
-			ok = SCNetworkSetSetCurrent(set);
-			if (!ok) {
-				SCPrint(TRUE, stdout,
-					CFSTR("could not initialize \"%@\": %s\n"),
-					setName,
-					SCErrorString(SCError()));
-				(void) SCNetworkSetRemove(set);
-				CFRelease(setName);
-				CFRelease(set);
 				return;
 			}
 
 			if (net_set != NULL) CFRelease(net_set);
 			net_set = set;
+			CFRetain(set);
 
 			setCreated = TRUE;
 
-			CFRelease(setName);
-			CFRetain(set);
+			if (sets != NULL) {
+				CFRelease(sets);
+				sets = NULL;
+			}
 		}
 	}
 
diff --git a/scutil.tproj/net.h b/scutil.tproj/net.h
index d838285..3386d78 100644
--- a/scutil.tproj/net.h
+++ b/scutil.tproj/net.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2006, 2011, 2014 Apple Inc. All rights reserved.
+ * Copyright (c) 2004, 2006, 2011, 2014, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -49,10 +49,11 @@ typedef enum {
 	isHelp,
 	isChooseOne,
 	isChooseMultiple,
-	isBoolean,
-	isNumber,
-	isString,
-	isStringArray
+	isBool,			// CFBoolean
+	isBoolean,		// CFNumber (0 or 1)
+	isNumber,		// CFNumber
+	isString,		// CFString
+	isStringArray		// CFArray[CFString]
 } optionType;
 
 typedef const struct {
diff --git a/scutil.tproj/net_interface.c b/scutil.tproj/net_interface.c
index 69d4461..1c12c19 100644
--- a/scutil.tproj/net_interface.c
+++ b/scutil.tproj/net_interface.c
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2004-2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2011, 2013-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -497,6 +497,7 @@ _show_interface(SCNetworkInterfaceRef interface, CFStringRef prefix, Boolean sho
 		int		mtu_cur;
 		int		mtu_min;
 		int		mtu_max;
+		CFDictionaryRef	qosPolicy;
 
 		cap_current = SCNetworkInterfaceCopyCapability(interface, NULL);
 		if (cap_current != NULL) {
@@ -551,8 +552,8 @@ _show_interface(SCNetworkInterfaceRef interface, CFStringRef prefix, Boolean sho
 				CFNumberRef	num;
 
 				num = CFDictionaryGetValue(configuration, kSCPropNetEthernetMTU);
-				if (isA_CFNumber(num)) {
-					CFNumberGetValue(num, kCFNumberIntType, &mtu_req);
+				if (isA_CFNumber(num) &&
+				    CFNumberGetValue(num, kCFNumberIntType, &mtu_req)) {
 					if (mtu_cur != mtu_req) {
 						mtu_cur = mtu_req;
 						isCurrent = ' ';
@@ -682,6 +683,52 @@ _show_interface(SCNetworkInterfaceRef interface, CFStringRef prefix, Boolean sho
 		} else {
 			SCPrint(TRUE, stdout, CFSTR("\n"));
 		}
+
+		qosPolicy = SCNetworkInterfaceGetQoSMarkingPolicy(interface);
+		if (qosPolicy != NULL) {
+			CFBooleanRef	bVal;
+			CFArrayRef	bundleIDs;
+			Boolean		needComma	= FALSE;
+
+			SCPrint(TRUE, stdout, CFSTR("%@  qos marking          ="), prefix);
+
+			bVal = CFDictionaryGetValue(qosPolicy, kSCPropNetQoSMarkingEnabled);
+			if ((bVal != NULL) && isA_CFBoolean(bVal)) {
+				SCPrint(TRUE, stdout, CFSTR(" %senabled"),
+					CFBooleanGetValue(bVal) ? "" : "!");
+				needComma = TRUE;
+			}
+
+			bVal = CFDictionaryGetValue(qosPolicy, kSCPropNetQoSMarkingAppleAudioVideoCalls);
+			if ((bVal != NULL) && isA_CFBoolean(bVal)) {
+				SCPrint(TRUE, stdout, CFSTR("%s %sapple-av"),
+					needComma ? "," : "",
+					CFBooleanGetValue(bVal) ? "" : "!");
+				needComma = TRUE;
+			}
+
+			bundleIDs = CFDictionaryGetValue(qosPolicy, kSCPropNetQoSMarkingWhitelistedAppIdentifiers);
+			if ((bundleIDs != NULL) && CFArrayGetCount(bundleIDs)) {
+				CFIndex		n	= CFArrayGetCount(bundleIDs);
+
+				SCPrint(TRUE, stdout, CFSTR("%s applications = ("),
+					needComma ? "," : "");
+				for (CFIndex i = 0; i < n; i++) {
+					CFStringRef	bundleID;
+
+					bundleID = CFArrayGetValueAtIndex(bundleIDs, i);
+					if (!isA_CFString(bundleID)) {
+						bundleID = CFSTR("--invalid-bundle-id--");
+					}
+					SCPrint(TRUE, stdout, CFSTR("%s%@"),
+						(i > 0) ? ", " : "",
+						bundleID);
+				}
+				SCPrint(TRUE, stdout, CFSTR(")"));
+			}
+
+			SCPrint(TRUE, stdout, CFSTR("\n"));
+		}
 	}
 
 	supported = SCNetworkInterfaceGetSupportedInterfaceTypes(interface);
@@ -713,8 +760,9 @@ _show_interface(SCNetworkInterfaceRef interface, CFStringRef prefix, Boolean sho
 	SCPrint(TRUE, stdout, CFSTR("\n"));
 
 	isPhysicalEthernet = _SCNetworkInterfaceIsPhysicalEthernet(interface);
-	SCPrint(TRUE, stdout, CFSTR("%@  is physical ethernet = %s \n"),
-		prefix, (isPhysicalEthernet == TRUE) ? "YES" : "NO");
+	SCPrint(TRUE, stdout, CFSTR("%@  is%s physical ethernet\n"),
+		prefix,
+		isPhysicalEthernet ? "" : " not");
 
 	if (configuration != NULL) {
 		CFMutableDictionaryRef	effective;
@@ -1070,6 +1118,81 @@ updateInterfaceConfiguration(CFMutableDictionaryRef newConfiguration)
 }
 
 
+#pragma mark -
+#pragma mark QoS Marking Policy options
+
+
+static options qosOptions[] = {
+	{ "enabled"   , NULL, isBool       , &kSCPropNetQoSMarkingEnabled                  , NULL, NULL },
+	{ "apple-av"  , NULL, isBool       , &kSCPropNetQoSMarkingAppleAudioVideoCalls     , NULL, NULL },
+	{ "bundle-ids", NULL, isStringArray, &kSCPropNetQoSMarkingWhitelistedAppIdentifiers, NULL, NULL },
+
+	{ "?"         , NULL, isHelp       , NULL                                          , NULL,
+	    "\nQoS marking policy commands\n\n"
+	    " set interface qos [enabled {yes|no}]\n"
+	    " set interface qos [apple-av {yes|no}]\n"
+	    " set interface qos [bundle-ids bundle-id[,bundle-id]]\n"
+	}
+};
+#define	N_QOS_OPTIONS	(sizeof(qosOptions) / sizeof(qosOptions[0]))
+
+
+static int
+__doQoSMarking(CFStringRef key, const char *description, void *info, int argc, char **argv, CFMutableDictionaryRef newConfiguration)
+{
+	CFStringRef		interfaceName;
+	CFMutableDictionaryRef	newPolicy;
+	Boolean			ok;
+	CFDictionaryRef		policy;
+
+	if (argc < 1) {
+		SCPrint(TRUE, stdout, CFSTR("set what?\n"));
+		return -1;
+	}
+
+	interfaceName = SCNetworkInterfaceGetBSDName(net_interface);
+	if (interfaceName == NULL) {
+		SCPrint(TRUE, stdout, CFSTR("no BSD interface\n"));
+		return -1;
+	}
+
+	policy = SCNetworkInterfaceGetQoSMarkingPolicy(net_interface);
+	if (policy != NULL) {
+		newPolicy = CFDictionaryCreateMutableCopy(NULL, 0, policy);
+		CFDictionaryRemoveValue(newPolicy, kSCResvInactive);
+	} else {
+		newPolicy = CFDictionaryCreateMutable(NULL,
+						      0,
+						      &kCFTypeDictionaryKeyCallBacks,
+						      &kCFTypeDictionaryValueCallBacks);
+	}
+
+	ok = _process_options(qosOptions, N_QOS_OPTIONS, argc, argv, newPolicy);
+	if (!ok) {
+		goto done;
+	}
+
+	if (((policy == NULL) && (CFDictionaryGetCount(newPolicy) > 0)) ||
+	    ((policy != NULL) && !CFEqual(policy, newPolicy))) {
+		if (!SCNetworkInterfaceSetQoSMarkingPolicy(net_interface, newPolicy)) {
+			if (SCError() == kSCStatusNoKey) {
+				SCPrint(TRUE, stdout, CFSTR("could not update per-interface QoS marking policy\n"));
+			} else {
+				SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
+			}
+			goto done;
+		}
+
+		_prefs_changed = TRUE;
+	}
+
+	done :
+
+	if (newPolicy != NULL) CFRelease(newPolicy);
+	return argc;
+}
+
+
 #pragma mark -
 #pragma mark Bond options
 
@@ -1080,8 +1203,8 @@ static options bondOptions[] = {
 	// xxx  { "-device"   , ... },
 
 	{ "?"         , NULL , isHelp     , NULL                            , NULL,
-		"\nBond configuration commands\n\n"
-		" set interface [mtu n] [media type] [mediaopts opts]\n"
+	     "\nBond configuration commands\n\n"
+	     " set interface [mtu n] [media type] [mediaopts opts]\n"
 	}
 };
 #define	N_BOND_OPTIONS	(sizeof(bondOptions) / sizeof(bondOptions[0]))
@@ -1163,9 +1286,13 @@ static options airportOptions[] = {
 
 	{ "rank"      , NULL, isOther      , NULL                            , __doRank, NULL },
 
+	{ "qos"       , NULL, isOther      , NULL                            , __doQoSMarking, NULL },
+
 	{ "?"         , NULL, isHelp       , NULL                            , NULL,
 	    "\nAirPort configuration commands\n\n"
 	    " set interface [mtu n] [media type] [mediaopts opts]\n"
+	    " set interface [rank [{First|Last|Never|Scoped}]]\n"
+	    " set interface [qos ]]\n"
 	}
 };
 #define	N_AIRPORT_OPTIONS	(sizeof(airportOptions) / sizeof(airportOptions[0]))
@@ -1243,9 +1370,9 @@ __doCapability(CFStringRef key, const char *description, void *info, int argc, c
 
 
 static options ethernetOptions[] = {
-	{ "mtu"       , NULL, isNumber     , &kSCPropNetEthernetMTU         , NULL, NULL },
-	{ "media"     , NULL, isString     , &kSCPropNetEthernetMediaSubType, NULL, NULL },
-	{ "mediaopt"  , NULL, isStringArray, &kSCPropNetEthernetMediaOptions, NULL, NULL },
+	{ "mtu"       , NULL, isNumber     , &kSCPropNetEthernetMTU             , NULL, NULL },
+	{ "media"     , NULL, isString     , &kSCPropNetEthernetMediaSubType    , NULL, NULL },
+	{ "mediaopt"  , NULL, isStringArray, &kSCPropNetEthernetMediaOptions    , NULL, NULL },
 
 	{ "av"        , NULL, isOther      , &kSCPropNetEthernetCapabilityAV    , __doCapability, NULL },
 	{ "lro"       , NULL, isOther      , &kSCPropNetEthernetCapabilityLRO   , __doCapability, NULL },
@@ -1253,11 +1380,15 @@ static options ethernetOptions[] = {
 	{ "tso"       , NULL, isOther      , &kSCPropNetEthernetCapabilityTSO   , __doCapability, NULL },
 	{ "txcsum"    , NULL, isOther      , &kSCPropNetEthernetCapabilityTXCSUM, __doCapability, NULL },
 
-	{ "rank"      , NULL, isOther      , NULL                            , __doRank, NULL },
+	{ "rank"      , NULL, isOther      , NULL                               , __doRank, NULL },
 
-	{ "?"         , NULL, isHelp       , NULL                            , NULL,
+	{ "qos"       , NULL, isOther      , NULL                               , __doQoSMarking, NULL },
+
+	{ "?"         , NULL, isHelp       , NULL                               , NULL,
 	    "\nEthernet configuration commands\n\n"
 	    " set interface [mtu n] [media type] [mediaopts opts]\n"
+	    " set interface [rank [{First|Last|Never|Scoped}]]\n"
+	    " set interface [qos []]\n"
 	}
 };
 #define	N_ETHERNET_OPTIONS	(sizeof(ethernetOptions) / sizeof(ethernetOptions[0]))
@@ -1580,9 +1711,9 @@ static options ipsecOnDemandOptions[] = {
 
 	{ "?"                          , NULL    , isHelp , NULL                                       , NULL               ,
 	    "\nOnDemandMatch configuration commands\n\n"
-	    " set interface OnDemandMatch always domain-name[,domain-name]\n"
-	    " set interface OnDemandMatch retry  domain-name[,domain-name]\n"
-	    " set interface OnDemandMatch never  domain-name[,domain-name]\n"
+	    " set interface OnDemandMatch [always domain-name[,domain-name]]\n"
+	    " set interface OnDemandMatch [retry  domain-name[,domain-name]]\n"
+	    " set interface OnDemandMatch [never  domain-name[,domain-name]]\n"
 	}
 };
 #define	N_IPSEC_ONDEMAND_OPTIONS	(sizeof(ipsecOnDemandOptions) / sizeof(ipsecOnDemandOptions[0]))
@@ -1643,18 +1774,18 @@ static options ipsecOptions[] = {
 	{ "OnDemandMatch"          , NULL, isOther      , NULL                                   , __doIPSecOnDemandMatch    , NULL },
 
 	{ "?"         , NULL , isHelp     , NULL                            , NULL,
-		"\nIPSec configuration commands\n\n"
-		" set interface [AuthenticationMethod {SharedSecret|Certificate|Hybrid}]\n"
-		" set interface [LocalIdentifier group]\n"
-		" set interface [LocalIdentifierType {KeyID}]\n"
-		" set interface [RemoteAddress name-or-address]\n"
-		" set interface [SharedSecret secret]\n"
-		" set interface [SharedSecretEncryption {Keychain}]\n"
-		" set interface [XAuthEnabled {enable|disable}]\n"
-		" set interface [XAuthPassword password]\n"
-		" set interface [XAuthPasswordEncryption {Keychain}]\n"
-		" set interface [OnDemandEnabled {enable|disable}]\n"
-		" set interface [OnDemandMatch ]\n"
+	    "\nIPSec configuration commands\n\n"
+	    " set interface [AuthenticationMethod {SharedSecret|Certificate|Hybrid}]\n"
+	    " set interface [LocalIdentifier group]\n"
+	    " set interface [LocalIdentifierType {KeyID}]\n"
+	    " set interface [RemoteAddress name-or-address]\n"
+	    " set interface [SharedSecret secret]\n"
+	    " set interface [SharedSecretEncryption {Keychain}]\n"
+	    " set interface [XAuthEnabled {enable|disable}]\n"
+	    " set interface [XAuthPassword password]\n"
+	    " set interface [XAuthPasswordEncryption {Keychain}]\n"
+	    " set interface [OnDemandEnabled {enable|disable}]\n"
+	    " set interface [OnDemandMatch ]\n"
 	}
 };
 #define	N_IPSEC_OPTIONS	(sizeof(ipsecOptions) / sizeof(ipsecOptions[0]))
@@ -1881,13 +2012,13 @@ __doPPPAuthPWType(CFStringRef key, const char *description, void *info, int argc
 
 
 static options l2tp_ipsecOptions[] = {
-	{ "SharedSecret"          , NULL, isOther      , &kSCPropNetIPSecSharedSecret          , __doIPSecSharedSecret    , NULL                                        },
-	{ "SharedSecretEncryption", NULL, isOther      , &kSCPropNetIPSecSharedSecretEncryption, __doIPSecSharedSecretType, NULL                                        },
+	{ "SharedSecret"          , NULL, isOther      , &kSCPropNetIPSecSharedSecret          , __doIPSecSharedSecret    , NULL },
+	{ "SharedSecretEncryption", NULL, isOther      , &kSCPropNetIPSecSharedSecretEncryption, __doIPSecSharedSecretType, NULL },
 
 	{ "?"         , NULL , isHelp     , NULL                            , NULL,
-		"\nIPSec configuration commands\n\n"
-		" set interface ipsec [SharedSecret secret]\n"
-		" set interface ipsec [SharedSecretEncryption {Keychain}]\n"
+	    "\nIPSec configuration commands\n\n"
+	    " set interface ipsec [SharedSecret secret]\n"
+	    " set interface ipsec [SharedSecretEncryption {Keychain}]\n"
 	}
 };
 #define	N_L2TP_IPSEC_OPTIONS	(sizeof(l2tp_ipsecOptions) / sizeof(l2tp_ipsecOptions[0]))
diff --git a/scutil.tproj/net_protocol.c b/scutil.tproj/net_protocol.c
index 7e8f004..a1b6f60 100644
--- a/scutil.tproj/net_protocol.c
+++ b/scutil.tproj/net_protocol.c
@@ -1594,7 +1594,7 @@ show_protocols(int argc, char **argv)
 			((net_protocol != NULL) && CFEqual(protocol, net_protocol)) ? '>' : ' ',
 			i + 1,
 			protocolType,
-			(int)(sizeof("AppleTalk") - CFStringGetLength(protocolType) - 1),
+			(int)(sizeof("Proxies") - CFStringGetLength(protocolType) - 1),
 			"");
 
 		if (SCNetworkProtocolGetEnabled(protocol)) {
diff --git a/scutil.tproj/net_service.c b/scutil.tproj/net_service.c
index 3d7d9dc..b17fa45 100644
--- a/scutil.tproj/net_service.c
+++ b/scutil.tproj/net_service.c
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2004-2010, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2010, 2013, 2014, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -670,8 +670,9 @@ set_service(int argc, char **argv)
 				return;
 			}
 		} else if (strcmp(command, "rank") == 0) {
-			SCNetworkServicePrimaryRank	rank	= kSCNetworkServicePrimaryRankDefault;
-			SCNetworkServiceRef		service	= (argc < 2) ? net_service : NULL;
+			SCNetworkServicePrimaryRank	rank		= kSCNetworkServicePrimaryRankDefault;
+			SCNetworkServiceRef		service		= (argc < 2) ? net_service : NULL;
+			Boolean				useActive	= FALSE;
 
 			if (argc < 1) {
 				SCPrint(TRUE, stdout, CFSTR("rank not specified\n"));
@@ -706,16 +707,19 @@ set_service(int argc, char **argv)
 				serviceID = SCNetworkServiceGetServiceID(net_service);
 				service = _SCNetworkServiceCopyActive(store, serviceID);
 				CFRelease(store);
+				useActive = TRUE;
 
 				argv++;
 				argc--;
 			}
 
 			ok = SCNetworkServiceSetPrimaryRank(service, rank);
-			if (service != net_service) CFRelease(service);
-			if (ok) {
-				if (service == net_service) _prefs_changed = TRUE;
-			} else {
+			if (useActive) {
+				CFRelease(service);
+			} else if (ok) {
+				_prefs_changed = TRUE;
+			}
+			if (!ok) {
 				SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
 				return;
 			}
diff --git a/scutil.tproj/net_set.c b/scutil.tproj/net_set.c
index fb4f0e8..8028abd 100644
--- a/scutil.tproj/net_set.c
+++ b/scutil.tproj/net_set.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2005, 2009-2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (c) 2004, 2005, 2009-2011, 2013-2015 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -534,6 +534,10 @@ set_set(int argc, char **argv)
 		} else {
 			SCPrint(TRUE, stdout, CFSTR("set what?\n"));
 		}
+
+		if (net_set == NULL) {
+			break;
+		}
 	}
 
 	return;
diff --git a/scutil.tproj/notifications.c b/scutil.tproj/notifications.c
index 0ccd02c..dbf6a09 100644
--- a/scutil.tproj/notifications.c
+++ b/scutil.tproj/notifications.c
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2000-2005, 2008-2014 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2005, 2008-2015 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@
  */
 
diff --git a/scutil.tproj/prefs.c b/scutil.tproj/prefs.c
index bd5c026..605cd2a 100644
--- a/scutil.tproj/prefs.c
+++ b/scutil.tproj/prefs.c
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2003-2008, 2011-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2008, 2011-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -28,21 +28,22 @@
  * - initial revision
  */
 
+#include 
 #include 
 #include 
 #include 
 #include 
-#include 
-
-#include 
-#if	!TARGET_OS_IPHONE
-#include 
-#endif	/* !TARGET_OS_IPHONE */
 
 #include "scutil.h"
 #include "commands.h"
 #include "prefs.h"
 
+#include "SCNetworkConfigurationInternal.h"
+
+#if	!TARGET_OS_IPHONE
+#include 
+#endif	/* !TARGET_OS_IPHONE */
+
 
 /* -------------------- */
 
@@ -50,22 +51,14 @@
 #if	!TARGET_OS_IPHONE
 static void *
 __loadSecurity(void) {
-	static void *image = NULL;
-	if (NULL == image) {
-		const char	*framework		= "/System/Library/Frameworks/Security.framework/Security";
-		struct stat	statbuf;
-		const char	*suffix			= getenv("DYLD_IMAGE_SUFFIX");
-		char		path[MAXPATHLEN];
-
-		strlcpy(path, framework, sizeof(path));
-		if (suffix) strlcat(path, suffix, sizeof(path));
-		if (0 <= stat(path, &statbuf)) {
-			image = dlopen(path, RTLD_LAZY | RTLD_LOCAL);
-		} else {
-			image = dlopen(framework, RTLD_LAZY | RTLD_LOCAL);
-		}
-	}
-	return (void *)image;
+	static void		*image	= NULL;
+	static dispatch_once_t	once;
+
+	dispatch_once(&once, ^{
+		image = _SC_dlopen("/System/Library/Frameworks/Security.framework/Security");
+	});
+
+	return image;
 }
 
 
@@ -566,12 +559,18 @@ do_getPref(char *pref, int argc, char **argv)
 		return;
 	}
 
-	// Add support to parse out extended get
+	// process extended get
 	// ie. scutil --get   
 	do_prefs_init();
+
 	do_prefs_open(argc, argv);
-	do_prefs_get(--argc, ++argv);
+	if (SCError() != kSCStatusOK) {
+		SCPrint(TRUE, stderr, CFSTR("%s\n"), SCErrorString(SCError()));
+		_prefs_close();
+		exit(1);
+	}
 
+	do_prefs_get(--argc, ++argv);
 	if (value != NULL) {
 		CFStringRef key;
 		CFStringRef prefs_val;
@@ -986,32 +985,38 @@ __private_extern__
 void
 do_log(char * log, int argc, char **argv)
 {
+	Boolean	verbose	= FALSE;
+
 	if (strcmp(log, "IPMonitor")) {
-	    exit(0);
+		exit(0);
 	}
+
 	if (argc == 0) {
-	    printf("IPMonitor log is %s\n",
-		   on_off_str(IPMonitorControlPrefsIsVerbose()));
+		SCPrint(TRUE, stdout, CFSTR("IPMonitor log is %s\n"),
+			on_off_str(IPMonitorControlPrefsIsVerbose()));
+		exit(0);
 	}
-	else {
-	    Boolean	verbose = FALSE;
 
-	    if (strcasecmp(argv[0], "on") == 0) {
-		verbose = TRUE;
-	    }
-	    else if (strcasecmp(argv[0], "off") == 0) {
+	if        ((strcasecmp(argv[0], "disable") == 0) ||
+		   (strcasecmp(argv[0], "no"     ) == 0) ||
+		   (strcasecmp(argv[0], "off"    ) == 0) ||
+		   (strcasecmp(argv[0], "0"      ) == 0)) {
 		verbose = FALSE;
-	    }
-	    else {
-		    fprintf(stderr, "%s invalid, must be 'on' or 'off'\n",
-			    argv[0]);
-		    exit(1);
-	    }
-	    if (IPMonitorControlPrefsSetVerbose(verbose) == FALSE) {
-		    fprintf(stderr, "failed to set preferences\n");
-		    exit(2);
-	    }
+	} else if ((strcasecmp(argv[0], "enable") == 0) ||
+		   (strcasecmp(argv[0], "yes"   ) == 0) ||
+		   (strcasecmp(argv[0], "on"   ) == 0) ||
+		   (strcasecmp(argv[0], "1"     ) == 0)) {
+		verbose = TRUE;
+	} else {
+		SCPrint(TRUE, stdout, CFSTR("invalid value, must be 'on' or 'off'\n"));
+		exit(1);
+	}
+
+	if (!IPMonitorControlPrefsSetVerbose(verbose)) {
+		SCPrint(TRUE, stderr, CFSTR("failed to set preferences\n"));
+		exit(2);
 	}
+
 	exit(0);
 	return;
 }
@@ -1047,7 +1052,7 @@ copy_configured_interface(SCPreferencesRef prefs, CFStringRef if_name)
 		SCNetworkServiceRef	s;
 
 		s = (SCNetworkServiceRef)CFArrayGetValueAtIndex(services, i);
-		if (SCNetworkServiceGetEnabled(s) == FALSE) {
+		if (!SCNetworkServiceGetEnabled(s)) {
 			/* skip disabled services */
 			continue;
 		}
@@ -1079,7 +1084,7 @@ copy_configured_interface(SCPreferencesRef prefs, CFStringRef if_name)
 static void
 disable_until_needed_usage(void)
 {
-	fprintf(stderr, "usage: scutil --disable-until-needed  [ on | off ]\n");
+	fprintf(stderr, "usage: scutil --disable-until-needed  [on|off|default]\n");
 	return;
 }
 
@@ -1092,32 +1097,31 @@ do_disable_until_needed(int argc, char **argv)
 	const char * 		if_name;
 	CFStringRef		if_name_cf;
 	SCNetworkInterfaceRef	net_if;
-	Boolean			on = FALSE;
+	Boolean			on		= FALSE;
+	const char *		on_off		= "?";
 	Boolean			ok;
-	Boolean			set_value;
+	Boolean			set_default	= FALSE;
+	Boolean			set_value	= FALSE;
 
 	if (argc < 1 || argc > 2) {
 		disable_until_needed_usage();
 		exit(1);
 	}
 	if_name = argv[0];
-	if (argc == 1) {
-		set_value = FALSE;
-	}
-	else {
-		const char *	on_off = argv[1];
-
-		set_value = TRUE;
+	if (argc > 1) {
+		on_off = argv[1];
 		if (strcasecmp(on_off, "on") == 0) {
 			on = TRUE;
-		}
-		else if (strcasecmp(on_off, "off") == 0) {
+		} else if (strcasecmp(on_off, "off") == 0) {
 			on = FALSE;
-		}
-		else {
+		} else if ((strcmp(on_off, "") == 0) || (strcasecmp(on_off, "default") == 0)) {
+			set_default = TRUE;
+			on_off = "default";
+		} else {
 			disable_until_needed_usage();
 			exit(1);
 		}
+		set_value = TRUE;
 	}
 	ok = _prefs_open(CFSTR("scutil --disable-until-needed"), NULL);
 	if (!ok) {
@@ -1137,14 +1141,18 @@ do_disable_until_needed(int argc, char **argv)
 		exit(1);
 	}
 	if (set_value) {
-		if (SCNetworkInterfaceSetDisableUntilNeeded(net_if, on) == FALSE) {
+		if (!set_default) {
+			ok = SCNetworkInterfaceSetDisableUntilNeeded(net_if, on);
+		} else {
+			ok = __SCNetworkInterfaceSetDisableUntilNeededValue(net_if, NULL);
+		}
+		if (!ok) {
 			fprintf(stderr, "failed to turn disable-until-needed %s\n",
-				on_off_str(on));
+				on_off);
 			exit(1);
 		}
 		_prefs_save();
-	}
-	else {
+	} else {
 		on = SCNetworkInterfaceGetDisableUntilNeeded(net_if);
 		printf("%s disable-until-needed is %s\n", if_name, on_off_str(on));
 	}
diff --git a/scutil.tproj/prefs.h b/scutil.tproj/prefs.h
index 5df667f..fcf3bcb 100644
--- a/scutil.tproj/prefs.h
+++ b/scutil.tproj/prefs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005-2007, 2012, 2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2003, 2005-2007, 2012, 2013, 2015, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -35,7 +35,7 @@
 #include 
 
 
-Boolean	_prefs_changed;
+extern Boolean	_prefs_changed;
 
 
 __BEGIN_DECLS
diff --git a/scutil.tproj/scutil.c b/scutil.tproj/scutil.c
index ea5c8d7..cb15a5a 100644
--- a/scutil.tproj/scutil.c
+++ b/scutil.tproj/scutil.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2014 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -69,10 +69,8 @@
 #include "session.h"
 #include "tests.h"
 
-
 #define LINE_LENGTH 2048
 
-
 __private_extern__ AuthorizationRef	authorization	= NULL;
 __private_extern__ InputRef		currentInput	= NULL;
 __private_extern__ Boolean		doDispatch	= FALSE;
@@ -191,7 +189,7 @@ getLine(char *buf, int len, InputRef src)
 		if (line == NULL)
 			return NULL;
 
-		strncpy(buf, line, len);
+		strlcpy(buf, line, len);
 	} else {
 		if (fgets(buf, len, src->fp) == NULL)
 			return NULL;
@@ -214,7 +212,6 @@ getLine(char *buf, int len, InputRef src)
 		history(src->h, &ev, H_ENTER, buf);
 	}
 
-
 	return buf;
 }
 
@@ -362,6 +359,10 @@ usage(const char *command)
 		SCPrint(TRUE, stderr, CFSTR("\n"));
 		SCPrint(TRUE, stderr, CFSTR("   or: %s --log IPMonitor [off|on]\n"), command);
 		SCPrint(TRUE, stderr, CFSTR("\tmanage logging.\n"));
+
+		SCPrint(TRUE, stderr, CFSTR("\n"));
+		SCPrint(TRUE, stderr, CFSTR("   or: %s --disable-until-needed  [on|off ]\n"), command);
+		SCPrint(TRUE, stderr, CFSTR("\tmanage secondary interface demand.\n"));
 	}
 
 	if (getenv("ENABLE_EXPERIMENTAL_SCUTIL_COMMANDS")) {
@@ -381,11 +382,11 @@ usage(const char *command)
 static char *
 prompt(EditLine *el)
 {
-#if	!TARGET_IPHONE_SIMULATOR
+#if	!TARGET_OS_SIMULATOR
 	return "> ";
-#else	// !TARGET_IPHONE_SIMULATOR
+#else	// !TARGET_OS_SIMULATOR
 	return "sim> ";
-#endif	// !TARGET_IPHONE_SIMULATOR
+#endif	// !TARGET_OS_SIMULATOR
 }
 
 
@@ -548,9 +549,9 @@ main(int argc, char * const argv[])
 
 	if (doSnap) {
 		if (!enablePrivateAPI
-#if	!TARGET_IPHONE_SIMULATOR
+#if	!TARGET_OS_SIMULATOR
 		    || (geteuid() != 0)
-#endif	// !TARGET_IPHONE_SIMULATOR
+#endif	// !TARGET_OS_SIMULATOR
 		   ) {
 			usage(prog);
 		}
@@ -573,15 +574,22 @@ main(int argc, char * const argv[])
 
 	/* are we looking up a preference value */
 	if (get) {
-		if (argc != 2) {
+		if (argc == 0) {
 			if (findPref(get) < 0) {
 				usage(prog);
 			}
-		} else {
-			/* need to go back one argument
-			 * for the filename */
+		} else if (argc == 2) {
+			/*
+			 * extended --get
+			 *   i.e. scutil --get   
+			 *
+			 * need to go back one argument to re-use the 1st "--get"
+			 * argument as the prefs path name
+			 */
 			argc++;
 			argv--;
+		} else {
+			usage(prog);
 		}
 
 		do_getPref(get, argc, (char **)argv);
diff --git a/scutil.tproj/scutil.h b/scutil.tproj/scutil.h
index 4c0d0b9..3de23a9 100644
--- a/scutil.tproj/scutil.h
+++ b/scutil.tproj/scutil.h
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2000-2005, 2009, 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2005, 2009, 2012, 2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -31,15 +31,16 @@
  * - initial revision
  */
 
-#ifndef _SC_H
-#define _SC_H
+#ifndef _SCUTIL_H
+#define _SCUTIL_H
 
 #include 
 #include 
 
+#define SC_LOG_HANDLE	_SC_LOG_DEFAULT()
 #include 
-#include 
 #include 
+#include 
 
 
 typedef struct {
@@ -65,9 +66,10 @@ extern CFMutableArrayRef	watchedPatterns;
 __BEGIN_DECLS
 
 Boolean		process_line		(InputRef	src);
+
 CFStringRef	_copyStringFromSTDIN	(CFStringRef	prompt,
 					 CFStringRef	defaultValue);
 
 __END_DECLS
 
-#endif /* !_SC_H */
+#endif /* !_SCUTIL_H */
diff --git a/scutil.tproj/tests.c b/scutil.tproj/tests.c
index a243962..b80f9a1 100644
--- a/scutil.tproj/tests.c
+++ b/scutil.tproj/tests.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2001, 2003-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -48,12 +48,12 @@
 #include 
 #include 
 
-#define my_log(__level, fmt, ...)	SCPrint(TRUE, stdout, CFSTR(fmt "\n"), ## __VA_ARGS__)
+#define	my_log(__level, __format, ...)	SCPrint(TRUE, stdout, CFSTR(__format "\n"), ## __VA_ARGS__)
 
 #include 
 #include "dnsinfo_internal.h"
 #include 
-#include "network_information_priv.h"
+#include "network_state_information_priv.h"
 #include "SCNetworkReachabilityInternal.h"
 #include 
 
@@ -714,7 +714,7 @@ do_watchNWI(int argc, char **argv)
 						  }
 					  });
 	if (status != NOTIFY_STATUS_OK) {
-		SC_log(LOG_INFO, "notify_register_dispatch() failed for nwi changes, status=%u", status);
+		SCPrint(TRUE, stderr, CFSTR("notify_register_dispatch() failed for nwi changes, status=%u\n"), status);
 		exit(1);
 	}
 
@@ -897,7 +897,7 @@ do_watchDNSConfiguration(int argc, char **argv)
 						  }
 					  });
 	if (status != NOTIFY_STATUS_OK) {
-		SC_log(LOG_INFO, "notify_register_dispatch() failed for DNS configuration changes, status=%u", status);
+		SCPrint(TRUE, stderr, CFSTR("notify_register_dispatch() failed for nwi changes, status=%u\n"), status);
 		exit(1);
 	}
 
@@ -929,20 +929,19 @@ __private_extern__
 void
 do_showProxyConfiguration(int argc, char **argv)
 {
-	CFMutableDictionaryRef	options = NULL;
 	CFDictionaryRef		proxies;
 
 	if (getenv("BYPASS_GLOBAL_PROXY") != NULL) {
+		CFMutableDictionaryRef	options ;
+
 		options = CFDictionaryCreateMutable(NULL, 0,
 						    &kCFTypeDictionaryKeyCallBacks,
 						    &kCFTypeDictionaryValueCallBacks);
 		CFDictionaryAddValue(options, kSCProxiesNoGlobal, kCFBooleanTrue);
-	}
-
-	proxies = SCDynamicStoreCopyProxiesWithOptions(NULL, options);
-
-	if (options != NULL) {
+		proxies = SCDynamicStoreCopyProxiesWithOptions(NULL, options);
 		CFRelease(options);
+	} else {
+		proxies = SCDynamicStoreCopyProxies(NULL);
 	}
 
 	if (proxies != NULL) {
-- 
2.45.2